# 《计算机是怎样跑起来的》知识点全解 > AI生成|2026年10月29日|codebuddy|原书:矢泽久雄《计算机是怎样跑起来的》,人民邮电出版社,2015-05-01 > **我的阅读**:进度 100%|累计 4小时31分钟|开始 2018-08-15|最近 2024-05-15|读完 2019-04-03 ## 一句话总结 把"计算机"从黑箱拆回可理解的机器:先用三大原则给出统一视角,再从通电的电路一路走到汇编指令、程序流程、算法、数据结构、面向对象、数据库和网络,让读者建立起"从晶体管到应用"的完整因果链,从而在面对新技术时能迅速定位它落在哪一层。 ## 适合谁 / 前置知识 **适合**:非科班转行的开发者、刚入学的计算机专业学生、需要与工程师对话的产品/测试/运维人员,以及"会用框架但说不清底层"的从业者。本书以图配文、以 Z80 这类可理解的芯片为标本,阅读门槛在同类书里偏低。 **不适合**:已有系统级功底、想深入性能优化或内核实现的读者——本书定位是"建立直觉",不是"提供深度"。想读 CPU 微架构、虚拟内存页表、TCP 拥塞控制细节,需要另找专著。 **前置知识**:只需初中数学与"二进制/十六进制"的模糊印象;会一点点 C 或任意语言有助于理解变量与内存,但不是必需。全书不要求高数、不要求电路基础。 ## 一、全书地图 全书是一条"自底向上"的纵向主线,第 1 章定坐标,第 2–3 章讲硬件与机器码,第 4–7 章讲软件构造,第 8 章讲数据落地,简介提及的网络/加密/XML/系统开发属于"对外连接与工程化"的延伸段(出版社目录节选未展开其章节号,此处不补编号)。 | 层次 | 章节 | 核心问题 | 与前后章的关系 | |---|---|---|---| | 总纲 | 第1章 计算机的三大原则 | 计算机到底是什么 | 给全书提供三把尺子,后面每章都在验证它 | | 硬件 | 第2章 试着制造一台计算机吧 | 一台能跑的机器由哪些元件、哪些线组成 | 把第1章的"输入/运算/输出"落到电路与总线 | | 硬件→软件 | 第3章 体验一次手工汇编 | CPU 到底在执行什么 | 承接第2章的存储器,向下打通到指令编码 | | 软件 | 第4章 程序像河水一样流动着 | 指令如何组织成流程 | 从单条指令上升到控制结构 | | 软件 | 第5章 与算法成为好朋友的七个要点 | 如何设计解题步骤 | 流程之上是"解法",与第6章互为表里 | | 软件 | 第6章 与数据结构成为好朋友的七个要点 | 数据如何摆放 | 算法的时间/空间成本由数据结构决定 | | 软件 | 第7章 成为会使用面向对象编程的程序员吧 | 大型程序如何组织 | 数据结构与流程的组织学,面向规模 | | 数据 | 第8章 一用就会的数据库 | 数据如何持久化与共享 | 从进程内内存走向进程外的持久存储 | | 延伸 | 网络 / 加密 / XML / 系统开发与SE(简介提及) | 机器之间如何通信、如何保证可信、如何交付 | 把单机知识扩展为系统与工程 | 一句话读法:**第1章当索引,第2–3章当"实物课",第4–7章当"写法课",第8章当"存法课"**。若时间有限,2、3、8 三章的"祛魅"价值最高。 ## 二、核心知识点 ### 1. 三大原则:一切技术的归位坐标 **是什么**:①计算机是执行输入、运算、输出的机器;②程序是指令和数据的集合;③计算机的处理方式常与人的直觉不同(对它而言什么都是数字)。 **为什么重要**:它是全书的认识论。任何新技术——容器、GPU、消息队列——都可以问三句:输入是什么、运算是什么、输出是什么;它的"指令"和"数据"分别在哪;它把什么连续的东西离散化成了数字。 **怎么用**:读一个陌生中间件文档时,先画"输入→运算→输出"三格,再标出状态存在哪。往往十分钟就能判断它属于计算密集型还是搬运型。 **常见误区**:把第三条理解成"计算机很笨"。真正的含义是**离散化**:声音被采样成数字、颜色被拆成 RGB、文字被编码成码位,精度与连续性的取舍才是工程难点。 ### 2. 硬件最小闭环:CPU、内存、I/O、总线 **是什么**:一台可运行的计算装置只需四类部件——运算与控制核心(CPU)、存放指令与数据的存储器、与外界交换的 I/O、以及把它们连起来的总线(地址总线、数据总线、控制总线)。 **为什么重要**:第2章的"造机"实验证明计算机没有神秘部件。理解了这个闭环,就能理解为什么内存带宽会成为瓶颈、为什么 I/O 常是性能短板。 **怎么用**:排查"程序慢"时按闭环分段——CPU 算得慢(算力)、内存取不到(带宽/缓存未命中)、I/O 等太久(磁盘/网络)。三段定位比盲目优化有效。 **常见误区**:以为"总线"是一根线。它是一组按位并行的通道,地址总线位宽决定可寻址空间,数据总线位宽决定单次搬运量。 ### 3. 地址空间:内存与 I/O 可以统一编号 **是什么**:CPU 通过地址总线发出地址,再用控制信号区分这次访问是读还是写、目标是内存还是 I/O。第2章专门用引脚说明了这种"读写对象判别"。 **为什么重要**:这是"内存映射 I/O"的思想源头——设备寄存器被安排进地址空间,用普通读写指令即可操作硬件。今天读 `/dev`、操作寄存器、理解 MMIO,都源于此。 **怎么用**:看到一个外设手册给出"寄存器基地址 + 偏移",就知道那是一片被映射的地址;访问它和访问数组在指令层面可能只差一个地址常量。 **常见误区**:把"地址"当成"物理内存条上的位置"。地址是 CPU 视角的编号,中间可能还有译码、分页、重映射。 ### 4. 时钟信号:同步是数字电路的前提 **是什么**:时钟提供节拍,各部件在节拍沿上采样与翻转,从而在"组合逻辑的延迟"与"寄存器的稳定"之间取得确定行为。 **为什么重要**:主频不是"算得多快"的魔法数字,而是"每拍留给电路稳定的时间有多少"。这解释了为什么提升频率会遇到功耗与信号完整性墙,也解释了流水线、并行度的价值。 **怎么用**:估算一段代码的耗时,先看指令条数,再看每条指令的周期数(CPI),最后乘时钟周期;量级对了,再去查缓存与分支预测的修正项。 **常见误区**:用"主频高 = 性能好"跨架构比较。不同微架构的 IPC 差异可以让低频芯片反超。 ### 5. 机器语言与汇编语言:一一对应的两个视角 **是什么**:机器语言是 CPU 真正执行的二进制编码;汇编语言用助记符(如 `LD`、`ADD`、`JP`)表示同样的指令,经汇编器翻译成机器码。二者基本一一对应,而高级语言的一行往往对应多条指令。 **为什么重要**:第3章的"手工汇编"是全书的认知转折点——当你能把一条 `ADD` 手写成字节,CPU 就不再是黑箱。它也解释了为什么反汇编、调试器、漏洞分析都停留在这一层。 **怎么用**:遇到"这行代码为什么编译出这么多指令",用 `objdump`/反汇编看一眼;遇到性能热点,先确认编译器是否把循环优化掉了。 **常见误区**:以为汇编一定更快。现代编译器在寄存器分配与指令调度上常优于手写,汇编的价值更多在**可控**(特定指令、特定布局)而非**更快**。 ### 6. 寄存器与 CPU 执行模型(以 Z80 为例) **是什么**:CPU 内部有一小组高速存储:通用寄存器(Z80 的 A、B、C、D、E、H、L 等,可配对成 16 位)、标志寄存器 F(保存零标志、进位、符号等)、程序计数器 PC(下一条指令地址)、栈指针 SP。 **为什么重要**:这四类角色在所有架构上都存在(x86 的 RAX/RIP/RSP、ARM 的 X0/PC/SP)。理解了"取指—译码—执行—写回"和 PC 的自增,就理解了程序为何能"流"下去。 **怎么用**:读崩溃栈时,把 PC 当"事故地点"、SP 当"调用链的书签"、标志位当"上次比较的结论"。函数调用本质是压栈返回地址 + 跳转。 **常见误区**:认为寄存器越多越好。寄存器数量受指令编码位宽限制,且上下文切换要保存,过多会增加开销。 ### 7. 程序的三种基本流程 **是什么**:顺序、分支(选择)、循环。任何复杂流程都可由这三者组合而成。 **为什么重要**:第4章把"程序像河水一样流动"讲透——流程图不是文档装饰,而是把控制流外化的工具。它决定了你能否在写代码前发现死循环、漏分支。 **怎么用**:写函数前先用三块积木画出流程;若出现"从循环中间跳出去到另一个循环",说明结构已被破坏,应重构。 **常见误区**:把 `switch` 当成第四种结构。它只是多路分支的一种写法;`break`/`continue`/`return` 也只是分支的语法糖。 ### 8. 结构化程序设计:单入单出 **是什么**:用顺序、选择、循环三种结构组装程序,限制随意跳转(`goto`),使每个程序块只有一个入口和一个出口。 **为什么重要**:单入单出保证了"局部可推理"——读一个块不必考虑它是从哪跳进来的。这是后来所有模块化、函数式、微服务边界思想的远祖。 **怎么用**:审查代码时找"多入口":被多处 `goto` 跳入的标签、被外部直接修改的全局状态、能从中途 `return` 且副作用未清理的函数。 **常见误区**:教条地认为 `goto` 一律有害。内核与错误清理路径中,集中跳转到 `cleanup` 反而是更清晰的单出口写法。 ### 9. 中断处理与事件驱动 **是什么**:中断是硬件或软件打断当前流程、转去执行处理函数再返回的机制;事件驱动则是把"等待"变成"注册回调,事件到来时被调用"。 **为什么重要**:这两者让程序从"我按顺序问"变成"有事才叫我",是 GUI、服务器、嵌入式实时系统的共性基础。理解中断就能理解为什么临界区要关中断、为什么回调里不能做重活。 **怎么用**:设计服务时区分"轮询"与"事件":低频且要求简单用轮询,高频且要求实时用事件;事件处理函数只做入队,重活交给工作线程。 **常见误区**:在中断/回调里做阻塞 I/O 或长时间计算。这会拖住事件循环,表现为"系统没崩但全部变慢"。 ### 10. 算法的七个要点(可迁移的解题纪律) **是什么**:步骤明确且有限;计算机只机械执行、不靠直觉;掌握典型算法;利用计算机的速度;用编程技巧提速;从数字中找规律;先在纸上想清楚。 **为什么重要**:这七条其实是"问题形式化 → 复杂度判断 → 模式匹配 → 常数优化 → 数学洞察 → 先设计后编码"的完整流水线,比记住快排代码有用得多。 **怎么用**:拿到需求先问"输入规模 n 大概多少"。n 很小就写最直白的解法;n 很大再考虑排序、哈希、二分、前缀和这些"熟语"。 **常见误区**:一上来就优化常数。复杂度选错,常数优化再多也是白费;反之复杂度对了,常数优化才有边际收益。 ### 11. 数据结构:内存布局决定操作成本 **是什么**:数组是连续同型元素的集合,靠下标做 O(1) 随机访问;栈是后进先出;队列是先进先出;结构体把异型字段打包;链表靠指针把离散节点串起来;二叉树用左右子树实现有序查找。 **为什么重要**:第6章的落脚点是"变量即内存"。理解了地址与偏移,就理解了为什么数组按下标快、链表按下标慢、结构体有内存对齐填充。 **怎么用**:需要频繁随机读 → 数组;需要频繁头尾增删 → 链表或双端队列;需要"最近使用优先" → 栈;需要"先来先服务" → 队列;需要有序范围查询 → 平衡二叉树/B+树。 **常见误区**:把"逻辑结构"和"物理实现"混为一谈。栈既可用数组实现也可用链表实现,`stack` 是行为约定,不是内存布局。 ### 12. 面向对象的七个观点与三种用法 **是什么**:OOP 可以被理解为——拼装组件、提升开发效率与可维护性、面向大型程序、为现实世界建模、借助 UML 设计、通过消息驱动、使用继承/封装/多态。类有三种典型用法:作为**模板**创建实例、作为**组件**被复用、作为**类型**参与多态。 **为什么重要**:第7章的价值在于"多视角"——OOP 不是一条定义,而是一组权衡。只记住"封装继承多态"会写出为了继承而继承的深层树。 **怎么用**:设计时先问"变化点在哪"。变化在算法 → 策略模式(多态);变化在结构 → 组合优于继承;变化在创建 → 工厂。类名应是名词,方法名应是动词,消息即调用。 **常见误区**:把"为现实世界建模"当成"照抄现实分类"。软件建模只保留与需求相关的属性与行为,过度建模会得到庞大而僵硬的类层次。 ### 13. 数据库:从文件到 DBMS **是什么**:数据文件是裸存储,DBMS 在其上提供并发控制、事务、查询与完整性约束,数据库应用程序则是面向用户的那一层。设计流程是:确定实体与属性 → 拆表消除冗余(规范化)→ 用主键唯一标识行、外键表达表间关系 → 为高频查询建索引 → 设计界面 → 用 SQL 做 CRUD。 **为什么重要**:这是"数据"与"程序"解耦的分水岭。规范化减少更新异常,索引用空间换查询时间——两个动作方向相反,必须按读写比例取舍。 **怎么用**:建表先写到第三范式(每列只依赖主键),确认无更新异常后,再为报表类查询**有意**反规范化;给 WHERE/JOIN 的高选择度列建索引,但别给低基数列(如性别)建。 **常见误区**:索引越多越好。每个索引都会拖慢写入并占用空间;`LIKE '%x%'`、函数包裹列、隐式类型转换都会让索引失效。 ### 14. 网络与加密:把单机扩展为系统(简介提及的延伸段) **是什么**:TCP/IP 用分层把"应用—传输—网络—链路"解耦,IP 负责寻址与路由,TCP 负责可靠传输与流量控制,端口区分进程。加密分为对称(快、密钥分发难)、非对称(慢、可解决分发)、哈希(不可逆、用于完整性)。 **为什么重要**:分层让每层可以独立演进;HTTPS 正是"非对称协商 + 对称传输 + 证书验证"的组合。理解了分工,就不会问"为什么不用 RSA 加密全部流量"。 **怎么用**:排查连通性按层自下而上——物理/链路通不通、IP 能否 ping 通、端口能否 telnet、应用层是否返回错误码。设计鉴权时区分"传输加密"与"身份认证"两件事。 **常见误区**:用哈希存密码却不加盐、不做慢哈希。哈希保证不可逆,但不加盐会被彩虹表击穿。 ## 三、关键概念速查表 | 概念 | 一句话解释 | 用在哪儿 | |---|---|---| | 三大原则 | 输入运算输出、指令加数据、一切皆数字 | 给任何新技术定位 | | 总线 | 地址/数据/控制三组并行通道 | 判断寻址空间与搬运带宽 | | 时钟周期 | 电路完成一拍稳定的时间单位 | 估算指令耗时、理解主频 | | 机器语言 | CPU 直接执行的二进制编码 | 反汇编、调试、漏洞分析 | | 汇编语言 | 用助记符一一对应机器指令 | 理解编译产物、写启动代码 | | 寄存器 | CPU 内的高速暂存单元 | 读崩溃栈、理解调用约定 | | PC / SP | 下一条指令地址 / 栈顶地址 | 定位崩溃点与调用链 | | 结构化程序设计 | 只用顺序、选择、循环,单入单出 | 代码审查、降低耦合 | | 中断 | 打断当前流程转去处理的机制 | 实时系统、驱动、异步 I/O | | 事件驱动 | 注册回调,事件到来才执行 | GUI、服务端、消息消费 | | 数组 | 连续同型元素,下标 O(1) | 随机访问、缓存友好场景 | | 栈 / 队列 | 后进先出 / 先进先出 | 撤销、表达式求值 / 任务调度 | | 链表 | 指针串联离散节点 | 频繁插入删除、内存不连续 | | 二叉树 | 每节点至多两子,可有序 | 有序查找、范围查询 | | 封装 / 继承 / 多态 | 隐藏实现 / 复用扩展 / 同一接口多种实现 | 控制变化点、解耦调用方 | | 规范化 | 拆表消除冗余与更新异常 | 表结构设计第一步 | | 主键 / 外键 | 唯一标识行 / 引用他表主键 | 保证实体与参照完整性 | | 索引 | 以额外空间换取查询速度的有序结构 | 高频 WHERE / JOIN 列 | | CRUD | 增删改查四类数据操作 | SQL 与接口设计的最小集 | | TCP / IP | 可靠传输 / 寻址路由,分层协作 | 网络排障与协议选型 | | 对称 / 非对称加密 | 同一密钥 / 公私钥配对 | 批量加密 / 密钥协商 | ## 四、可复用的方法/框架 **1. 三层归位法(读任何新技术)** ① 它接收什么输入、产出什么输出 → ② 它的"指令"(控制逻辑)和"数据"(状态)分别存在哪 → ③ 它把哪些连续量离散化了、精度代价是什么。三问之后再看 API,理解速度会明显不同。 **2. 自底向上定位性能问题** 先判层:算力(CPU 饱和)、取数(缓存未命中/内存带宽)、等待(I/O、锁、网络)。层判错,优化必错。判层之后才谈算法复杂度与常数优化。 **3. 算法设计的七步检查单** 问题能否用有限步骤描述 → 规模 n 是多少 → 有没有典型算法可套 → 是否该让机器暴力算 → 常数层面能否优化 → 数据里有没有可利用的规律 → 是否已在纸上画清。任何一步缺失都先停下来补。 **4. 数据结构选型四问** 需要随机访问吗(数组)→ 需要按序取出吗(栈/队列/堆)→ 增删频繁且位置不定吗(链表)→ 需要有序范围查询吗(树/索引)。四个问题基本覆盖日常选择。 **5. 表设计的两阶段法** 第一阶段严格规范化到第三范式,确认没有插入/更新/删除异常;第二阶段针对确定的查询模式做**有意识**的反规范化与索引,并记录理由。禁止在第一阶段就为"可能快一点"而冗余。 **6. 排障的分层收敛法** 网络按 TCP/IP 层自下而上;程序按"输入是否到达 → 状态是否改变 → 输出是否发出"三段收敛。每层只回答一个是/否,避免同时怀疑所有组件。 ## 五、我的阅读轨迹 | 项目 | 数据 | |---|---| | 阅读进度 | 100% | | 累计阅读时长 | 4 小时 31 分钟 | | 开始阅读 | 2018-08-15 | | 最近阅读 | 2024-05-15 | | 读完时间 | 2019-04-03 | **轨迹解读**:2018 年 8 月开读、2019 年 4 月读完,首轮跨度约 8 个月,属于"边读边消化"的节奏;2024 年 5 月仍有回访,说明这本书被当作工具书而非一次性读物。4.5 小时的累计时长也印证了它的定位:**轻量、可跳读、适合反复抽查**。 **复习建议**:全书已读完,不必线性重读,按"遗忘成本"排序复习—— - **优先**:第3章(手工汇编)。寄存器与指令编码最容易忘,且是理解后续一切的地基。 - **其次**:第6章(数据结构)与第5章(算法)。这两章是面试与日常编码的高频区,建议配合手写代码复习。 - **再次**:第8章(数据库)。规范化与索引的取舍需要在真实表结构上练,光看会"以为懂了"。 - **抽查即可**:第1、2、4、7 章。三大原则、总线、三种流程、OOP 七观点属于"看一遍能记很久"的类型。 - **补读提示**:简介提及的网络、加密、XML、系统开发与 SE 部分,若当时未细读,可作为下一轮的重点;这部分在本书中偏概览,建议搭配专书。 ## 六、行动清单 1. 用三大原则给手头正在用的一个框架写三行说明:输入、运算、输出分别是什么。 2. 找一段自己写的热点代码,反汇编后数一数实际指令条数,验证对"一行代码 ≠ 一条指令"的直觉。 3. 手写一个只用顺序、选择、循环的函数,刻意不用 `goto` 与提前 `return`,体会单入单出的可读性差异。 4. 用数组和链表各实现一次队列,测量 10 万次入队出队的耗时差,记录结论。 5. 为一个已有业务表画 ER 图,标出主键与外键,检查是否存在更新异常。 6. 给一条慢查询加索引,用执行计划对比加索引前后的扫描行数。 7. 用 `traceroute` 与 `curl -v` 各跑一次,把一次请求按 TCP/IP 分层拆开写下来。 8. 把本文"关键概念速查表"做成抽认卡,每月自测一次,答不出的回到对应章节。 ## 七、延伸阅读 1. **《编码:隐匿在计算机软硬件背后的语言》——Charles Petzold** 关联:同样讲"从继电器到计算机",但硬件推演更细、更连续。**先读**它可把第2章的电路直觉打牢;若已读本书,则用它补齐"门电路如何搭出加法器"的链条。 2. **《计算机科学概论》——J. Glenn Brookshear** 关联:横向铺开的教材式全景,覆盖操作系统、网络、算法、数据抽象。**在本书之后读**,把本书的纵向主线扩展成学科地图,适合作为长期案头参考。 3. **《深入理解计算机系统》(CSAPP)——Randal E. Bryant / David R. O'Hallaron** 关联:本书第3、6章的"深水区"。**最后读**,需要 C 语言与一定动手能力;读完后回看本书的汇编与内存章节,会有"原来如此"的回收感。 **建议顺序**:本书(建立直觉)→ 《编码》(补硬件)→ 《计算机科学概论》(补广度)→ CSAPP(补深度)。若目标是面试速成,可先本书 + 数据结构专章,CSAPP 择章精读。