面试追问地图
| 主问题 | 必讲关键点 | 下一层追问 |
|---|---|---|
| 冯·诺依曼体系 | 五大部件、存储程序原理 | 哈佛结构区别、为什么”程序=数据” |
| 数据表示 | 原码/反码/补码、IEEE 754 | 阶码/尾数/规格化、浮点精度丢失 |
| 存储器层次 | 金字塔、局部性原理 | 每层容量/延迟的数量级差异 |
| Cache | 映射方式、替换策略、写策略 | 多级 Cache 为什么 L1/L2/L3 越来越慢越来越大 |
| 虚拟存储器 | 页表、TLB、缺页 | 与 OS 虚拟内存在不同层面的视角 |
| 指令系统 | 操作码/地址码、寻址方式 | CISC vs RISC 设计哲学 |
| 指令流水线 | 五阶段、流水线冒险 | 分支预测、超标量、乱序执行 |
| 中断与异常 | 中断向量表、中断处理过程 | 中断嵌套、中断优先级 |
| DMA | 直接内存访问、DMA 控制器 | 与通道的区别、总线仲裁 |
| 总线 | 数据/地址/控制总线、仲裁 | 同步 vs 异步通信 |
组成原理题要能画框图(CPU+存储器+I/O 三件套的连接关系),并说清数据在组件间如何流动。
一、计算机体系结构
冯·诺依曼体系结构与哈佛体系结构的区别是什么?
是什么:冯·诺依曼体系是”指令和数据放在同一存储器中,共享同一总线”的经典计算机模型;哈佛体系将指令和数据分存于两个独立存储器,各有独立总线。
| 维度 | 冯·诺依曼 | 哈佛 |
|---|---|---|
| 存储方式 | 指令+数据同一存储器 | 指令/数据分开存储 |
| 总线 | 共享总线 | 独立总线 |
| 瓶颈 | 冯·诺依曼瓶颈(取指和数据争用总线) | 无此瓶颈 |
| 适用 | PC、服务器 | DSP、MCU(嵌入式) |
为什么冯·诺依曼是主流:硬件简单、成本低;现代 CPU 用 Cache 分离(L1 指令 Cache + L1 数据 Cache) 在内部实现类哈佛结构,对外仍用统一内存,折中取两者之长。
常见追问:现代 CPU 到底是冯·诺依曼还是哈佛?→ 外部看是冯·诺依曼(统一内存),内部看是哈佛(L1 指令/数据 Cache 分开),叫”改进型哈佛架构”。
存储程序原理是什么?它对计算机设计有何重要意义?
是什么:程序以指令的形式预先存入存储器,CPU 按顺序从存储器中取出指令并执行。
意义:程序是可修改的”数据”——改变存储内容就能改变程序行为,无需重新接线。这是现代计算机的基石:编译器产出二进制指令→存磁盘→加载到内存→CPU 执行,整个软件栈都建立在这个前提上。
通用概念:存储程序原理使得”指令”和”数据”在物理上统一,是软件可编程性的基础。同类:JVM 字节码存入方法区,解释器逐条取出执行(见JVM类加载与执行引擎)。
什么是计算机体系结构?它与计算机组成原理有什么关系?
是什么:体系结构是程序员看到的”逻辑视图”(指令集、寄存器、内存模型、IO 模型);组成原理是实现这些逻辑的”物理硬件”(加法器设计、Cache 实现、流水线、总线连接)。
类比:体系结构 = 方向盘/油门/刹车(驾驶员看到的接口),组成原理 = 发动机/变速箱/转向机(怎么实现这些接口)。同一个 x86 指令集(体系结构),Intel 和 AMD 内部实现(组成原理)完全不同。
二、数据表示与运算
计算机中的编码方式有哪些?原码、反码、补码分别是什么?
是什么:三种有符号整数编码:
| 编码 | 规则 | 特点 |
|---|---|---|
| 原码 | 最高位符号位,其余位表示绝对值 | 简单直观,但 +0 和 -0 两个零 |
| 反码 | 负数:符号位为 1,其余位按位取反 | 仍有 +0/-0 问题 |
| 补码 | 负数:反码 + 1 | 一个零;[-128, 127] 范围比原码多一个负数 |
为什么计算机用补码:补码把减法变成加法——A - B = A + (-B)补码,CPU 只需一套加法电路,无需减法器。+0 和 -0 统一为 00000000。
常见追问:-128 的补码为什么是 10000000?→ 按规则 -127 补码 = 10000001,再减 1 = 10000000;没有对应的 +128(8 位有符号范围 -128~127),所以 10000000 就是 -128 的补码表示。
浮点数的表示方法是什么?IEEE 754 标准如何规定?
是什么:浮点数 = (-1)^S × 1.M × 2^(E - 偏移量)。以 32 位 float 为例:
31 30 23 22 0
+---+---------------+-----------------------+
| S | E (8 位) | M (23 位尾数) |
+---+---------------+-----------------------+
偏移量 = 127(双精度用 1023)- 规格化数:E 不全 0 且不全 1,尾数隐含前导 1(所以 23 位尾数实际表示 24 位精度)
- 非规格化数(E 全 0):表示非常接近 0 的数,前导为 0,用于填平 0 附近的”下溢缺口”
- 特殊值:E 全 1 + M 全 0 = 无穷大,E 全 1 + M 非 0 = NaN
常见追问:0.1 + 0.2 != 0.3 为什么?→ 0.1 和 0.2 转成二进制是无限循环小数,IEEE 754 只能存有限位,舍入误差累积导致。金融计算用 BigDecimal(见Java基础)。
计算机中的移位操作有哪些?各自的作用是什么?
是什么:四类移位操作:
| 操作 | 规则 | 作用 |
|---|---|---|
| 逻辑左移 | 低位补 0 | 乘 2^n |
| 逻辑右移 | 高位补 0(无符号) | 无符号数除 2^n |
| 算术右移 | 高位补符号位 | 有符号数除 2^n(向下取整) |
| 循环移位 | 移出的位补到另一端 | 位操作、加密 |
常见追问:Java >> 和 >>> 的区别?→ >> 算术右移(补符号位),>>> 逻辑右移(补 0);Java 没有 <<<。
ALU(算术逻辑单元)的功能和作用是什么?
是什么:CPU 内的执行部件,负责算术运算(加减乘除)和逻辑运算(与/或/非/异或)。由加法器(核心)+ 逻辑门电路 + 移位器组成,输入操作数 → 控制信号选择运算类型 → 输出结果和标志位。
什么是计算机的运算器?它的主要功能是什么?
是什么:运算器 = ALU + 累加器 + 通用寄存器组 + 状态寄存器(PSW/FLAGS)。ALU 负责计算,寄存器组暂存操作数和中间结果,PSW 记录进位/溢出/零/符号等标志位。
三、存储器层次结构
什么是计算机的存储器层次结构?它如何提高存储性能?
是什么:按速度/容量/成本从 CPU 向外逐级排列:
CPU 寄存器(~1ns, KB级) → L1 Cache(~1ns, 64KB) → L2 Cache(~7ns, 256KB~1MB)
→ L3 Cache(~20ns, 8~32MB) → 主存 DRAM(~100ns, GB级) → SSD/HDD(μs~ms, TB级)为什么这么设计:寄存器快但极贵,硬盘便宜但极慢——单级存储做不到”既快又大又便宜”,多级存储靠程序局部性原理把常用数据逐级向上缓存,使平均访存时间接近上层。
程序访问的局部性原理:
- 时间局部性:刚访问过的数据/指令很可能再次访问(循环体、热点变量)
- 空间局部性:刚访问过的地址附近的数据很可能即将访问(数组遍历、顺序执行)
通用概念:多级存储是”快慢搭配,逐级缓存”——CPU Cache 缓存内存热点、TLB 缓存页表项、MySQL Buffer Pool 缓存磁盘数据页、Redis 缓存数据库结果,都是同一模式在不同层级的具体化。
Cache 存储器的作用是什么?如何提高计算机性能?
是什么:Cache 是 CPU 与主存之间的高速小容量存储器(SRAM),利用局部性原理缓存热点数据,让 CPU 大部分访存命中 Cache(1~20ns)而非访问主存(~100ns)。
Cache 关键设计参数:
- 映射方式:直接映射(简单但冲突多)、全相联(灵活但硬件贵)、组相联(折中,主流)
- 替换策略:LRU(最近最少使用)、随机(简单硬件实现)、FIFO
- 写策略:写直达(每次同时写 Cache 和主存,一致性简单但慢)/ 写回(只写 Cache 标记脏,置换时写回,性能好但需一致性协议)
Cache 替换策略有哪些?各有什么优缺点?
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| LRU | 淘汰最久未使用的行 | 利用时间局部性,命中率高 | 硬件开销大(需维护访问顺序) |
| 随机 | 随机选一个淘汰 | 硬件极简单 | 可能淘汰正在用的热数据 |
| FIFO | 淘汰最早加载的行 | 硬件简单 | 不区分冷热,可能出现 Belady 异常 |
| LFU | 淘汰访问次数最少的 | 适合长期热点 | 历史高频但不再用的数据迟迟不淘汰 |
常见追问:什么是 Belady 异常?→ FIFO 在增大 Cache 容量后反而命中率下降——因为 FIFO 不依据”局部性”淘汰,增加容量只扩大了”管理范围”而非”命中概率”。LRU 和 LFU 属于栈算法,无此异常。
SRAM 与 DRAM 的区别是什么?各自应用场景如何?
| 维度 | SRAM | DRAM |
|---|---|---|
| 存储单元 | 6 个晶体管(触发器) | 1 个晶体管 + 1 个电容 |
| 速度 | 快(~1ns) | 慢(~100ns) |
| 集成度 | 低(芯片面积大) | 高(面积小) |
| 刷新 | 不需要 | 需要定期刷新(电容漏电) |
| 功耗 | 空闲功耗低 | 需刷新功耗 |
| 价格 | 贵 | 便宜 |
| 用途 | CPU Cache | 主存(内存条) |
多级存储体系是如何提高系统性能的?
核心原理:利用局部性 + 包含关系(L1 ⊂ L2 ⊂ L3)。L1 小而快(命中延迟 1ns),L2 大一些但慢一点(7ns),L3 再大再慢(20ns)。CPU 先查 L1,miss 了查 L2,再 miss 查 L3,仍 miss 才访问主存——大部分请求在 L1 命中,平均访问时间接近 L1。
为什么 L1/L2/L3 越来越慢越来越大:越靠近 CPU 对速度要求越高,容量受限于”能在这个延迟内完成寻址的最大面积”;L3 是大共享池,用面积换命中率。
什么是虚拟存储器?它如何实现内存的扩充?
是什么:从组成原理角度看,虚拟存储器是 MMU 完成的”虚拟地址→物理地址”映射,让每个进程认为自己独占整个地址空间,实际物理内存按需分配。
对应 OS 视角的虚拟内存已在操作系统详解,本节聚焦硬件层面:MMU 查 TLB → miss 则硬件 walk 页表 → 找不到则触发缺页中断交给 OS 处理。
存储保护的概念是什么?通常采用什么方法实现?
是什么:防止进程访问不属于自己的内存区域。实现方式:
- 界限寄存器:存”基址 + 长度”,每次访存检查是否越界
- 页表保护位:每页设 R/W/X 权限位,MMU 在地址翻译时检查
- 特权级(内核态/用户态):内核态可访问所有内存,用户态受限
与操作系统的关系:OS 设置页表保护位,MMU 硬件执行检查——是软硬件协同的典型例子。
四、指令系统
机器指令与微指令的区别是什么?
| 维度 | 机器指令 | 微指令 |
|---|---|---|
| 层级 | 程序员可见 | CPU 内部,不可见 |
| 粒度 | 一条机器指令对应一个完整操作 | 一条机器指令 = 多条微指令 |
| 执行者 | CPU(软件驱动) | 微程序控制器(硬件驱动) |
| 示例 | ADD R1, R2 | ① R1→ALU-A ② R2→ALU-B ③ ALU 做加法 ④ 结果→R1 |
微指令的作用:CISC 复杂指令用微程序实现,每条机器指令对应一段微程序序列;RISC 指令简单,通常用硬连线而非微程序。
指令的寻址方式有哪些?各有什么特点?
| 寻址方式 | 操作数位置 | 特点 |
|---|---|---|
| 立即寻址 | 指令自带 | 快,但值固定 |
| 直接寻址 | 指令给出有效地址 | 简单,但地址范围受限 |
| 间接寻址 | 指令→地址→操作数 | 灵活,但多一次访存 |
| 寄存器寻址 | 在寄存器中 | 最快,主流方式 |
| 寄存器间接寻址 | 寄存器存地址→内存 | 指针操作 |
| 变址寻址 | 基址 + 变址寄存器 | 数组访问 |
| 相对寻址 | PC + 偏移量 | 跳转指令 |
| 堆栈寻址 | 栈顶 | 函数调用传参 |
指令周期与机器周期的区别是什么?
| 维度 | 指令周期 | 机器周期 |
|---|---|---|
| 定义 | 取一条指令到执行完全过程 | 一次总线操作(如一次访存) |
| 包含关系 | 1 个指令周期 = 多个机器周期 | 1 个机器周期 = 多个时钟周期 |
| 典型过程 | 取指→译码→执行→访存→写回 | 从内存读一个字到 CPU |
常见追问:不同指令的指令周期一样长吗?→ 不一样。MOV 可能只需取指 + 执行,DIV 需要多轮执行微操作。现代 CPU 指令流水线把不同指令的阶段重叠执行,平均 CPI 接近 1。
什么是计算机的指令系统?它如何影响计算机的性能?
是什么:指令集(ISA)定义了 CPU 支持的全部指令,包括:操作码、寻址方式、寄存器组、数据类型。x86(CISC)指令变长、功能复杂;ARM/RISC-V(RISC)指令定长、功能简单。
CISC vs RISC:
| 维度 | CISC(x86) | RISC(ARM、RISC-V) |
|---|---|---|
| 指令长度 | 变长(1~15 字节) | 定长(4 字节) |
| 指令数量 | 多(几百条复杂指令) | 少(几十条简单指令) |
| 寻址方式 | 多种 | 仅 load/store 访存 |
| 实现方式 | 微程序控制 | 硬连线控制 |
| 编译器 | 压力小 | 需要好的编译器配合 |
| 现代趋势 | 内部转 RISC 微操作 | 手机/嵌入式/IoT 主导 |
常见追问:现代 x86 到底算 CISC 还是 RISC?→ 取指是 CISC 指令,内部译码器拆成 RISC 风格的微操作再执行——CISC 外壳 + RISC 内核。
五、CPU 架构
CPU 中的寄存器有哪些?各自的作用是什么?
| 寄存器 | 作用 |
|---|---|
| 通用寄存器 | 存放操作数和中间结果(x86 的 EAX/EBX 等) |
| 程序计数器 PC | 存放下一条指令地址 |
| 指令寄存器 IR | 存放当前正在执行的指令 |
| 堆栈指针 SP | 指向栈顶 |
| 状态寄存器 PSW/FLAGS | 进位/零/溢出/符号等标志位 |
| 地址寄存器 | 存放访存地址 |
| 数据寄存器 | 暂存从内存读/写的数据 |
什么是流水线技术?如何提高 CPU 性能?
是什么:将一条指令的执行过程拆成多个阶段(取指→译码→执行→访存→写回),不同指令的不同阶段重叠执行。理想情况下,每个时钟周期完成一条指令(CPI=1)。
流水线冒险(让流水线不能全速运转的问题):
| 冒险类型 | 原因 | 解决方法 |
|---|---|---|
| 结构冒险 | 硬件资源冲突(如取指和访存共用同一 Cache) | 指令/数据 Cache 分离 |
| 数据冒险 | 后一条指令依赖前一条指令的结果 | 前递/旁路、流水线暂停 |
| 控制冒险 | 分支指令导致 PC 不确定 | 分支预测、延迟槽 |
常见追问:流水线深度越大越好吗?→ 不是。深度增加提升主频但增加单级延迟和冒险惩罚(分支预测失败要清空更多级),且功耗/复杂度上升。Intel 奔腾 4 的 NetBurst 架构(31 级流水线)是反面教材。
什么是计算机的并行性?提高并行性的技术有哪些?
是什么:同时执行多个操作或任务的能力。从 CPU 微架构到集群多层面:
- 指令级并行(ILP):流水线、超标量、乱序执行
- 数据级并行(DLP):SIMD(一条指令处理多个数据,如 SSE/AVX)、向量处理
- 线程级并行(TLP):多核、超线程(SMT)
- 任务级并行:多机集群
CPU 和 GPU 区别:CPU 重延迟(少核高频,大 Cache,ILP 导向),GPU 重吞吐(数千小核,小 Cache,DLP 导向)。CPU 适合分支复杂的控制流,GPU 适合大规模并行计算(图形渲染、矩阵运算)。
计算机中的控制器是如何工作的?主要功能是什么?
是什么:控制器是 CPU 的”指挥中心”,负责取指令、译码、生成控制信号、协调各部件工作。由 PC、IR、时序发生器、译码器、控制信号生成逻辑组成。
工作流程:PC→地址总线取指令→放入 IR→译码器解析→生成控制信号→ALU 执行→访存/写回→PC 更新为下一条指令地址。
六、中断与异常
什么是中断?中断的处理过程是怎样的?
是什么:CPU 在执行过程中遇到特殊事件,暂停当前任务,转去执行中断处理程序,处理完返回继续执行。中断是 CPU 与外部设备异步通信的核心机制。
处理过程:
- 外设发中断请求信号
- CPU 完成当前指令,检查中断允许
- 保存现场(PC、PSW、寄存器入栈)
- 查中断向量表,跳转到对应中断处理程序
- 恢复现场,中断返回
中断 vs 异常:中断是外部异步事件(键盘、磁盘),异常是 CPU 内部同步事件(除零、缺页、非法指令)。中断的返回地址是下一条指令,异常的返回地址通常是当前指令(修复后重试)或异常处理。
什么是中断向量表?在中断处理中有什么作用?
是什么:一块存储中断处理程序入口地址的表。每个中断类型有一个编号(中断向量号),CPU 用它查表找到对应的处理程序地址。x86 实模式下在内存低端 0~1023 字节(256 个中断向量 × 4 字节/项)。
中断优先级是如何设置的?有什么作用?
是什么:当多个中断同时发生时,CPU 按优先级决定先处理哪个。常见优先级:机器错误 > 时钟中断 > 磁盘 I/O > 网络 I/O > 键盘。高优先级中断可嵌套中断低优先级中断的处理。
什么是 DMA 控制器?它如何减轻 CPU 的负担?
是什么:DMA(Direct Memory Access)控制器让外设不经过 CPU 直接与内存交换数据。CPU 只需告诉 DMA 控制器”源地址、目标地址、传输长度”,DMA 控制器接管总线完成传输,完成后发中断通知 CPU。
为什么需要 DMA:没有 DMA 时,磁盘读 1KB 数据需要 CPU 逐字节从磁盘控制器读到寄存器再写到内存(PIO 模式),全程占用 CPU;DMA 让 CPU 只需要发起+收尾,传输期间 CPU 可以执行其他任务。
常见追问:DMA 和 CPU 如何共享总线?→ 总线仲裁(DMA 优先级通常高于 CPU),DMA 采用周期窃取(cycle stealing)——趁 CPU 不使用总线时插入一个 DMA 周期的数据传输。
什么是计算机的通道?它与 DMA 有什么异同?
| 维度 | DMA | 通道 |
|---|---|---|
| 复杂度 | 简单,只能做数据搬运 | 有自己的指令集,可执行通道程序 |
| 独立性 | 受 CPU 控制 | 独立于 CPU,可管理多个 I/O 设备 |
| 适用 | 微机 | 大型机 |
什么是计算机的输入输出系统?主要功能是什么?
是什么:CPU 与外部设备之间的数据交换桥梁。包括 I/O 接口(硬件)和 I/O 控制方式(软件协同)。
I/O 控制方式(从 CPU 参与度由高到低):
- 程序查询:CPU 循环检查设备状态,全程占用 CPU
- 程序中断:设备就绪发中断,CPU 响应处理
- DMA:CPU 只发起和收尾,传输由 DMA 控制
- 通道:通道独立执行 I/O 程序,CPU 仅在开始/结束介入
I/O 接口与端口的区别:I/O 接口是设备与总线的连接部件(硬件实体),端口是接口中可被 CPU 访问的寄存器(地址空间中的编号,如 x86 的 I/O 端口 0~65535)。
七、总线
总线的分类及其功能是什么?
是什么:总线是连接 CPU、内存、I/O 设备的数据传输通道。按功能分为三类:
| 总线 | 功能 | 方向 |
|---|---|---|
| 数据总线 | 传输实际数据 | 双向 |
| 地址总线 | 传输访存地址 | 单向(CPU→内存/I/O) |
| 控制总线 | 传输控制信号(读/写/中断等) | 各信号固定方向 |
总线宽度和频率对性能的影响:数据总线宽度决定一次传输的字节数;地址总线宽度决定最大寻址空间(如 32 位地址总线 → 4GB 地址空间);总线频率决定传输速度的上限。
什么是同步通信和异步通信?各有什么优缺点?
| 维度 | 同步通信 | 异步通信 |
|---|---|---|
| 时序 | 靠统一时钟同步 | 靠握手信号(请求/应答) |
| 速度 | 快(时钟频率决定) | 较慢(握手开销) |
| 兼容性 | 所有设备必须支持同一时钟频率 | 快慢设备可以混合连接 |
| 实现 | 简单 | 复杂 |
| 适用 | 高速总线(CPU 内部总线) | 异构设备(串口、USB) |
什么是总线仲裁?常见方式有哪些?
是什么:多个设备同时请求使用总线时,决定谁先用的机制(类似多线程竞争锁)。
| 仲裁方式 | 原理 | 特点 |
|---|---|---|
| 链式查询 | 仲裁信号沿菊花链传递 | 简单,但优先级固定且故障传播 |
| 计数器查询 | 仲裁器轮询各设备号 | 灵活,但需要额外地址线 |
| 独立请求 | 每个设备有独立请求/应答线 | 最快,但信号线多 |
八、指令流水线进阶
指令流水线中的结构冒险、数据冒险、控制冒险怎么解决?
结构冒险(硬件冲突):指令 Cache 和数据 Cache 分离(L1-I + L1-D),避免取指和访存争用。
数据冒险(RAW 依赖):前递/旁路(不等写回就把 ALU 结果直接转发给下一条指令的输入)、流水线暂停(插入气泡)。
控制冒险(分支跳转):静态分支预测(编译器提示)、动态分支预测(BTB + 分支历史表)、投机执行(预测方向先执行,错了再回滚)。
什么是超标量和乱序执行?
- 超标量:一个时钟周期发射多条指令(多套 ALU、多套译码器),IPC > 1
- 乱序执行:指令按数据就绪顺序执行(而非程序顺序),有空闲 ALU 就上,最后按序提交保证结果正确
常见追问:乱序执行的结果怎么保证正确?→ 重排序缓冲区(ROB)暂存结果,按程序顺序提交(写回寄存器/内存),异常时精确恢复。
九、其他重要概念
CPU 和 GPU 的主要区别是什么?
| 维度 | CPU | GPU |
|---|---|---|
| 核数 | 少(4~32 核) | 多(数千核) |
| 单核性能 | 强(高主频、大 Cache) | 弱(简单控制逻辑) |
| 设计目标 | 低延迟(单线程快) | 高吞吐(并行处理多数据) |
| 适合任务 | 复杂控制流、分支多 | 数据并行(图形、矩阵运算、深度学习) |
| 内存 | 小容量高带宽 | 大容量超高带宽(HBM) |
计算机中的编码和解码过程是怎样的?
是什么:编码是指令→二进制机器码的过程(汇编器/编译器完成);解码是 CPU 译码器将机器码还原为操作码+操作数地址的控制信号。
示例:ADD R1, R2, R3(ARM)→ 0xE0811003(32 位机器码),译码器从高 4 位识别出”数据处理指令”,从中间位识别出”ADD”和寄存器编号,生成 ALU 加法控制信号。
什么是计算机的流水线技术?它如何提高 CPU 的性能?
超标量 + 流水线 + 乱序执行的组合是现代 CPU 性能的核心:
- 流水线:提高吞吐率(理想 CPI=1)
- 超标量:突破 CPI=1 限制(IPC>1)
- 乱序执行:在指令间找并行机会,填满流水线气泡