八股文 / 操作系统速查

操作系统面试速查题库

本页用于学完后的复习与面试表达。第一次学习请从 操作系统系统课 开始,先理解内核状态、资源队列和完整执行路径。


〇、操作系统介绍

1. 什么是操作系统

操作系统是介于硬件资源和应用程序之间的系统软件,能控制和管理计算机系统的硬件和软件资源,调度计算机工作与资源分配,为用户和软件提供服务。

2. 操作系统的特征

  • 并发:多个程序同时执行的能力
  • 共享:资源可供多个并发进程使用
    • 互斥共享:一段时间内仅一个进程访问
    • 同时访问:多个进程交替访问
  • 虚拟:物理实体转化为逻辑对应物
  • 异步:进程以不可预知的速度推进

3. 操作系统的功能

  1. 资源分配与回收 - 管理CPU、内存、硬盘、I/O设备
  2. 为应用程序提供服务 - 通过系统调用提供统一接口
  3. 管理应用程序 - 控制进程生命周期
  4. 内核功能 - 进程调度、内存管理、硬件通信、系统调用

4. 操作系统的角色

  • 管理者:CPU、内存、外存、I/O管理
  • 魔术师:使每个进程感觉独占资源

5. 用户程序与操作系统的关系

相互调用的关系——操作系统启动后管理所有进程,进程调用操作系统服务实现功能。


一、进程与线程

1. 进程和线程的区别

简要回答:

  • 进程:计算机中一个执行的程序实例,是操作系统资源分配的最小单位
  • 线程:比进程更小的概念,也称”轻量级进程”,一个进程可拥有多个线程
维度 进程 线程
调度单位 在引入线程前是调度最小单位 引入内核级线程后是调度最小单位
资源分配 资源分配最小单位 拥有少量资源
并发性 多进程可并发执行 多线程可并发执行
独立性 默认不共享全局变量,独立地址空间 共享大部分资源
系统开销 通信和切换开销大 通信和切换开销小
多处理机 单进程只运行在一个处理机 多线程进程可充分利用多处理机

详细回答:

进程具有四个主要特点:动态性、并发性、独立性和异步性。引入线程的优势包括进一步提高并发性、共享地址空间、更轻量级,以及提升交互性。

线程实现方式:

  1. 用户级线程:应用程序实现管理,操作系统感知不到
  2. 内核级线程:由操作系统内核支持,线程是系统调度最小单位

2. 进程间通信方式

  1. 信号量机制 - 通过P/V操作控制资源访问,解决同步互斥问题
  2. 共享存储机制 - 允许多个进程直接访问同一块内存区域,传输高效
  3. 消息传递机制 - 需要内核支持,通过消息队列传递数据块
  4. 管道通信机制 - 分为匿名管道(父子进程)和命名管道(无关进程)
  5. 套接字机制 - 网络通信方式,支持不同主机间进程通信

详细说明:

  • 信号量:同步通信机制,支持P()和V()原子操作
  • 共享存储:细分为共享数据结构和共享存储区两种方式
  • 消息传递:包括直接通信和间接通信(信箱模式)
  • 管道:匿名管道常用于亲缘进程,命名管道可用于无亲缘进程;它是内核维护的字节流,容量和原子写入边界依操作系统实现与配置,不能固定理解为 4KB
  • Socket:支持TCP(面向连接)或UDP(无连接)

3. 进程调度算法

七大调度算法:

  1. 先来先服务(FCFS) - 非抢占式,按到达顺序执行。优点:简单公平;缺点:长作业阻塞短作业
  2. 短进程优先(SPF/SRT) - SPF(非抢占)vs SRT(抢占式),优化平均等待时间,问题:长作业可能饥饿
  3. 优先级调度(PSA) - 根据优先级分配处理器,适用:实时系统,风险:低优先级进程饥饿
  4. 高响应比优先(HRRN) - 响应比 = (等待时间 + 运行时间) / 运行时间,兼顾公平性与效率
  5. 时间片轮转(RR) - 每个进程分配等量时间片,适用:交互式系统
  6. 多级队列调度 - 多个队列采用不同算法,可根据任务类型定制策略
  7. 多级反馈队列调度 - 现代操作系统标准方案,新进程从最高优先级开始,逐级降级
算法 特性 优点 缺点
FCFS 非抢占 简单公平 可能convoy效应
SJF 非抢占 最小平均等待 可能饿死长作业
RR 抢占 公平性好 上下文切换开销
优先级 可选 支持优先级区分 可能低优先级饿死
MLFQ 抢占 自适应调度 实现复杂

