IBM 手册写得太差,他索性成了计算机科学家

原标题The IBM Manual Was So Bad He Became a Computer Scientist

Donald Knuth 与 Lex Fridman 对谈:他在 IBM 650 上写的第一批程序、文学化编程(literate programming)、Knuth-Morris-Pratt 算法,以及他证明过的最难的一条定理。

DKDonald Knuth嘉宾
频道
Lex Fridman Podcast
发布
2021年9月9日
视频
2:21:27
阅读
31 分钟
原文
英语
在 YouTube 打开
往下滚动阅读时,视频会缩到右下角继续播放。字幕跟随阅读语言。
阅读语言共 2 种语言可读
由 AI 从英语原文翻译。打开“对照原文”可以逐段核对。
摘要

30 秒看懂

1957 年夏天,还没读完大一的 Donald Knuth 深夜坐在 IBM 650 前,用手一条一条地拨入十进制指令。在与 Lex Fridman 的第二次对谈中,这位图灵奖得主沿着那台控制台,讲到文学化编程(literate programming)、TeX 排版系统、Conway 的超现实数(surreal numbers),以及巨大连通分支(giant component)的诞生。贯穿其中的,是一种执拗的谦逊:弄懂机器在做什么,写出一年后人还能读懂的代码,不去假装一个无解的问题已经有了答案。

  1. 1Knuth 的井字棋(tic-tac-toe)学习程序惩罚失误,却不奖励精彩的走法。因此,在约六百局随机对随机的对弈之后,它收敛到了一种稳妥的平局:它学会的是不输,并没有学会怎样赢。
  2. 2他在奥斯陆的一家酒店里写《超现实数》,文字涌出来的速度比他思考还快。第六天写完,第七天休息;接着他坐下来,想向秘书交代怎样打印书稿,却连一个完整的句子也写不出来。
  3. 3对 Knuth 来说,Feynman 在巴西的故事说的不只是一本尴尬的教科书:学校正在从传授知识,滑向发放资格证书。Bob Floyd 最喜欢的一幅漫画,也向一台快速的机器提出了同样的问题:你怎么知道它是对的?
  4. 4Jim Morris 把一个巧妙的字符串匹配程序放进了伯克利 Unix,却没有做任何解释。几个月后,有人看了代码,觉得它看起来不对,便把它拆掉了。没人读得懂的算法,跟不存在差不多。
  5. 5Knuth 用 π 的数字来生长随机图时,π 本身并没有什么特别的魔力。它是一个没人知道规律的比特来源,和掷骰子一样好用,这正是他一直用它的原因。
  6. 6他给年轻人的建议一如既往:不要追逐时髦,去尝试。人生是一次二分查找。有些实验适合你的脑子,有些则与你无缘,只有试过才知道。
全文

按章节阅读整理后的全文

只看原始文稿
01

IBM 650 的手册糟到让一个大一新生觉得自己有天分

Lex Fridman 开场问的是 Knuth 在 1957 年夏天写下的第一个大型程序。Knuth 当即纠正了这个前提:他用的是十进制机器语言,不是汇编,当时几乎没有人听说过汇编。你看的是用户手册。69 的意思是“装载分配器”,然后再给出地址。每条指令由十位十进制数字组成:两位是操作码,四位是操作数地址,另外四位是下一条指令的取址位置。整台机器只有两千个字的内存,地址从 0000 到 1999。

录制前一天,计算机历史博物馆的 Dag Spicer 给 Knuth 发来一个 YouTube 链接,内容是 IBM 1956 年的进展报告。影片里有 500 号机附近的装配线,还有斯坦福、MIT 以及 Knuth 自己所在的凯斯理工学院的教室,那时 IBM 已经向这些学校捐赠了 650。影片里,一位老师在黑板上写下“69 8000”,教学生给这台十进制机器编程。Knuth 说,他就是从这样一间教室开始的。如果随机附带的手册写得好,他大概根本不会走上计算机科学这条路。手册烂到什么程度呢?一个大一新生觉得自己能写得更好,就去计算中心找了份工作,开始写手册。

他的第一个程序不是井字棋。它对控制台开关上拨入的一个数做因数分解,再把因数打在卡片上。最初大约二十行,调试时越改越长。夜深人静,没有别人在,Knuth 坐在控制台前单步执行,用四个开关设置一个停止地址,好让他看着机器先除以二,再除以三,一直除到平方根。第一个晚上,他大概得到了 30 = 2 × 3 × 5。然后真正的 bug 来了:有些数的因数超过八个,一张卡片只有八十列,而每个因数占十列,就意味着要多出一张他没计划过的卡片。要是喂给它一个很大的素数,650 可能要转上十分钟,慢到你分不清这是一段很长的计算,还是死循环。

