For AI agents: the complete documentation index is available at https://tingfeng347.github.io/windwiki/llms.txt, the full documentation bundle is available at https://tingfeng347.github.io/windwiki/llms-full.txt, and this page is available as Markdown at https://tingfeng347.github.io/windwiki/terminology/operating-system.md.

操作系统 · 面试清单

面试权重:★★★★☆ 校招必考;社招多作为「系统设计 / 线上排查」的追问出现。


一、进程、线程与协程

术语一句话释义
进程 Process资源分配的基本单位,有独立虚拟地址空间、文件描述符表
线程 ThreadCPU 调度的基本单位,同进程内共享地址空间与 fd,只私有栈、寄存器、PC
协程 Coroutine用户态调度的轻量任务,切换不陷入内核、开销约百纳秒级,适合高并发 IO
进程切换 vs 线程切换进程切换要换页表并刷新 TLB,比同进程内线程切换贵得多
上下文切换 Context Switch保存/恢复寄存器、栈指针、PC;真实开销主要来自缓存与 TLB 失效
PCB(进程控制块)内核里描述进程的结构体,进程存在的唯一标志
进程五态新建 → 就绪 → 运行 → 阻塞 → 终止;阻塞不能直接转运行,必须回就绪
僵尸进程 Zombie子进程已退出但父进程没 wait(),占着 PCB;处理办法是父进程回收或 SIGCHLD 处理
孤儿进程 Orphan父进程先退出,被 init/PID 1 收养,由它负责回收
守护进程 Daemon脱离控制终端、在后台长期运行;setsid() 新建会话
用户态 / 内核态特权级划分;访问硬件、改页表必须经系统调用陷入内核
系统调用 System Call用户态请求内核服务的唯一入口,开销远大于函数调用
中断 / 异常 / 陷阱中断来自外部异步事件;异常来自指令执行出错;陷阱是主动陷入(如系统调用)

二、CPU 调度

术语一句话释义
抢占式 vs 非抢占式抢占是时间片到或更高优先级到来就换人;非抢占必须等进程主动让出
FCFS先来先服务,实现简单,长作业会拖垮后面(护航效应)
SJF / SRTF最短作业(剩余时间)优先,平均周转时间最优,但需预知运行时间且会饿死长作业
HRRN高响应比优先,响应比 =(等待+服务)/服务,兼顾等待时间与执行时间
时间片轮转 RR按时间片轮流占用 CPU,时间片过大退化成 FCFS,过小则切换开销占比高
多级反馈队列 MLFQ多队列 + 动态升降级,优先级高的队列时间片短;通用性最好,Linux/Windows 都在用
优先级反转低优先级进程持锁,被中优先级抢走 CPU,导致高优先级进程长期等待;解法是优先级继承或优先级天花板
CFS(Linux 完全公平调度)用 vruntime 记录虚拟运行时间,总是挑 vruntime 最小的任务跑,靠红黑树组织
nice 值用户可见的静态优先级,-20(最高)~19(最低),权重差约 1.25 倍
CPU 亲和性 Affinity把进程绑到指定 CPU,减少跨核缓存失效
Load Average运行中 + 不可中断(D 状态)任务的均值,Linux 下含 IO 等待,所以可能是高负载但 CPU 空闲

三、进程间通信与同步

术语一句话释义
管道 pipe匿名、半双工、仅父子等有亲缘关系的进程可用,本质是内核缓冲区
命名管道 FIFO有文件路径的无亲缘管道,可用于任意进程
消息队列 Message Queue内核维护的消息链表,有类型边界,可随机读取
共享内存最快(零拷贝数据),但必须自己配信号量做同步
信号 Signal异步通知机制,如 SIGTERM(可捕获)、SIGKILL(不可捕获)
Socket跨主机通信,本地也可用 Unix Domain Socket,性能优于 TCP 回环
互斥锁 mutex睡眠等待,适合持锁时间长的临界区,会产生上下文切换
自旋锁 spinlock忙等不睡眠,适合极短临界区,且不能在单核抢占下乱用;内核里用得多
读写锁读共享、写独占,适合读多写少
信号量 Semaphore计数型同步原语;P 申请(可能阻塞)、V 释放
条件变量必须与互斥锁配合使用,等待前释放锁、唤醒后重新持有;判断条件要用 while 而不是 if(防虚假唤醒)
CAS比较并交换,一条原子指令实现无锁(lock-free)编程的基础,需处理 ABA 问题
内存屏障 Barrier约束编译器与 CPU 的指令重排,保证可见性与顺序性
管程 Monitor把共享变量与操作封装起来、内置互斥的抽象,Java 的 synchronized 是其实现

四、死锁

术语一句话释义
死锁四个必要条件互斥、请求与保持、不可剥夺、循环等待,四者同时成立才可能死锁
死锁预防破坏任一条件,如一次性申请全部资源(破坏请求与保持)、按序申请(破坏循环等待)
死锁避免运行时判断是否进入不安全状态,代表是银行家算法,成本高、现实少用
死锁检测与恢复资源分配图找环,可做的是杀进程或回滚;数据库里很常见
鸵鸟策略不处理,靠重启;大多数通用 OS 的实际选择
活锁 Livelock进程没阻塞但一直在重试,谁也推进不了;可加随机退避破解
饥饿 Starvation某进程长期拿不到资源(如低优先级总被抢),而系统整体仍在推进
死锁 vs 饥饿死锁是循环等待谁都不动;饥饿是别人一直在动、自己被跳过

五、内存管理

