00-Linux 基础

初探 Linux

Linux 简介

通过以下三点可以概括 Linux 到底是什么:

  • 类 Unix 系统:Linux 是一种自由、开放源码的类似 Unix 的操作系统。
  • Linux 本质是指 Linux 内核:严格来讲,Linux 这个词本身只表示 Linux 内核,单独的 Linux 内核并不能成为一个可以正常工作的操作系统。所以,就有了各种 Linux 发行版。
  • Linux 之父(林纳斯·本纳第克特·托瓦兹 Linus Benedict Torvalds):一个编程领域的传奇式人物,真大佬!我辈崇拜敬仰之楷模。他是 Linux 内核 的最早作者,随后发起了这个开源项目,担任 Linux 内核的首要架构师。他还发起了 Git 这个开源项目,并为主要的开发者。

Linux 之父

Unix 和 Linux 有什么区别

Linux 和 Unix 都是功能强大的操作系统,都是应用广泛的服务器操作系统,有很多相似之处,甚至有一部分人认为 Unix 和 Linux 操作系统是一样的,然而,事实并非如此,以下是两者的区别:

  1. 开源性。Linux 是一款开源操作系统,不需要付费,即可使用;Unix 是一款对源码实行知识产权保护的传统商业软件,使用需要付费授权使用。
  2. 跨平台性。Linux 操作系统具有良好的跨平台性能,可运行在多种硬件平台上;Unix 操作系统跨平台性能较弱,大多需与硬件配套使用。
  3. 可视化界面。Linux 除了进行命令行操作,还有窗体管理系统;Unix 只是命令行下的系统。
  4. 硬件环境。Linux 操作系统对硬件的要求较低,安装方法更易掌握;Unix 对硬件要求比较苛刻,按照难度较大。
  5. 用户群体。Linux 的用户群体很广泛,个人和企业均可使用;Unix 的用户群体比较窄,多是安全性要求高的大型企业使用,如银行、电信部门等,或者 Unix 硬件厂商使用,如 Sun 等。
    相比于 Unix 操作系统,Linux 操作系统更受广大计算机爱好者的喜爱,主要原因是 Linux 操作系统具有 Unix 操作系统的全部功能,并且能够在普通 PC 计算机上实现全部的 Unix 特性,开源免费的特性,更容易普及使用!

Linux 诞生

1989 年,Linus Torvalds 进入芬兰陆军新地区旅,服 11 个月的国家义务兵役,军衔为少尉,主要服务于计算机部门,任务是弹道计算。服役期间,购买了安德鲁·斯图尔特·塔能鲍姆所著的教科书及 minix 源代码,开始研究操作系统。1990 年,他退伍后回到大学,开始接触 Unix。

Minix 是一个迷你版本的类 Unix 操作系统,由塔能鲍姆教授为了教学之用而创作,采用微核心设计。它启发了 Linux 内核的创作。

1991 年,Linus Torvalds 开源了 Linux 内核。Linux 以一只可爱的企鹅作为标志,象征着敢作敢为、热爱生活。

OPINION: Make the switch to a Linux operating system | Opinion ...

什么是 Linux 内核

Linus Torvalds 开源的只是 Linux 内核,我们上面也提到了操作系统内核的作用。一些组织或厂商将 Linux 内核与各种软件和文档包装起来,并提供系统安装界面和系统配置、设定与管理工具,就构成了 Linux 的发行版本。

内核主要负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。

常见的 Linux 发行版本

Linux 的发行版本可以大体分为两类:

  • 商业公司维护的发行版本:比如 Red Hat 公司维护支持的 Red Hat Enterprise Linux (RHEL)。
  • 社区组织维护的发行版本:比如基于 Red Hat Enterprise Linux(RHEL)的 CentOS、基于 Debian 的 Ubuntu。

对于初学者学习 Linux,推荐选择 CentOS,原因如下:

  • CentOS 免费且开放源代码。
  • CentOS 基于 RHEL,功能与 RHEL 高度一致,安全稳定、性能优秀。