他的目标并不是找到一个纪录级的素数。他想看灯一闪一闪,看机器把人工要算上很久的事情一下子做完。第二个程序是二进制转十进制,简单得多。第三个是井字棋。那几年,上机时间就意味着深夜。大一到大二之间,他几乎不需要睡觉;高中时,他已经每周一熬夜编校学生报纸。Rodney Brooks 后来告诉 Fridman,Knuth 个子很高,站在一台坏掉的机器旁边等着修好,好让他能回去继续写 TeX,那副样子让他有点发怵。Knuth 自己的说法则更平淡:斯坦福人工智能实验室的操作系统每天都有才华横溢的程序员在改,于是它越来越好,也越来越容易崩溃;而他几乎把整本 TeX 手册都写在了机器停机的空档里。

02

三个大脑下井字棋,唯一学会东西的那个,学会的只是不输

三乘三棋盘上,每一格可以是空的、X 或 O,所以一共有 3^9 种局面。650 的存储总共只有两万个十进制数位,这份预算既要容纳程序、提示语和输出逻辑,还要存下已经见过的局面。Knuth 利用了对称性:把棋盘旋转四个方向再翻转,八种布局就归并成一种,表格因此缩小约八倍。每个局面只存一个数字,零代表不利,九代表有利,初始值大约是五或六。谁赢了,就提高自己这一方的值,降低对手的值。

他把程序拆成了三个“大脑”。第一个大脑随机走到一个空格。第二个大脑使用一套已知最优的现成策略。第三个大脑是学习者。他可以让任意两个大脑相互对弈,也可以让它们对战人类。两个一无所知的第一类大脑,大约下了六百局之后,收敛到了一种稳妥的平局。这一结果很容易被忽略:随机对随机,最终得到的是两个不再犯错的玩家。Knuth 明确解释了原因:他设计的学习方式,学到的是怎样不犯错。它并没有去争取获胜,它只是努力不输。如果换一个奖励函数,奖励精彩的走法,得到的就会是另一种学习者。

他后来才知道,Charles Babbage 在一百多年前,就曾为那台未完成的分析机构想过井字棋的编程。Knuth 自己的灵感则离得更近:在他成为大一新生之前,他曾在芝加哥科学与工业博物馆看过一台贝尔实验室的继电器展品,它会下这个游戏。写完那个程序之后,他觉得自己懂编程了。他那时还没有去想图灵机,也没有想过计算“究竟是什么”。对一个爱折腾的大一新生来说,那太哲学了。他到大四才在 Martin Davis 那里学了可计算性,因为他需要应付考试。真正让他兴奋的,是在一台他能够掌控的机器上,亲眼看着奇迹一样的事情发生。

03

一年后没人读得懂的程序,没有通过真正的考验

Fridman 问,Knuth 读程序时,怎么能分辨出作者换了人。Knuth 说,区别不在于 Hemingway 和 Joyce 那样的文风。他曾读过一个卡内基梅隆大学的编译器,其中有大段代码,做一次寄存器传送用了三条指令,本来一条就够;而另一些地方又会忽然冒出一条指令完成两个目的,因为作者很了解这台机器。他能根据技术功底来辨认作者,而不是看节奏。问到他自己的代码有什么标记,他说,现在他写的是文学化编程,英文和 C 混在一起。只看 C 部分的话,人们会注意到其中有很多全局变量,习惯内联展开而不是调用函数,还有他个人化的一小部分语言用法。

他说,文学化编程是 TeX 项目带来的最重要的成果:程序是给人读的,而不只是给计算机执行的,而排版能大大促进这一点。他向听众推荐 Matt Pharr 等人合著的《基于物理的渲染》,这本书获得过奥斯卡奖,因为电影里的图形本身就是算法;而整本书也是一个既能阅读、又能运行的文学化程序。对他来说,教编程就是在程序中讲一个故事。他的验收标准很个人化:一周后,或者一年后,他还能轻松看懂吗?

什么样的程序才算漂亮?他之前一直回避这个问题,并解释了原因:答案有几十种,而且一个小时就可能变一次。能跑起来,就可以算漂亮;容易理解,就可以算漂亮;能当作文学来读,就可以算漂亮;能让人笑出来,也可以算漂亮。Fridman 同意他的看法:可读性、思路的优雅和机智都很重要。Knuth 认为幽默应该放在注释里,并且对此有一套精细的标准,他曾不得不向 Addison-Wesley 出版社为这套标准辩护。《计算机程序设计艺术》第一卷的主要审读人 Bob Floyd 会标出那些笑话;出版社甚至为此组织过焦点小组。Knuth 的规则是:理想的笑话,是读者知道它多半就在那里,只是要读懂才看得出来,这恰恰促使读者多想一想。

那些笑话,他有一些留了下来。第二卷里藏着一段密码,要破解它,就得攻破一个比现在人们能攻破的更大的 RSA 密钥。如果机器继续变快,一百年后也许有人能解出这段话,然后笑出声来。他说,幽默是生活的一部分,讲编程的书也应当好玩。不同的世纪和文化会发明不同类型的幽默,所以语气要轻快,而不能过分。他甚至在一首以《圣经》为题材的管风琴作品里,也放了些小玩笑。耍宝不是目的,重点是在纸面上留下一个人。

04

Copilot 看起来像文学化编程,直到你问它怎么知道自己是对的

Fridman 描述了 GitHub Copilot:你先用注释写下一个函数的开头,OpenAI Codex 就会接着补全,常常补得不错,但并不能证明它是对的。他从中听到了文学化编程的回响,只不过人的角色变成了修补者,而不再是从零开始写。Knuth 的第一个问题,也是这一段对话的主线:你怎么知道它做得好?他说,每一年,我们对机器在做什么的掌控都在减少,而回答“它看起来能用”的人却越来越多。1960 年代在加州理工学院时,他认识一位同事,讲座很能鼓舞人,但听完一个小时后你已经复述不出内容;这位同事真心认为,计算机给出的答案是否正确并不要紧,要紧的是它们能不能让人开心。在他的哲学里,快乐排在真理前面。这个人不信真理,他是个哲学家。

Knuth 看到这种态度正在蔓延。相互竞争的利益,让一些决定连双方的人都看不懂。我们仍然承认这是不好的;可是再过五到十年,每一层都建立在去年那个不透明的层之上,疏离感只会更严重。Fridman 给出了乐观的读法:把这些杂乱的部分交给自动化,让人类保留编程中那一小块需要天才的部分。Knuth 不打算为此写书,也绝不会建议学生去做那些系统。他站在理解的一边。医学诊断、一次有指导的实验、一种被治愈的疾病:这些都很好。而随着年复一年,代码逐渐漂移到自主武器上,那就是另一回事了。眼下它看起来只是网站上的一小段 JavaScript。他想让宇宙的热寂稍微推迟一点,并希望还有一些意识留着,最好是人类的意识,来欣赏这一切。他补充说,也许这正是我们收不到来自其他地方信号的原因。他们也发明了这个。

被问到他是否乐观,他没有直接谈心情。他说,看看这个房间:铅笔、书、桌子、话筒、衣服、食物,每一样都是有人发明的,我们继承了数以百万计、数以十亿计的人造物,每一样都可能出错,可其中大部分却运转良好。这种惊奇,正是他乐观的来源,包括对人工智能的乐观。我们开车过桥,使用自己并不理解的技术;每个人都拥有其中的一小块;它出故障的频率足以让人察觉,于是我们去改进它,改进往往并不是最优的。随后他给这份希望加了个限定。他知道怎样进行的那些改进,要求人类是理性的,而他越来越没有把握人类是理性的。Fridman 回答说,人也许并不理性,但他们很聪明,而且只要有机会,大多数人都愿意彼此友善。

05

过早优化,是编译器作者对一种心理错误的诊断

Fridman 引用了《计算机程序设计艺术》里的那句名言:程序员花了太多时间,在不该担心效率的地方、不该担心的时候担心效率;过早优化是万恶之源,至少在编程里,它是大多数罪恶的根源。Knuth 先解释这个词。他是编译器作者,所以“优化”指的是一种更好的翻译,让程序在机器上跑得更快,也就是你在编译器上设置的那个开关。1960 年代初的一部未删节词典,把 optimize 解释为“以乐观的态度看待”。后来整个领域都借用了这个词。他使用它的时候,指的是针对某台机器调整程序。

这种心理错误很具体。程序员往往以为,自己写起来最费劲的那几页,计算机执行起来也最慢。十页代码,其中一页花了一周,于是脑子里就会想象机器运行到那一页时会慢下来。当然这很可笑,但你在写代码的时候,并不知道计算机真正把时间花在了哪里。他曾经对一个 Fortran 编译器做过性能剖析,发现它超过百分之八十的时间,都花在读取注释卡片上。作者们曾担心复杂表达式里的嵌套括号,而那部分只占不到百分之一。在注释这条路径上花上十分钟的功夫,速度就可能提高一倍多。这些只有在程序写出来之后,靠测量才能看到。

他很高兴这句话流传开来,尽管当初他是在一个有限的语境里说的。这句话还适用于另一层意思:一种能提升运行速度的优化,可能让程序在下周就无法修改,因为数据结构已经无法适应变化。计算机科学里有一条重要原则,叫晚绑定:能推迟的决定就尽量推迟。从准时制生产开始,人们写过不少论文来论证这种做法的价值:懒惰往往有它的最优性。他和 Fridman 都认为,这句话之所以引起共鸣,是因为程序员其实*喜欢*优化。一段调校得当的代码有它自己的优雅,是另一种美,而难点在于控制这种欲望,不要过早地做决定。

06

意识问题仍然提得太差,Knuth 无法投票

Fridman 提到 Roger Penrose 的观点:人类发现数学思想的方式,超出了图灵机的能力,而意识正是这“超出”的一部分。Knuth 淡淡地提到,他女儿的孩子曾经和 Penrose 的孩子在牛津一起玩过。被问到他是否认为存在这样的限制,他说,他可以回答“是”或“不是”,但他没有理由那样回答。他觉得在这里凭直觉下判断没有什么用。在他看来,这个问题要么无法回答,要么至少他并不比别人更能回答,他也不希望别人把他的话当作专业结论来引用。我们可以猜测的事情很多,包括一个针尖上能跳多少个天使的舞。他宁愿去想黎曼猜想。

Fridman 相信,人类心智的运作原理终有一天会在科学的范围之内。Knuth 并不反对。他还开玩笑说,也许是 AI 创造了宇宙,是某个 AI 的智能设计。他拒绝做出断言。他是一位传授知识的老师,对意识问题并没有什么特殊的发言权。他认为,John McCarthy 对这类说法完全不买账。图灵在提出模仿游戏的那篇论文里,也不喜欢“机器能否思考”这个问题。Knuth 不认为这个问题重要:他把它归到那些超出知识范围的事情里,意思是它甚至还没有被形式化到能够清楚地提问的程度。据他最近的判断,理解意识大约还要两百年。

二十年前,在 American Academy 的一场研讨会上,开场白就是:关于意识的一切论述都是废话。Knuth 对此略有不同看法。他并不反对 Fridman 从工程角度来看这个问题:一旦 AI 系统有了个性和身份,这个问题就不再只是哲学问题。在那些更早的讲座上,神经学家已经指出,在人意识到自己做出决定之前,信号就已经传到了手臂。Leslie Valiant 提出过一种大脑的架构。Christos Papadimitriou 与两位同事在这次对话的前一年,于《美国国家科学院院刊》上发表了一个模型,它与意识实验相吻合,甚至还配有一种用于撰写和检验假说的机器语言。Knuth 自己喜欢的图景,是颅骨之内一场持续的适者生存竞争:他说话时,各种可能的下一句话进行投票,胜出的那一句会塑造接下来的内容。它听上去像是一个清晰的故事,就像文学化编程一样;而底下那团杂乱的计算,则生成了你愿意相信的那套叙述。

07

Conway 的生命游戏让自由意志一目了然;一张餐巾纸写成了一本书

Knuth 很欣赏生命游戏,因为它表明,事物可以在创造者并不比简单规则理解得更多的情况下演化。对他来说,最重要的教训是自由意志。生命是完全确定性的,他很难相信有过孩子的人会不相信自由意志;这个游戏把其中的张力表现得一清二楚。John Conway 曾经想过:在一次特别精彩的运行之后关掉计算机,是否不道德。从简单的初始条件出发,你完全清楚这个系统如何运作;可是,如果允许自己忘掉一些细节,只看那些较大的图案,它们看起来就像活的一样。Fridman 说,如果宇宙是有限的,那我们就都身处一场加速版的生命游戏之中。Knuth 在《计算机程序设计艺术》第 4 卷第 6 分册里,有十几道练习题分析它,他还提到 Bill Gosper 的算法,让 Golly 模拟器快了数千倍。

他不止一次在 Conway 家里过夜。两人第一次见面是 1967 年在牛津,一次会议上,Conway 讲了关于结的研究,那是他中学时期做的工作,他从未发表过,后来却成了数千篇论文的源头。讲座接近高潮时,Conway 在台下观众面前,用小塑料片拼出几个结,又把它们一一拆开。1972 年春天,他们恰好同一天在卡尔加里,一起吃了午饭,Conway 在一张餐巾纸上写满了关于他所谓“数”的定理。Knuth 觉得这些定理美得不可思议。那年十二月,Knuth 在挪威休学术假,半夜醒来,想到 Conway 的理论可以用来让学生体会做研究的乐趣。他当时正在读 Alfréd Rényi 写的一部苏格拉底式的数学对话。早上,他把妻子 Jill 叫醒,说他想写一本书。