术语一句话释义
连续分配首次适应 / 最佳适应 / 最坏适应,核心是找空闲分区,都会产生外部碎片
内部碎片分配出去的块比请求的大,浪费在块内部(分页的最后一页)
外部碎片空闲块分散且太小,总量够但拼不出连续空间(分段、伙伴系统)
分页 Paging把地址空间切成固定大小页(常见 4KB),页表做映射;有内部碎片、无外部碎片
分段 Segmentation按逻辑单位(代码段、数据段)划分,便于共享与保护,会产生外部碎片
段页式先分段再分页,兼顾逻辑性与内存利用率,x86 传统模式即此
页表 Page Table虚拟页号 → 物理页框号的映射表,进程级私有
多级页表分级按需分配,省内存;代价是一次访问要多级访存
TLB(快表)页表项的硬件缓存,命中则免访存;mmap 大页可减少 TLB miss
大页 HugePage2MB/1GB 页,显著减少页表项与 TLB miss,数据库与 JVM 常用
交换 Swapping把整个进程换出到磁盘;与「页面置换」是不同粒度

六、虚拟内存与页面置换

术语一句话释义
虚拟内存每个进程看到独立连续地址空间,由 MMU 翻译成物理地址,实现隔离与超配
局部性原理时间局部性(刚访问的还会访问)+ 空间局部性(邻近地址会被访问),是虚拟内存成立的前提
缺页中断 Page Fault访问的页不在内存,陷入内核从磁盘装入;分「主缺页」与「次缺页」
按需调页 Demand Paging只在真正访问时才载入页面,启动快、内存省
OPT(最优置换)淘汰未来最久不用的页,理论最优但不可实现,只作基准
FIFO淘汰最早进入的页,实现最简单,可能命中率随内存增大反而下降
Belady 异常增加物理页框反而缺页更多,FIFO 独有,LRU/OPT 不会有
LRU淘汰最久未使用的页,效果好但纯实现成本高,实际用 Clock/二次机会近似
抖动 Thrashing内存不足导致频繁换页,CPU 利用率反而暴跌
工作集 Working Set某时间窗口内进程实际访问的页集合,是分配页框的依据
写时复制 COWfork 后父子共享物理页,谁写谁复制,避免立即整页拷贝
mmap文件或匿名内存映射到地址空间,读写走页缓存
OOM Killer内存耗尽时内核按评分杀进程;overcommit 允许分配超过物理内存
内存回收与 LRU 链内核维护 active/inactive 链表,回收的其实是文件页与匿名页的冷数据

七、文件系统与磁盘

术语一句话释义
文件描述符 fd进程级非负整数,指向内核打开文件表项,0/1/2 分别是标准输入/输出/错误
inode存放文件元数据与数据块指针,与文件名解耦;一个 inode 可有多个名字
目录项 dentry名字到 inode 的映射,构成目录树
硬链接 vs 软链接硬链接共享同一 inode、不能跨文件系统、删源文件仍有效;软链接是独立文件存路径,可跨分区、源删即失效
VFS虚拟文件系统,为 ext4/NFS/tmpfs 等提供统一接口
日志式文件系统先写日志再改metadata,崩溃后可重放,ext4/XFS 都属此类
页缓存 Page Cache内核对文件内容的缓存,读写默认走它;dd oflag=direct 可绕过
缓冲区 vs 页缓存历史上缓冲块设备、页缓存文件内容,现代内核已合并
RAID 0/1/5/100 条带无冗余、1 镜像、5 单校验(允许坏 1 块)、10 镜像+条带,性能与安全折中
块设备 vs 字符设备块设备可随机访问、有缓存;字符设备按字节流、无缓存(如终端)
机械盘延迟构成寻道时间 + 旋转延迟 + 传输时间;所以随机 IO 远慢于顺序 IO
SSD 与 TRIM有擦除块限制,需 TRIM/GC 维持写性能,随机读性能远优于机械盘

八、IO 模型与性能

术语一句话释义
阻塞 IO调用后线程睡到数据就绪并拷贝完成,简单但一连接一线程
非阻塞 IO立即返回,需轮询,浪费 CPU
IO 多路复用用一个线程监听多个 fd,就绪后再读;主流方案
信号驱动 IO内核就绪时发信号通知,实际用得少
异步 IO(AIO / io_uring)提交后完全由内核完成并回调,调用方全程不阻塞;Linux 上是 io_uring
select有 fd 数量上限(FD_SETSIZE 1024),每次调用要全量拷入拷出,O(n) 扫描
poll去掉数量上限,仍是 O(n) 遍历
epoll内核红黑树管理 fd + 就绪链表回调,只返回就绪项,O(1) 取事件,适合大量连接
epoll LT / ETLT 未处理完会持续通知,写起来简单;ET 只在状态变化时通知一次,必须配合非阻塞 + 循环读到 EAGAIN
Reactor 模式主线程只负责事件分发,业务线程池处理,Netty/Redis 都是这个套路
Proactor 模式由内核完成读写后回调,需要真正的异步 IO 支持
零拷贝 Zero-Copy消灭用户态与内核态之间的冗余拷贝。sendfile 让数据不进用户态,做文件传输最有效
mmap + write少一次拷贝,但仍有系统调用与页表开销,适合随机访问大文件
splice管道间零拷贝转发,用于代理场景
DMA设备直接读写内存,CPU 只做配置,避免 PIO 占用 CPU
C10K / C10M 问题单机支撑万级/百万级并发连接的经典命题,答案就是 epoll + 非阻塞 + 多路复用

参考资料