操作系统原理经典面试题 20 道(通俗版)

适合面试速记与复习,每题配通俗类比,难度从基础到进阶递增。

基础篇

1. 进程和线程的区别

通俗理解:

  • 进程好比一个工厂,有独立的厂房、设备、资源(独立内存空间)。
  • 线程好比工厂里的工人,共享工厂的资源一起干活。
对比 进程 线程
资源 独立内存空间 共享所属进程的内存
开销 创建/切换开销大 开销小
通信 复杂(需IPC) 简单(直接读共享内存)
奔溃影响 互不影响 一个奔溃可能拖垮整个进程

一句话:进程是资源分配的最小单位,线程是 CPU 调度的最小单位。


2. 什么是死锁?产生的 4 个必要条件

通俗理解: 两个人过独木桥,各走到中间互不相让,谁也过不去–这就是死锁。

4 个必要条件(缺一不可):

  1. 互斥:资源同时只能被一个人占用。
  2. 占有并等待:占着资源还要等别的资源。
  3. 不可剥夺:别人的资源不能强抢。
  4. 循环等待:A 等 B、B 等 A,形成环

怎么破?破坏任意一个条件即可,最常用的是破坏循环等待–规定大家按统一顺序申请资源(比如先拿 1 号锁再拿 2 号锁)

3. 进程间通信(IPC)有哪些方式

通俗说就是“进程之间怎么传话”:

  • 管道(Pipe):像水管,一头进一头出(如ls | grep)。
  • 消息队列:像邮局信箱,存着消息慢慢取。
  • 共享内存:开一块公共的白板,大家都能读写(最快)。
  • 信号量(Semaphore):交通信号灯,控制谁能进。
  • 信号(Signal):拍一下肩膀通知一声(如Ctrl+C)。
  • 套接字(Socket):可跨机器通信,网络程序都靠它。

4. 进程的几种状态

通俗理解(以打工人为例):

  • 就绪:万事具备,排队等 CPU 上班。
  • 运行:正在 CPU 上干活。
  • 阻塞:在等外卖(等I/O),干不了活先歇着。
1
2
3
就绪<----->运行
^ |
|<--阻塞<--

运行时间片用完 -> 回就绪;运行中要等 I/O -> 进阻塞;I/O 完成 -> 回就绪。


5. 虚拟内存是什么?有什么用

通俗理解: 你只有 8G 内存,却能开几十个程序,加起来远超 8G–靠的就是虚拟内存”画大饼“。

  • 给每个程序一个假装很大的连续内存空间(虚拟地址)。
  • 实际上数据散落在物理内存 + 硬盘上。
  • 暂时用不到的数据换出到硬盘(交换区/页面文件),用到再换入

好处: 程序以为内存无限大、各程序互相隔离更安全、内存利用率更高。


6. 什么是缺页中断(Page Fault)

通俗理解: 你想看某页书,发现这页不在手边(不在物理内存),得去仓库(硬盘)取。

流程:CPU 访问的页不在内存 -> 触发缺页中断 -> 操作系统从硬盘把页调进内存 -> 如果内存满了,按算法淘汰一页 -> 重新执行。