4. 作业调度、内存调度、进程调度的区别

  • 作业调度(高级调度/长程调度):从后备队列中选择作业调入内存并创建进程,调度频率低(分钟到小时级),控制系统并发度
  • 内存调度(中级调度/中程调度):在内存紧张时将部分进程交换到外存,调度频率中等(秒到分钟级)
  • 进程调度(低级调度/短程调度):从就绪队列选择进程执行,调度频率极高(毫秒级)

二、CPU状态与模式

1. 处理机的两种状态

  • 核心态(Kernel Mode):CPU执行操作系统内核代码时的工作状态,可执行所有指令、访问所有内存、直接操作硬件
  • 用户态(User Mode):CPU运行用户应用程序时的工作状态,只能执行非特权指令,通过操作系统接口间接完成硬件操作

状态切换途径:

  1. 系统调用(应用程序主动请求)
  2. 中断(外部设备请求)
  3. 异常(程序错误或特殊条件)

模式切换开销:

  • 直接开销:保存/恢复寄存器、切换栈指针、更新CPU模式位
  • 间接开销:缓存和分支预测状态可能被扰动;TLB 是否失效取决于是否切换地址空间及硬件地址空间标识等机制

2. 用户态和内核态

  • 用户态:应用程序在用户空间执行代码时的运行模式,CPU仅能运行部分指令且只能访问用户空间内存
  • 内核态:CPU可运行全部指令、访问全部内存空间,具有硬件完全访问权限
  • 交互机制:系统调用作为安全接口,触发用户态到内核态的切换

三、中断与异常

1. 什么是中断、异常

中断(Interrupt):

  • 由外部硬件设备产生的异步事件信号
  • 特性:异步、可屏蔽、可嵌套
  • 分类:硬件中断(可屏蔽INTR和非屏蔽NMI)、软件中断(INT指令触发)

异常(Exception):

  • CPU内部执行指令时检测到的同步事件
  • 特性:同步、不可屏蔽、精确性
  • 分类:故障(缺页异常,可恢复)、陷阱(断点、系统调用)、终止(硬件故障,严重错误)

2. 中断和异常的区别

维度 异常 中断
同步性 同步于指令执行 异步于当前指令
来源 CPU内部 CPU外部
返回点 因类型而异 被中断指令的下一条

中断响应阶段(硬件自动完成):

  1. 关中断,禁止新中断响应
  2. 保存断点和程序状态字
  3. 引出中断服务程序

中断处理阶段(软件执行):

  1. 保护现场(保存通用寄存器)
  2. 执行中断处理程序
  3. 恢复现场并开中断

3. 中断处理流程

四个阶段:中断请求 → 中断响应 → 中断处理 → 中断返回

关键步骤:中断源产生 → 中断控制器仲裁 → CPU保存程序计数器和状态字 → 向量表查询 → 执行中断服务程序 → 恢复现场

中断分类: 硬中断(IRQ)、软中断(INT指令)、异常(除零、缺页)、不可屏蔽中断(NMI)


四、同步与互斥

1. 线程的同步方式

内核级线程同步方式:

  • 互斥锁(Mutex):确保同一时间只有一个线程进入临界区,Linux的futex优化减少上下文切换
  • 信号量(Semaphore):控制资源访问数量,包括计数信号量和二进制信号量
  • 条件变量:用于线程间状态通知,需搭配互斥锁使用,典型应用是生产者-消费者模型
  • 读写锁:允许多读单写,适合读多写少场景
  • 自旋锁:忙等待锁,适用于多核短临界区

用户级线程同步方式:

  • 原子操作:通过CAS等原子指令避免锁开销
  • 协程同步原语:如Go的channel,通过消息传递替代共享内存
  • 轻量级锁:先尝试用户态自旋,失败后升级为内核锁

2. 几种典型的锁

  • 互斥锁:保护临界区,确保独占访问,通常与条件变量配合使用
  • 读写锁:读锁共享,写锁独占,适合缓存系统、数据库等读多写少场景
  • 自旋锁:通过忙等待实现,避免线程切换开销,适用于锁占用时间极短的场景

信号量、锁和条件变量的关系: 信号量是通用同步机制,互斥锁是其特例(二进制信号量)。读写锁和自旋锁不属于信号量特例,是针对不同场景的锁类型。

