操作系统课程完整学习指南
给自己学习操作系统的指南
适用对象:计算机科学与技术、软件工程、网络工程、人工智能等专业本科生
核心目标:不仅“会考试”,还要真正理解 程序、操作系统内核与计算机硬件之间是如何协同工作的,并具备继续学习 Linux 内核、系统编程、计算机体系结构、网络与分布式系统的基础。
建议学习周期:12~16 周
推荐环境:Linux / WSL2 / Ubuntu 虚拟机 + C 语言 + Git + GDB + QEMU
目录
- 为什么要学操作系统
- 学完应该达到什么水平
- 前置基础
- 整门课知识地图
- 正确学习方法
- 各章节应学到什么程度
- 16 周学习路线
- 实验与实践路线
- 综合项目
- 教材、课程、网站与资源
- Linux 工具箱
- 笔记方法
- 计算题方法
- 课程考试与 408
- 常见误区
- 章节验收清单
- 最终综合验收标准
- 深入路线
- 推荐的最终学习组合
- 附录:学习强度、每周闭环、自测题与环境配置
一、为什么要学操作系统
操作系统不是一门“背定义”的课程。它真正研究的问题是:
一台只有 CPU、内存、磁盘和各种设备的计算机,如何同时运行大量程序,并让这些程序安全、高效、方便地使用硬件资源?
如果没有操作系统,应用程序就需要自己处理 CPU 分配、内存分配、磁盘访问、键盘输入、屏幕输出、资源共享、权限隔离、异常处理等大量问题。
操作系统把这些复杂问题封装起来,为应用程序提供统一的抽象。
┌──────────────────────────────────────┐
│ 用户程序 │
│ 浏览器 / IDE / 游戏 / Python / Java │
└──────────────────┬───────────────────┘
│ API / 系统调用
▼
┌──────────────────────────────────────┐
│ 操作系统内核 │
│ 进程管理 内存管理 文件系统 I/O │
│ 调度 同步互斥 网络 安全 │
└──────────────────┬───────────────────┘
│ 控制硬件
▼
┌──────────────────────────────────────┐
│ 硬件 │
│ CPU / 内存 / SSD / 网卡 / GPU / I/O │
└──────────────────────────────────────┘ 所以,学习操作系统本质上是在回答:
程序到底是怎样在计算机上真正运行起来的?
二、学完操作系统应该达到什么水平
建议把学习目标分成四层。
Level 1:课程及格层——知道概念
至少知道:
- 操作系统作用
- 用户态与内核态
- 系统调用
- 进程与线程
- PCB
- CPU 调度
- 同步与互斥
- 信号量
- 死锁
- 分页
- 虚拟内存
- 页面置换
- 文件系统
- I/O
- 中断与 DMA
这一层能应付基础概念题,但仍属于“知道是什么”。
Level 2:本科课程掌握层——能解释、会做题
应该能够:
- 解释一次系统调用发生了什么
- 解释 PCB 为什么存在
- 画进程状态转换图
- 计算 FCFS、SJF、SRTF、RR 等调度算法
- 正确完成 P/V 操作题
- 分析死锁和银行家算法
- 完成逻辑地址到物理地址转换
- 分析 TLB、页表和缺页
- 手工执行 FIFO、LRU、OPT、Clock
- 解释文件描述符、inode、目录关系
- 解释中断、DMA、设备驱动的基本过程
这是学校《操作系统》课程结束后至少应该达到的标准。
Level 3:计算机专业扎实层——能用 Linux 验证
会使用:
ps
top
pstree
strace
lsof
free
vmstat
iostat
ls -li
stat
cat /proc/... 能写简单 C 程序使用:
fork()
exec()
wait()
pthread_create()
pipe()
open()
read()
write()
mmap() 并能解释“一条 Linux 命令执行时,操作系统内部大概经历了什么”。
Level 4:系统方向入门层——能读教学 OS 源码
进一步能够:
- 配置 xv6
- 使用 QEMU 启动 xv6
- 阅读 xv6 的进程、调度、虚拟内存、系统调用、文件系统代码
- 跟踪一个系统调用的执行路径
- 增加简单系统调用
- 修改简单调度或内存机制
- 使用 GDB 调试内核
三、学习操作系统前需要哪些基础
3.1 C 语言
需要重点掌握:
指针
数组
结构体
函数指针
位运算
内存布局
动态内存
指针与数组
指针与结构体 至少能轻松读懂:
struct process {
int pid;
int state;
void *memory;
}; 以及:
p->state
(*p).state
&a
*a
void * 3.2 数据结构
需要熟悉:
- 链表
- 队列
- 栈
- 哈希表基本概念
- 树基本概念
- 位图
- 环形队列
因为操作系统内部大量使用这些结构:
就绪队列 → 队列
页表 → 多级树结构
空闲内存 → 链表 / Buddy
文件目录 → 树
文件描述符表 → 数组 / 表 3.3 计算机组成 / 体系结构基础
至少知道:
CPU
寄存器
PC
SP
内存
Cache
中断
异常
指令
地址
MMU 特别要理解:
CPU 真正执行的是指令,而“进程”是操作系统构造出来的执行抽象。
3.4 Linux 基础
至少熟悉:
cd
ls
pwd
cp
mv
rm
cat
grep
find
ps
kill
gcc
make
git 学习环境可选:
- WSL2
- Ubuntu 虚拟机
- Linux 双系统
- Linux 云服务器
对本科阶段而言,WSL2 或 Ubuntu 虚拟机已经足够。
四、先建立整门课的知识地图
4.1 三条核心主线
非常推荐使用 OSTEP 的框架理解操作系统:
操作系统
│
┌─────────┼─────────┐
▼ ▼ ▼
虚拟化 并发 持久化
Virtualization Concurrency Persistence 虚拟化
CPU 虚拟化 → 进程 / 调度
内存虚拟化 → 虚拟地址 / 页表 / 虚拟内存 并发
进程
线程
锁
信号量
条件变量
死锁 持久化
文件
目录
文件系统
磁盘
I/O
日志
缓存 4.2 从资源管理角度理解
操作系统
│
┌───────────────┼───────────────┐
▼ ▼ ▼
CPU 内存 I/O / 存储
│ │ │
▼ ▼ ▼
进程 地址空间 文件
线程 分页 目录
调度 页表 文件系统
同步 TLB 设备驱动
死锁 虚拟内存 中断 / DMA 4.3 从程序运行过程理解
用户启动程序
│
▼
创建进程
│
▼
建立虚拟地址空间
│
▼
装载程序
│
▼
进入就绪队列
│
▼
CPU 调度
│
▼
开始执行
│
├──── 系统调用 ────► 内核
├──── 缺页 ───────► 内存管理
├──── 文件访问 ───► 文件系统
├──── I/O ────────► 设备驱动
└──── 并发 ───────► 同步机制
│
▼
程序退出
│
▼
OS 回收资源 如果最终能把这条链解释清楚,操作系统就基本真正学通了。
五、操作系统的正确学习方法
5.1 不采用“定义 → 背诵”模式
错误方式:
进程定义是什么?
PCB 定义是什么?
临界区定义是什么? 正确方式:
为什么需要进程?
进程解决了什么问题?
进程在内核中如何表示?
CPU 如何切换进程?
如果没有 PCB 会怎样? 学习任何机制,都问六个问题:
- 为什么需要它?
- 它解决什么问题?
- OS 提供了什么抽象?
- 底层机制是什么?
- 有哪些算法?
- Linux / xv6 中怎样实现?
5.2 六层学习法
以虚拟内存为例:
第一层:问题
为什么每个程序都感觉拥有巨大、连续、独立的内存?
第二层:抽象
操作系统提供:
虚拟地址空间 第三层:机制
虚拟地址
│
▼
页号 + 页内偏移
│
▼
TLB / 页表
│
▼
物理页框
│
▼
物理地址 第四层:异常
页面不在内存:
Page Fault 第五层:算法
FIFO
OPT
LRU
Clock 第六层:实际系统
进一步认识:
Linux 虚拟内存
mmap
Copy-on-Write
Page Cache 5.3 一定要画图
建议至少自己画:
- OS 总体结构图
- 用户态 / 内核态转换图
- 系统调用流程
- 进程状态转换
- fork 流程
- 上下文切换
- CPU 调度时间线
- 信号量同步流程
- 死锁资源图
- 虚拟地址转换
- 多级页表
- TLB
- 缺页处理
- 文件打开过程
- inode 结构
- I/O 中断过程
5.4 一定要“理论 + Linux + 源码”
推荐顺序:
教材理论
↓
自己画图
↓
完成计算题
↓
Linux 实验
↓
xv6 源码
↓
Linux Kernel 不要一上来直接读 Linux 内核源码。
六、各章节到底应该学到什么程度
6.1 操作系统概述
必须掌握:
- OS 的目标与作用
- 批处理、多道程序、分时、实时
- 内核
- 用户态、内核态
- 中断、异常、系统调用
- 单体内核、微内核、模块化内核
必须回答:
为什么应用程序不能直接随便访问硬件?
用户态为什么需要切换到内核态?
系统调用与普通函数调用有什么不同?
中断、异常、系统调用有什么区别?
达标标准:能画出
用户程序
│
│ system call
▼
系统调用接口
│
▼
内核
│
▼
驱动程序
│
▼
硬件 6.2 进程
必须掌握:
- 程序 vs 进程
- PCB
- 进程地址空间
- 进程状态
- 就绪队列
- 阻塞队列
- 上下文切换
- 进程创建和终止
- 父子进程
- fork / exec / wait
- 僵尸进程
- 孤儿进程
核心图:
调度
Ready ─────────► Running
▲ │
│ │ I/O请求
│ ▼
└────────────── Waiting
I/O完成 PCB 至少要知道包含:
PID
进程状态
程序计数器
CPU 寄存器
内存信息
调度信息
打开文件
父子关系 Linux 实验:
ps aux
pstree
top 达标标准:
能完整解释 CPU 怎样从进程 A 切换到进程 B。
6.3 线程
必须掌握:
- 为什么需要线程
- 进程与线程区别
- 用户级线程
- 内核级线程
- 多线程模型
- 线程上下文切换
- pthread 基础
教学上的典型概括:
进程 = 资源分配单位
线程 = CPU 调度执行单位 实践:
pthread_create()
pthread_join() 6.4 CPU 调度
评价指标:
CPU 利用率
吞吐量
周转时间
带权周转时间
等待时间
响应时间 算法:
FCFS
SJF
SRTF
Priority
Round Robin
多级队列
多级反馈队列 必须会画甘特图,然后计算:
完成时间
周转时间
等待时间
平均周转时间 做题时始终问:
当前有哪些进程已经到达?
当前算法应该选择谁?
何时触发重新调度?
6.5 进程同步与互斥
建议学习顺序:
并发
↓
竞态条件
↓
临界区
↓
互斥
↓
锁
↓
信号量
↓
条件变量
↓
经典同步问题 理解:
count++; 可能被拆成:
load count
add 1
store count 多线程交错执行会产生 Race Condition。
必须掌握:
- 临界区
- 竞态条件
- 原子性
- 自旋锁
- Mutex
- Semaphore
- P/V 操作
- Condition Variable
- Monitor
三大经典题必须真正掌握:
- 生产者—消费者
- 读者—写者
- 哲学家进餐
不要只背代码,要知道:
为什么信号量初值是这个数?
为什么 P 放在这里?
如果调换操作顺序会发生什么?
6.6 死锁
四个必要条件:
互斥
请求并保持
不可剥夺
循环等待 必须区分:
死锁预防
死锁避免
死锁检测
死锁解除 重点算法:
银行家算法 理解:
Available
Max
Allocation
Need 以及:
Need = Max - Allocation 达标标准:
- 能判断当前状态是否安全
- 能找安全序列
- 能判断某个资源请求能否满足
6.7 内存管理基础
学习顺序:
物理内存
↓
连续分配
↓
固定分区
↓
动态分区
↓
内部碎片 / 外部碎片
↓
分页
↓
分段
↓
段页式 动态分区:
First Fit
Best Fit
Worst Fit
Next Fit 分页核心:
虚拟地址 = 页号 + 页内偏移 页表:
页号 → 页框号 物理地址:
页框号 × 页面大小 + 页内偏移 6.8 TLB 与多级页表
为什么需要 TLB:
如果每次访存都先查页表,则可能出现:
查页表一次
+
真正访问数据一次 TLB 本质上是:
页表项的高速缓存。
多级页表解决:
页表本身占用巨大物理内存的问题。
要能把虚拟地址拆成:
一级页号
二级页号
...
页内偏移 并完成转换。
6.9 虚拟内存
必须掌握:
- Demand Paging
- Page Fault
- 页面调入
- 页面换出
- 局部性原理
- 工作集
- 抖动
页面置换:
OPT
FIFO
LRU
Clock 不要只会数缺页次数,还要理解:
LRU 为什么可能有效?
关键在:
时间局部性 6.10 文件与目录
必须掌握:
- 文件
- 文件属性
- 文件操作
- 文件描述符
- 目录
- 路径
- 硬链接
- 符号链接
理解:
int fd = open("a.txt", ...); 返回的整数不是“文件本身”。
大致关系:
进程
│
▼
文件描述符表
│
▼
打开文件对象
│
▼
inode
│
▼
磁盘数据块 6.11 文件系统实现
掌握:
- inode
- 文件分配
- 空闲空间管理
- 目录结构
- 缓存
- 日志文件系统基本思想
文件分配:
连续分配
链接分配
索引分配 Linux 实验:
ls -li
stat filename
ln
ln -s 6.12 I/O 与设备管理
必须掌握:
设备控制器
设备驱动
中断
DMA
缓冲
缓存
假脱机 完整 I/O:
用户程序
│
▼
系统调用
│
▼
内核
│
▼
设备驱动
│
▼
设备控制器
│
▼
硬件设备
│
▼
中断
│
▼
内核
│
▼
唤醒进程 6.13 磁盘调度
掌握:
FCFS
SSTF
SCAN
C-SCAN
LOOK
C-LOOK 做题时画磁道位置轴,而不是只背公式。
6.14 保护与安全
至少掌握:
- 用户态 / 内核态
- 权限
- 身份认证
- 访问控制
- 最小权限
- 隔离
- Linux rwx
- chmod
- UID / GID 基本概念
七、建议的 16 周学习路线
| 周次 | 理论主题 | 重点实践 | 本周验收 |
|---|---|---|---|
| 1 | OS 总体结构、内核态、系统调用、中断 | strace echo hello、观察 /proc | 能画 OS 总体图 |
| 2 | 进程、PCB、状态、上下文切换 | fork()、ps、pstree | 能解释进程切换 |
| 3 | 线程与 IPC | pthread、pipe | 能区分进程/线程 |
| 4 | CPU 调度 | 写调度模拟器 | 能手算主要算法 |
| 5 | 并发、竞态、锁 | counter++ 竞态实验 | 能解释 Race Condition |
| 6 | 信号量、条件变量 | 生产者消费者 | 能独立写同步逻辑 |
| 7 | 死锁 | 银行家算法 | 能找安全序列 |
| 8 | 连续分配、分页、分段 | 地址转换题 | 能做分页计算 |
| 9 | 页表、TLB、多级页表 | /proc/PID/maps | 能解释地址翻译 |
| 10 | 虚拟内存、页面置换 | 写置换模拟器 | 能做 FIFO/LRU/OPT |
| 11 | 文件、目录、fd、inode | stat、ls -li、lsof | 能解释 fd→inode |
| 12 | 文件系统实现 | 读 xv6 文件系统章节 | 理解分配与缓存 |
| 13 | I/O、中断、DMA、驱动 | iostat、strace read | 能解释 I/O 全流程 |
| 14 | xv6 入门 | QEMU 启动 xv6 | 能定位核心源码 |
| 15 | 系统调用源码追踪 | 跟踪 fork/read/write | 能讲用户态到内核态 |
| 16 | 综合复习 | 画完整知识图 | 能讲程序从启动到退出 |
八、实验与动手实践路线
Level A:Linux 观察实验
实验 1:观察进程
ps aux
pstree
top 实验 2:观察内存
free -h
vmstat
cat /proc/meminfo 实验 3:观察文件
ls -li
stat file
lsof 实验 4:观察系统调用
strace ls 实验 5:观察进程地址空间
cat /proc/<PID>/status
cat /proc/<PID>/maps Level B:C 系统编程
建议依次完成:
fork
exec
wait
pipe
pthread
mutex
semaphore
mmap
open/read/write/close Level C:xv6
建议按照:
xv6 启动
↓
system call
↓
process
↓
scheduler
↓
virtual memory
↓
locking
↓
file system 逐步阅读。
九、推荐做的综合项目
项目 1:CPU 调度模拟器 ⭐
实现:
FCFS
SJF
RR
Priority 输入:
PID
Arrival Time
Burst Time
Priority 输出:
甘特图
Waiting Time
Turnaround Time
Average Waiting Time 项目 2:页面置换模拟器 ⭐
实现:
FIFO
LRU
OPT
Clock 输出每一步:
内存状态
缺页次数
缺页率 项目 3:Mini Shell ⭐⭐⭐
实现:
mysh> 支持:
ls
cd
pwd
echo 进阶支持:
|
>
<
& 会用到:
fork
exec
wait
pipe
dup2 这是非常经典、非常值得做的操作系统项目。
项目 4:生产者消费者 ⭐⭐
实现:
Producer
Consumer
Buffer
Mutex
Semaphore 项目 5:简易内存分配器 ⭐⭐⭐
实现简化:
malloc / free 理解:
free list
first fit
split
merge 项目 6:修改 xv6 ⭐⭐⭐⭐
例如:
新增系统调用
统计系统调用次数
修改调度算法
增加进程信息输出 十、教材、课程、网站与资源推荐
原则:
1 本主教材
+
1 本辅助教材
+
1 个公开课程
+
Linux 实践
+
xv6 不要同时铺开十几套资源。
10.1 OSTEP
《Operating Systems: Three Easy Pieces》
作者:
- Remzi H. Arpaci-Dusseau
- Andrea C. Arpaci-Dusseau
核心结构:
Virtualization
Concurrency
Persistence 优点:
- 非常强调“为什么”
- 特别适合建立操作系统思维
- 有模拟题、作业和实验
- 对进程、虚拟内存、并发、文件系统讲得很好
官网:
https://pages.cs.wisc.edu/~remzi/OSTEP/
电子书:
https://pages.cs.wisc.edu/~remzi/OSTEP/book-electronic.html
10.2 Operating System Concepts
作者:
- Abraham Silberschatz
- Peter B. Galvin
- Greg Gagne
常被称为“恐龙书”。
优点:
- 知识体系完整
- 适合作为标准教科书
- 适合课程学习和查阅
10.3 Modern Operating Systems
作者:
Andrew S. Tanenbaum 中文常译《现代操作系统》。
适合在基本掌握以后拓宽视野。
10.4 学校指定教材
学校教材应作为:
考试主线 OSTEP 等作为:
理解主线 因为学校考试中的名词、算法、计算题和章节顺序通常以课堂内容为准。
10.5 MIT 6.1810 Operating System Engineering
MIT 的操作系统工程课程使用 xv6/RISC-V 作为教学系统,围绕系统调用、进程、虚拟内存、文件系统、并发等主题展开,并配有实验。
课程主页:
https://pdos.csail.mit.edu/6.S081/
OpenCourseWare:
https://ocw.mit.edu/courses/6-1810-operating-system-engineering-fall-2023/
建议在基础理论学完 50%~70% 后进入。
10.6 xv6
源码:
https://github.com/mit-pdos/xv6-riscv
配套书:
https://github.com/mit-pdos/xv6-riscv-book
建议顺序:
OS Interfaces
↓
System Calls
↓
Processes
↓
Page Tables
↓
Traps
↓
Scheduling
↓
Locking
↓
File System 10.7 UC Berkeley CS162
课程:
Operating Systems and System Programming 课程信息:
https://www2.eecs.berkeley.edu/Courses/CS162/
适合作为 MIT 课程之外的另一套高质量参考。
10.8 Linux Kernel Documentation
官方文档:
初学时不建议从头阅读。后期按专题查:
scheduler
memory
locking
filesystems
driver 10.9 Linux man-pages
网站:
https://man7.org/linux/man-pages/
特别重要:
Section 2 → System Calls
Section 3 → Library Functions
Section 7 → Overview 例如:
man 2 fork
man 2 execve
man 2 open
man 2 read
man 2 mmap 10.10 Nand2Tetris
官网:
它适合建立:
硬件
↓
机器语言
↓
虚拟机
↓
编译器
↓
操作系统 的完整计算机系统观。
Project 12:
https://www.nand2tetris.org/project12
10.11 408 / 王道类资料
如果需要兼顾考研 408,可以使用:
- 王道《操作系统考研复习指导》
- 历年 408 真题
- 学校题库
主要用途:
强化计算题
+
熟悉考试题型
+
考前快速复习 不要只依赖应试资料学习原理。
十一、Linux 工具箱
11.1 进程
ps
top
htop
pstree
kill
nice 11.2 内存
free
vmstat
pmap
cat /proc/meminfo
cat /proc/PID/maps 11.3 文件
ls
stat
df
du
lsof
ls -li 11.4 系统调用
strace 例如:
strace cat hello.txt 你会看到类似:
openat
read
write
close 这相当于直接观察用户程序如何请求内核服务。
11.5 调试
gdb 后期可用于调试 C 程序和 xv6。
11.6 性能分析
后期了解:
perf
iostat
vmstat 十二、如何记操作系统笔记
不要只写:
定义
特点
分类
优点
缺点 推荐每章使用固定模板:
1. 本章解决什么问题?
例如:
为什么需要虚拟内存?
2. OS 提供什么抽象?
例如:
虚拟地址空间 3. 核心结构图
自己画。
4. 核心机制
写清:
输入是什么
内部发生什么
输出是什么 5. 核心算法
例如:
FIFO
LRU
Clock 6. 典型题型
记录:
地址转换
缺页次数
TLB 命中 7. Linux 对应
例如:
free
pmap
/proc/PID/maps 8. 自己的问题
例如:
页表本身放在哪里?
TLB 满了怎么办?
fork 后页表如何处理?
十三、如何做操作系统计算题
13.1 CPU 调度题
永远先画时间轴。
每一步问:
当前有哪些进程已经到达?
CPU 是否空闲?
当前算法选择谁?
什么时候重新调度? 13.2 页面置换
建议画表:
| 时刻 | 页面 | Frame1 | Frame2 | Frame3 | 缺页 |
|---|---|---|---|---|---|
| 1 | 7 | 7 | ✓ | ||
| 2 | 0 | 7 | 0 | ✓ | |
| 3 | 1 | 7 | 0 | 1 | ✓ |
一步一步模拟。
13.3 银行家算法
固定步骤:
Need = Max - Allocation
Work = Available 寻找满足:
Need_i <= Work 的进程,执行完后:
Work += Allocation_i 直到所有进程都可完成,或找不到满足条件的进程。
13.4 地址转换
固定流程:
逻辑地址
↓
页号 + 页内偏移
↓
TLB / 页表
↓
页框号
↓
物理地址 公式:
物理地址 = 页框号 × 页面大小 + 页内偏移 十四、课程考试与 408 如何兼顾
如果同时考虑学校课程、基础能力和未来 408,可以使用:
50% 学校课程
30% 原理理解
20% 408 题 前期:
理解 > 刷题 考试前:
刷题 > 扩展 课程考试高频模块通常包括:
进程状态
CPU 调度
PV 操作
死锁
银行家算法
分页地址转换
TLB
页面置换
文件分配
磁盘调度 这些必须能独立做题。
十五、常见学习误区
误区 1:疯狂背定义
解决方法:
每次先问“它解决什么问题?”
误区 2:一上来读 Linux 内核
正确路线:
教材
↓
Linux 实验
↓
xv6
↓
Linux Kernel 误区 3:只看视频
真正检验是否掌握:
关掉视频
自己画
自己讲
自己做题
自己写代码 误区 4:只刷 408
408 对算法、计算题、概念训练很好,但不能代替真实系统实践。
误区 5:把章节当成孤岛
例如:
read(fd, buf, 100); 背后可能同时涉及:
进程
↓
系统调用
↓
文件描述符
↓
文件系统
↓
缓存
↓
设备驱动
↓
磁盘
↓
中断
↓
进程唤醒
↓
CPU 调度 十六、章节验收清单
OS 基础
- 能解释操作系统为什么存在
- 能解释用户态 / 内核态
- 能解释系统调用
- 能区分中断、异常、系统调用
- 能画整体架构图
进程
- 能区分程序和进程
- 知道 PCB 保存什么
- 能画进程状态图
- 能解释上下文切换
- 能解释 fork
- 能解释 exec
- 能解释 wait
- 会用 ps / pstree
线程
- 能解释线程为什么存在
- 能区分进程和线程
- 会使用 pthread
- 能解释线程共享哪些资源
调度
- FCFS
- SJF
- SRTF
- RR
- Priority
- MLFQ
- 会画甘特图
- 会算等待时间
- 会算周转时间
并发
- 理解 Race Condition
- 理解 Critical Section
- 理解 Atomicity
- 会用 Mutex
- 理解 Semaphore
- 会做 P/V
- 会生产者消费者
- 会读者写者
- 会哲学家进餐
死锁
- 四个必要条件
- 预防
- 避免
- 检测
- 解除
- 银行家算法
- 安全序列
内存
- 连续分配
- 内部碎片
- 外部碎片
- 分页
- 分段
- 页表
- 多级页表
- TLB
- 地址转换
虚拟内存
- Demand Paging
- Page Fault
- FIFO
- OPT
- LRU
- Clock
- 局部性
- 工作集
- 抖动
文件系统
- file descriptor
- inode
- directory
- hard link
- symbolic link
- 文件分配
- 空闲空间管理
- 缓存
- 日志基本思想
I/O
- interrupt
- DMA
- device driver
- buffer
- cache
- 磁盘调度
十七、最终综合验收标准
A 档:课程通过
理解所有基本概念
+
完成课程作业
+
会主要计算题 B 档:本科扎实
在 A 档基础上:
能独立解释核心机制
+
完成 Linux 实验
+
会写基础系统调用程序 C 档:真正理解
在 B 档基础上:
Mini Shell
+
调度模拟器
+
页面置换模拟器
+
并发程序 S 档:系统方向入门
进一步:
读 xv6
+
做 MIT 6.1810 部分实验
+
修改系统调用
+
理解 xv6 调度
+
理解 xv6 页表
+
理解 xv6 文件系统 十八、进一步深入的路线
完成基础 OS 后,可以继续:
操作系统
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Linux Kernel 系统编程 分布式系统
│ │ │
Scheduler C/C++ RPC
Memory Socket Consensus
Filesystem IPC Storage
Driver epoll Distributed FS 还可以延伸到:
虚拟化
Docker
容器
Kubernetes
云计算
数据库系统
高性能计算
安全
嵌入式系统 十九、推荐的最终学习组合
如果不希望资源太多,直接执行这一套。
第一阶段:课堂同步
学校教材
+
老师 PPT 目标:
跟上课程
+
掌握考试范围 第二阶段:真正理解
使用:
OSTEP 每学一个机制都问:
为什么?
怎么实现? 第三阶段:做题
学校习题
+
408 操作系统题 重点训练:
调度
PV
死锁
地址转换
页面置换
磁盘调度 第四阶段:Linux 实践
至少完成:
fork
exec
wait
pthread
pipe
open/read/write
mmap
strace
/proc 第五阶段:项目
优先:
Mini Shell 其次:
CPU Scheduler Simulator
Page Replacement Simulator
Producer-Consumer 第六阶段:xv6
进入:
MIT 6.1810 阅读:
xv6 book
+
xv6 source 二十、最终应形成的思维
不要停留在:
什么是 PCB?
什么是 LRU?
什么是 inode? 而应该思考:
一个程序双击以后为什么能够运行?
CPU 为什么会运行这个程序?
多个程序为什么能“同时”运行?
程序如何获得自己的内存?
虚拟地址如何找到真实内存?
程序读取文件时发生了什么?
硬盘完成读取后 CPU 怎么知道?
两个线程同时访问数据为什么会错?
操作系统怎样保证不同程序互不破坏? 最终把整门课串成:
程序
↓
进程 / 线程
↓
CPU 调度
↓
系统调用
↓
虚拟内存
↓
文件系统
↓
设备驱动 / I/O
↓
硬件 横向还有:
并发
↓
同步
↓
互斥
↓
死锁 如果能够脱离教材,把这两条主线完整讲给一个刚学计算机的人听,并能通过 Linux 实验和简单代码证明自己的解释,那么你就不是“学过操作系统”,而是真正建立了操作系统知识体系。
附录 A:三种学习强度方案
方案 1:课程型——每周 4~5 小时
课堂复习 1.5h
教材 / OSTEP 1.0h
习题 1.5h
Linux 实验 0.5~1h 适合主要目标为学校课程和考试。
方案 2:扎实型——每周 7~8 小时
理论 2h
画图 / 笔记 1h
习题 2h
Linux / C 实验 2h
复盘 1h 推荐大多数计算机专业本科生选择。
方案 3:系统方向型——每周 10~12 小时
在扎实型基础上增加:
xv6 源码阅读
MIT Labs
GDB
系统项目 适合未来希望学习:
Linux Kernel
系统软件
云计算
数据库内核
高性能系统
基础设施 附录 B:每周固定学习闭环
每一章都执行:
Step 1 预习:知道这一章解决什么问题
↓
Step 2 听课:理解老师的知识框架
↓
Step 3 阅读:学校教材 + OSTEP
↓
Step 4 画图:自己重建机制
↓
Step 5 做题:计算题 + 概念题
↓
Step 6 实验:Linux / C 验证
↓
Step 7 复述:脱离笔记讲一遍
↓
Step 8 复盘:整理不会的问题 附录 C:30 个最终自测问题
学完整门课后,尝试不查资料回答:
- 操作系统为什么存在?
- 内核是什么?
- 用户态和内核态为什么要分开?
- 系统调用发生时 CPU 做了什么?
- 中断、异常、系统调用有什么区别?
- 程序和进程有什么区别?
- PCB 为什么存在?
- 上下文切换为什么有成本?
fork()做了什么?exec()为什么不是“创建一个新进程”?- 线程为什么通常比进程更轻量?
- CPU 如何决定下一个运行哪个进程?
- RR 的时间片太大或太小分别有什么问题?
- 为什么
counter++会产生竞态? - Mutex 和 Semaphore 有什么区别?
- P/V 操作为什么必须原子执行?
- 死锁为什么需要四个条件同时成立?
- 什么是安全状态?
- 为什么分页可以消除外部碎片?
- 页表为什么会很大?
- TLB 为什么能加速地址转换?
- 缺页异常发生后 OS 做什么?
- LRU 为什么利用了局部性?
- 为什么会发生抖动?
- 文件描述符是什么?
- inode 是什么?
- 硬链接与软链接有什么区别?
read()从调用到返回可能经历什么?- DMA 为什么能降低 CPU 负担?
- 一个程序从启动到退出,操作系统到底做了什么?
如果其中 25 个以上可以清楚回答,而且不是背定义,而是能讲出过程、机制和例子,基础已经比较扎实。
附录 D:推荐环境安装清单
Ubuntu / WSL2 可准备:
sudo apt update
sudo apt install \
build-essential \
gcc \
gdb \
make \
git \
strace \
lsof \
htop \
valgrind \
qemu-system \
qemu-user 不同发行版的软件包名称可能略有差异。
建议建立个人实验仓库:
os-learning/
├── 01-process/
├── 02-thread/
├── 03-scheduling/
├── 04-sync/
├── 05-deadlock/
├── 06-memory/
├── 07-virtual-memory/
├── 08-filesystem/
├── 09-io/
├── 10-shell/
└── xv6/ 每个目录维护:
README.md
源码
实验结果
问题记录
总结 一个学期结束后,这个仓库会成为你自己的操作系统学习档案。
0 次表情反馈 · 0 条评论