在《《对线面试官》| 高频 Linux 面试题 Part1》一文中,给大家分享了一些在校招面试中常见的 Linux 面试题
闲话少说,接着给大家分享干货!
Linux 操作系统的核心是内核 Kernel
内核是 Linux 操作系统的关键组件,它借助进程间的通信和系统调用,管理着系统上的所有软硬件,充当软件和硬件之间的桥梁角色
内核的任务:
总结:内核是硬件与软件之间的一个中间层,当软件(应用程序)需要去操作底层硬件时,需要通过内核来实现。例如你想播放一首歌曲,则播放程序就会去向内核发起请求,内核则会去调用音箱播放歌曲(对于应用程序来说它是不知道底层硬件的,它的认知最底层就是内核)
PS:进程三种状态的切换
处于就绪态的进程,当进程调度程序为其分配了一个CPU后,该进程便由就绪态转为执行态
处于执行状态的进程在执行过程中,因分配的时间片用完而不得已让出 CPU,便由执行态转
变成就绪态
处在执行态的进程因等待某个事情发生而无法继续执行时,便由执行态转变成阻塞态
处于阻塞态的进程,如果等待的事件已经发生,便由阻塞态转变成就绪态
grep -Ev "^#|^$" file
^#:以#开头,即注释
^$:空行
通过 lsof 命令,在 Linux 中一切皆文件,通过 lsof 命令我们可以知道所有被进程打开的文件
举个例子:有一个文件一直被某个进程打开写入导致你删除不了这个文件,你就可以使用 lsof 命令找到是哪个进程占用文件,再将进程 kill 掉就能删掉文件了
僵尸进程:
当子进程比父进程先结束,而父进程又没有回收子进程、释放子进程占用的资源,此时子进程就会变成僵尸进程
即僵尸进程是一个早已死亡的进程,但在进程表中仍占据一个位置
孤儿进程:
如果父进程先结束,子进程就会变成孤儿进程,会被 init 进程接管,子进程结束后其占用资源就会被 init 进程回收
为了避免孤儿进程退出时所占资源无法被回收而变成僵尸进程,init 进程会接管这些孤儿进程,被Init接管的所有进程都不会变成僵尸进程
使用 stat 命令,可以查看到文件的详细信息
使用 md5sum——计算检验 MD5 校验码
md5sum命令采用MD5报文摘要算法(128位)计算和检查文件的校验和
有 A.txt 和 B.txt 两份文件,可以通过 MD5sum A.txt B.txt 命令来比较这两个文件内容是否相同
/etc/reslove.conf
分时日月周
系统负载表示处在可执行状态和不可中断睡眠状态的进程数量
CPU使用率是指在单位时间内CPU处在非空闲态的时间比,反映了CPU的繁忙程度
比如说:比如说单核CPU一秒内处在非空闲态的时间为0.6秒,那么它的CPU使用率就是60%
而双核CPU一秒内处在非空闲态的时间分别为0.6s和0.4s,那么它的CPU使用率为(0.4+0.6)/ 2 * 100% = 50%
举个例子:
比如说有一家银行,只有一个业务窗口,每次只能接待一个人(单核CPU)
这一天,有五个人要来办理业务,由于只有一个窗口,就会出现一人办理另外四人等待的情况(平负载为5)
在业务窗口那个人只有真正办理业务才算是真正使用这个窗口,才意味着窗口正在忙碌(CPU使用率)
总结:
先来了解下什么是 CPU 上下文
Linux是一个多任务操作系统,它支持远大于CPU数量的任务同时运行,但这些任务并不是真正在同时运行,而是系统在很短时间内将CPU轮流分配给它们,造成了多任务同时进行的错觉(宏观上并发)
比如说B任务在就绪队列等待CPU执行完A任务后执行它,那么CPU就需要知道任务从哪里加载,从哪里开始执行,这些都是系统事先帮它设置好CPU寄存器和程序计数器,即 CPU 上下文
CPU上下文切换
CPU上下文切换就是先把前一个任务(A任务)的CPU上下文(也就是 CPU 寄存器和程序计数器)保存起来然后加载新任务(B任务)的上下文到CPU寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务而保存起来的上下文,会存储在系统内核中,当该任务重新调度执行时会再次加载进来,从而保证任务原来状态不受影响
进程是无法之间访问物理内存的,只有内核才可以访问物理内存
Linux 内核给每个进程都提供了一个独立的连续的虚拟地址空间,通过这个空间进程就可以访问到虚拟内存,而这个虚拟地址空间又被分为内核空间和用户空间
进程在用户态时能访问用户地址空间,在内核态可以访问内核地址空间
每个进程的内核空间内存关联的都是相同的物理内存,方便进程切换到内核态后访问
不是所有的虚拟内存都会被分配到物理内存的,只有那些实际使用的虚拟内存才被分配物理内存,并且通过内存映射来管理
内存映射:虚拟内存地址映射到物理内存地址为了完成内存映射,内核为每个进程都维护了一张页表,记录虚拟地址与物理地址的映射关系
先来看下 Linux 的两个函数——fork() 和 exec()
了解了这两个函数的作用后,再来看下写时复制技术
Linux 写时复制技术(copy-on-write),简称 COW
传统做法下,父进程 fork 出一个和它完全相同的子进程,会直接将父进程的数据拷贝到子进程中,父子进程之间的数据段和堆栈是相互独立的
一般来说,子进程被 fork 出之后都会执行 exec() 来实现自己想要的功能
所以如果按照传统的做法,父进程 fork 子进程时拷贝过去的数据是没用的,因为子进程会执行 exec() ,导致原数据被清空
既然很多时候父进程拷贝给子进程的数据是无效的,于是便有了写时复制这项技术
COW介绍:
COW原理:
COW好处:
PS:除了 fork() 之外其实有个 vfork()
这个 vfork() 更牛掰,内核连子进程的虚拟地址空间结构也不创建了,直接共享父进程的虚拟空间,也意味着共享了父进程的物理空间
总结:写时复制,即资源的复制只有在需要写入的时候才进行,不然就是以只读的形式共享,这样可以省去了 fork 子进程时的无用数据复制所需的开销
我们知道,计算机只认识 0 和 1,所以无论用哪种语言编写代码,最后都需要通过某种方法将其翻译成二进制文件,才能在计算机中运行起来
而为了让这些代码能够正常运行,我们往往还要给它提供数据,这些数据加上代码本身的二进制文件存放在磁盘上,就是我们平常所说的一个个**”程序“**
然后我们就可以在计算机上运行这个程序了
首先操作系统将这个程序从磁盘读到内存当中,然后去交给 CPU 去执行,CPU 与 内存协作,又会使用到 CPU 寄存器存放数值,内存堆栈保存执行的命令和变量,如果有输入和输出,I/O 设备也会去执行
一旦程序被执行起来,它就从磁盘上的二进制文件,变成了内存中的数据、寄存器里的值,堆栈中的指令,被打开的文件,以及各种设备状态信息的一个集合,由静态变成了动态
像这样一个程序运行起来后的计算机执行环境的总和,就是进程
总结:程序是存储在磁盘上的二进制文件,进程是程序的运行时