本文是专栏《从零看懂计算机》的第 16 篇(共 16 篇连载)——收官之作。
没有新概念了。这一篇只做一件事:把 15 篇攒下的全部零件,装进同一台机器。网页上四块实时跳动的图表——CPU、内存、磁盘、网络——每一块都是你亲手解剖过的器官。第 10 篇和第 11 篇埋的最后两颗雷,本篇实测引爆;六本登记册、四颗雷、十六条军规,同一天收线。
文章目录
- 写在前面
- 一、项目总览:给机器挂上仪表盘
- 1.1 架构三层(每层都是学过的)
- 1.2 动手前先想清楚两笔账(系列条件反射)
- 二、动手:三步搭起看板
- 2.1 后端:采样线程 + HTTP 接口(约 100 行)
- 2.2 前端:每秒跳动的四块图表
- 2.3 一键构建:出厂
- 三、GIL 雷终爆:多线程采集,实测说话
- 3.1 实验设计
- 3.2 读数:两种结局都合法
- 四、泄漏雷终爆:24 小时长跑体检
- 4.1 体检怎么做
- 4.2 两把止血刀待命(第 11 篇)
- 五、全系列总合龙
- 5.1 六本登记册大地图
- 5.2 机器=一栋楼:类比总图
- 5.3 雷台账:全部清零
- 5.4 军规十六条合龙
- 5.5 世界观收官词
- 六、结业三件套
- 6.1 研究报告(交付物一)
- 6.2 知识地图(交付物二)
- 6.3 收官拼图测验:10 题(交付物三)
- 七、本文总结
- 写在最后(系列终章)
- 附:术语速查表(收官纪念版·精选 16 词)
写在前面
本篇你能搞懂:
- 怎么把 16 天的知识装进一个真实项目(不是"复习",是上岗);
- GIL 雷终爆:多线程采集到底快不快——用你自己的数字说话;
- 泄漏雷终爆:长跑体检,曲线平的才是好服务;
- 全系列总合龙:登记册大地图、类比总图、军规十六条、世界观收官词。
先看项目成品长什么样:浏览器打开一个本地网页,四块图表每秒跳动——CPU 占用、内存占用、磁盘读写速度、网络流量。后端是约一百行 Python:采样线程不停量"器官",HTTP 接口对外报数,前端网页每秒来取一次。第 7 篇你为"卡"分诊的四行表(CPU 满载/等缓存/等换页/GPU 供不上帧)——从今天起,你有仪表盘了。
一、项目总览:给机器挂上仪表盘
1.1 架构三层(每层都是学过的)
| 层 | 用什么 | 哪篇的本事 |
|---|---|---|
| 采集端 | Python + psutil,后台线程每秒采样 | 第 9 篇进程视角、第 10~11 篇线程与内存 |
| 接口端 | 裸 HTTP 服务(不用框架,复用 D13 迷你框架思路) | 第 13 篇 socket、第 14 篇好莱坞原则 |
| 展示端 | 单文件网页 + 图表,每秒拉取刷新 | 第 7 篇帧率直觉、第 8 篇信封 |
数据流:psutil 量器官 → 采样线程存最近数值 →/stats接口报 JSON → 网页每秒来取 → 图表动起来。一条第 12~13 篇的"流",从文件流换成了网络流。
1.2 动手前先想清楚两笔账(系列条件反射)
- 刷新率账(第 7 篇帧率直觉):监控数据 1 秒变一次,网页刷 60 次也是同一个数——内容变化频率决定刷新率,1 秒拉取刚刚好。为什么不是 10 秒?鼠标点开进程列表那一下,你等不起(第 9 篇响应式错觉);
- 量纲账(第 12 篇条件反射):磁盘"MB/s"和内存"MB"不是一回事——接口输出前先统一好单位,前端不许做除法猜量纲。
二、动手:三步搭起看板
2.1 后端:采样线程 + HTTP 接口(约 100 行)
请用 Python 标准库 + psutil 写一个"机器资源监视看板"后端: 1. 一个后台采样线程:每 1 秒用 psutil 采集 CPU 占用、内存占用、 磁盘读写速度(disk_io_counters 差值/秒)、网络收发速度 (net_io_counters 差值/秒),存进一个全局字典(最近 N 次历史); 2. 一个 HTTP 服务(socket 裸写,不用框架): GET / → 返回看板网页(单文件 HTML) GET /stats → 返回 JSON:四项指标的当前值+最近 60 秒历史 (注意:单位在服务端统一好——速度用 KB/s、容量用 MB); 3. 代码里用注释标出:哪几行是"框架主循环(它跑的)"、 采样线程在哪行启动——我要看清好莱坞原则和"它调你"。跑起来curl http://127.0.0.1:9879/stats——第 13 篇偷看浏览器开场白的位置,这次轮到你当服务器。
2.2 前端:每秒跳动的四块图表
接着给 / 的看板网页(单 HTML 文件,可用 Chart.js/ECharts 图表库): 1. 四块图表:CPU、内存、磁盘速度、网络速度——折线滚动 60 秒; 2. setInterval 每 1 秒 fetch('/stats') 更新数据; 3. 注释说明:为什么不用更快的刷新(数据 1 秒才变一次); 4. 页面加载失败要显示错误横幅(第 8 篇"哪层出问题查哪层"的 应用层自查)。浏览器打开——四块器官开始跳动。这是你自己机器的心电图。
2.3 一键构建:出厂
把第 15 篇的build.sh跑在这个项目上:venv →pip install -r requirements.txt→ pytest → zip。从源码到成品,一条命令——第 14/15 篇的纪律(清单+lock+合格证)全部上岗。
三、GIL 雷终爆:多线程采集,实测说话
第 10 篇记的账,原话在此:“GIL 只锁’执行字节码’的时刻,线程在等 IO 时会放锁——采集线程会不会被 GIL 卡死?”第 13 篇你已见过预演,今天正式结案。
3.1 实验设计
请写一个"采样对决"脚本: 1. 串行版:主线程里依次采 4 类指标(CPU/内存/磁盘/网络), 连续 30 秒,统计平均一轮耗时; 2. 多线程版:4 个线程各盯一类指标,同样 30 秒; 3. 打印两种模式的平均耗时和比值; 4. 把 CPU 占有率也打印出来(我要看采样本身吃多少 CPU)。3.2 读数:两种结局都合法
- 多线程明显更快:采样的大部分时间花在等 psutil 读数(IO 等待)——等待时放锁让路,4 线程轮流上独木桥,等待被并行摊掉(第 13 篇压测同款结论,正式版);
- 差别不大:psutil 单次读数太快、等待占比太低——放锁省下的时间不够抵线程切换成本。这不是"理论错了",是你这台机器上等待占比本来就小。
无论哪种结局——GIL 雷拆除的标志不是"多线程赢了",是"你现在能用等待占比解释一切":第 10 篇说"CPU 密集白招"(等待占比≈0,独木桥全程占用)、本篇看板"IO 密集有戏"(等待占比高)——一个模型,两段命运,以你的实测为准。CPU 密集真要并行?开多个进程(每进程一间独立车间+独木桥各归各)——multiprocessing 一句话带走,不展开。
四、泄漏雷终爆:24 小时长跑体检
第 11 篇记的账:“D16 收官项目要长跑一个采集服务——真程序连跑几天:内存曲线平的才是好服务。”
4.1 体检怎么做
请把看板后端改造成"长跑模式": 1. 加一个 /health 接口:返回当前进程的内存占用(RSS) 和已运行的秒数; 2. 我要把它跑一整天——给出观察方案:每隔 10 分钟记录一次 RSS(可以写个小脚本自动记 CSV); 3. 说明判断标准:曲线平=通过;持续爬升=有泄漏嫌疑 (先查全局历史列表是不是只增不减——最常见事故)。4.2 两把止血刀待命(第 11 篇)
- 曲线爬升先别慌:先查全局
history列表(只增不减=设计 bug,不是 Python 的锅)——加个上限只留最近 60 秒,刀到病除; - 真循环引用泄漏再上
gc.collect()(第二把刀)——先诊断后开刀,只认曲线(军规五:虚拟大≠泄漏,泄漏只认长跑曲线)。
跑一夜。明早看曲线——平的,恭喜:你写的第一个"生产级"服务通过了出厂体检。这是结业研究报告里最值钱的一张图。
五、全系列总合龙
看板跑起来了,最后把 15 篇的资产全部收线入柜。
5.1 六本登记册大地图
| # | 登记册 | 翻什么 | 出处 |
|---|---|---|---|
| 一 | 页表 | 假地址→真格子(每个程序独占一层楼的障眼法) | 第 5 篇 |
| 二 | FTL | 逻辑页→物理块(SSD 的障眼法) | 第 6 篇 |
| 三 | 文件系统台账 | 文件名→格子集合 | 第 6 篇 |
| 四 | 字节码 | 源语言→中间速记语 | 第 10 篇 |
| 五 | 依赖清单 | 项目→零件来源(范围) | 第 14 篇 |
| 六 | lock | 整棵依赖树钉死存档 | 第 14 篇 |
一本比一本离硬件远、离工程近——但每一本干的是同一件事:建一张"从你手里的名字,查到机器里的实体"的表。看板的今天:psutil 的进程名查 PID、URL 路径查 handler、import 查字节码——你写的每一行代码都在查某种登记册。
5.2 机器=一栋楼:类比总图
┌─ 车间(进程/线程=工人) ─ 托盘架(栈) + 仓库空地(堆) 一栋楼 ───┼─ 格子墙(内存/页表假象) + 便签抽屉书架(CPU缓存L1/L2/L3) (计算机) ├─ 仓库(存储: 唱片机HDD/电子开关SSD + 六本登记册) ├─ 厨房(CPU: 大厨+洗车流水线+节拍器) ——— 画工队(GPU) └─ 大门(socket)→四层信封(网络)→对岸的楼上篇给了你硬件的物理真相,下篇给了你软件的布景机关。今天看板项目里:采样线程是工人、/stats 接口是大门、JSON 是纸箱清单、build.sh 是中央厨房——你在这栋楼里当了一天的物业总管。
5.3 雷台账:全部清零
| 雷 | 埋于 | 爆于 | 炸出来什么 |
|---|---|---|---|
| 缓冲三雷(条子/页缓存/灯跳) | 第 4/6/9 篇 | 第 12 篇 | syscall 攒车+writeback 一条流水线 |
| GIL 独木桥 | 第 10 篇 | 本篇三 | 等待占比解释一切 |
| 泄漏长跑 | 第 11 篇 | 本篇四 | 曲线平的才是好服务 |
四颗雷,全部实爆——没有一颗用"记住了"糊弄过去:每颗雷的引信都是一句"实测见分晓",而实测你都亲手做了。
5.4 军规十六条合龙
从第 3 篇到本篇,防幻觉军规一条条长大,今天是点兵总日:
| # | 军规 | 篇 |
|---|---|---|
| 一 | AI 只生成骨架,参数读者自查喂入 | 3 |
| 二 | 数字换算逐行脚本验算 | 3 |
| 三 | 只解读规格,不编跑分 | 3 |
| 四 | 不许先报理论值 | 4 |
| 五 | 虚拟大≠泄漏,只认长跑曲线 | 5 |
| 六 | 不许替你的盘编参数 | 6 |
| 七 | 不许报理论帧率 | 7 |
| 八 | 不许猜网络归因 | 8 |
| 九 | 不许编你机器的进程清单 | 9 |
| 十 | 语言倍数不许背 | 10 |
| 十一 | 不许凭代码诊泄漏 | 11 |
| 十二 | 不许报"复制应该几秒" | 12 |
| 十三 | 回环延迟≠网络性能 | 13 |
| 十四 | 不许替你背版本号 | 14 |
| 十五 | 不许保证"构建一次成功" | 15 |
| 十六 | 收官合龙:从硬件规格到软件行为,一切以实测为准 | 16 |
十六条是一条:AI 的话是假设,机器的读数才是事实。这句话你现在不用背了——16 篇里每一篇你都用行动执行过它。
5.5 世界观收官词
上篇收官送你的是:“没有任何一处快慢是玄学。”(第 8 篇——每个延迟都拆到了物理账单)
下篇一路讲的是:每个布景后面都有通道——每个"魔法"背后都是你走过的机关:障眼法有页表、加速有缓存、并发有调度、可靠有握手。
两句合龙,就是这 16 篇的全部:
这台机器没有魔法——只有你能理解、能实测、能亲手再造一遍的机制。
从"拆开一台机器"到"给机器挂上自己写的仪表盘",你走完的不是 16 篇文章,是从用户到主人的那条路。
六、结业三件套
6.1 研究报告(交付物一)
给你的看板项目写一份结业报告(1000 字左右,结构照抄):
请帮我搭一份结业研究报告骨架: 1. 做了什么:项目一句话 + 架构图(三层); 2. 测到什么数字:GIL 对决的两种耗时、长跑体检的曲线结论、 构建流水线的耗时——全部贴实测截图; 3. 对应哪天学的什么:每个数字后面标(第 N 篇),至少标 8 处; 4. 收获与反思:哪条军规救过你、哪个雷炸得最疼、下一个想 做什么项目。报告的含金量在第 2~3 节:数字必须是你机器上跑出来的(军规十六总验收),出处必须能对回具体某篇——这份报告同时是你的知识地图实体化。
6.2 知识地图(交付物二)
把 5.1/5.2/5.3/5.4 的四张表抄录(或重画)进你的笔记——登记册、楼、雷、军规——这就是 16 天的知识总拼图。以后忘了任何一块,按图索骥回具体某篇补课,十分钟后归位。
6.3 收官拼图测验:10 题(交付物三)
排序题:把下列步骤按真实发生顺序排列——
- ① 页表登记 ② 加载器搬成品进车间 ③
bash build.sh打包 ④ 采样线程第一次被调度 ⑤pip install拉零件 - ① DNS 查地址 ② 三次握手 ③ make 发现时间戳没变 ④ writeback 脏页刷盘 ⑤ 你在浏览器看见图表
填空题(答案标出处篇号):
- 六本登记册里,翻"位置"的是______、翻"语言"的是______、翻"零件来源"的是______。(第 5/6/10/14 篇)
- make 的增量靠比较______,和 OS 只刷______思想同源。(第 12/15 篇)
- 线程等 IO 时会______,所以 IO 密集多线程能绕开______。(第 10/16 篇)
- write() 返回≠落盘:数据在______里被标成______,由______批量刷盘。(第 12 篇)
- 框架和库的分界线:是框架的,你是被调用的——这条原则叫,最早干这行的是______。(第 14 篇)
- CPU 缓存 L1/L2/L3 是硬件层对程序______的;IO 缓冲是软件层______的——思想同源:______。(第 4/12 篇)
综合题:
- 你的看板前端 1 秒拉一次 /stats——这 1 秒里,浏览器、OS、网卡、服务器各自干了什么?至少写 6 个环节,每个标注出处篇号。
- 用"等待占比"一个模型,解释:为什么压测服务器多线程加速比到不了线程数、为什么 psutil 采样多线程可能没提升、什么情况下该开多进程。(第 10/13/16 篇)
- ⑤③②①④(build.sh 一条命令内部先拉零件⑤、跑测试、最后才打成 zip③——zip 是"打包完成"的时刻;之后目标机器上加载器搬成品②→登记页表①→线程才轮到被调度④;第 15/14/2/5/9 篇)
- 正解①②④⑤,③是干扰项——make 增量构建发生在构建期(第 15 篇),浏览器此刻拉取的是早已出厂的成品;④writeback 是服务器侧后台同时在干的活(写访问日志的脏页在刷盘——第 12 篇)。此题考"构建期 vs 运行期"的分界——最容易被忽略的一道墙。
- 位置:页表/FTL/文件台账(第 5/6 篇);语言:字节码(第 10 篇);零件来源:依赖清单/lock(第 14 篇)
- 时间戳;脏页(第 15/12 篇)
- 放锁;GIL 独木桥(第 10/16 篇)
- 页缓存;脏页;writeback(第 12 篇)
- 主流程;好莱坞原则(Don’t call us, we’ll call you);操作系统(第 14/9 篇)
- 透明;可见可调;摊薄固定成本(第 4/12 篇)
- 参考链:浏览器发请求(V8 车间/10)→DNS/握手(8/13)→四层信封封包(8)→网卡变电信号(1/8)→回环进服务器大门 accept(13)→好莱坞原则调你的 handler(14)→psutil 读/proc 查登记册(9)→JSON 纸箱清单打包(13/14)→原路返回→画工队渲染图表(7)→writeback 落盘不参与此秒但后台在跑(12)——满 6 个即合格,10 个全对说明你已经把这栋楼住熟了
- 压测:等待占比高但线程切换有成本、CPU 段仍独木桥(13);采样:psutil 读太快等待占比低,放锁省的抵不过切换(16);CPU 密集等待占比≈0 → 每进程一间车间,multiprocessing(10/16)
七、本文总结
📌① 项目即地图:四块图表=四个器官,三层架构=三篇功夫——结业项目是全课程知识的实体化,不是复习。
📌② 双雷实爆:GIL 用等待占比结案(两种实测结局都合法)、泄漏用长跑曲线结案(平的才是好服务)——第 10/11 篇的引信全部烧完,无一哑炮。
📌③ 总合龙:六本登记册一表收线、一栋楼总图归位、军规十六条点兵、"没有魔法"收官——从用户到主人的路,16 篇走完。
写在最后(系列终章)
16 篇,从"拆开一台机器"开始,到"给机器挂上你自己写的仪表盘"结束。
中间你经历过:装机单与带宽金字塔(1)、开机四幕(2)、CPU 的功耗墙与缓存阶梯(3/4)、内存的障眼法(5)、仓库的伺候账(6)、一帧画面的诞生(7)、一封信的四层信封(8);然后换了视角:操作系统的通道(9)、同一段代码的三种命运(10)、变量的一生(11)、三颗雷在一条流水线上合爆(12)、程序开口说话(13)、轮子大军(14)、出厂流水线(15)、今天的仪表盘(16)。
**上篇教你"看见"硬件,下篇教你"住进"软件,收官篇让你"接管"整机。**如果你跟完了全部实验——量过延迟、爆过雷、跑过一夜长跑——你已经拥有和任何一台计算机打交道的底气:它吓不到你,因为你拆过它;它骗不到你,因为你量过它。
这门课没有下一篇了。但你的机器还在跳——/stats每秒返回一次,四块图表就是你俩的对话。哪天某个数字不对劲,你不会再问"怎么办",而是问"哪一层、哪笔账"——那一刻,这门课才算真正毕业。
(专栏《从零看懂计算机》全 16 篇完结。目录见置顶评论,知识地图见本篇 6.2——欢迎回来补课,随时。)
附:术语速查表(收官纪念版·精选 16 词)
| 术语 | 一句话 | 出处 |
|---|---|---|
| 带宽金字塔 | 各级车道/延迟的物理底账 | 1 |
| 引导(Boot) | 把 OS 从仓库请成活进程 | 2 |
| 功耗墙 | 主频竞赛的物理终点 | 3 |
| 缓存阶梯 | 便签→抽屉→书架→图书馆 | 4 |
| 页表 | 第一本登记册:假地址翻真格子 | 5 |
| 伺候账 | HDD 随机 13ms 的三步成本 | 6 |
| 双缓冲 | 画工队后台画、前台翻页 | 7 |
| 四层信封 | 数据上网络的标准包装 | 8 |
| 系统调用 | 程序碰硬件的合法通道 | 9 |
| 三种命运 | 同一行代码的 C++/Java/Python 三条路 | 10 |
| GIL 独木桥 | 字节码同一时刻只一个线程过 | 10/16 |
| writeback | 脏页批量刷盘(灯还在跳的真身) | 12 |
| socket 四步 | 造门框→挂牌→营业→迎客 | 13 |
| 好莱坞原则 | 别打给我们,我们会打给你 | 14 |
| 增量构建 | 时间戳比较,变过的才重做 | 15 |
| 等待占比 | 解释多线程一切的钥匙 | 16 |
常见问题
- Q:看板只能看本机?想看别的机器呢?把服务端跑在目标机器、端口对局域网开放(bind 0.0.0.0),你浏览器访问它的 IP——跨机器版本就是"对岸换成了别人的楼"(第 13 篇姿势原样适用);注意安全:监控接口别裸奔到公网。
- Q:为什么不用现成监控工具(Prometheus 等)?它们是"用轮子"(第 14 篇完全合法);本篇是"造轮子"(教学目的)——造过一遍,再用轮子时你看得懂它每个零件在干嘛。
- Q:1 秒采样会不会漏掉瞬间尖峰?会(采样窗口内的脉冲看不见)——想抓尖峰要更快采样或事件钩子;这是"采样频率 vs 观察目标"的经典权衡,先用你的数字说话(军规十六)。
- Q:长跑 24 小时太久了?教学最小版可以缩到 1 小时看趋势;但真"生产级"的信心要靠真时长——第 11 篇的口径:曲线平的才是好服务,时长你自己定。
- Q:下一步学什么?顺着本系列的三条岔路任选:造更多轮子(框架/容器,第 14/15 篇延长线)、把看板变真产品(数据库/认证/部署)、或回到第 1 篇再拆一台新机器(ARM?)——知识地图在你手里,路由自己选。
- Q:报告写不出来怎么办?先把 6.3 测验做一遍——哪题卡壳,答案里标了篇号;补完那一篇再回来写,报告自然就出来了。