3. 进程的同步与互斥

同步:多个进程按一定顺序执行,确保数据正确性和一致性 互斥:多个进程不能同时访问共享资源,防止数据竞争

实现方法:

  • 软件实现:单标志法、双标志先检查法、双标志后检查法、Peterson算法
  • 硬件实现:关中断方法、TSL和Swap指令
  • 高级机制:信号量、管程、屏障、条件变量

四条设计准则:

  1. 空闲让进:无进程在临界区时立即允许进入
  2. 忙则等待:有进程在用临界资源时其他进程等待
  3. 有限等待:保证进程在有限时间内进入临界区
  4. 让权等待:无法进入时释放处理器

五、死锁

1. 什么是死锁及如何避免

定义:多个进程或线程因竞争资源而互相等待,导致无法继续执行的现象

四个必要条件:

  1. 互斥条件:资源一次仅被一个进程占用
  2. 请求和保持条件:持有资源的同时请求其他资源
  3. 不可抢占条件:资源只能由进程主动释放
  4. 循环等待条件:存在进程的循环等待链

预防方法:

  1. 破坏互斥条件:允许资源被多个进程共享
  2. 破坏请求和保持条件:请求资源时必须释放已持有资源
  3. 破坏不可抢占条件:允许系统抢占已占用资源
  4. 破坏循环等待条件:对资源排序,按顺序请求

2. 产生死锁的原因

  • 资源竞争:多进程争用有限资源
  • 推进顺序不当:进程执行顺序不合理
  • 资源分配策略问题:缺乏预防和避免机制
  • 程序设计缺陷:未考虑资源获取顺序

死锁处理策略: 预防 → 避免(银行家算法)→ 检测(资源分配图检测环路)→ 恢复(终止进程或剥夺资源)

3. 银行家算法

由Dijkstra提出的动态资源分配算法,对于每次资源申请实时判断死锁风险。

数据结构:

  • Available[m]:系统各类资源可用数量
  • Max[n][m]:进程最大资源需求矩阵
  • Allocation[n][m]:当前资源分配矩阵
  • Need[n][m]:进程剩余需求 = Max - Allocation

安全性检查: 使用Work向量和Finish数组,寻找满足 Finish[i] == FALSE && Need[i][j] ≤ Work[j] 的进程,依次分配直至所有进程完成或无法继续。

优缺点: 严格避免死锁、资源利用率较高,但需预先声明最大需求、时间复杂度O(n²)。


六、内存管理

1. 虚拟内存

概念:操作系统提供的逻辑扩充内存的方法,为每个进程提供独立连续的地址空间,结合物理内存和磁盘空间扩展可用内存。

核心机制:

  • 地址空间隔离:每个进程拥有独立虚拟地址空间(32位系统通常4GB)
  • 分页机制:将虚拟内存和物理内存划分为固定大小的页(通常4KB)
  • 按需调页:仅在实际访问时才将页面加载到物理内存
  • 写时复制:多个进程共享只读页面,写操作时再创建副本
  • 内存映射文件:将文件直接映射到进程地址空间

实现方式: 请求分页(固定大小页面)和请求分段(不同大小段落)

2. 内存分段和分页

分段存储管理: 将程序逻辑地址空间划分为多个可变长度的段(代码段、数据段、堆栈段),便于编程但容易产生外部碎片。

分页存储管理: 将物理内存划分为固定大小的页框和页面,通过页表实现地址映射,消除外部碎片但可能产生内部碎片。

维度 分段 分页
地址类型 二维(段号+偏移) 一维(页号+偏移)
碎片类型 外部碎片 内部碎片
用户可见性 不透明 透明

现代操作系统主要采用分页机制,结合TLB和MMU硬件支持。

3. 页面置换算法

算法 优点 缺点 适用场景
OPT(最佳置换) 理论最优,缺页率最低 无法实现,需预知未来 理论分析参考
FIFO(先进先出) 实现简单,开销低 可能引发Belady异常 简单系统
LRU(最近最久未使用) 性能接近OPT 实现复杂,开销较高 高性能要求系统
LFU(最少使用) 适合频率差异明显场景 对突发模式不敏感 访问模式稳定系统
Clock(时钟置换) 实现简单,性能接近LRU 引用位判断可能不准确 平衡性能和复杂度
改进Clock 减少I/O开销 实现更复杂 I/O性能要求高

Belady异常:增加内存帧数反而导致缺页率上升,FIFO算法容易出现。

