Skip to Content
面试题库Operating System操作系统

很多人学操作系统的时候,感觉自己背了很多零碎概念:什么内核态和用户态、什么进程线程、什么分页分段、什么调度算法,背的时候都懂,一到面试就散。

其实操作系统的题目真正的主线只有一条,那就是:

操作系统本质上是在解决三件事:怎么安全地使用硬件,怎么高效地组织执行,怎么合理地管理内存与资源。 你只要沿着这三条线去讲,整个操作系统就不会出现问题。

所以,这篇内容,其实是在回答四个连续问题:

  1. 程序怎么安全地访问系统资源? 操作系统通过用户态和内核态做权限隔离,通过系统调用提供安全入口;在 IO 场景里,为了减少数据搬运和上下文切换,又引出了零拷贝这条性能优化主线。
  2. 多个执行流怎么被组织和协调? 操作系统要组织程序执行,于是有了进程、线程、协程,也有了线程状态、PCB、进程通信机制这些配套结构。
  3. 有限的内存怎么被抽象和复用? 为了解决内存有限和地址隔离问题,操作系统演化出了分页、分段、虚拟内存、地址映射这一整套内存管理体系。
  4. 有限的 CPU 怎么被合理分配? 最后,为了让多个任务合理共享 CPU,又有了生产者消费者模型代表的同步控制问题,以及批处理、交互式、实时系统下不同目标导向的调度算法。

操作系统的三大态

面试官一上来很喜欢问内核态、用户态、系统调用。本质上是在问你:为什么操作系统一定要做权限隔离?

因为应用程序是不可信的。假设每个进程都可以直接访问网卡、磁盘、内存页表,任何一个程序写错地址,整个系统就会被拖死。所以操作系统把执行级别拆成了两个世界:

  • 用户态:业务代码大部分时间待的地方,权限受限,不能直接执行特权指令。
  • 内核态:操作系统内核待的地方,可以管理进程、内存、文件系统和硬件设备。

那用户程序如果真的要读文件、发网络请求怎么办?答案就是系统调用。系统调用本质上是用户态向内核态申请服务的标准入口。

相关阅读:

这条线继续往下,马上就会引出另一个经典问题:一次 IO 到底为什么慢?

因为很多时候慢的不是“算”,而是“搬”。数据从磁盘到内存、从内核缓冲区到用户缓冲区、再从用户缓冲区到网卡缓冲区,这里面既有数据拷贝,也有用户态和内核态来回切换。

所以所谓零拷贝,本质上并不是一字面意义上的“完全不拷贝”,而是尽量减少 CPU 参与的数据搬运次数,以及减少不必要的上下文切换。常见的几个关键词你要能连起来:

  • DMA:负责让设备和内存直接搬数据,减轻 CPU 负担。
  • mmap:把文件映射进进程地址空间,减少一次从内核到用户的显式拷贝。
  • sendfile:适合“文件直接发网络”的场景,绕开用户态中转。

相关阅读:


操作系统是怎么组织“执行中的程序”的?

接下来要讲的是进程、线程、协程。这一块的核心不是背区别,而是先回答一句话:

为什么会从进程演化出线程,又为什么在线程之上还会有协程?

进程是资源分配的基本单位,它的隔离性最强,但切换和通信成本也最高。线程共享进程的地址空间和打开文件,能把“执行流”拆得更轻,所以它成了 CPU 调度的基本单位。再往后,线程切换和锁竞争依然有成本,于是又有了协程,让应用自己在用户态做调度。

所以你可以这么理解:

  • 进程解决的是隔离和资源拥有权。
  • 线程解决的是同一进程内的并发执行。
  • 协程解决的是“线程太重、调度太贵”的问题。

相关阅读:

讲完执行单元,面试官通常会继续追问两个配套问题。

第一个是:线程有哪些状态?

这个问题不是要你死记状态名,而是看你能不能理解线程为什么会停下来。线程可能是在等 CPU,也可能是在等锁,也可能是在等 IO,也可能是主动 sleep。真正要抓住的是“状态变化背后的原因”。

相关阅读:

第二个是:并发、并行、同步、异步、阻塞、非阻塞这些词到底有什么区别?

这组词非常容易混,但其实它们根本不是一个维度:

  • 并发和并行,说的是任务怎么被执行。
  • 同步和异步,说的是你拿结果的方式。
  • 阻塞和非阻塞,说的是调用方线程会不会被挂住。

真正厉害的回答,不是一个个背定义,而是知道:同步不等于阻塞,异步也不天然等于非阻塞。

