简介:这份PDF笔记是面向山东大学操作系统课程期末备考的复习资料,以导论、操作系统结构、进程管理三大模块为主线,覆盖了操作系统概念与功能、启动过程、简单结构/分层/微内核三种结构设计、进程组成与状态转换、PCB、调度队列、进程间通信等高频考点。笔记中特别就进程与程序的区别、运行/等待/就绪三态转换时机、共享内存与消息传递的优缺点等易混淆问题给出了对比整理,适合考前快速回顾核心概念与代码题要点。压缩包内为1个PDF文档,共2.91MB,内容结构清晰,直接按章节顺序编排即可系统学习。该资源已有973人浏览学习,对需要针对山东大学操作系统期末考点进行集中梳理的同学有较好的参考价值。
1. 操作系统期末复习:这份按重点标注的笔记能帮你少走一半弯路
期末复习操作系统,最怕的就是打开课本发现十章内容全是考点,最后哪章都没吃透。这份笔记的价值在于它不是教材的简单摘抄,而是把整门课压缩成了带明确作战标记的复习地图。进程管理、CPU调度、进程同步、死锁、内存管理、文件系统这些章节都被标注了重点和计算题/代码题属性,哪些要写代码、哪些要会算周转时间和等待时间、哪些只要背概念,一眼就能分清。适合两类人:一类是整个学期没怎么听课、考前只剩一到两周需要抱佛脚的;另一类是听课了但不知道考试侧重点、想把知识体系快速结构化梳理一遍的。笔记里对概念辨析和易混淆点的整理比较到位,比如进程和程序的区别、并发与并行的差异、死锁和饥饿的异同,这些恰恰是考试里最容易出简答题的地方。
2. 先用 30 分钟把笔记结构读透:它是笔记但也是一份考点权重表
拿到这份笔记,第一件事不是从导论开始背,而是花半小时把整体结构看一遍,搞清楚它覆盖了哪些章节、每个章节在考试中的可能权重、以及哪些内容是必须动手算或动手写的。
2.1 章节地图:十章内容背后其实是四条主线
这份笔记大致覆盖了操作系统课程的核心章节:导论与结构(U1/U2)、进程与线程(U3/U4)、CPU调度(U5)、进程同步(U6)、死锁(U7)、内存管理(U8/U9)、文件系统(U10/U11)。粗看是独立章节,但本质上可以归并成四条主线。
主线一是「操作系统是什么、怎么搭起来」,对应 U1 和 U2。这部分主要解决概念题和简答题,比如操作系统的作用、启动过程、用户态和内核态的区别。容易被忽略的是「操作系统是由中断驱动的」这个说法,它串起了后面进程调度的很多逻辑。
主线二是「进程怎么管理」,对应 U3 到 U7。这条线是整门课的绝对核心,也是最容易出大题的地方。进程的状态转换、调度算法计算、同步互斥的 PV 操作、死锁的判定和处理,每一块都值得反复刷。笔记里大量标注了「重点」字样,基本都是这条线上的内容。
主线三是「内存怎么管」,对应 U8 和 U9。固定分区、可变分区、分页、分段、虚拟内存、页面置换算法,这些章节既有概念题也有计算题。特别是页面置换的几种算法,FIFO、LRU、时钟算法,几乎每年都会考一道计算比较。
主线四是「文件怎么存」,对应 U10 和 U11。这部分内容在考试中通常占比不如前面几条主线,但文件分配方式和目录结构是简答题的常客,FCB 和文件打开流程也是需要能完整描述出来的知识点。
2.2 从标注看复习优先级:笔记自带的「考点权重表」
看一下笔记里的标注规律。「重点&代码题」出现在进程章节和同步章节,「重点&计算」出现在调度、死锁、内存、虚拟内存、文件系统实现。「概念题」虽然没有明说,但像分时操作系统、实时操作系统这些特征描述,显然是为简答题准备的。
按标注密度来排,进程管理的优先级最高,因为这里既可考概念题(进程和程序区别),又可考代码题(父子进程的 fork 逻辑),还可考调度计算。其次需要重点投入的是内存管理和虚拟内存,因为这部分概念多且计算密集,很多人在 TLB 命中、缺页次数计算上翻车。进程同步的重点集中在互斥、信号量和经典同步问题的代码写法上,这部分是区分度最大的题型之一。死锁的理论框架要背熟,银行家算法的安全性检查必须会手动推演。
如果复习时间严重不足,可以优先把标注了「重点」的章节过一遍,U1、U2 和 U10 可以放到最后冲刺阶段用碎片时间背诵。
2.3 笔记的使用节奏:三轮过法而不是从头到尾读一遍
我一般会建议把复习分成三轮。第一轮是「梳理框架」,按上面说的四条主线把章节重新分组,目标是知道每章考什么题型,这一轮控制在一天内完成。第二轮是「逐章打透」,按优先级从进程管理开始,概念、计算、代码三线并进,每章结束后做一次自我默写或口头复述。第三轮是「查漏补缺」,拿到一套往年真题或模拟题,按照考试时间完整做一遍,把暴露出来的薄弱点再回到笔记里补。
这个节奏的核心思想是:笔记是一张地图,不是一本小说。逐字逐句读十遍不如带着考点定位读两遍。
3. 进程与调度:从状态转换图到调度算法计算全流程拆解
进程章节是整份笔记里体量最大、标注最多的部分,也是概念题和计算题的密集区。这一章学扎实了,后面死锁和内存管理很多概念都能串起来。
3.1 进程状态转换图:四个转换一个都不能少
笔记里列出了四个状态转换关系:运行到等待(等待某事件发生,典型是发出 I/O 请求)、等待到就绪(等待的事件发生了)、运行到就绪(时间片到,或出现更高优先级进程)、就绪到运行(被调度程序选中)。这四个转换必须能默画出来。
画图时有几个容易出错的边界要格外注意。新建态和终止态在笔记里没有重点展开,但状态转换图通常是要包含这两个状态的,完整的状态图应该从新建到就绪、从运行到终止都画出来。第二个坑是「运行到等待」和「运行到就绪」的区别,前者是进程自愿让出 CPU,等待外部事件,后者是被迫让出 CPU,比如时间片耗尽了或者被更高优先级的进程抢占了。第三个坑是把「等待到就绪」和「就绪到运行」混在一起,这两个转换之间还可能隔着调度器的选择过程,并不是等待的事件一发生就立刻上 CPU 运行。
提示:考场上画状态转换图,建议把四个转换原因都标在箭头上,只画图不标原因是常见的丢分点。
PCB(进程控制块)这部分需要记住:进程 = 程序 + 数据 + PCB,这是构成进程的三要素。PCB 里记录了进程的标识信息、处理机状态、调度信息、控制信息,是系统感知进程存在与否的唯一实体。概念题如果问「进程和程序的联系与区别」,除了笔记里列的四点之外,可以补充一句「进程是程序的一次执行过程,同一个程序被多次执行会对应多个不同的进程」。
3.2 调度算法计算:FCFS、SJF、RR 的公式化记忆
调度章节标注了「重点&计算」,这意味着要会动手算。笔记里出现的算法包括 FCFS、SJF(含抢占式 SRTF)、HRRN、优先级调度、RR 时间片轮转。衡量指标有 CPU 使用率、吞吐量、周转时间、等待时间、响应时间。
计算周转时间和等待时间是考试最常见的考法。周转时间 = 完成时间 − 到达时间,等待时间 = 周转时间 − 执行时间(也就是真正占用 CPU 的时间)。如果题目给出了进程的到达时间和需要的 CPU 时间,先用甘特图画出调度序列,然后逐个进程算出完成时间,再套公式。
FCFS 的劣势是护航效果:一个长进程排在前面,后面所有短进程都要等。SJF 在非抢占形式下能得到最小平均等待时间,但缺点是容易让长作业饥饿。RR 的时间片选择是关键参数:时间片太大退化成 FCFS,太小则上下文切换开销太大。笔记里有一句很精辟的话——「希望时间片比上下文切换时间长」,这是做选择题时判断时间片设置是否合理的重要依据。
HRRN(最高响应比优先)的响应比公式是 (等待时间 + 服务时间) / 服务时间,这个算法综合了 FCFS 和 SJF 的思路,既照顾短作业又避免长作业饥饿。考试中如果出现 HRRN 的计算题,一般会给出进程的到达时间和执行时间,要求按动态计算响应比的方式确定调度顺序。
3.3 多级队列与多级反馈队列:弄懂设计思想差异才能答好简答题
笔记里专门提到了一个可能考 10 分的大题:多级队列调度和多级反馈队列调度的设计思想有何不同。这两个算法都在就绪队列上做了文章,但思路正好相反。
多级队列的核心思想是「分类隔离」:把就绪队列按进程属性分成多个独立队列,比如前台交互进程放一队、后台批处理进程放一队,每个队列有自己的调度算法,队列之间用固定优先级抢占调度。它的特点是进程一旦进入某个队列就不会再换队列,优先级低的队列永远不会被高优先级队列抢占时误伤。
多级反馈队列的核心思想是「动态调整」:允许进程在不同队列之间移动。如果一个进程占用 CPU 时间过长,它会被挪到更低优先级的队列去,避免长期霸占 CPU;如果一个进程在低优先级队列等待时间过长了,会被提升到更高优先级队列。设计目标是兼顾响应时间和吞吐量。
答题时可以从三个维度对比:进程是否可在队列间移动(前者否、后者是)、优先级是否固定(前者固定、后者动态)、设计目标(前者是区分交互进程和批处理进程、后者是同时兼顾 I/O 约束和 CPU 约束进程)。从算法优劣评价的角度,多级反馈队列更灵活,但又更复杂、更难调参。
4. 同步与死锁:信号量代码、银行家算法和安全序列是一对搭档
进程同步和死锁这两章是复习时最容易产生「听懂了但不会做题」感觉的地方。听懂了是因为概念不算复杂,不会做题是因为代码题和安全性检查需要动手练熟。
4.1 信号量与 PV 操作:别只背 P 和 V,要会写完整同步代码
信号量的概念本身不复杂:S 是一个整数变量,除了初始化之外只能通过 P 操作和 V 操作访问。P 操作(也称为 wait、down)是申请资源,若 S≤0 则阻塞;V 操作(也称为 signal、up)是释放资源,唤醒等待队列中的进程。计数信号量的值域不受限制,二进制信号量(互斥锁)的值只能是 0 或 1。
笔记里提到的自旋锁值得单独拎出来理解。自旋锁是忙等待的信号量变体,进程在等待锁的时候不阻塞自己,而是持续循环检查锁是否可用。它在单处理器上是有问题的:只有一个 CPU,拿着锁的进程和被卡在自旋里的进程需要争抢同一个处理器。但在多处理器系统中是有意义的:一个线程在一个处理器上自旋等待,另一个线程可以在另一个处理器上执行临界区代码,等临界区执行完,自旋的线程就能立刻拿到锁,避免了阻塞和唤醒的上下文切换开销。这是面试和笔试都爱考的知识点。
考试中的信号量代码题主要有三种:生产者-消费者问题、读者-写者问题、哲学家就餐问题(笔记里没有展开哲学家问题,但生产者-消费者和读者-写者是明确写了的)。写这类代码有几个固定套路:互斥锁保护缓冲区的操作、empty 信号量控制缓冲区空位数、full 信号量控制缓冲区满位数。生产者每次 P(empty) 再 P(mutex),消费者每次 P(full) 再 P(mutex),释放时先 V(mutex) 再 V(full) 或 V(empty)。这个顺序不能反过来,否则可能发生死锁。读者-写者问题的核心是「写者优先还是读者优先」的选择,笔记里写的是要求写者对数据库有排他的访问,那就是读者优先的经典版本——第一个读者进入时加锁阻止写者,最后一个读者离开时解锁放行写者。
4.2 死锁四条件:背下来只是及格,能解释才拿分
死锁的四个必要条件是:互斥、占有并等待、非抢占、循环等待。考试最常见的题型是给一个资源分配场景,让你判断是否可能发生死锁。判断逻辑是:只要四条件有一个不成立,就不会死锁;但四条件同时成立也不一定死锁,只是可能死锁。
笔记里对死锁处理和死锁预防的策略分得很清楚。死锁预防是静态策略,在设计资源分配算法时就确保至少有一个条件不成立。比如「进程在执行前申请并获得所有需要的资源」对应打破占有并等待,「把所有资源类型进行完全排序并要求按递增顺序申请」对应打破循环等待,「把非抢占变为抢占」对应打破非抢占条件。死锁避免是动态策略,在资源分配过程中通过算法判断是否安全,最常见的就是银行家算法。
银行家算法的关键点在于「安全状态」的判断。安全状态是指存在一个进程序列,让每个进程所需的资源数都小于当前可用资源数加上它前面所有进程释放的资源数。考试时把 Allocation(已分配)、Max(最大需求)、Available(当前可用)三张表列出来,先算 Need = Max − Allocation,然后用安全性算法逐个模拟进程能否顺利完成。做题的快捷方式是每次都从 Need 能小于当前 Available 的进程里挑一个,执行完把它占用的 Allocation 释放回 Available,重复直到所有进程都执行完,或出现某个进程的 Need 大于当前 Available 就停止。
资源分配图的判断也是常考内容。如果图中没有环,一定不会死锁;有环的情况下,如果每种资源都只有一个实例,那么环的存在意味着死锁。若一个资源有多个实例,有环只是可能死锁,需要通过计算验证。
4.3 死锁和饥饿:五个维度的辨析要写全
笔记里专门有一段关于死锁和饥饿异同的对比,这是简答题里比较有区分度的考点。相同点是两者都由竞争资源引起。不同点可以从五个角度写:
第一,状态不同。死锁进程都处于等待状态;饥饿进程可能处于忙等待(比如自旋)状态。第二,等待的对象不同。死锁等待的是永远不会被释放的资源;饥饿等待的是会被释放但不会分配给自己的资源。第三,是否构成循环。死锁一定有循环等待,饥饿不需要循环。第四,涉及进程数量不同。死锁一定涉及多个进程彼此纠缠;饥饿可能只涉及一个被冷落的进程。第五,系统整体表现不同。饥饿发生时至少有一个进程能正常运行,只是某个进程得不到执行机会;死锁可能导致整个系统崩溃。答题时把这五点写全,比只写两三句拿到的分数要高得多。
5. 内存与虚拟存储:页面置换、TLB 和缺页计算的避坑指南
内存管理是概念和计算并重的章节。U8 讲的是基本的内存分配方式,U9 讲的是虚拟内存,这两章在考试中的计算题主要集中在分页系统、置换算法和缺页次数的统计上。
5.1 分页与分段:两张表、两次访问、TLB 的作用
分页和分段的对比是概念题的经典考法。分页是按固定大小把用户进程空间切成页,物理内存切成同样大小的帧,页表做映射。分段是按程序自身逻辑划分成段,每段独立编址,段表记录段号和段基址的映射。分页没有外碎片只有内碎片(页内浪费),分段没有内碎片但有外碎片(段间空隙),段页式则综合了两者。
分页系统的地址访问流程要能说清楚:CPU 生成逻辑地址后,先用页号在 TLB 中查找。TLB 是并行的,同时和每一项比较,命中直接拿到帧号;未命中则访问内存中的页表,拿到帧号后再访问主存。笔记里提到二级页表要访问三次内存——两次查页表、一次访问数据。这个「访问次数」是选择题常考的点。
有一点需要特别提醒:逻辑地址和物理地址的概念辨析。逻辑地址是 CPU 生成的,物理地址是内存单元实际看到的。编译时和加载时绑定产生的逻辑地址与物理地址相同,运行时绑定方案下两者不同。答题时先用一句话给出定义,再用编译/加载/运行时三个阶段说明差异即可。
5.2 页面置换算法:FIFO、LRU、时钟算法的计算差异
页面置换是虚拟内存章节里计算题的集中区域。给出一串页面访问序列和帧数,统计缺页次数是标准题型。FIFO 缺页次数好数,先进先出即可;LRU 需要看最近一次访问时间,每次淘汰最近最久没被访问的页;最优置换算法在考场上没法实际用,因为需要预知未来的访问序列,它只能作为理论下界和其他算法做对比。
时钟算法(二次机会算法)是从 FIFO 演进出来的,也是考试里区分度较高的算法。每个页维护一个引用位 U,初始为 1。发生缺页时,指针指向最早调入的页,如果 U=0 就置换它;如果 U=1 则把 U 改成 0,指针移到下一页继续检查。这相当于给了每个页面一次「免死金牌」——在最近一轮中被访问过的页面不会立刻被淘汰。增强型二次机会算法再增加一个修改位 M,优先淘汰 (U=0, M=0) 的页面,然后是 (U=0, M=1),因为修改过的页在换出时需要写回磁盘,代价更高。
做这类题的常见错误是忘了按位更新访问位。LRU 用栈实现时,每次访问某个页都要把它从栈中移到栈顶,题做的多了你会发现这个操作比想象中繁琐,但考场上最好还是用「最近访问时间登记表」的方式手工模拟,不容易出错。
注意:FIFO 可能产生 Belady 异常,即增加帧数反而导致缺页次数增加。LRU 和最优置换不会。这是一个常问的知识点,值得单独记。
5.3 系统颠簸:现象、成因和解决路径
颠簸(thrashing)是虚拟内存里的高频概念题。定义为:一个进程的换页时间已经大于运行时间,系统频繁地在内存和磁盘之间搬运页面,CPU 使用率反而下降。派生的现象是「CPU 使用率低,磁盘 I/O 频繁」,原因是分配给进程的帧数不足以容纳其工作集。
解决路径可以用笔记里的页错误率策略来描述:页错误率过高则增加分配帧数,页错误率过低则减少分配帧数。此外,还可以采用局部置换(每个进程只从自己分到的帧里选置换页),或通过工作集模型预估进程需要的最小帧数。理解颠簸不需要死记定义,把它想成「进程还没热起来就被换出,换回来又要重新积累工作集」就通了。
5.4 文件系统:连续、链接、索引三种分配方式的适用场景
U11 文件系统实现里,为文件分配空间的三种方式——连续分配、链接分配、索引分配——是简答题的常规考点。连续分配简单且访问性能好,但存在外碎片、文件扩展困难;链接分配没有外碎片,文件扩展容易,但不支持直接访问(要顺着链表走),而且指针本身的损坏会导致整条链无法使用;索引分配把指向每个块的指针集中在索引块里,兼顾了随机访问和扩展性,但需要额外的索引块空间开销。FAT(文件分配表)可以简单理解为把链接分配方法中的指针统一收到内存中的一个表里,表中的下标是块号、值指向下一个块号,这样既保留了链式分配的灵活性,又能加快随机访问的速度。
页面共享的概念题也不难。共享页面要求代码是「可重入」的(不会在执行期间修改自身),每个进程有自己的数据页和寄存器副本,这样多个进程的页表里可以把同一份代码页映射到同一个物理帧。答题时画一个多个进程页表指向同一帧的示意图即可。
6. 考前如何用这份笔记做最终验证:三遍默写法与重点抽样测验
笔记使用到最后阶段,重心要从「学」变成「验」。如果不做输出验证,很多内容就像沙漏里的沙子,看着满满的,倒过来就漏光了。
我常用的方法是「三遍默写」。第一遍对着笔记章节标题,把所有能想起来的关键词写在白纸上。进程章节:PCB、状态转换五态、fork、僵尸进程、共享内存、信号量……写完对照笔记查漏。第二遍是针对计算题做抽样测验,从笔记的调度算法、银行家算法、页面置换三个部分各抽两三道场景题,自己设计一个访问序列或内存分配表并手算。第三遍是挑简答题进行全文默写,比如「描述进程与程序的四点区别」「死锁与饥饿的异同」,这一遍最关键,因为考场上前两种题型丢分空间有限,简答题的表述完整度决定分数波动。
验证的另一个维度是「做真题」。如果有往年的模拟卷或真题,掐时间做一套,做完把错题对应的笔记片段找出来看。这一步会暴露出很多平时复习注意不到的细节,比如时间片的定义用反了、逻辑地址和物理地址的转换公式记差了。
最后说一个小技巧:把笔记里所有「重点&计算」「重点&代码题」标记的章节单独列一张清单,当作复习的「必过名单」,每过一章就在清单上打个勾。我当年期末复习时吃过一次亏,临考前三天才发现文件分配方式需要比较三种形式的异同,之前一直没完整梳理过。从那以后我每次拿到别人的复习笔记,都会强制自己先按标注做优先级排序再动手复习。希望这份拆解能帮你在同样的时间里少走一点弯路。
本文还有配套的精品资源,点击获取