Appearance
操作系统笔试题 共82题
说明:
- 高频方向:进程线程、同步互斥、死锁、虚拟内存、页表、缺页、中断/系统调用、IPC、I/O 多路复用、调度、内存泄漏与卡顿分析。
第 1 部分
题目清单
- S20:死锁四条件不包括?
- S21:进程和线程的区别是?
单选题
S20. 单选题
死锁四条件不包括?
A. 可抢占 B. 互斥 C. 占有且等待 D. 循环等待
答案:A
解析:死锁要求不可抢占;如果可抢占,必要条件被破坏。

S21. 单选题
进程和线程的区别是?
A. 进程资源隔离,线程共享进程地址空间 B. 线程一定比进程慢 C. 进程不能并发 D. 线程都有独立虚拟地址空间
答案:A
解析:进程是资源分配单位,线程是调度单位,共享同一进程地址空间。

第 2 部分
一、单选题
1. 进程和线程的本质区别更接近哪一项?
A. 进程是资源分配的基本单位,线程是 CPU 调度的基本单位
B. 线程拥有独立地址空间,进程共享地址空间
C. 进程不能并发,线程可以并发
D. 线程不能访问堆内存
答案:A
解析:进程拥有独立地址空间和资源;同一进程内线程共享进程资源,线程是调度执行单位。
2. 同一进程内的多个线程通常共享的是?
A. 代码段、数据段、堆等进程资源
B. 各自独立的虚拟地址空间
C. 各自独立的文件系统
D. 各自独立的进程号
答案:A
解析:线程共享进程地址空间和打开文件等资源,但每个线程有自己的栈和寄存器上下文。
3. 线程上下文切换通常需要保存和恢复什么?
A. 寄存器、程序计数器、栈指针等执行上下文
B. 显示器分辨率
C. 网卡 MAC 地址
D. 磁盘分区表
答案:A
解析:上下文切换要保存当前执行现场,并恢复下一个线程或进程的执行现场。
4. 死锁产生的四个必要条件不包括?
A. 可抢占
B. 互斥
C. 占有且等待
D. 循环等待
答案:A
解析:死锁必要条件是互斥、占有且等待、不可抢占、循环等待。
5. 银行家算法主要用于?
A. 死锁避免
B. CPU 指令译码
C. 磁盘格式化
D. 网络拥塞控制
答案:A
解析:银行家算法通过判断资源分配后系统是否仍处于安全状态来避免死锁。
6. 互斥锁 mutex 的主要作用是?
A. 保护临界区,保证同一时间只有一个线程访问共享资源
B. 提升 GPU 性能
C. 压缩内存
D. 替代进程调度
答案:A
解析:mutex 用于互斥访问共享资源,避免数据竞争。
7. 条件变量 condition_variable 通常要配合什么使用?
A. 互斥锁和条件谓词
B. 显卡驱动
C. 文件后缀
D. DNS 服务器
答案:A
解析:条件变量等待/唤醒共享状态变化,通常要用互斥锁保护条件检查。
8. 自旋锁适合哪种场景?
A. 临界区很短且线程等待时间极短
B. 等待磁盘 I/O 很久
C. 网络阻塞读取
D. 长时间睡眠
答案:A
解析:自旋锁等待时不让出 CPU,适合短临界区;长等待会浪费 CPU。
9. 信号量 semaphore 和互斥锁的区别之一是?
A. 信号量可表示多个同类资源数量
B. 互斥锁一定可跨机器使用
C. 信号量只能保护一个资源
D. 二者完全没有区别
答案:A
解析:互斥锁可看作资源数为 1 的互斥控制;信号量可控制 N 个资源。
10. 操作系统中临界区指的是?
A. 访问共享资源且需要互斥保护的代码段
B. 显卡渲染区域
C. 磁盘坏道
D. 网络端口范围
答案:A
解析:临界区访问共享资源,多个线程同时进入可能造成竞态。
11. 虚拟内存的主要作用不包括?
A. 让每个进程看到独立连续地址空间
B. 提供地址隔离
C. 支持按需加载和换页
D. 让物理内存容量无限大
答案:D
解析:虚拟内存改善管理和隔离,但不能让物理内存真正无限。
12. 页表的主要作用是?
A. 完成虚拟地址到物理地址的映射
B. 存储玩家账号
C. 记录网络包长度
D. 压缩纹理
答案:A
解析:页表由操作系统和硬件协作维护,用于地址翻译。
13. TLB 的作用是?
A. 缓存页表项,加速地址转换
B. 缓存 DNS 结果
C. 保存线程源码
D. 加密内存
答案:A
解析:TLB 是地址转换旁路缓存,减少访问页表的开销。
14. 缺页异常 page fault 通常表示?
A. 访问的虚拟页当前不在物理内存或权限不满足
B. 网线断开
C. CPU 没有时钟
D. 程序一定崩溃
答案:A
解析:缺页可能触发从磁盘调页,也可能因非法访问导致进程异常。
15. 堆和栈的区别中,正确的是?
A. 栈通常由系统自动管理,堆通常由程序显式申请释放
B. 堆只能存函数参数
C. 栈必须手动 free
D. 堆不能跨函数使用
答案:A
解析:栈随函数调用自动分配释放;堆生命周期更灵活,但需要管理。
16. 栈溢出常见原因是?
A. 递归过深或栈上申请过大数组
B. 网络包太小
C. 显示器太亮
D. 使用 UDP
答案:A
解析:递归层数过多或大对象放栈上可能超过线程栈大小。
17. 内存泄漏指的是?
A. 申请的内存不再使用但没有释放且无法访问
B. CPU 频率降低
C. 网络丢包
D. 页面被换出
答案:A
解析:泄漏会使长期运行程序内存不断增长,游戏客户端尤其要注意。
18. 内存碎片通常会导致?
A. 可用内存分散,大块连续分配失败或效率降低
B. TCP 握手失败
C. 显示器黑屏
D. 编译器变慢
答案:A
解析:频繁分配释放不同大小块可能产生碎片。
19. 进程间通信 IPC 不包括?
A. 共享内存
B. 管道
C. 消息队列
D. 虚函数表
答案:D
解析:虚函数表是 C++ 多态实现相关,不是 OS IPC 机制。
20. 共享内存的特点是?
A. 速度快,但需要额外同步机制
B. 一定可靠有序
C. 只能传字符串
D. 不能被多个进程访问
答案:A
解析:共享内存避免内核态复制,但并发访问要用锁/信号量等同步。
21. 管道 pipe 通常用于?
A. 有亲缘关系进程或命令间的数据流通信
B. GPU 渲染
C. 内存分页
D. DNS 查询
答案:A
解析:管道是一种字节流 IPC 机制,常用于父子进程或 shell 命令连接。
22. 中断的主要作用是?
A. 让 CPU 响应外部或内部事件
B. 删除进程
C. 增加内存容量
D. 保证 TCP 可靠
答案:A
解析:中断让 CPU 暂停当前执行,转去处理中断服务程序。
23. 系统调用的本质是?
A. 用户态程序请求内核服务的接口
B. C++ 函数重载
C. 显卡 API
D. DNS 协议
答案:A
解析:文件、进程、网络等底层操作通常通过系统调用进入内核。
24. 用户态和内核态的区别是?
A. 权限级别不同,内核态可执行特权指令
B. 用户态一定更快且可访问所有硬件
C. 二者没有区别
D. 内核态不能访问内存
答案:A
解析:OS 通过 CPU 权限级别保护内核和硬件资源。
25. 进程调度算法中,时间片轮转 RR 的特点是?
A. 每个就绪进程按时间片轮流运行
B. 永远只运行最短任务
C. 只用于磁盘
D. 不发生上下文切换
答案:A
解析:RR 适合分时系统,时间片太小会增加切换开销。
26. 优先级调度可能带来的问题是?
A. 低优先级任务饥饿
B. 无法创建进程
C. 无法使用内存
D. 文件系统消失
答案:A
解析:长期高优先级任务可能使低优先级任务得不到运行。
27. 生产者消费者问题常用什么同步工具解决?
A. 互斥锁 + 条件变量/信号量
B. 虚函数
C. 纹理压缩
D. HTTP Cookie
答案:A
解析:生产者消费者需要互斥访问队列,并在空/满时等待唤醒。
28. 读写锁适合哪种场景?
A. 读多写少
B. 只有写没有读
C. 每次操作都需要独占很久
D. 不共享数据
答案:A
解析:读写锁允许多个读者并发,写者独占。
29. fork 后父子进程通常?
A. 拥有独立地址空间,常通过写时复制优化
B. 共享同一个栈且互相覆盖
C. 一定运行同一条 CPU 指令直到结束
D. 不能再通信
答案:A
解析:fork 创建子进程,现代 OS 常用 copy-on-write 优化。
30. exec 的作用是?
A. 用新程序替换当前进程映像
B. 创建新线程
C. 释放锁
D. 执行 DNS 查询
答案:A
解析:fork + exec 是 Unix/Linux 创建并运行新程序的常见组合。
31. 僵尸进程 zombie 是指?
A. 子进程已退出但父进程未回收其退出状态
B. 进程正在睡眠
C. 线程持有锁
D. 内存不足
答案:A
解析:父进程 wait/waitpid 回收后,僵尸进程表项才释放。
32. 孤儿进程 orphan 是指?
A. 父进程先退出,子进程被 init/systemd 接管
B. 没有线程的进程
C. 没有内存的进程
D. 没有文件的进程
答案:A
解析:孤儿进程通常会被 1 号进程或系统服务接管。
33. select/poll/epoll 主要解决什么问题?
A. I/O 多路复用
B. 内存分页
C. 进程创建
D. 图像采样
答案:A
解析:I/O 多路复用允许一个线程管理多个 fd 的事件。
34. epoll 相比 select 的常见优势是?
A. 更适合大量连接,避免每次线性扫描所有 fd
B. 只能用于 Windows
C. 只能监听一个 fd
D. 不支持网络
答案:A
解析:epoll 使用事件驱动机制,适合高并发网络服务。
35. 阻塞 I/O 的特点是?
A. 调用方等待操作完成才返回
B. 永远立即返回
C. 只用于 GPU
D. 不会进入内核
答案:A
解析:阻塞调用会挂起当前线程,直到数据就绪或操作完成。
二、不定项选择题
1. 进程通常拥有的资源包括?
A. 独立虚拟地址空间
B. 打开文件表相关资源
C. 进程 ID
D. 同进程所有线程共享的代码段
答案:A、B、C、D
解析:这些都属于进程资源或进程内共享资源。
2. 线程通常独有的内容包括?
A. 线程栈
B. 寄存器上下文
C. 程序计数器
D. 同进程堆内存
答案:A、B、C
解析:堆内存是进程内线程共享资源。
3. 死锁必要条件包括?
A. 互斥
B. 占有且等待
C. 不可抢占
D. 循环等待
答案:A、B、C、D
解析:四个条件同时满足才可能产生死锁。
4. 避免或处理死锁的方法包括?
A. 破坏死锁条件
B. 银行家算法
C. 检测并恢复
D. 永远不加锁
答案:A、B、C
解析:永远不加锁不现实,也不能解决所有共享资源问题。
5. 线程同步方式包括?
A. 互斥锁
B. 信号量
C. 条件变量
D. 读写锁
答案:A、B、C、D
解析:这些都是常见同步原语。
6. 进程间通信方式包括?
A. 管道
B. 消息队列
C. 共享内存
D. Socket
答案:A、B、C、D
解析:Socket 也可用于本机或跨机器进程通信。
7. 虚拟内存带来的好处包括?
A. 地址空间隔离
B. 简化内存管理
C. 按需分页
D. 让程序认为有连续地址空间
答案:A、B、C、D
解析:虚拟内存是现代 OS 的核心机制。
8. 发生缺页异常后,操作系统可能做什么?
A. 检查访问是否合法
B. 从磁盘加载页面
C. 更新页表
D. 直接让显卡重启
答案:A、B、C
解析:缺页处理与显卡重启无关。
9. 关于堆和栈,正确的是?
A. 栈空间通常较小
B. 堆生命周期更灵活
C. 栈由调用关系自动回收
D. 堆分配过多可能碎片化
答案:A、B、C、D
解析:这些都是常见区别。
10. 可能导致线程安全问题的是?
A. 多个线程无同步写共享变量
B. 一个线程读一个线程写共享变量且无同步
C. 对共享容器并发修改
D. 只读常量数据
答案:A、B、C
解析:只读不可变数据一般没有数据竞争。
11. I/O 多路复用相关系统包括?
A. select
B. poll
C. epoll
D. kqueue
答案:A、B、C、D
解析:Linux 常见 select/poll/epoll,BSD/macOS 常见 kqueue。
12. 调度算法可能关注的指标包括?
A. 响应时间
B. 吞吐量
C. 公平性
D. 周转时间
答案:A、B、C、D
解析:不同系统对调度目标权重不同。
13. 页面置换算法包括?
A. FIFO
B. LRU
C. Clock
D. OPT
答案:A、B、C、D
解析:这些都是常见页面置换算法或理论算法。
14. 用户态切换到内核态的情况可能包括?
A. 系统调用
B. 中断
C. 异常
D. 普通函数内联
答案:A、B、C
解析:普通函数内联仍在用户态。
15. 游戏客户端中可能引起卡顿的 OS 层因素有?
A. 主线程阻塞 I/O
B. 频繁内存分配触发缺页或碎片
C. 锁竞争
D. 线程过多导致调度开销
答案:A、B、C、D
解析:实时程序要避免主线程长时间阻塞和频繁抖动。
三、判断题
1. 进程之间默认共享同一个虚拟地址空间。
答案:错
解析:不同进程通常有独立虚拟地址空间。
2. 同一进程内线程共享堆内存。
答案:对
解析:线程共享进程地址空间,因此共享堆。
3. 互斥锁可以保护临界区。
答案:对
解析:mutex 常用于保护共享资源。
4. 死锁只要发生,操作系统一定能自动完美恢复。
答案:错
解析:死锁检测和恢复依赖系统策略,很多应用层死锁需要程序自己避免。
5. 虚拟内存地址一定等于物理内存地址。
答案:错
解析:虚拟地址需要通过页表转换到物理地址。
6. TLB 命中可以减少页表访问开销。
答案:对
解析:TLB 缓存近期地址翻译结果。
7. 栈上大数组可能导致栈溢出。
答案:对
解析:线程栈空间通常有限。
8. 共享内存速度快,但必须考虑同步。
答案:对
解析:共享内存本身不提供互斥。
9. 系统调用通常会涉及用户态和内核态切换。
答案:对
解析:系统调用是用户程序请求内核服务的入口。
10. 自旋锁等待时会主动睡眠并释放 CPU。
答案:错
解析:自旋锁会忙等,占用 CPU。
四、填空题
1. 死锁四个必要条件是互斥、占有且等待、不可抢占、______。
答案:循环等待
解析:破坏循环等待可预防死锁。
2. 线程是 CPU ______ 的基本单位。
答案:调度
解析:线程是调度执行单位。
3. 进程是系统进行资源分配的基本单位,拥有独立的 ______ 地址空间。
答案:虚拟
解析:进程虚拟地址空间相互隔离。
4. 页表用于完成 ______ 地址到物理地址的映射。
答案:虚拟
解析:地址翻译依赖页表。
5. TLB 用于缓存 ______。
答案:页表项
解析:TLB 加速虚拟地址翻译。
6. 生产者消费者模型常使用互斥锁配合 ______ 变量实现等待和唤醒。
答案:条件
解析:条件变量用于线程等待条件成立。
7. fork 后父子进程的内存常通过 ______ 技术优化。
答案:写时复制
解析:copy-on-write 避免立即复制所有页面。
8. 子进程退出后,父进程可通过 wait 或 ______ 回收其退出状态。
答案:waitpid
解析:waitpid 可指定进程并支持非阻塞等选项。
9. I/O 多路复用中,Linux 下适合大量连接的机制常见是 ______。
答案:epoll
解析:epoll 常用于高并发网络服务。
10. 栈溢出常见原因包括递归过深或栈上申请过大的 ______。
答案:局部数组
解析:大局部数组会占用大量栈空间。
五、简答题
1. 简述进程和线程的区别。
参考答案:进程是资源分配的基本单位,拥有独立虚拟地址空间、进程 ID、文件等资源;线程是 CPU 调度的基本单位,同一进程内线程共享代码段、数据段、堆和打开文件,但每个线程有自己的栈、寄存器和程序计数器。线程切换通常比进程切换更轻,但共享资源带来同步问题。
2. 什么是死锁?如何预防或避免?
参考答案:死锁是多个执行流互相等待对方持有的资源,导致都无法继续。死锁产生需要互斥、占有且等待、不可抢占、循环等待四个条件。预防可破坏其中条件,如按固定顺序加锁破坏循环等待;避免可用银行家算法;也可检测死锁后回滚或杀死进程。
3. 解释虚拟内存的作用。
参考答案:虚拟内存为每个进程提供独立连续的虚拟地址空间,通过页表映射到物理内存。它提供地址隔离、权限保护、按需加载、换页能力,也简化程序内存模型。代价是地址转换开销和缺页处理开销。
4. 互斥锁、自旋锁、信号量有什么区别?
参考答案:互斥锁用于保护临界区,拿不到锁时通常阻塞;自旋锁拿不到锁时忙等,适合临界区极短的场景;信号量维护资源计数,可表示多个同类资源,也能用于同步。选择时要看等待时间、是否允许阻塞、资源数量和上下文。
5. 什么是缺页异常?
参考答案:进程访问某个虚拟页时,如果该页不在物理内存、页表项无效或权限不满足,会触发缺页异常。操作系统会判断访问是否合法;合法则可能从磁盘加载页面、更新页表并恢复执行;非法则向进程发送异常信号或终止进程。
6. select、poll、epoll 有什么区别?
参考答案:select 使用固定大小 fd 集合,数量受限,每次调用需要拷贝和线性扫描;poll 用数组表示 fd,突破 select 的 fd 数量限制,但仍需要线性扫描;epoll 采用事件驱动方式,适合大量连接,避免每次扫描全部 fd,是 Linux 高并发网络服务常见选择。
7. 游戏客户端主线程为什么不应该做阻塞 I/O?
参考答案:游戏主线程通常负责输入、逻辑和渲染调度,如果在主线程做磁盘或网络阻塞 I/O,会导致帧时间突然变长,表现为卡顿、掉帧甚至无响应。工程上通常用异步 I/O、工作线程、任务队列、资源预加载和分帧处理降低影响。
六、场景分析题
1. 场景:游戏客户端偶尔卡顿,Profiler 显示主线程在等待一个资源加载线程持有的锁。请分析可能原因和优化方案。
参考答案:可能是锁粒度过大、资源线程持锁期间执行了耗时 I/O 或解压,主线程竞争锁导致帧阻塞。优化方向:缩小临界区,只在交换共享状态时加锁;耗时加载、解压、解析放在锁外;使用无锁队列或双缓冲传递结果;主线程尝试非阻塞获取并延迟处理;对资源加载做异步化和分帧调度;监控锁等待时间和持锁栈。
2. 场景:某客户端长时间运行后内存持续增长,最终崩溃。请从操作系统和工程角度分析排查步骤。
参考答案:先确认是内存泄漏、缓存增长还是碎片问题。可观察进程 RSS/虚拟内存、堆分配统计、对象数量、资源引用计数。排查未释放的纹理/网格/音频、C++ new/delete 不匹配、智能指针循环引用、对象池只进不出、资源缓存无上限。工具上可用平台内存分析器、AddressSanitizer、Visual Studio Diagnostic Tools、操作系统进程监控。修复时建立资源生命周期、引用释放、缓存淘汰和压力测试。
3. 场景:两个线程偶发死锁,一个线程更新资源表,一个线程卸载资源。你会如何定位和修复?
参考答案:定位时记录锁获取顺序、线程栈、锁等待日志,确认是否存在 A 线程持有锁 1 等锁 2,B 线程持有锁 2 等锁 1。修复可统一加锁顺序,合并锁或拆分锁,使用 std::scoped_lock 同时获取多个锁,减少持锁范围,避免持锁调用外部回调或 I/O,必要时使用 try_lock 超时和诊断日志。