相关阅读:

还有一个经常被忽略但很基础的点,叫 PCB(进程控制块)。为什么说创建进程、撤销进程,本质上都是在操作 PCB?

因为对操作系统来说,进程不是一段抽象代码,而是一组被记录下来的运行信息:进程状态、寄存器现场、内存映射、打开文件、调度信息,这些都装在 PCB 里。没有 PCB,操作系统就没法感知和管理这个进程。

相关阅读:

既然进程要并发运行,就一定会涉及“进程之间怎么交换信息”。所以这一段自然会落到 IPC,也就是进程通信机制。

  • 低成本本机通信:管道、命名管道、共享内存。
  • 需要同步互斥配合的通信:共享内存 + 信号量。
  • 跨机器或者更通用的通信:消息队列、Socket。

共享内存最快,但同步问题最重;Socket 最通用,但成本更高。

相关阅读:


内存管理

操作系统的内存管理,本质上是在做四件事:给进程分配内存;回收不用的内存;做地址转换和隔离;尽量提升内存利用率。

最基础的三种管理方式是:

  • 页式管理:固定大小切分,便于管理,利用率高。
  • 段式管理:按逻辑意义切分,比如代码段、数据段,更符合程序结构。
  • 段页式管理:先分段,再分页,兼顾逻辑和管理效率。

相关阅读:

这里面最容易被单独拿出来问的一题,是分页和分段到底有什么区别。一定要抓住两个关键词:

  • 分页是为了操作系统管理方便,页面本身没有业务语义。
  • 分段是为了符合程序逻辑结构,段是有含义的。

再往下一层,就是页表和段表。页表负责把虚拟页号映射到物理块号,段表负责记录每一段的基址和长度。也就是说,分页和分段不只是“切法不同”,连地址转换的组织方式都不一样。

相关阅读:

而真正把整个内存管理体系串起来的,是虚拟内存

虚拟内存为什么重要?因为它解决了一个根本矛盾:程序需要的地址空间,往往大于机器当下真正可用的物理内存。

操作系统给每个进程看到的是一整块连续的虚拟地址空间,至于哪些页真正在内存里,哪些页暂时在外存里,交给底层去动态换入换出。这背后利用的是局部性原理,也就是程序在某段时间内只会高频访问一小部分数据。

相关阅读:

虚拟内存一旦讲清楚,虚拟地址和物理地址就顺理成章了。程序员写代码时操作的是虚拟地址,不是物理地址。虚拟地址经过 MMU 和页表映射后,才落到真正的物理内存位置。这样做的价值非常大:

  • 每个进程的地址空间相互隔离。
  • 程序不用关心真实物理地址细节。
  • 操作系统可以灵活做换页、保护和共享。

相关阅读:


生产者-消费者模型

生产者消费者模型是几乎把并发控制的核心元素都放进来了:共享缓冲区,互斥访问,条件同步,资源计数。

典型写法里会有三个信号量:

  • mutex:保证临界区互斥。
  • items:表示当前已有多少个可消费资源。
  • space:表示当前还有多少个空位可生产。

这个题最容易体现你是否真正理解并发控制,因为你不只是要知道“上锁”,还要知道为什么先等资源、再进临界区,否则会把线程白白锁死在里面。

相关阅读:


调度算法: CPU的运行逻辑

这一段就是调度算法。很多人一看到 FCFS、SJF、时间片轮转就开始背,但如果你抓不住“系统目标”,这些算法就永远记不牢。

先看批处理系统。这类系统几乎不强调交互体验,更关心的是吞吐量和周转时间。所以常见算法是:

  • FCFS:先来先服务,公平但容易让短任务吃亏。
  • SJF:短作业优先,整体效率高,但长作业可能饿死。
  • SRTN:最短剩余时间优先,是 SJF 的抢占式版本,更激进地优先短任务。

相关阅读:

再看交互式系统。这类系统最重要的是用户感受到的响应速度,所以常见算法会变成:

  • 时间片轮转:大家轮流用 CPU,强调响应公平。
  • 优先级调度:高优任务先跑,但要防止低优任务长期饿死。
  • 多级反馈队列:把短任务优先、长任务下沉、优先级动态调整结合到一起。

相关阅读:

最后是实时系统。这类系统和前两类最大的区别是,它不是追求“平均更快”,而是追求“必须按时”。

  • 硬实时:错过截止时间就是失败,比如飞控、汽车安全控制。
  • 软实时:偶尔超时可以接受,但整体要尽量稳定,比如音视频播放、在线会议。

相关阅读:

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册