常见页面置换算法:

  • FIFO:先进先出(最老的先淘汰)。
  • LRU:最近最少使用(很久没用的先淘汰,最常考
  • LFU:最不经常使用(用得最少得先淘汰)。

7. 用户态和内核态的区别?为什么要分

通俗理解: 内核态是“管理员模式”,用户态是”普通用户模式“。

  • 用户态:跑普通程序,权限受限,不能直接碰硬件。
  • 内核态:操作系统核心,权限最高,可直接操作硬件。

为什么分? 防止普通程序乱搞硬件搞奔系统。普通程序想读文件、申请内存等,必须通过系统调用(System Call)“申请”切到内核态去办–相当于办事要走正规窗口。


8. 进程调度算法有哪些

通俗理解(以排队办事为例):

  • FCFS(先来先服务):按到达顺序,公平但慢的人堵后面。
  • SJF(短作业优先):办事快的先办,但长任务可能一直排不上(饿死)。
  • 优先级调度:VIP 优先,低优先级可能饿死。
  • 时间片轮转(RR):每人办固定几分钟,没办完去队尾重排(交互系统常用)。
  • 多级反馈队列:综合以上,兼顾响应和公平(实际系统常用)。

9. 什么是上下文切换 (Context Switch)

通俗理解: 你正在写作业,突然被叫去吃饭,得先记下写到哪了(保存现场),吃完回来接着写(回复现场)。

CPU 切换进程/线程时:

  1. 保存当前进程的状态(寄存器、程序计数器等)到内存。
  2. 加载下一个进程的状态。

代价: 切换本身不干活,纯属开销。切换太频繁会降低系统效率,所以线程毕进程切换更快(共享资源,要保存的东西少)。

10. 同步、互斥、临界区?怎么实现线程同步

通俗理解:

  • 临界区:同时只能一个人用的公共资源(如公共厕所)。
  • 互斥:保证同一时刻只有一个线程进临界区(锁门)。
  • 同步:多个线程按一定顺序协调干活(如生产者-消费者)。

实现手段:

  • 互斥锁(Mutex):锁门,一把钥匙,用完归还。
  • 信号量(Semphore):可允许 N 个人同时进(计数)。
  • 条件变量:等条件满足才被唤醒(如等仓库有货)。
  • 读写锁:读可并发,写要独占。

经典问题:生产者-消费者读者-写者哲学家就餐


进阶篇

11. 自旋锁 vs 互斥锁

通俗理解:

  • 互斥锁(Mutex):拿不到锁就睡觉,等别人叫醒(线程挂起,让出CPU)。
  • 自旋锁(Spinlock):拿不到锁就原地转圈死等(一直问“好了没?”),不让出 CPU。
对比 互斥锁 自旋锁
等待方式 睡眠,让出 CPU 忙等,占着 CPU 空转
适用场景 锁占有时间长 锁占用时间极短
开销 有上下文切换开销 无切换,但空转浪费 CPU

一句话:等得久用互斥锁(睡一会划算),等得短用自旋锁(睡一觉醒来反而更亏)。


12. IO 多路复用:select、poll、epoll的区别

通俗理解: 一个服务员(线程)要同时盯着很多张桌子(连接),谁举手就去服务谁。

  • select:服务员挨个桌子问“你要点餐吗?”,桌子数量还有上限(1024)。
  • poll:跟 select 差不多,但去掉了数量上限
  • epoll:桌子要服务时自己按铃,服务员只处理按铃的桌子(事件回调)。性能最好,高并发首选(Nignx、redis 都用它)。

核心差异:select/poll 每次都要遍历所有连接(O(n)),epoll 只关心活跃连接 (O(1))。


13. 什么零拷贝 (Zero-Copy)

通俗理解: 把文件从硬盘发到网络,传统方式数据要再“内核<->用户空间”之间来回搬好几趟,很浪费。零拷贝就是少搬几次

  • 传统方式:硬盘 -> 内核缓冲区 -> 用户缓冲区 -> socket 缓冲区 -> 网卡(4 次拷贝 + 多次切换)。
  • 零拷贝(如sendfile):数据不进用户空间,直接在内核里走完,减少拷贝和切换。

好处: 省 CPU、省内存带宽、提升吞吐。Kafka、Nignx 传文件都靠它。


14. 分页和分段有什么区别

通俗理解:

  • 分页(Paging):把内存切成固定大小的小格子(页),像方格本。由系统管理,对程序员透明。
  • 分段(Segmentation):按逻辑功能分块(代码段、数据段、栈段),大小不固定,符合程序员的逻辑视角。
对比 分页 分段
大小 固定 不固定
角度 物理角度(管理内存) 逻辑角度(程序结构)
开销 有内部碎片 外部碎片

现代系统多用段页式:先分段,段内再分页,取两者之长。


15. 什么是僵尸进程和孤儿进程

通俗理解:

  • 僵尸进程(Zombie):孩子死了,但爹没去收尸(父进程没回收字进程退出状态),尸体还占着进程表的坑位。有害,多了会占满进程号。
    • 解决:父进程调用 wait() / waitpid() 回收。
  • 孤儿进程(Orphan)爹先死了,孩子还活着。无害,会被系统的 init (1 号进程) 收养,善终有人管。

记忆:僵尸 = 子死父不收(有害);孤儿 = 父死子还在(无害)。


16. 什么 CPU 缓存?为什么要分多级缓存

通俗理解:

17. 中断和轮询有什么区别

通俗理解:

18. 什么是用户级线程和内核级线程

通俗理解:

19. 什么是内存碎片?内部碎片和外部碎片的区别

通俗理解:

20. 生产者-消费者怎么解决

通俗理解: