📄 一句话概括

编程就是把你想让电脑做的事,拆成一份 CPU 听得懂的指令清单。CPU 只会百来条基本动作、忠实地逐条执行,所以编程的真正功夫不在"写代码",而在"把大问题拆碎"。


1. 一个反常识的起点:CPU 其实很笨

前三篇我们造出了加法器(03),知道了晶体管怎么变成芯片(04)。现在把镜头对准芯片里真正的"决策者"——CPU(中央处理器),你会发现一个意外:

它不会思考,不会理解,甚至不会变通。它只会执行事先设计好的一套动作。

这套动作的总和叫指令集(Instruction Set),总共就百来条,比如:

动作类型 例子 大白话
数据搬运 MOV "把这个数搬到那儿"
算术运算 ADD、SUB "加一下"、"减一下"
逻辑运算 AND、OR、XOR 03 篇讲过的那些门
比较 CMP "这两个数一样吗?"
跳转 JMP、JZ "下一步不按顺序走了,跳到第 N 条"

就这么点词汇量。程序再庞大——微信有几千万行代码——拆到底全都是这几条动作的排列组合。

📝 为什么"跳转"这条最关键

有了 JMP(跳转),程序就能重复("没算完就跳回去再算一遍")和分情况("结果是 0 就走这条路,不是 0 走那条")。加上加法和搬运,理论上就能写出任何程序——这是 1936 年图灵证明过的:只要会"读、写、按条件跳",就能模拟一切计算。

2. 一条指令长什么样:动词 + 宾语

CPU 的每条指令都是一串固定的 0/1,结构永远是两段:

10111000 00000101
└──操作码──┘└─操作数─┘
  "放入"     "数字 5"

💡 类比:指令就是菜谱

菜谱:"取鸡蛋 2 个 → 打散 → 热油 → 下锅 → 翻炒 3 分钟"。 程序:"取 5 放入 A → 取 3 放入 B → A 加 B → 结果存入内存 → 显示"。 写程序 = 写菜谱。区别只在于:这位厨师一丝不苟到病态,菜谱少写一个字它就停摆,写错一个字它就照做不误。

寄存器是什么?就是 CPU 里离加法器最近的几个小抽屉(每个能存一个数)。算之前先把数从内存搬进抽屉,算完再搬回去——因为加法器(03 篇)只认抽屉里的数。

3. 同一件事,四种写法

任务:算 5 + 3,把结果存起来。看看它在不同层次的模样:

层次 写法 谁来看
机器语言 10111000 00000101 00000110 00000011… 只给 CPU 看
汇编语言 MOV AL, 5
ADD AL, 3
MOV 结果, AL
给爱较真的人看
C 语言 int result = 5 + 3; 给程序员看
Python result = 5 + 3 给人和程序员看

四种写法干的是同一件事,只是抽象层级不同:

📝 关键洞察:高级语言出现的意义

不是"更好写",而是把人和机器解耦了。程序员从此描述"要做什么",至于翻译成哪几条机器指令——那是编译器的事。这就是下一节的主角。

4. 翻译官:编译器与解释器

电脑不认识 result = 5 + 3,中间必须有个翻译官把高级语言翻成机器码。翻译有两种方式:

编译(提前翻译) 解释(现场翻译)
类比 出版前整本书译好 同声传译,说一句译一句
代表语言 C、C++、Rust Python、JavaScript
流程 源代码 → 编译器 → 可执行文件(.exe) 源代码 → 解释器边读边执行
优点 译好了直接跑,速度快 拿来就跑,改起来快
缺点 每次改完要重新编译 每次跑都要重新译,慢一些

📝 严格说,还有个中间层

Java、C# 这类语言走中间路线:先编译成"半成品"(字节码),运行时再由一个"虚拟机"现场翻给 CPU。现代解释型语言(Python、JavaScript)其实也带各种即时编译优化。小白阶段记住"要么提前译好,要么现场翻译"这个骨架就够了。

5. 存储程序:最漂亮的一步棋

现在把 03、04、05 串起来,看计算机体系结构里最核心的一条设计——存储程序(Stored Program)思想,1945 年由冯·诺依曼团队确立:

程序本身也是 0 和 1,和数据一样,存在同一块内存里。

这一句话的分量极重:

