为了今天讲课我特意搞了这份讲义,以为待会车速太快没办法平稳停车。

我是在2005年,那年我读初中二年级,在学校发读信息技术教科书上看到Linux这个词的。我知道大部分初高中同学在拿到信息技术这类教材的时候都是直接塞桌底的。高中Linux用得少,没什么机会搞事情。到了高三毕业的时候,好友给我一个上网本,他自己安装的Linux系统。别以为是什么好事情,这货自己把上网本搞出问题来,让我帮忙修来着,我修不了,顺带手自己在U盘里搞了一个Linux,然后从U盘启动,他电脑硬件没坏。到了大学,大一大二我都是用Ubuntu,刚开始来大一的时候还是用雨林木风的,大三的时候用Slackware,大四用FreeBSD,现在滚到macOS了。但是就是觉得用Linux很爽,写代码在命令行下编译,不用纠结用那个IDE环境,各个IDE环境的界面还不一样,尤其是编译运行调试的快捷键都不一样,搞得我差不多需要写个纸条贴在屏幕边上告诉我哪个快捷键是哪个IDE下编译的快捷键。大一下学期我就在蓄谋我们学校OJ的事情了。当时还是在自己笔记本电脑上安装环境,然后在上面导入一些大佬分享出来的题目数据。这样我回家的时候就能正常刷题了。理解一下山区孩子没网但要刷题的迫切需要。

大二下学期,我刚好加入了学校信安实践工作室,那里刚好有一台指导老师用的服务器,于是我跟老师申请在上面安装学校OJ,于是就有了JustOJ v0.1. 后来折腾服务器,多次把老师的服务器搞崩,导致老师上课的学生无法正常提交作业。但是服务器崩了,老师自己又修复不了,只能让我来,所以老师也不好说我什么。

本科毕业以后,当时正好学校把信息学院从原来的学院楼搬到了新的学院楼,服务器被停了。后来我找到学院老师,又把服务器恢复起来了。当时还申请了22,80端口的,后来学校又把端口给封了。导致现在学校OJ这个样子了。只能内网访问。今年我争取把OJ对公网端口给申请下来。

0x00 什么是Linux

Linux内核最初只是由芬兰人李纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的。

Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。

Linux能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

0x01 Linux发行版

Linux的发行版说简单点就是将Linux内核与应用软件做一个打包。

Linux有很多发行版,发行版之间大同小异。就跟现在的Android智能手机一样,大家用的都是Google家的Android系统,然后自己再定制一下,于是就有了MiUI,Flyme,锤子系统等。那么在Linux下发行版就有很多了,国外比较出名的有Ubuntu、RedHat、CentOS、Debian、openSUSE、Slackware等。国内也有做得比较好的,比如早期,大概是2011年的时候有雨林木风还是不错的,目前国内比较不错的就算deepin了。

0x02 Linux和ACM-ICPC

在ACM-ICPC正式比赛的现场赛,所有赛点提供给选手使用的电脑上都只安装Ubuntu系统。所以ACM选手或多或少都需要了解Linux并学会简单使用。

现场赛提供的环境大致如下:

操作系统:Ubuntu 14.04 LTS 64-bit
判题系统:PC^2 9.2.4
支持语言:C/C++ 4.8.2, Java 1.7.0_65
提供的IDE:Code::Blocks 13.12 / Eclipse JDT & CDT 3.8.1 / Netbeans 7.0.1
(这是我最后一场比赛上海赛区提供的比赛环境。)

0x03 Linux基本使用

桌面环境的话,大致上跟大家使用手机使用电脑都没有什么太大差别,都是哪里不会点哪里。在座的各位,你们在第一次使用手机之前应该没有谁是会去看操作手册/使用说明书的吧。

0x04 Linux命令行

在大部分人看来,会玩Linux的都是不需要鼠标的,一个命令行窗口一顿噼里啪啦乱敲,然后屏幕上一堆代码闪过,然后远看对面政府大楼就停电了。

无参数命令

ls / ps / ll / top / htop / date / ifconfig / history

带参数命令

Linux下命令基本上都是带参数的。Linux环境下的命令大致上和编程的时候的函数/方法差不多一个意思。都是完成某种功能。函数也有参数,比如 int sum (int a, int b)表示将两个数字进行加和,int max(int a, int b)表示比较两个数字,并返回其中较大的数字。