次年一月,他在奥斯陆市中心租了一间由某个宣教组织经营的旅馆房间,一个星期里什么别的事也没做。餐巾纸已经丢了,他便凭记忆从两条公理出发,把理论重新推了一遍。他自己犯的每个错误,书中的人物也都照犯不误。文字涌出来的速度比他思考还快。第六天,他写完了;第七天休息;接着他想给秘书写打字说明,却再也写不出东西了。缪斯女神彻底离开了他,仿佛他之前只是在替别人传话。Conway 回信说,其中一条公理有误:在逻辑推演中,“小于等于”和“不大于”是有区别的,而 Knuth 选的是较难的那一个。那年夏天,他又在挪威的山里待了一周,把它重写了一遍。这本书就是《超现实数》。

后来,Knuth 在蒙特利尔做了七场关于稳定婚姻问题的讲座。第六场和第七场之间的一次聚会上,他遇见了 Conway,向他介绍了这个课题。Conway 当场证明了一条定理:所有稳定匹配构成一个分配格,并给出了求两个稳定配对的最大下界和最小上界的简单办法。Knuth 第二天就用上了它。他和 Jill 刚刚庆祝了相识六十年的“婚姻美满”。两人相识,是因为他大二时正在和 Jill 的室友约会,想请 Jill 帮忙出主意;结果他更喜欢 Jill 的建议,而不是那位室友。她是艺术家,他是个极客。她不得不修一门计算机课,还得读他写的一本手册。他们每年都会一起做一张圣诞卡,在各自对美的理解之间相互妥协。他说,“稳定婚姻”是个技术术语,但人间的版本也一样:要妥协,要起起伏伏,也不会指望一天二十四小时都是幸福。他笑着说,直到他弄明白她是怎么亲的,他才真正喜欢上亲吻。

08

Feynman 随手翻开任何一页,都能指出哪里有问题

在加州理工学院,Knuth 和 Richard Feynman 常常去听对方的课。要是 Knuth 在前排看见 Feynman,他就会漏掉几句话。他反复提起的,是 Feynman 在巴西的经历:他认为,那里的物理系学生在学怎样应付考试,而不是在学物理。Feynman 提议随便翻开教科书的任意一页,指出其中哪里有问题;他真这么做了,而且是在那本书的作者面前。在此之前,他先问了一句,他是否应当说实话。对 Knuth 来说,这件事集中体现了各个领域的教育是如何走偏的,又必须定期被拉回来,从发放资格证书转回传授知识。这与相信计算机的答案,是同样的要求。Bob Floyd 很喜欢一幅漫画:两个人站在一台大机器前,这台机器一秒钟能算完一百万人要算一百年的活。另一个人问:“你怎么知道它是对的?”

Knuth 起初主修物理,后来转到了数学。他能在物理考试中拿到 A+,却不知道老师是怎么设计那些题目的;在数学里,他知道题目为什么要这样出,也能自己编出新的题目。他擅长代数,不擅长几何。物理学家习惯用波来思考;他也能,但感觉像狗在用两条后腿走路。他认为,计算机科学很大程度上是由那些大脑与某些概念产生共鸣的人推动的;量子计算则需要另一种大脑,它位于物理与计算机科学的交界处。他读《科学美国人》上的文章,看不懂量子力学;但物理学家彼此之间用的那套特征值语言,他就能看懂。霍金说,书里每多一个公式,就会失去一半的读者;所以 Knuth 根本读不懂那本书。

