
1. 第一章在全书的真实位置以及我为什么把它翻来覆去啃了三遍操作系统这门课我在准备考试和工作复盘时前后过了三遍每遍的抓手都不一样。第一遍是跟着王道考研的课程把“计算机系统概述”从头到尾听下来第二遍是自己动手把概念画成流程图和对比表第三遍是上岸之后回头做项目才发现第一章里那些当时觉得“背一背就行”的概念其实全都在后面章节里反复出现。很多同学会觉得这一章分值不高、内容又碎随便翻翻就跳过去了结果到了第二章进程管理连“内核态”和“用户态”为什么能切换都说不清楚后面的概念就成了空中楼阁。计算机系统概述这一章的地位有点像盖楼时的地基放线你在地面上看不出多少视觉效果但后面所有墙体的位置都由它决定。它讲的是操作系统的定义、特征、功能、运行机制、中断异常、系统调用、体系结构这些内容几乎每一个概念都会在后续章节被再次调用。比如“并发”要在进程里用“共享”要在同步互斥里用“系统调用”要在文件管理和设备管理里用“内核态与用户态”更是贯穿整个运行机制的底层逻辑。把这些概念第一次就理解正确比后面反复返工要省太多时间。这篇内容我打算按笔记复盘的方式来写不会照搬讲义而是把我自己整理时的思路、踩过的坑、以及实际做实验验证过的细节都摊开讲。适合两类人看一类是正在准备考研、想把这一章彻底吃透的同学另一类是已经工作、想回头把操作系统底层补齐的开发者。无论你基础如何只要你愿意跟着一步步拆这一章不会再只是“背了忘、忘了背”的循环。1.1 先看清楚这一章到底要掌握到什么程度我把这一章的考点按照“必须理解、必须记忆、可以放过”三档做了区分效率比一锅端要高很多。必须理解的是运行的底层逻辑比如为什么要有特权指令、为什么用户态不能直接访问硬件、状态切换靠什么触发必须记忆的是分类和定义比如中断的几种类别、四大特征各自的含义、宏内核和微内核的区别可以放过的是那些偏冷门的历史细节比如早期某型号批处理系统的具体参数这些考到的概率极低。具体到题型这一章主要以选择题形式出现偶尔在综合题里作为背景知识出现。选择题的可怕之处在于它的选项往往只差一两个字比如“并发”和“并行”、“中断”和“异常”、“库函数”和“系统调用”稍不留神就选错。所以这一章的复习重点不是长篇大论而是把易混淆的概念对齐整齐做到看到选项就能立刻反应出差别在哪里。我给自己定的标准是合上书能用大白话把“操作系统是什么、它在什么时候进入工作、靠什么手段管理硬件、应用程序怎么找它帮忙”这一整条链路讲清楚。如果这条链路中间卡壳说明这一章还没过关需要回头补。这个标准后来证明非常有用因为它把零散的概念串成了一条线记忆负担反而小了。1.2 我的笔记整理方式概念卡加对比表我整理这一章没有用大段抄写而是用了两种载体。第一种叫概念卡每张卡只写一个概念正面写名称背面写“一句话定义 一个生活类比 一个反例”。比如“并发”这张卡正面写并发背面写“宏观上同时、微观上交替执行”类比是“一个人一边打电话一边敲键盘其实手和嘴在快速切换”反例是“并行那是真有两个人在干”。这样一张卡反复过几遍概念就很难再混淆。第二种载体是对比表专门用来处理成对出现的概念。这一章里成对的概念特别多内核态与用户态、特权指令与非特权指令、中断与异常、外中断与内中断、宏内核与微内核、系统调用与库函数。把这些放进同一张表里横向对照差异点一目了然比分开记忆靠谱得多。我在下面几个章节里会把关键的表直接给出来你可以直接拿去用也可以按自己的理解再改。这里先给一个我踩过的坑早期我整理笔记时喜欢把讲义原话抄下来觉得抄一遍就记住了实际效果很差因为抄写的时候大脑是关闭的。后来改成“看完一段合上书用自己的话写三行”记忆留存率明显提高。这个方法很笨但很有效尤其是这一章概念密集、理解门槛不高的情况下主动复述是性价比最高的手段。2. 操作系统的概念、特征与功能把所有定义拆到不能再拆这一章的很多概念看起来是“送分题”实际上是最容易丢分的地方因为太熟悉反而会忽略细节。我的做法是把每个定义拆成“它解决什么问题、它怎么解决、它的边界在哪里”三层来理解。比如操作系统的定义如果只背“管理硬件和软件资源”那遇到“操作系统是不是一种软件”这种判断题就会犹豫。只有理解了它是系统软件、是硬件之上的第一层软件、向下管理硬件向上提供服务才能应对各种变形问法。另外要提醒一点概念之间的关系比概念本身更重要。并发和共享为什么互为存在条件虚拟和异步为什么是建立在并发基础上的这些关联点才是选择题喜欢挖坑的地方。下面我把特征和功能逐条拆开尽量用生活场景来对应让抽象的东西落地。2.1 操作系统到底是什么从一台裸机说起一台只有CPU、内存、硬盘、显示器、键盘的机器如果不装任何软件它本质上就是一堆精密但没有灵魂的电子元件。你给它通电CPU会从固定的地址开始取指令执行但取到什么、做什么全看里面预置了什么代码。操作系统就是在这台裸机上铺设的第一层“管理平台”它把硬件的复杂性封装起来向上提供一套相对统一、友好的接口让应用程序不用关心硬盘是哪个牌子、内存条插在哪个插槽。从资源角度看操作系统是一个资源管理者。CPU时间、内存空间、磁盘容量、外设使用权这些都是有限的资源多个程序同时想用就必须有人来分配、调度、回收。这个角色很像一个仓库管理员谁要借工具、借多久、怎么归还都要登记和协调否则就会乱套。操作系统还要负责记录每个资源的使用状态防止冲突和死锁。从用户角度看操作系统又是一个服务提供者。你想读一个文件不需要自己去操作磁盘的磁头只要调用文件系统提供的接口你想让程序运行不需要手动分配内存操作系统会帮你完成地址映射。这种“屏蔽底层细节、暴露上层接口”的定位是操作系统最核心的价值。理解了这一点后面所有关于系统调用、接口、内核的讨论就都有了落脚点。有一点要区分清楚操作系统本身是系统软件不是硬件也不是普通应用软件。它随机器启动而运行运行在最高的权限级别直接和硬件打交道。这个定位决定了它必须有特权、必须稳定也决定了它的代码必须非常谨慎任何一处错误都可能导致整机崩溃。2.2 并发与共享一对绑在一起的兄弟并发指的是两个或多个事件在同一时间间隔内发生。注意这里是“时间间隔”不是“同一时刻”。单核CPU上程序其实是交替执行的只是切换速度极快让人感觉它们在一起跑。并行则不同它要求同一时刻真的有多条指令在多个处理单元上执行比如多核CPU上两个线程同时跑。所以“单核上不存在并行但存在并发”这句话是对的考试里经常拿它做判断题。共享指的是系统中的资源可以被多个并发执行的进程共同使用。共享有两种方式互斥共享和同时共享。互斥共享的资源在一段时间内只允许一个进程访问典型例子是打印机两个进程同时往同一台打印机发数据会乱掉所以必须排队同时共享的资源允许多个进程“同时”访问比如磁盘上的文件多个进程可以同时读因为读操作不会破坏数据一致性。这里的“同时”在单核上依然是宏观同时、微观交替但逻辑上互不干扰。并发和共享的关系是互为存在条件。没有并发就没有多个进程同时存在共享也就无从谈起反过来如果资源不能共享多个进程无法协调使用同一套硬件并发执行也就没法实现。这个相互依赖的关系是高频考点看到“并发和共享的关系”这类问法直接答“互为存在条件缺一不可”基本不会错。我当年第一次做这道题时只写了一半漏了反向依赖扣了分印象特别深。2.3 虚拟与异步最容易背错的另外两个特征虚拟是指把一个物理实体变成若干个逻辑对应物。听起来抽象拆开看就两种实现方式时分复用和空分复用。时分复用是把时间切片比如CPU只有一个但通过快速切换让每个进程都以为自己独占了一颗CPU这就是虚拟处理器空分复用是把空间切分比如物理内存只有8GB但通过虚拟内存技术每个进程都以为自己拥有完整的地址空间这就是虚拟存储器。虚拟技术的前提依然是并发因为没有并发就不需要这种“欺骗式”的抽象。异步是指进程的执行不是一气呵成的而是走走停停以不可预知的速度向前推进。为什么不可预知因为进程什么时候被调度、什么时候被中断、什么时候能拿到资源取决于操作系统的调度策略和其他进程的行为。这种不确定性是并发的必然结果。理解了异步就能明白为什么并发程序需要同步机制为什么共享数据要加锁因为如果不加控制两个进程的执行顺序可能完全出乎意料结果自然不可控。这两个特征经常被一起考常见问法是“虚拟和异步分别建立在什么基础上”。标准答案是虚拟以并发为基础异步也以并发为基础而并发又以共享为条件。整条逻辑链是共享支撑并发并发产生虚拟和异步。把这条链条理清楚四个特征就不再是四个孤立的名词而是一个有内在联系的整体。2.4 四大管理功能与两类接口操作系统的功能通常归纳为四个方面处理机管理、存储器管理、文件管理、设备管理。处理机管理负责进程的创建、调度、同步、通信和死锁处理是并发控制的核心存储器管理负责内存分配、地址映射、内存保护和虚拟内存解决的是“多个进程抢内存”的问题文件管理负责文件的组织、存储、检索和权限控制让用户能按名字方便地存取数据设备管理负责外设的分配、驱动和缓冲屏蔽不同硬件的差异。除了管理功能操作系统还提供两类接口。第一类是命令接口分为联机命令接口和脱机命令接口。联机接口就是你打开终端一条一条敲命令系统执行一条你敲一条脱机接口是批处理方式你事先把一批命令写成脚本交给系统系统一次性执行完。第二类是程序接口由一组系统调用组成供应用程序在代码中调用比如读写文件、申请内存。程序接口是应用程序和操作系统之间的正式通道也是后面要重点讲的内容。这里有个容易忽略的点图形界面算不算接口从用户使用的角度看它当然是一种交互方式但在教材的体系里图形界面通常被归为命令接口的一种延伸或者独立的用户界面考试时按题目要求回答即可。我建议把重点放在命令接口和程序接口这两个大类上图形界面的细节不必过度纠结。记住“面向用户的是命令接口面向程序的是系统调用”这条主线就够用了。3. 运行机制内核态、用户态与那条不能碰的红线运行机制是第一章里最抽象、也最容易被低估的部分。很多同学背下来“内核态管态、用户态目态”就觉得完事了结果一到题目里问“谁能在用户态执行”“状态切换靠什么触发”就开始犯迷糊。我的理解方式是把CPU想象成一个有权限等级的执行环境高权限环境里什么指令都能跑低权限环境里只能跑安全指令两者之间的切换必须走特定通道。这个类比虽然简化但抓住了本质。这一节的关键是把“指令、状态、切换”三件事串起来。指令决定了哪些操作是危险的状态决定了当前能执行哪些指令切换则是从一个状态跳到另一个状态的机制。三者环环相扣任何一个环节不清楚后面的中断、系统调用就都理解不透。下面分三小节拆开讲。3.1 为什么非得分成两种状态如果所有程序都能直接操作硬件后果会非常严重。一个普通程序可以随意修改内存中其他程序的数据可以关闭中断让系统失去响应可以直接控制磁盘导致数据损坏。为了避免这种混乱硬件层面就设计了权限分级把指令分成特权指令和非特权指令把CPU运行状态分成内核态和用户态。内核态下可以执行全部指令用户态下只能执行非特权指令一旦用户态程序试图执行特权指令硬件会直接拦截并触发异常。这种设计的思路和现实中的门禁很像。大楼里普通访客只能走公共区域只有持卡的管理员才能进机房、配电室。公共区域的设施随便用但涉及核心设备的操作必须由专人来做。操作系统内核就是这个“管理员”普通应用程序就是“访客”。访客要办涉及核心设备的事不能自己动手只能通过窗口提交申请由管理员代为处理。理解了这个设计动机就能明白为什么“用户态程序不能直接访问硬件”。不是技术上做不到而是安全机制不允许。这也解释了为什么系统调用必须切换到内核态因为很多操作本质上是特权操作必须在高权限环境下完成。把这个逻辑记牢后面遇到“谁在什么态下运行”的题目就不会靠猜了。3.2 特权指令与非特权指令怎么判特权指令是指那些只能在内核态执行的指令常见的有输入输出指令、置时钟指令、关中断和开中断指令、清主存指令、修改程序状态字寄存器的指令、切换进程的指令等。判断标准其实很简单只要这条指令能影响到整个系统的运行状态、能访问其他程序的资源、能改变硬件配置它就是特权指令。非特权指令则是普通运算、赋值、跳转这类只影响当前程序自身状态的指令。考试里常考的坑是把“陷入指令”当成特权指令。陷入指令又叫访管指令它的作用是从用户态主动切到内核态而它本身是在用户态执行的。这一点非常关键因为它是唯一一条在用户态执行、却能引发状态切换的指令。很多同学会想当然认为“能切换状态的指令肯定是特权指令”结果就选错了。记住陷入指令在用户态执行它的执行结果才是进入内核态。还有一个容易混的点是“修改PSW的指令”。程序状态字里保存了CPU的运行状态标志能改它的指令当然属于特权指令否则用户程序可以把自己改成内核态整个保护机制就废了。所以凡是涉及状态寄存器、中断控制、内存管理寄存器的操作一律按特权指令处理。判断时抓“是否影响全局”这条主线基本不会跑偏。3.3 状态切换的时机以及一个高频陷阱从用户态切到内核态只有三个途径中断、异常、系统调用。更准确地说系统调用本身是通过陷入指令触发的而陷入属于内中断的一种所以教材里常说“中断和异常是用户态进入内核态的唯一途径”。这句话里的“中断”是广义的包含了外中断和异常。理解这一点题目再怎么变形都能应对。从内核态切回用户态则是通过执行一条特权指令来修改程序状态字把状态位改回用户态然后返回用户程序继续执行。注意这个动作只能在内核态做用户态自己做不了。整个切换过程由硬件和操作系统配合完成用户程序感知不到细节只知道自己发起了一个请求然后拿到了结果。这里有个高频陷阱状态切换一定会引起进程切换吗答案是不一定。中断处理完可能直接返回原进程系统调用也可能只是短暂进内核处理完就返回不涉及调度其他进程。只有当中断或异常导致当前进程需要让出CPU时才会发生进程切换。这两个概念分开考的时候很多同学会混淆记住“状态切换是权限层面的进程切换是执行主体层面的两者不等价”就行。4. 中断与异常操作系统的神经中枢中断和异常是操作系统从“被动等待”变成“主动响应”的关键机制。没有中断CPU只能按顺序执行程序外设完成了工作它也不知道多道程序根本无从谈起。可以说中断机制是现代操作系统能够运转的神经中枢所有并发、调度、I/O完成通知都建立在它之上。这一节内容多、分类细是选择题的重灾区我把容易混淆的地方单独拎出来对比。学这一节我建议抓住一条主线谁触发的、在什么状态下触发的、处理完往哪返回。把这三个问题问清楚外中断、内中断、故障、终止、陷入这几种情况就能分得明明白白。下面先讲分类再讲处理流程最后讲一个必考的结论。4.1 内外中断怎么分别被名字骗了中断按来源分为外中断和内中断。外中断又叫中断来自CPU外部与当前执行的指令无关比如时钟中断、I/O设备完成中断、键盘输入中断。它的特点是“别人通知你”你正在干活的时候外部设备或定时器发来信号你必须暂停手头的活去响应。外中断又可分为可屏蔽中断和不可屏蔽中断前者可以通过关中断暂时屏蔽后者通常是紧急事件不能被屏蔽。内中断又叫异常来自CPU内部与当前执行的指令直接相关比如除零、地址越界、缺页、非法操作码、系统调用。它的特点是“自己出了问题或主动求助”。异常通常细分为三类陷入是主动发起的典型就是系统调用故障是执行指令过程中出现的可恢复错误比如缺页处理完可以重新执行那条指令终止是出现了无法恢复的严重错误比如硬件故障、控制器出错只能终止当前程序。这里最大的坑是把“系统调用”归到外中断去。很多人一看到“调用”就以为是从外面进来的实际上系统调用是通过陷入指令主动触发的属于内中断里的陷入。判断的时候不要看名字要看触发源来自CPU外部的硬件信号是外中断来自CPU内部执行指令产生的都是异常。抓住这条标准再花哨的题目也能拆开。4.2 中断处理流程从关中断到中断返回中断处理的完整流程可以拆成几个阶段。第一个阶段是中断隐指令这部分由硬件自动完成不需要操作系统介入主要包括关中断、保存断点保存程序计数器PC和程序状态字PSW、根据中断向量找到中断服务程序的入口地址。注意“中断隐指令”不是真正的指令而是硬件在响应中断时自动执行的一系列动作这个名字容易让人误以为是软件指令。第二个阶段是保存现场和屏蔽字。进入中断服务程序后需要把当前寄存器的内容保存到栈里同时保存中断屏蔽字防止处理过程中被某些中断打断。然后开中断允许更高优先级的紧急中断进来这叫中断嵌套。接着执行具体的中断服务程序处理完关中断恢复现场和屏蔽字再开中断最后执行中断返回指令回到被中断的程序。整个流程里“开中断”的时机是有讲究的。如果一直关中断紧急事件无法及时响应如果一进来就开中断又可能在现场还没保存好的时候被打断导致数据错乱。所以标准做法是先保存现场、再开中断让高优先级中断可以嵌套进来。这些细节在选择题里经常以“下列顺序正确的是”的形式出现把顺序记牢就不会丢分。4.3 为什么说中断是用户态进入内核态的唯一入口前面提过用户态切到内核态只有中断、异常、系统调用三个途径而系统调用本质上是陷入属于异常所以教材用一句话概括中断和异常是用户态进入内核态的唯一途径。这句话之所以重要是因为它把“用户程序如何获得操作系统服务”这个问题回答清楚了。用户程序自己不能执行特权操作只能通过触发中断或异常把控制权交给内核由内核代劳。理解这一点就能明白为什么操作系统必须处理中断。如果内核不能及时响应中断系统调用就得不到处理I/O完成通知也收不到整个系统会陷入僵局。中断机制就像是内核和外界沟通的电话线没有它内核就成了聋子和哑巴。这也是为什么“关中断”被列为特权指令因为谁掌握了这个开关谁就掌握了系统响应能力。还有一个延伸结论中断处理程序一定运行在内核态。因为响应中断需要执行特权指令比如保存和恢复状态、访问硬件这些在用户态做不了。所以只要是在处理中断CPU必然处于内核态。这个结论在判断“某个程序运行在哪个态”的题目里非常有用看到中断服务程序直接判内核态不会错。5. 系统调用应用程序叩开内核大门的正确姿势系统调用是第一章里和实际开发联系最紧密的部分。写代码的时候我们经常调用read、write、fork这些函数但很少有人去区分哪些是系统调用、哪些是库函数包装。这一节我想把系统调用的执行链路完整讲一遍再带大家用工具亲手验证一次把纸面知识和真实系统对上号。系统调用的本质是操作系统提供给应用程序的一组“标准服务窗口”。应用程序不能直接操作硬件但可以通过这些窗口提交请求由内核代为完成。理解系统调用的关键是搞清楚“请求怎么发出去、内核怎么接住、结果怎么回来”这三步。下面逐层展开。5.1 系统调用执行的完整链条一次系统调用大致经历这样的过程应用程序先把系统调用需要的参数准备好比如文件描述符、缓冲区地址、读写长度这些参数通常通过寄存器或栈传递。然后执行陷入指令这条指令在用户态执行作用是触发一个内中断把CPU状态切换到内核态同时把控制权交给内核中对应的处理程序。内核接到请求后会根据系统调用号找到对应的服务例程执行真正的操作比如从磁盘读取数据、向终端输出字符、创建新进程。执行完成后内核把返回值放到指定位置执行一条特权指令把状态改回用户态返回应用程序继续执行。整个过程对应用程序来说是透明的它只知道自己调用了一个函数然后拿到了结果。这里要特别注意陷入指令是用户态执行的但处理系统调用的服务例程运行在内核态。这条链路上有明确的权限边界用户程序负责“发起”内核负责“执行”两者分工清晰。考试里问“系统调用过程中CPU状态如何变化”标准答案是“从用户态切换到内核态处理完再切回用户态”中间不接受任何“一直保持用户态”的说法。5.2 系统调用、库函数、API 三者不是一回事很多同学把库函数和系统调用混为一谈这是理解上的一大障碍。系统调用是操作系统内核直接提供的服务接口运行在内核态库函数是编程语言或第三方库提供的函数运行在用户态它可能内部封装了系统调用也可能完全不涉及内核比如纯计算的数学函数。API 则是更上层的概念是一组接口的统称既可以是库函数接口也可以是系统调用接口。举个例子C语言里的printf是库函数它最终会调用write这个系统调用来输出内容但它自己还做了格式化处理这部分是在用户态完成的。而read、write、open这些在不同的系统里可能直接就是系统调用的封装也可能经过一层库的包装。判断的关键不是看名字而是看它有没有请求内核提供服务。凡是需要内核代劳的操作底层一定有系统调用。为什么操作系统不直接让应用程序调用系统调用还要搞一层库函数一方面是为了跨平台兼容不同系统的系统调用细节不同库函数可以屏蔽差异另一方面是为了方便使用库函数提供了更友好的接口和缓冲机制性能往往更好。理解了这层关系就不会再纠结“我调用的到底是系统调用还是库函数”这种问题了。5.3 动手验证用 strace 亲眼看看系统调用纸上得来终觉浅我强烈建议你在Linux环境下用strace命令实际观察一次系统调用。比如写一个最简单的C程序只做一次输出然后用strace跟踪它的执行你会看到一长串系统调用记录包括execve加载程序、brk分配内存、mmap映射文件、write输出内容、exit_group退出。这些都是真实的系统调用不是书本上的抽象概念。操作步骤很简单先准备一个输出hello的程序并编译然后在终端执行strace -f ./程序名观察输出。你会看到每一行都是一次系统调用格式是“调用名(参数) 返回值”。如果只关心某几类调用可以用-e tracewrite,read这样的过滤选项。再加上-T可以显示每次调用耗时加-c可以统计各类调用的次数和总时间。实测下来这个小实验对理解的帮助非常大。你会直观地看到程序启动过程中触发了多少次内核服务也会发现看似简单的一句输出背后有多少系统调用在支撑。更进阶一点可以用ltrace观察库函数调用和strace对照着看库函数与系统调用的层次关系就一目了然了。这种“亲手看一眼”的方式比死记硬背概念要牢靠得多。6. 内核体系结构宏内核、微内核与虚拟机的取舍操作系统内核怎么组织是一个典型的工程权衡问题。功能全放在内核里性能好但维护难功能拆到用户态稳定易扩展但切换开销大。这一节讲的就是不同体系结构的取舍逻辑以及虚拟机这个延伸概念。这部分内容理解起来不难但对比点多适合用表格来整理。我学这一节的体会是不要孤立地记“宏内核有什么特点”而要理解它为什么这么设计、代价是什么。任何体系结构都是在性能、可靠性、可维护性之间做平衡没有绝对的好坏只有适不适合具体场景。带着这个视角去看很多细节就顺理成章了。6.1 宏内核与微内核的正面交锋宏内核又叫大内核它的思路是把操作系统的绝大部分功能都放在内核里包括进程管理、内存管理、文件系统、设备驱动、网络协议栈。优点是各模块之间可以直接函数调用不需要频繁的状态切换性能高、效率好。缺点是内核体积庞大、耦合度高一处出错可能拖垮整个系统维护和扩展都比较困难。传统的主流操作系统大多采用这种结构。微内核走的是相反路线它只把最核心的功能留在内核里比如时钟管理、中断处理、原语操作、进程通信其他功能如文件系统、设备驱动都移到用户态作为服务进程运行。优点是内核小巧、稳定可靠、易于扩展某个服务崩溃不会影响内核。缺点是服务之间通信需要频繁的状态切换和消息传递性能开销大。这两种结构的选择本质上是“性能优先”还是“可靠性优先”的取舍。对比维度可以整理成一张表来记对比项宏内核微内核功能分布大部分功能在内核态仅核心功能在内核态性能高调用开销小较低状态切换频繁可靠性较低耦合度高高服务隔离可维护性较差较好典型代表传统通用操作系统强调可靠性的系统考试里问“微内核的性能为什么低”答案就是服务之间通过消息传递通信涉及频繁的用户态与内核态切换开销比内核内直接调用大得多。这个因果关系要讲清楚不能只说“微内核慢”。6.2 分层、模块化与外核除了宏内核和微内核还有几种组织结构值得一提。分层结构把操作系统分成若干层每层只能调用相邻下层的接口优点是结构清晰、便于调试和验证缺点是层次划分困难、效率较低因为一次请求可能要穿越多层。模块化结构则是把功能拆成独立模块模块之间可以按需调用灵活性和效率都不错但模块间的依赖关系可能变得复杂。外核结构的思路比较特别它不直接提供传统意义上的抽象而是把硬件资源的分配和具体的资源管理分开内核只负责资源的安全分配具体怎么用交给用户态的程序库去决定。这样做的好处是减少了抽象层的开销灵活性更高但编程复杂度也上去了。外核在实际系统中用得不多但作为考点偶尔出现了解其基本思想即可。这几种结构不用背得太细重点是理解它们的核心思路和典型优缺点。我的记忆方法是抓住“抽象层次”这个关键词分层是纵向切模块化是横向切外核是把抽象权下放。抓住这条线索几种结构的区别就清楚了。6.3 虚拟机与系统引导虚拟机的本质是用软件模拟出一台完整的计算机让多个操作系统可以在同一套物理硬件上互不干扰地运行。按实现方式可以分为两类第一类虚拟机管理程序直接运行在硬件上它自己就像一个精简的操作系统负责分配硬件资源给各个虚拟机第二类则运行在宿主操作系统之上依赖宿主系统来管理硬件。两种方式在性能和隔离性上各有特点第一类通常更接近硬件、开销更小。系统引导是另一个常考的小点。机器加电后CPU从一个固定的地址开始执行固件中的引导程序引导程序负责硬件自检、初始化基本设备然后找到并加载操作系统的内核到内存中把控制权交给内核内核再完成初始化并启动第一个用户进程。整个过程环环相扣任何一步失败机器都无法正常启动。理解引导过程有助于理解“操作系统是第一个在机器上运行的复杂软件”这个定位。虚拟机这一块我在实际工作中用得比较多体感是它对学习和测试非常有价值。你可以在虚拟机里随便折腾装系统、改配置、模拟故障都不影响宿主机。这种“安全沙箱”的特性让它成为学操作系统最实用的工具之一。建议有条件的话自己装一个虚拟机环境把这一章提到的概念在实践中过一遍。7. 操作系统发展历程与常见问题速查发展历程这部分内容偏历史考试分值不高但梳理清楚有助于理解“为什么操作系统会演化成今天这个样子”。我的建议是不要死记年份而是记住每个阶段的驱动因素是什么需求推动了这种形态的出现它解决了什么问题又带来了什么新问题。带着问题意识去看发展脉络记忆会轻松很多。这一节我还整理了一份常见问题速查表把这一章里最容易混淆的几组概念集中对比。复习后期我基本只靠这张表来回滚效率很高。你可以把它打印出来贴在书桌前每天扫一眼比反复翻讲义有用。7.1 发展脉络从手工操作到分时实时最早的阶段是手工操作用户直接通过插线板或控制台操作机器一人独占效率极低。随后出现批处理系统目的是提高资源利用率。单道批处理一次只允许一个程序在内存中运行CPU经常等待I/O利用率依然不高多道批处理允许内存中同时驻留多道程序当一道程序等待I/O时切换另一道执行CPU利用率大幅提升但用户无法交互作业周转时间长。为了解决交互问题分时系统出现了。它把CPU时间切成很短的时间片轮流分配给各个终端用户用户感觉自己独占了一台机器。分时系统的特征包括多路性、独立性、及时性和交互性重点在“及时响应”和“人机交互”。再往后是实时系统它要求系统在规定时间内必须完成处理分为硬实时和软实时前者超时会造成严重后果后者超时只影响体验。实时系统最看重的是可靠性和及时性而不是吞吐量。再往后还有网络操作系统和分布式操作系统。网络操作系统是给网络环境下的计算机提供通信和资源共享功能分布式系统则更强调整体性和透明性多个机器对外表现为一个系统。这两个概念容易混记住“网络系统是互联分布式是协同”这个区别就够了。至于个人计算机操作系统就是我们现在最熟悉的那一类追求易用性和丰富的应用生态。7.2 常见疑问速查表下面这张表是我反复整理后留下的精华版把最容易出错的几组概念摆在一起对比概念对核心区别记忆抓手并发 vs 并行并发是宏观同时、微观交替并行是同一时刻真并行单核只有并发多核才能并行互斥共享 vs 同时共享互斥共享一次一个同时共享可多个并发访问打印机 vs 磁盘文件特权指令 vs 非特权指令特权指令只在内核态执行非特权指令可用户态执行影响全局的就是特权指令内核态 vs 用户态内核态可执行全部指令用户态只能执行非特权指令权限高低不同外中断 vs 内中断外中断来自CPU外部内中断来自指令执行内部时钟中断 vs 系统调用故障 vs 终止故障可恢复处理后重执行终止不可恢复只能结束缺页 vs 硬件故障系统调用 vs 库函数系统调用进内核态库函数多在用户态是否请求内核服务宏内核 vs 微内核宏内核功能集中性能高微内核功能分散可靠性高性能 vs 可靠这张表建议配合概念卡一起用先看表建立整体印象再用卡片逐个击破细节。我在考试前一周基本就是表加卡片来回滚效果比漫无目的地翻书好太多。还有几个零散的高频问题一并列出来。问“用户态程序能不能直接访问硬件”答不能必须通过系统调用。问“中断处理程序运行在哪个态”答内核态。问“系统调用属于内中断还是外中断”答内中断里的陷入。问“操作系统是硬件还是软件”答系统软件。这些问题看着简单但越是简单越容易在紧张时答错提前把它们固化下来很有必要。8. 复盘我在这一章踩过的坑和最后的记忆方式写到这里我把这一章最核心的内容基本都过了一遍。回顾我自己的学习过程有几个坑是反复踩的值得单独拿出来提醒。第一个坑是把“并发”和“并行”混用选择题里两个词经常同时出现一旦混了就必错第二个坑是把系统调用误判成外中断原因是我早期只记了“中断是外部来的”这一半第三个坑是忽略状态切换和进程切换的区别导致后面的调度章节理解吃力。这些坑的共同点都是没有把概念的边界划清楚。后来我找到的比较有效的记忆方式是把整章内容压缩成一条主线故事操作系统的任务是什么它用什么特征来描述自己靠什么机制运行怎么被打断怎么接收请求内核怎么组织一路演化成什么样。沿着这条线走一遍每个知识点都有它自己的位置不再是孤立的名词。比如中断是“怎么被打断”这一环系统调用是“怎么接收请求”这一环状态切换则是贯穿这两环的底层机制。如果让我给正在准备这一章的同学一个建议那就是别急着刷题先把这条主线讲给自己听一遍讲不顺的地方就是薄弱点。讲顺之后再去做选择题正确率会明显不一样。另外动手实验的价值远超想象有条件就在虚拟机里跑跑strace、看看中断信息把纸面概念和真实系统对上号记忆会牢得多。关于这一章后续还能怎么扩展我的做法是把它和第二章的进程管理连起来学。理解了状态切换再去看进程切换和上下文切换会非常顺理解了系统调用再去看进程创建和文件操作也就水到渠成。第一章打下的这些地基会在后面每一章里反复派上用场所以别嫌它碎值得多花两个晚上把它彻底盘清楚。