cd

cp

echo

ping

ps -ef

ls -l

ls -Slh

ls -a

Ubuntu常用的软件命令

应用管理命令apt/apt-get,用来安装软件的。

apt-get install clisp
apt-get remove clisp

0x05 Linux命令原理

在0x04中我们讲解了Linux下常用命令的使用。我们首先了解了一些不带参数的命令,一下可以加参数的命令。而Linux中的命令都是一些程序,基本上在/bin、/usr/bin、/usr/sbin等目录中可以看到。在这些目录下的文件都是可执行文件(这里稍微解释一下,Linux下的文件基本上可执行文件是不需要后缀名的,这点和Windows程序不同,因为Windows可执行文件大都都是.exe后缀)。

接下来我将带领大家写一个简单的Linux命令。

/**
 * file name : addsum.cpp
 * description : Add numbers
 * author : ismdeep
 */

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int string_2_int (string str) {
    stringstream ss;
    ss << str << endl;
    int ans;
    ss >> ans;
    return ans;
}

int main(int argc, char const *argv[]) {
    int sum = 0;
    for (int i = 1; i < argc; ++i) {
        sum += string_2_int ( argv[i] );
    }
    cout << sum << endl;
    return 0;
}

在这个程序中,程序的main函数跟我们之前写题目的时候的main函数似乎有一些不同。这个地方是用来接收程序在启动时传入的参数。

在执行这个程序的时候我们就可以加上参数了。

addsum 1 2 3 4 5 6 7 8

输出的结果是36

再来讲讲命令组合吧

命令组合就是将几个命令结合起来使用并实现强大的功能。在Linux下,程序尽可能小,用途单一。然后将程序连接起来,共同完成复杂功能。比如你需要判断一堆数字加起来的和是否是偶数。这个时候你可以使用两个程序来完成,一个程序把这些数字进行加和,一个数字用来判断某数字是否为偶数。

echo 12 3 4 5 6 | addsum | is_even

bash脚本

bash脚本就是将很多Linux上面的命令组合在一个文件中,然后按顺序执行。

如何执行远程服务器上的bash脚本

0x06 ACM-ICPC在需要用到的命令

gcc/g++

这两个命令是分别用来编译C代码和C++代码的。后面使用的参数格式是一样的。常用的参数有:-g -W -D -o
-g 表示开启gdb调试信息,通过-g编译出来的exe文件会带上调试信息,可以使用gdb对生成的可执行文件进行调试。
-W 表示编译过程中提示那些错误信息,强迫症患者一般开启所有,也就是-Wall
-D 表示编译时带入的宏定义,比如编译的时候使用-DLOCALTEST
-o 表示输出文件到哪里,所以-o后面还需要加一个文件名。

如下代码:

#include <iostream>
using namespace std;

int main() {
    int a, b;
    while (scanf("%d%d", &a, &b) != EOF) {
        #ifdef LOCALTEST
        printf("The a and b you have just inputed are : %d and %d\n", a, b);
        #endif
        printf("%d\n", a + b);
    }
    return 0;
}

编译指令

g++ -g -Wall -DLOCALTEST main.cpp -o main

运行命令:

echo 1 2 | ./main

输出

ismdeep@MacBookPro: ~/Desktop
 $ echo 1 2 | ./main
The a and b you have just inputed are : 1 and 2
3

java

java就没有什么好说的了,在ACM-ICPC中java代码文件都必须是Main.java,自然类名也需要是Main了。编译命令也就是

javac Main.java

运行命令:

java Main

time命令

time ./main < in.txt > out.txt

接下来讲讲ACM刷题流程吧

以杭电上 http://acm.hdu.edu.cn/showproblem.php?pid=5585 为例

输入输出不需要等输入全部结束然后最后才来输出。

推荐一个网站

很多同学的电脑上都是没有安装Linux的,下面推荐大家一个网站:https://coding.net

有时候如果突然想写一个题目,自己电脑或者在网吧清流的时候,又没有好的环境。而且虽然Windows上可以使用MinGW,但是有时候自己还是倾向用纯正的UNIX/Linux环境。

在coding.net上注册账号之后,可以找到这网站的IDE功能。网址:https://ide.coding.net