Feynman 把深入的计算藏在直觉的表演之下,有一次交流让 Knuth 几十年都难忘。Knuth 箭头记号(Knuth's arrow notation)可以表示极其巨大的数:重复的加法变成乘法,重复的乘法变成幂(一个箭头),两个箭头则构成幂塔。哪怕是很小的一座塔,也已经大得无法想象。Feynman 说,不要只停留在整数上,要考虑复数。把双箭头插值到 2.5 并不太难,但双箭头到 i 呢?Feynman 断言,没有任何解析函数能完成这件事。Knuth 始终没明白他为什么能如此肯定。Feynman 接着问,箭头的数量能不能是复数。这样的问题,Knuth 记了一辈子。

09

Morris 的 Unix 代码被拆掉,因为没人看得懂

Knuth 说,Knuth-Morris-Pratt 算法本应叫 Morris-Pratt-Knuth;他们在论文里按字母顺序排的名。问题是每个用搜索引擎的人都熟悉的那种:在一长串文本里找一个词。最直接的办法是先找第一个字母,再找第二个;一旦失配,就回退重来。Jim Morris 注意到,匹配之后读过的那些字母,如果不可能成为新的起点,就不必重新读一遍。遇到像 abracadabra 这样的模式,开头、中间和结尾都有重复片段,事情就变得微妙了。Morris 想通了这个办法,把它放进伯克利 Unix 系统软件里,却没有解释。几个月后,有人看了代码,觉得它看起来不对,就把它拆掉了。算法其实是存在的,只是因为没人看得懂,它没能保存下来。

一两年后,Vaughan Pratt 独立发现了同样的思路,他的出发点是回文串,而不是文本搜索。Knuth 自己的路径就更曲折一些。当时在伯克利任教的 Steve Cook,证明了一条关于栈自动机(stack automata)的奇特定理。Knuth 认为,没有给 Cook 终身教职,是计算机系最大的失误。这种机器只能看到栈顶,只能压栈或弹栈,比图灵机弱得多。Cook 证明:如果一个栈自动机能在任意时间内识别长度为 n 的字符串语言,那么一台普通计算机就能在 n log n 的时间内识别同一种语言。Knuth 把这个构造套用到一种语言上:他知道栈自动机能处理它,却看不出怎样快速识别。他原以为自己还算是个不错的程序员。他在黑板上写满了 Cook 的构造,盯着看,直到缺失的规律浮现出来,于是忽然就有了一个高效的程序。如果没有那条纯粹抽象的定理,他绝不会写出这个程序。

随后他意识到,字符串匹配也是栈自动机能够识别的另一种语言,同样的转换还精确地告诉他,扫描文本时该记住哪些东西。他写了一篇短文,题为《自动机理论也能有用》。他读过很多自动机论文,但没有一篇能改进他日常的编程;它们更像是期刊上有趣的材料。这是一个转折点:一个他写不出程序的问题,一条定理,然后才是程序。他把这篇短文拿给 Pratt 看,Pratt 说它和自己正在做的东西很接近。Jim Morris 当时也在伯克利。每个人都摸到了大象的一部分。把这些部分拼在一起,才得到了一个算法,而写成论文则是 Knuth 的任务。

10

最难的问题,是让随机图中的大爆炸慢下来

被问到他解过的最难的问题,Knuth 毫不犹豫地说:巨大连通分支的诞生。从 n 个点开始,它们彼此都一样,没有几何结构。把 π 的数字两个两个地取出来——31、41、59、26——从 31 连一条边到 41,再从 59 连到 26;或者干脆掷骰子。π 没有什么特殊地位,因为没有人知道其中的规律,所以它是一个随机源。边不断积累。Paul Erdős 和 Alfréd Rényi 把这个过程称为随机图的演化。当边数达到 0.49n 时,比如一百万个点、490000 条边,图几乎全是孤立的树,几乎没有环。到了 0.51n,突然出现了一个远大于其他部分的连通分支。这是一次相变,而且是双重相变:两件事同时发生。

Dick Karp 在伯克利的学生正在模拟这一过程,并每隔一段时间拍一张快照。一个消息传到了斯坦福:几乎每次观察,都只有一个分支带有环。一百万次实验,只有三四个例外。Knuth 的团队心想,如果这是真的,那背后就该有一整套理论在等着。仔细一看,这并不完全对,但几乎是对的:有一个很短的区间,会同时存在两三个带环的分支,它们很快就会合并。如果快门不够快,就会错过。问题于是变成了:怎样让这场大爆炸慢下来。Knuth 把一个分支的复杂度定义为边数减去顶点数。一棵十个顶点、九条边的树,复杂度是负一。一个单环,外加通向它的树枝,复杂度是零。多一条边,就是一辆“自行车”(bicycle),即两个环。复杂度加一,就是环的数量。

第一个环出现之后,那个传言说,下一步几乎总会是一辆“自行车”。事实上,分裂成两个独立环的概率大约是二十四分之五,不算小,不过它们很快就会合并。Knuth 算出了前五次转变。凌晨三点左右,分母的结果出来了,其中一个是 23023。他盯着看。从他写的第一个程序开始,他就知道 1001 = 7 × 11 × 13;而 23023 = 7 × 11 × 13 × 23。一个随机分数不会这样分解。分母里出现小素数,说明背后有原因。他取了对数,公式随之简化,他上床睡觉时觉得自己仿佛能看着这场爆炸慢动作地播放。第二天,Bill Gates 来到斯坦福,正被游说资助一座新的计算机系大楼。Knuth 在黑板上画出那张演化图,写着二十四分之五之类的数字。当晚,Gates 告诉开发办公室,他对 Knuth 教授关于巨大连通分支的讲解印象非常深。Knuth 很喜欢讲这个故事,因为它证明了理论计算机科学是有价值的。

他和两位合著者完成了分析。传言所说的“任何时刻都只有一个带环的分支”,概率达不到一,大约是百分之八十七。精确的值牵涉到 π,形式类似 12/π²。这是他证明过的最难的定理,还点亮了一批关于随机图的其他问题。它与物理的联系是玻色-爱因斯坦统计(Bose-Einstein statistics):没有几何与距离,分子如何彼此结合。分母被分解出来的第二天,一位正在四处募款的亿万富翁听了一场关于随机图中环的讲座。Knuth 认为,这正是这个学科存在的意义。

11

TeX 免费,因为收入是一道门槛;π 则是他证明自己没有作弊的办法

Knuth 发布 TeX 的时候,“开源”这个词还不存在。他不想要专有的权利,因为他见过那样的权利如何把东西捂住。1950 年代末,IBM 开发了 Fortran,本可以只留给 IBM 的机器使用;结果,任何能把 Fortran 移植到自己硬件上的人,都被允许去写编译器。排版领域则走了相反的路:每个厂商都有自己的页面描述语言,用户被锁定;而印刷设备可以摊销二十到三十年,新的机器却一年之内就会出现。他也不缺钱。他有工作,书也卖得不错,孩子们的教育费用也有了着落。收入是一个阈值函数:低于这个阈值,就得挨饿;高于它,人们才会开始考虑慈善,或者考虑把钱带进坟墓。他已经越过了这道门槛,所以看得出让 TeX 向所有人开放的好处。

他并不认为所有软件都应该免费。重要的软件应该收费,琐碎的软件则不该收费。拿 Adobe Photoshop 为例,它的撤销功能可以一直回退一千步复杂的图形操作,这背后是优美的算法,用他的话说,是诺贝尔奖级别的知识产权。专利在最理想的情况下,会把发明公开出来,使其不至于一直停留在商业秘密里。他自己用的是一台不联网的独立 Ubuntu 笔记本。需要网络和图形处理时,他就用 U 盘把文件搬到 Mac 上。他只把最珍贵的东西交给 Linux 来保管,因为他用的那个版本很稳定,哪怕它已经老到迟早得升级。

问到他最喜欢的字母、数字或符号,他先翻到索引的最后一页,指着 Dr. Seuss 的《On Beyond Zebra》里的一个记号。他比较喜欢这本书,而不是《The Cat in the Hat》;小时候,他就能背出《Bartholomew Cubbins》。随后他说起了 π,理由很实际:当他需要一个随机的例子时,π 没有已知的规律。他想在《计算机程序设计艺术》里举一个 Masyu 的例子。Masyu 是一种类似围棋的环路谜题,比数独还让人上瘾。他给自己定了个任务:把棋子摆在希腊字母 π 的像素格子上,再把它们涂成黑或白,让谜题的解恰好唯一。结果只有一种涂法。他说,用 π 就能证明,他并不是拿一个现成的实例来凑数。

最近,他在写关于优雅图(graceful graph)的内容:给顶点编号,使每条边两端数字之差的绝对值恰好是 1 到 m,且每个数只用一次。他选了一个极不对称的图:美国本土加上哥伦比亚特区,共四十九个地区,彼此之间可以开车到达,阿拉斯加和夏威夷则不算在内。他得到的编号,边上的差值分布在 1 到 117 之间,却有缺口,离完美的“从 1 到约 105 一个不缺”还差一点。他于是想出一个比赛。他的朋友 Tom Rokicki 花了一个下午,找到了一个完美的优雅编号,比赛就这样结束了。两天后,Rokicki 又回来了:华盛顿是 31,爱达荷是 41,沿北部边界的编号恰好是 π 的数字,并且仍然是优雅的。Knuth 非常高兴。他喜欢用 π,而 π 总会在最难的问题中间冒出来。

12

先做最讨厌的事;人生是二分查找;科学就是能讲给计算机听的东西

Knuth 的日程安排原则是:先做待办清单上他最讨厌的那件事。一周结束时,他会很高兴,因为讨厌的事情已经做完了。疫情期间,他的产出大约减半:用文字沟通很慢,他又不愿意发出一句写得不好的话,而图书馆也关了门。他母亲还教过他第二条规则,与机器人式的计划不同:看到需要做的事,就去做,而不是给清单排序。两条规则可以作为启发式方法并存。任何时候都有一组可能的任务,优先选那个你没有理由认为以后会做得更好的任务。有些工作,先做别的事会更有帮助;有些工作,则会因为忘了前期的基础而变得更难。他刚刚写完一段痛苦的书稿,现在来到了有趣的部分,但读者绝不能看出其中的痛苦。语气必须保持昂扬,要有幽默,偶尔来一句“这太酷了”。通往那份兴奋的道路满是痛苦,他必须把这一点藏起来。

给年轻人的建议,和他一贯给的一样,只是开头先说明:很多事情别人做得都比他好。不要因为时髦去做一件事。去做你自己真正感到召唤的事,而不是别人期待你做的事。怎么知道自己有没有被召唤?去试一试,成功或失败,你都会更了解自己。人生是一次二分查找。有的实验告诉你,你的背景有帮助,或者多花些力气就能走到;有的实验则告诉你,你没有这方面的直觉,这个问题与你无缘。当他看到大家都朝同一个方向涌去、觉得竞争很激烈时,他大概会反其道而行之,甚至反应过度。他大多数时候只是玩自己感兴趣的东西,后来才意识到,他学到的最重要的技能,是对几乎任何事情都能产生兴趣。

听到孩子们说某件事很无聊,他会觉得难过。他说,一个人如果不得不承认自己找不到有趣的东西,就应该感到不安:这说明他还没有学会享受生活,需要别人来逗他开心。Fridman 引用了 David Foster Wallace 关于如何不让自己感到无聊的一段话。Knuth 同意,这是一种能力,有的日子容易些,有的日子难些。疫情期间,他连续很多天没见过别的人,却依然过得相当愉快。他去录音时早到了几分钟,在福斯特城里走了走,在几个街区外的家得宝苗圃里看到了漂亮的花。他说,生活里充满了令人惊叹的东西。有时候,他只是坐着,盯着一棵树看。

Fridman 不肯让他绕过人生的意义这个问题。Knuth 先把“42”挡了回去,然后说出了自己的答案。他相信上帝存在,虽然他并不知道这句话具体指什么:某种超越人类能力的东西,也许是某种 AI。他可以试着去理解那个存在希望他做什么,并与之产生共鸣。他并不是以策略的方式来做选择。他会设想自己在遵循某个人的愿望,哪怕他并不聪明到能够知道那些愿望是什么;他相信,线索以及从一条线索走向另一条线索的过程,是可以变得有趣的。他读 Ken Follett 的《The Man From St Petersburg》时,丘吉尔需要与俄国结盟,一个无政府主义者则想阻止这件事,以挽救普通人的生命。读到这里,他意识到,如果自己负责别人的生命,他对自己做出的任何决定都没有信心。Fridman 说,不确定性与做决定的责任绑在一起,其实是件好事。Knuth 相信伟大的领导者会出现,这正是民主的希望所在。Fridman 则希望算法能增强他们。Knuth 给听众留下了他自己的一句话:科学,就是我们理解得足够透彻、能够讲给计算机听的东西。艺术,则是我们所做的其余一切。

同频道的其他文章

3:36:56EN → 简体中文
Lex Fridman· 2026年9月16日播客精神病学至今没有属于自己的青霉素主持 Lex Fridman历史学家 Andrew Scull 与 Lex Fridman 谈到,这门学科对症状有所缓解,但没有哪一种重大精神疾病真正被根治;过度自信的时候,代价要由病人来扛。Mental HealthPublic HealthNeuroscience
5:15:51EN → 简体中文
Lex Fridman· 2026年8月26日播客 · 2 人对谈DHH 没有亲手写一行 Omarchy Quattro 的代码嘉宾 DHH · 主持 Lex Fridman与 Lex Fridman 一次充满怀疑的对话过去十三个月后,Rails 的创造者讲述了 Opus 4.5、一群编码智能体(Agent)和一个一分钟的 Linux 安装器,如何结束了他一凿一凿手写 Ruby 的时代。编程智能体Vibe Coding智能体工程+3
3:12:58EN → 简体中文
Lex Fridman· 2026年8月12日播客 · 2 人对谈一个冷水澡,二十位冠军:Khabib Nurmagomedov 是如何炼成的嘉宾 Khabib Nurmagomedov · 主持 Lex Fridman在马哈奇卡拉的一间学校体育馆里,七十个人共用一个淋浴间,而且只有冷水。Martial ArtsCombat SportsCoaching+3
3:46:18EN → 简体中文
Lex Fridman· 2026年7月28日播客 · 2 人对谈抽掉奴隶制,就没有美国内战嘉宾 Gary Gallagher · 主持 Lex Fridman1860 年,美国奴隶主名下的奴隶价值,超过了全美所有铁路和工厂的总和。Political PhilosophyLeadershipHistory
3:51:47EN → 简体中文
Lex Fridman· 2026年6月30日播客 · 2 人对谈46% 的皇帝被暴力推翻,帝国照样延续下来嘉宾 Anthony Kaldellis · 主持 Lex Fridman历史学家 Anthony Kaldellis 与 Lex Fridman 一起走过 2200 年的罗马史,并主张我们所说的拜占庭,其实就是罗马本身。Political PhilosophyGeopoliticsLeadership
2:53:42EN → 简体中文
Lex Fridman· 2026年5月29日播客 · 2 人对谈月亮一直在下落,却总也落不到地球上嘉宾 Biggest Mysteries in Physics · 主持 Lex Fridman费米实验室(Fermilab)物理学家 Don Lincoln 在与 Lex Fridman 的对谈中说,物理学的历史就是一部统一的历史;反物质(antimatter)、暗能量(dark energy)和万物理论(theory of everything)依然远在我们能做的实验之外。Quantum MechanicsScience CommunicationPhilosophy of Science