局部性原理:时间局部性(最近访问的可能再次访问)和空间局部性(访问位置附近可能被访问)。

4. 内存连续分配管理方式

  • 单一连续分配:内存分为OS和用户程序两部分,同时仅一个用户进程,无碎片但CPU利用率极低
  • 固定分区分配:启动时划分为若干固定大小分区,产生内部碎片
  • 动态分区分配:不预先划分,按需分配。四种算法:首次适应、最佳适应、最坏适应、邻近适应。长期使用产生外部碎片

七、I/O与设备管理

1. I/O控制方式

  1. 程序直接控制(轮询) - CPU主动持续检查设备状态,实现简单但CPU利用率极低
  2. 中断驱动方式 - 设备完成后向CPU发送中断信号,CPU利用率提高
  3. DMA方式 - DMA控制器接管数据传输,CPU只需初始化,适合高速大批量数据
  4. 通道控制方式 - 通道作为专用I/O处理器独立执行,有自己的指令系统,CPU几乎完全解放

2. IO模型

5种IO模型:阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO

核心差异在于等待数据就绪阶段和数据拷贝阶段的处理策略。

模型 特点 适用场景
阻塞IO 简单但并发差 简单客户端、低并发
非阻塞IO 需轮询,CPU占用高 GUI应用、简单游戏服务器
IO多路复用 单线程处理多连接 Nginx、Redis、WebSocket
信号驱动IO 内核数据就绪时通知 UDP服务器、嵌入式
异步IO 真正异步,用户态不参与 高性能文件服务器、数据库

同步IO vs 异步IO: 前4种都是同步IO(数据拷贝阶段需进程参与),只有异步IO整个过程进程不需参与。

3. epoll为什么比select/poll高效

  • 事件驱动:仅返回就绪的文件描述符,避免遍历所有fd
  • 内核回调:通过回调机制通知就绪事件,O(1)时间复杂度
  • 共享内存:减少用户空间和内核空间的数据拷贝
  • 红黑树存储fd:插入删除为O(log n)
特性 select poll epoll
时间复杂度 O(n) O(n) O(1)
连接数限制 1024
内存拷贝 每次调用都拷贝 每次调用都拷贝 内核-用户共享
触发方式 水平触发 水平触发 支持水平/边缘触发

4. 磁盘调度算法

磁盘访问时间 = 寻道时间 + 旋转延迟 + 传输时间

算法 特点 缺陷 适用场景
FCFS 公平、简单 性能最差 轻负载、SSD
SSTF 性能好 可能饥饿 中等负载
SCAN 无饥饿 边缘请求等待长 多用户系统
C-SCAN 等待时间均匀 牺牲部分性能 实时系统
LOOK 改进SCAN 实现较复杂 文件服务器
C-LOOK 改进C-SCAN 实现较复杂 多媒体服务器

5. 设备管理的主要功能

  • 设备分配:独占分配(打印机)、共享分配(磁盘)、虚拟分配(SPOOLing)
  • 设备驱动:统一接口,硬件抽象,驱动模型分类(字符设备、块设备、网络设备)
  • 缓冲管理:单缓冲、双缓冲、循环缓冲、缓冲池
  • 中断处理:产生中断请求 → 保存现场 → 识别中断源 → 执行中断服务程序 → 恢复现场
  • 错误检测与恢复:ECC校验、重传机制、坏块管理

八、其他

1. 用户程序变为可执行程序

四个阶段:

  1. 预处理 - 展开头文件、宏替换、条件编译
  2. 编译 - 词法分析 → 语法分析 → 语义分析 → 代码优化 → 代码生成(汇编代码)
  3. 汇编 - 汇编代码转译为机器指令,生成目标文件
  4. 链接 - 符号解析 → 地址分配 → 重定位 → 库链接 → 生成可执行文件

静态链接 vs 动态链接: 静态链接将库代码直接复制到可执行文件;动态链接仅包含库引用,运行时加载。

2. 硬链接与软链接的区别

维度 硬链接 软链接(符号链接)
inode 共享相同inode 独立inode
文件系统 必须同一文件系统 可跨文件系统
删除原文件 仍可访问数据 成为悬空链接
链接目标 只能链接文件 可链接文件和目录
存储内容 目录项引用inode 存储目标路径字符串

硬链接不能跨文件系统的原因:inode号仅在同一文件系统内唯一,不同文件系统有各自独立的inode编号空间。


来源:卡码笔记