Linux 的基本组件是什么

就像任何其他典型的操作系统一样,Linux 拥有所有这些组件:内核、shell 和 GUI、系统实用程序和应用程序。Linux 比其他操作系统更具优势的是每个方面都附带其他功能,所有代码都可以免费下载。

Linux 的体系结构

从大的方面讲,Linux 体系结构可以分为两块:

  • 用户空间(User Space):用户空间又包括用户的应用程序(User Applications)、C 库(C Library) 。
  • 内核空间(Kernel Space):内核空间又包括系统调用接口(System Call Interface)、内核(Kernel)、平台架构相关的代码(Architecture-Dependent Kernel Code)。

什么是 LILO

LILO 是 Linux 的引导加载程序。它主要用于将 Linux 操作系统加载到主内存中,以便它可以开始运行。

什么是 CLI、GUI

  • 命令行界面(command-line interface,CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。也有人称之为字符用户界面(CUI)。
    命令行界面(CLI)没有图形用户界面(GUI)那么方便用户操作。因为,命令行界面的软件通常需要用户记忆操作的命令,但是,由于其本身的特点,命令行界面要较图形用户界面节约计算机系统的资源。在熟记命令的前提下,使用命令行界面往往要较使用图形用户界面的操作速度要快。所以,图形用户界面的操作系统中,都保留着可选的命令行界面。

  • 图形用户界面(Graphical User Interface,GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。
    图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。与通过键盘输入文本或字符命令来完成例行任务的字符界面相比,图形用户界面有许多优点。

Linux 开机启动过程?(了解即可)

  1. 主机加电自检,加载 BIOS 硬件信息。
  2. 读取 MBR 的引导文件(GRUB、LILO)。
  3. 引导 Linux 内核。
  4. 运行第一个进程 init (进程号永远为1)。
  5. 进入相应的运行级别。
  6. 运行终端,输入用户名和密码。

Linux 系统缺省的运行级别

  • 0:关机。
  • 1:单机用户模式。
  • 2:字符界面的多用户模式(不支持网络)。
  • 3:字符界面的多用户模式。
  • 4:未分配使用。
  • 5:图形界面的多用户模式。
  • 6:重启。

Linux 线程和进程

Linux 调度程序是根据进程的动态优先级还是静态优先级来调度进程的?

Liunx 调度程序是根据根据进程的动态优先级来调度进程的,但是动态优先级又是根据静态优先级根据算法计算出来的,两者是两个相关联的值。
因为高优先级的进程总是比低优先级的进程先被调度,为防止多个高优先级的进程占用 CPU 资源,导致其他进程不能占有 CPU,所以引用动态优先级概念。

Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?

  • 运行状态(R)或就绪状态:进程在运行中或者进程在运行队列里,在 run_queue 队列里的状态。
  • 可中断睡眠状态(S):其状态标志位为 TASK_INTERRUPTIBLE。处于这个状态的进程因为等待某事件的发生(比如等待 socket 连接、等待信号量),而被挂起。
    可中断的睡眠状态的进程会睡眠直到某个条件变为真,如产生一个硬件中断、释放进程正在等待的系统资源或是传递一个信号都可以是唤醒进程的条件。
  • 不可中断状态(D):其状态标志位为 TASK_UNINTERRUPTIBLE。不可中断睡眠状态与可中断睡眠状态类似,但是它有一个例外,那就是把信号传递到这种睡眠状态的进程不能改变它的状态,也就是说 它不响应信号的唤醒(如:kill 函数发出的信号)。
  • 暂停状态/跟踪状态(T):向进程发送一个 SIGSTOP 信号,它就会因响应该信号而进入 TASK_STOPPED 状态。当进程正在被跟踪时,它处于 TASK_TRACED 这个特殊的状态。“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。
  • zombie(僵尸)状态(Z):一个进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait 或 waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
    僵尸进程会以终止状态保持在进程表中,并且一直等待父进程读取状态退出代码。所以,只要子进程退出,父进程还在运行,但是父进程没有读取子进程状态,子进程进入Z状态。
  • 退出状态(X):一个进程退出且被检测好回收后,就是 X 状态。

什么是守护进程

守护进程是提供基本操作系统下可能无法使用的多种功能的服务。其主要任务是监听服务请求,同时对这些请求采取行动。服务完成后,它将断开连接并等待进一步的请求。

守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。

守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。

Linux 的大多数服务器就是用守护进程实现的。比如,Internet 服务器 inetd,Web 服务器 httpd 等。

一般情况下,守护进程可以通过以下方式启动:

  • 在系统启动时由启动脚本启动,这些启动脚本通常放在 /etc/rc.d 目录下;
  • 利用 inetd 超级服务器启动,如 telnet 等;
  • 由 cron 定时启动以及在终端用 nohup 启动的进程也是守护进程。

Linux 内存

内存溢出和内存泄露 ★★★

  • 内存溢出:(out of memory)通俗理解就是内存不够,指程序要求的内存超出了系统所能分配的范围,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。
    比如申请一个 int 类型,但给了它一个 bigint 才能存放的数,就会出现内存溢出,或者是创建一个大的对象,而堆内存放不下这个对象,这也是内存溢出。

  • 内存泄漏:(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

因此,我们从上面也可以推断出内存泄露可能会导致内存溢出。

二者的关系:内存溢出会抛出异常,内存泄露不会抛出异常,大多数时候程序看起来是正常运行的

什么是交换空间?

交换空间是 Linux 使用的一定空间,用于临时保存一些并发运行的程序。当 RAM 没有足够的内存来容纳正在执行的所有程序时,就会发生这种情况。

硬中断和软中断

  1. 硬中断:由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断。我们通常所说的中断指的是硬中断(hardirq)。

  2. 软中断:为了满足实时系统的要求,中断处理应该是越快越好。Linux 为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。

硬中断和软中断的区别

  1. 软中断是执行中断指令产生的,而硬中断是由外设引发的。
  2. 硬中断的中断号是由中断控制器提供的,软中断的中断号由指令直接指出,无需使用中断控制器。
  3. 硬中断是可屏蔽的,软中断不可屏蔽。
  4. 硬中断处理程序要确保它能快速地完成任务,这样程序执行时才不会等待较长时间,称为上半部。
  5. 软中断处理硬中断未完成的工作,是一种推后执行的机制,属于下半部。

Linux 环境变量

在 Linux 系统中,环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的主目录(HOME)。

环境变量分类

按照作用域来分,环境变量可以简单的分成:

  • 用户级别环境变量 : ~/.bashrc~/.bash_profile
  • 系统级别环境变量 : /etc/bashrc/etc/environment/etc/profile/etc/profile.d

上述配置文件执行先后顺序为:/etc/environment –> /etc/profile –> /etc/profile.d –> ~/.bash_profile –> /etc/bashrc –> ~/.bashrc

如果要修改系统级别环境变量文件,需要管理员具备对该文件的写入权限。

建议用户级别环境变量在 ~/.bash_profile 中配置,系统级别环境变量在 /etc/profile.d 中配置。

按照生命周期来分,环境变量可以简单的分成:

  • 永久的:需要用户修改相关的配置文件,变量永久生效。
  • 临时的:用户利用 export 命令,在当前终端下声明环境变量,关闭 shell 终端失效。

读取环境变量

通过 export 命令可以输出当前系统定义的所有环境变量。

1
2
# 列出当前的环境变量值
export -p

除了 export 命令之外,env 命令也可以列出所有环境变量。

echo 命令可以输出指定环境变量的值。

1
2
3
4
# 输出当前的 PATH 环境变量的值
echo $PATH
# 输出当前的HOME环境变量的值
echo $HOME

环境变量修改

通过 export 命令可以修改指定的环境变量。不过,这种方式修改环境变量仅仅对当前 shell 终端生效,关闭 shell 终端就会失效。修改完成之后,立即生效。

1
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

通过 vim 命令修改环境变量配置文件。这种方式修改环境变量永久有效。

1
vim ~/.bash_profile

如果修改的是系统级别环境变量则对所有用户生效,如果修改的是用户级别环境变量则仅对当前用户生效。

修改完成之后,需要 source 命令让其生效或者关闭 shell 终端重新登录。

1
source /etc/profile

CPU 负载和 CPU 利用率

CPU 负载和 CPU 利用率的区别 ★★★

  • CPU 利用率:显示的是程序在运行期间实时占用的 CPU 百分比。即 CPU 使用率 = CPU 时间片被程序使用的时间 / 总时间。比如 A 进程占用 10ms,然后 B 进程占用 30ms,然后空闲 60ms,再又是 A 进程占 10ms,B 进程占 30ms,空闲 60ms,如果在一段时间内都是如此,那么这段时间内的 CPU 占用率为 40%。CPU 利用率显示的是程序在运行期间实时占用的 CPU 百分比。
    CPU 利用率在 80% 左右是最优的。

  • CPU 负载:显示的是一段时间内 正在使用和等待使用 CPU 的平均任务数。CPU 利用率高,并不意味着负载就一定大。举例来说:如果我有一个程序它需要一直使用 CPU 的运算功能,那么此时 CPU 的使用率可能达到 100%,但是 CPU 的工作负载则是趋近于“1”,因为 CPU 仅负责一个工作嘛!如果同时执行这样的程序两个呢?CPU 的使用率还是100%,但是工作负载则变成 2 了。所以也就是说,当 CPU 的工作负载越大,代表 CPU 必须要在不同的工作之间进行频繁的工作切换。
    个人比较赞同 CPU 负载小于等于 0.5 算是一种理想状态。

如果 CPU 负载很高,利用率却很低该怎么办

CPU 负载很高,利用率却很低,说明处于等待状态的任务很多,负载越高,代表可能很多僵死的进程。通常这种情况是 IO 密集型的任务,大量任务在请求相同的 IO,导致任务队列堆积。

生产环境造成 CPU 利用率低负载高的具体场景常见的有如下几种。

  • 场景一:磁盘读写请求过多就会导致大量 I/O 等待。
    进程在 CPU 上面运行需要访问磁盘文件,这个时候 CPU 会向内核发起调用文件的请求,让内核去磁盘取文件,这个时候 CPU 会切换到其他进程或者空闲,这个任务就会转换为不可中断睡眠状态。当这种读写请求过多就会导致不可中断睡眠状态的进程过多,从而导致负载高,CPU 低的情况。

  • 场景二:MySQL 中存在没有索引的语句或存在死锁等情况。
    我们知道 MySQL 的数据是存储在硬盘中,如果需要进行 SQL 查询,需要先把数据从磁盘加载到内存中。当数据特别大的时候,如果执行的 SQL 语句没有索引,就会造成扫描表的行数过大导致 I/O 阻塞,或者是语句中存在死锁,也会造成 I/O 阻塞,从而导致不可中断睡眠进程过多,导致负载过大。

可以先通过 top 命令观察,假设发现确实是高负载低使用率。

然后,再通过命令 ps -aux 查看是否存在状态为 D 的进程,这个状态指的就是不可中断的睡眠状态的进程。处于这个状态的进程无法终止,也无法自行退出,只能通过恢复其依赖的资源或者重启系统来解决。

如果 CPU 负载很低,利用率却很高该怎么办

这表示 CPU 的任务并不多,但是任务执行的时间很长,大概率就是你写的代码本身有问题,通常是计算密集型任务,生成了大量耗时短的计算任务。

怎么排查?直接 top 命令找到 CPU 使用率最高的进程,定位到去看看就行了。如果代码没有问题,那么过段时间 CPU 使用率就会下降的。

如何来降低服务器的 CPU 负载

最简单办法的是更换性能更好的服务器,不要想着仅仅提高 CPU 的性能,那没有用,CPU 要发挥出它最好的性能还需要其它软硬件的配合。

在服务器其它方面配置合理的情况下,CPU 数量和 CPU 核心数(即内核数)都会影响到 CPU 负载,因为任务最终是要分配到 CPU 核心去处理的。两块 CPU 要比一块 CPU 好,双核要比单核好。

因此,我们需要记住,除去 CPU 性能上的差异,CPU 负载是基于内核数来计算的!有一个说法,“有多少内核,即有多少负载”。

服务占用 cpu 100%,如何排查问题? ★★★

  1. 执行 top。
    命令:查看所有进程占系统 CPU 的排序。极大可能排第一个的就是咱们的 Java 进程(COMMAND列)。PID 那一列就是进程号。

  2. 执行 top -Hp 进程号
    命令:查看 Java 进程下的所有线程占 CPU 的情况。

  3. 执行 printf "%x\n" 10

    命令:后续查看线程堆栈信息展示的都是十六进制,为了找到咱们的线程堆栈信息,咱们需要把线程号转成 16 进制。例如 printf "%x\n" 10 打印:a,那么在 jstack 中线程号就是 0xa.

确定占用 CPU 高的进程是不是自己的进程

  • 如果不是自己的进程,和进程所有者协商,看是不是能 kill 掉这个进程
  • 如果是自己的进程,那么一般会有这几种情况:代码里面有复杂的算法、加密、解密、正则匹配、压缩、解压缩、BUG、死循环等,可以借助监控工具看一下 cpu 正在执行哪些函数,像 jprofilerArthas 等工具

IO 密集型和 CPU 密集型 ★★★

CPU 密集型(CPU-bound)和 IO 密集型(IO-bound)是两种常见的计算密集型和 IO 操作密集型任务类型

  1. CPU 密集型任务:

    • CPU 密集型任务是指在执行过程中主要依赖于 CPU 处理能力的任务。
    • 这类任务通常涉及大量的计算、逻辑判断、数据处理等操作。
    • 例如:科学计算、图像处理、加密解密、复杂的算法、正则匹配、压缩、解压缩、BUG、死循环、视频编码解码、数据处理、科学计算。
    • 在 CPU 密集型任务中,CPU 的处理能力是主要瓶颈,而 IO 操作相对较少。
  2. IO 密集型任务:

    • IO 密集型任务是指在执行过程中主要依赖于 IO 操作(如磁盘读写、网络通信)的任务。
    • 这类任务通常涉及大量的读取和写入操作,而 CPU 的计算需求相对较少。
    • 例如,文件操作、数据库查询、网络爬虫。
    • 在 IO 密集型任务中,IO 操作的速度和效率是主要瓶颈,而 CPU 的处理能力往往有闲置。

实战

如何选择 Linux 操作系统版本

一般来讲,桌面用户首选 Ubuntu,服务器首选 CentOS,次选 RHEL。

根据具体要求:

  • 安全性要求较高,则选择 Debian 或者 FreeBSD。
  • 需要使用数据库高级服务和电子邮件网络应用的用户可以选择 SUSE。
  • 想要新技术新功能可以选择 Feddora ,Feddora 是 RHEL 和 CentOS 的一个测试版和预发布版本。
  • 【重点】根据现有状况,绝大多数互联网公司选择 CentOS。现在比较常用的是 6、7 系列,现在市场占有大概一半左右。另外的原因是 CentOS 更侧重服务器领域,并且无版权约束。

如何规划一台 Linux 主机,步骤是怎样?

  1. 确定机器是做什么用的,比如是做 WEB、DB、还是游戏服务器。不同的用途,机器的配置会有所不同。
  2. 确定好之后,就要定系统需要怎么安装,默认安装哪些系统、分区怎么做。
  3. 需要优化系统的哪些参数,需要创建哪些用户等等的。

00-Linux 基础
https://flepeng.github.io/interview-02-Linux-00-Linux-基础/
作者
Lepeng
发布于
2020年8月8日
许可协议