📌 5 + 3 在内存里的一生
  1. 双击程序 → 操作系统把机器码从硬盘复制进内存
  2. CPU 取指:把 5 放入寄存器 A
  3. CPU 取指:把 3 放入寄存器 B
  4. CPU 取指:A 加 B → 加法器(03 篇造的那个)通电,输出 8
  5. CPU 取指:结果送回内存
  6. CPU 取指:调用显示 → 屏幕出现 8 全程没有人手工干预——CPU 只是在忠实地念你的菜谱。

6. 程序员每天到底在干什么

知道了"编程 = 写菜谱",就能理解这个职业的真实日常:

  1. 拆问题:把"做个记账软件"拆成几百个 CPU 动作能表达的小步骤(这是主要工作,占 80%)
  2. 写代码:把步骤用编程语言精确地写下来
  3. 调试(Debug):菜谱写错了一步,厨师照做不误——结果菜是苦的。程序员的工作就是找到自己和机器之间理解不一致的地方。程序从不"出错",它只会精确执行你写错的指令
  4. 改需求:客人明天想加辣——回到第 1 步

📝 Bug 这个词的来历

1947 年,哈佛 Mark II 计算机(继电器机器,04 篇讲过)出了故障,工程师格雷丝·霍珀在继电器里揪出一只真·飞蛾,贴进了工作日志,写道"发现第一个 actual bug(虫子)"。从此"程序毛病"都叫 bug,"抓毛病"叫 debugging。你已经在 04 篇见过这只蛾子了。

7. 那我需要学一门编程语言吗?

先给结论:要不要背语法另说,"把问题拆成明确步骤"的能力,现在就值得练。

用大白话验证一下自己:能不能把"泡一杯茶"写成一份没有任何歧义的菜谱?试着写写看,你会发现:

这份"强迫症式拆解"就是编程思维(也叫算法思维)。语法是方言,随时能查;拆解是普通话,得练。

📝 和 AI 时代的关系

现在 AI 能帮你写代码了,那编程还有用吗?——AI 是更高一级的翻译官:你用自然语言说需求,它翻译成代码。但你依然得会拆解问题、看懂结果、发现"翻译错了"。上一层的翻译工具变了,"把意图拆精确"这个底层能力没变,反而更重要了。

8. 常见误区

⚠️ 误区一:编程需要数学很好

需要小学算术和逻辑清晰,不需要高数。程序员最常用的数学是加减乘除和比较大小。 [!warning] 误区二:编程语言就是英语,会英语就行 是形式语言,和英语的区别是:它不允许任何歧义,一个标点错了都不行。英语里说错话对方会脑补,机器不会——它只会照错执行。 [!warning] 误区三:电脑"理解"了我的程序 电脑从不理解任何东西。它只是高速、忠实地执行指令。所谓"智能软件",也是人把智能所需的步骤一条条写出来的。 [!warning] 误区四:改个后缀名就能换语言 .py 改成 .exe 不会变成可执行文件——格式看内容不看名字(这个坑到"文件与扩展名"篇细讲)。 [!warning] 误区五:代码越短越厉害 代码首先是写给人看的(第二才是给机器执行的)。清晰但长一点的代码,远好过玄妙但短一行的代码。

9. 可折叠自测题

❓ - Q1. CPU 的指令集大约有多少条指令?它能"理解"程序吗?

约百来条(搬运、加减、逻辑、比较、跳转)。 不能理解,只会忠实地逐条执行。"理解"从来都发生在写程序的人脑子里。 [!question]- Q2. 一条机器指令由哪两部分组成? 操作码(干什么,动词)+ 操作数(对谁做,宾语)。 例:10111000 00000101 = "把 5 放入寄存器"。 [!question]- Q3. 编译和解释的区别是什么?各举一门语言。 编译 = 出版前整本译好(C/C++ → 生成 .exe,跑得快); 解释 = 同声传译,边读边执行(Python/JavaScript,改起来快,跑得慢些)。 [!question]- Q4. "存储程序"思想说的是什么?它为什么让电脑变成万能机器? 程序本身也是 0/1 数据,和数据存在同一块内存里,CPU 取指→译码→执行循环处理。 因为程序是数据,就能被随时加载、更换——同一台硬件,装不同软件就是不同机器。 [!question]- Q5. 程序出 bug 了,是电脑"出错"了吗? 不是。电脑精确执行了你写错的指令。bug 的本质是"你写的"和"你想要的"不一致——所以调试是找回这个偏差,而不是修机器。


10. 下一步学什么


相关笔记