# 唐納德·克努特：演算法、TeX、人生與《計算機程式設計藝術》

> 電腦科學泰斗談演算法之美、TeX 的誕生、《計算機程式設計藝術》的漫長寫作與人生體悟。

- 原標題：Donald Knuth: Algorithms, TeX, Life, and The Art of Computer Programming
- 期數：特別節目
- 釋出日期：2019-12-30
- 嘉賓 / 主題：唐納德·克努特
- 網頁版：https://lex.qiaomu.ai/tw/ep/donald-knuth/
- 官方頁面：https://lexfridman.com/donald-knuth/
- 精讀字數：約 14353 字（閱讀約 32 分鐘）

> 本文為 lex.qiaomu.ai 基於原始訪談的 AI 改寫中文精讀，非官方翻譯；引用請註明出處並連結網頁版。

唐納德·克努特（Donald Knuth）給自己的人生做過一次結算。如果給幸福打分，滿分一百，他給自己打八十。在他看來，這件事本來就該這樣設計。

「0.8 就夠了。」這是他的原話。一個把《計算機程式設計藝術》寫了五十七年還沒寫完的人，一個把 TeX 打磨到連頁碼的「2」都容不下的人，在幸福這件事上卻給自己設了一個上限。他說，一個生物體如果百分之百快樂，那就像所有人都嗑了藥，什麼事情也做不成，系統會崩掉。所以快樂到八成就好，八成剛剛好，剩下那兩成留給沮喪、留給清醒、留給你第二天早上還想爬起來幹活的那點張力。

這就是克努特。技術問題他追求九點八分，人生問題他接受八分的自己。

Lex Fridman 的這期訪談錄於 2019 年，是那一年的收官之作。地點在克努特的書房，他管那地方叫「魔法發生的地方」。他沒有郵箱，Lex 為了約到這次對話費了不少周折。一個不查郵件、用鉛筆在紙上寫程式、一週工作七天的人，用了一百分鐘，聊了演算法、排版、文學、宗教、死亡，以及六十年沒變過的極客思維。

## IBM 650：只有兩千個字的記憶體

1957 年，克努特還是凱斯理工學院（Case Tech）的大一新生。他在統計組打工，負責打孔、錄入資料、再把資料拿到另一臺機器上排序。有一天學校來了一臺新機器，IBM 650。那臺機器填不滿一個房間，但很吵，面板上一排排燈不停地閃。

他當時並不著急用它。他手裡有那棟樓的鑰匙，能進去看，還能拿到一本手冊。他第一次程式設計靠的是一臺很大的打孔機。**那臺機器有兩千個字的記憶體，每個字是十個十進位制數字加一個符號位。**做一次加法，大概要等三毫秒。聽起來不賴。

> 「為什麼是三毫秒？因為磁鼓轉一圈要五毫秒，你得等。如果一條指令在磁鼓上的某個位置，你要等磁鼓轉到位才能讀出資料，再等幾個週期去取下一條指令。如果那條指令不在預想的位置，你就只能乾等。」（唐納德·克努特）

他的大四那年，學校才拿到五十個字的隨機儲存器。五十個字，那時是寶貝。他們每次把六十個字一塊的資料搬進隨機儲存器，用完再搬下一塊。克努特把這套生活叫「寫子程式，搬上去，再開始」。

Lex 問他，你當時能預測六十年後計算機的樣子嗎？克努特說，他被問過很多次「什麼讓你驚訝」，他能一口氣列出二十幾件。有一次一個採訪者反過來問他：有什麼是沒讓你驚訝的？他想了五分鐘，一件都想不出來。

這個反問很像他。預測未來不在他的興趣範圍內，他盯著的是眼前這臺機器到底在幹什麼，瓶頸在哪，下一行程式碼能不能更快。

## 極客的大腦長什麼樣

克努特反覆用過「geek」這個詞。他說五十年代 IBM 就注意到世界上存在這麼一群人，於是登廣告招聘，廣告上寫得很直白：「如果你下棋，來麥迪遜大道面試。」

他估計這類人大概佔總人口的百分之二。這個比例在他整個職業生涯裡基本穩定。現在可能變了，因為孩子們小時候的經歷不一樣了。

那麼，一個極客看到的世界，和普通人看到的世界，差別在哪？

他給出兩點。

**第一點，是在抽象層級之間跳躍的能力。**你能看到一個大問題，也能看到一個非常小的細節，而且能在兩者之間自由穿梭。你知道要解決某個大問題，下一步就是把某個暫存器加一；你也知道加一之後會落到演算法的哪一層。你不會真的想到電子的層面，但你知道那臺磁鼓轉一圈要多久，所以你知道這次運算是怎麼完成的。除錯的時候你一層層往下問：是打孔打錯了，是指令寫錯了，還是暫存器裡放錯了東西。每一層都不一樣，每一層你都能進去。

**第二點，是處理非一致性的能力。**一個演算法有十個步驟，每步幹一件不同的事，極客不覺得這有什麼難受。很多純數學的體系靠一兩條普遍規則推演一切，而像克努特這樣的人，可以跟一個比必要更復雜的系統共處。**有時候他們造出來的系統就是比需要的更復雜，因為他們不認為沒找到那條簡單規則是什麼大事。**

這也解釋了他的書為什麼長成那樣。《計算機程式設計藝術》從不止步於高層，也從不止步於低層。他把各層混在一起寫。有人批評他的書應該寫得「更好」，他承認這大概是對的；另一些人說，如果你就是這種思維方式，那這就是訓練自己的方式。他一路混著層級寫，一路練怎麼在層級之間跳。

## 圖靈：第一個百分百的正牌極客

克努特說，十九世紀那些大數學家，雅可比、波爾查諾、阿貝爾，可能多少帶點極客的症狀。第一個百分百的正牌極客，是艾倫·圖靈（Alan Turing）。

他年輕時對圖靈的瞭解只停留在可計算性理論和圖靈機上，那聽起來像非常純粹、非常抽象的理論工作。很多年後他才知道，圖靈設計過機器，給曼徹斯特的機器寫過一份漂亮的說明書，發明了子程式，而且是個手上沾油泥的駭客。

還有一個細節他印象很深。圖靈把數字倒著寫，從左往右寫，因為他用的機器內部就是這麼處理的。他會把 π 寫成 9 5 0 1 4 點 3。他訓練自己像計算機一樣思考。

> 「他訓練自己那麼做，因為他當時用的計算機內部就是這麼工作的。」（唐納德·克努特）

Lex 說，這就是極客思維。克努特說，對。

## 文學化程式設計：用兩種視角看同一件事

一個以形式化方法著稱的人，創造了「文學化程式設計」（literate programming）這個概念，主張程式應該寫成給人讀的文章，而非給機器執行的指令序列。這兩者矛盾嗎？

克努特的回答還是那套非一致性哲學。他不相信「一種尺寸適合所有人」，也不相信所有真理都藏在某一種專業能力裡。**他說自己的生活是英語和數學的凸組合。**他不但接受這一點，還希望自己的孩子也這樣，左右腦同時開著。

文學化程式設計的核心動作，是讓人透過至少兩種視角去理解同一個複雜的東西：形式地看一遍，非形式地看一遍。好的技術作者不會把這一點做得太明顯，但他會把同一件事說兩遍、三遍，一遍正式，一遍口語，目的只有一個：讓讀者把這個概念放進自己的腦子。

他說，寫作這件事，目標在讀者。作者要心裡有一個清晰的讀者形象，說出讀者下一步期待聽到的話，把自己覺得有意思的地方，讓讀者也覺得有意思。

寫程式也一樣。你寫的程式不只是給計算機下指令，它還要給將來維護這段程式碼的人、給正在除錯它的自己，講清楚「為什麼要這麼幹」。**老師講課用的所有闡述技巧，只要你寫的程式不是一次性用完就扔，都會讓你成為更好的程式設計師。**

Lex 問他，把形式和非形式結合起來有多難。克努特說，這個問題問他不見得合適，因為他是極客，這類事他做起來不難。但他也承認，有些人寫東西就是困難，可能是大腦結構的關係，也可能只是練得不夠。他不敢下判斷說任何人都能學會。

他能確定的是：寫作是他生命的一半。他把寫作和程式設計放在一起。哪怕寫一個只用一次的程式，他也會用文學化的方式寫，因為這樣他更快把它寫對。

## 從 1962 年的目錄說起

1962 年，克努特列了一份目錄。他要寫的書，主題是如何寫編譯器。那時候全世界寫過編譯器的人也就幾十個，他恰好是其中之一。他還給校報寫過稿，所以他覺得自己可以當那個記者，把別人那些絕妙的想法講清楚。

結果目錄越拉越長。他加了資料結構，因為編譯器作者得在一張表裡查變數；他加了搜尋，因為編譯器得判斷兩個地方出現的同名變數是不是同一個；他加了算術，加了他最喜歡的組合數學。原本第十二章才是編譯器，前面十一章全是鋪墊。

然後七十年代來了。組合數學領域發生了一次大爆發。他說，如果看 1975 年，電腦科學的期刊裡超過一半都在講組合方法。圖論佔主導，哈密頓路徑、旅行商問題，從圖論再往外走，是運籌學。運籌學當年只管那些有高效解的小問題，通常跟擬陣（matroid）這種特殊的數學結構有關。**可一旦問題從「兩個兩個地看」變成「三個三個地看」，難度就變了。**二元的可滿足性問題可以線上性時間裡判定，三元的可滿足性問題，到今天也沒人知道怎麼做。

這本原本打算寫十二個月的書，變成了七卷本的大工程。今天他寫到第四卷 B 分冊。有人問他能不能用一部電梯的時間概括這套書，他說，那得看這棟樓有幾層。

第一卷《基本演算法》，講的是你繞不開的東西：什麼是程式，什麼是演算法，一臺低層機器長什麼樣，輸入輸出、子程式、歸納法、數學預備知識。這本書和別的書不一樣的地方在於，**他不光給出演算法，還要定量地分析它**。他要回答的是「它工作得有多快」，「它能工作」只是起點。所以他需要數學。

第二卷《半數值演算法》，講的是針對數字的演算法。浮點算術、高精度算術、矩陣、隨機數、冪級數，計算機怎麼理解算術。

第三卷《排序與查詢》，他自己最喜歡的一卷。這裡處理的未必是數字，也可以是字母、是任何可以比較的物件。他特別提到，現在大家天天用 Google，本質上還是在找東西。

第四卷《組合演算法》，是「無數問題」的領域。這裡他不斷遇到這樣的情況：一個好想法可以讓某個演算法快一百萬倍以上。也有一堆問題可能永遠不會有高效解法。放棄依然沒有理由，你還有機會想出好點子，跑得更快。

> 「組合演算法是我一直最喜歡的，因為我的程式設計技能在這裡回報最大。一個顯而易見的演算法，和你後來想到的那個不那麼明顯、但能把前者遠遠甩在後面的演算法，差距就在這裡。電腦科學真正發揮作用的地方也在這裡。」（唐納德·克努特）

## 那張椅子，那沓紙，和七天的節奏

Lex 問他每天的寫作流程。克努特說，這大概是最好的問題，因為他一週七天都在做這件事。

他坐在一把椅子上，那把椅子是瑞典人設計的，是唯一一把他能連續坐幾個小時、坐到忘記自己坐在椅子上的椅子。旁邊有一張立式辦公桌。他的流程是：**先用鉛筆在紙上寫，然後站起來，打字，修改，重寫。**

他拿出一沓紙給 Lex 看。那是他四十年前在加拿大看望姐姐時買的，尺寸很大，行距很小，剛好適合他。他儲存著從六十年代開始的全部手稿。他打字很快，高中上過打字學校，**打字速度比思考速度還快**。所以當他把紙上的東西打到螢幕上時，風格和節奏會在打字的速度裡自然長出來。

Lex 問他會不會用宏，會不會用 LaTeX 那種思維方式寫東西。他說需要宏的時候會用，但他並不依靠宏來思考。他還說，他會為了版面改句子。如果換一種說法能省下一行，他會換，像寫俳句一樣，把句子重寫到在頁面上更好看為止。他說這大概只佔他百分之三的時間，他不該在這上面耗，可他忍不住。

Lex 說，也可以說生活就是這樣。克努特說，確實。**他每週花一天在花園裡，他的生活就是除草、抓蟲，只不過物件換成了程式。**

他說，樂趣出現在什麼時候？出現在你能把兩個人的想法拼到一起，而這兩個人彼此不知道對方的工作，你可能是第一個同時看到兩邊的想法的人。**那一刻你有機會做綜合，那就是創造。**

苦役出現在什麼時候？出現在你得把每件事追到根上。追根會把你帶進奇怪的地方，比如他為了寫書去學了梵文。他給每個作者寫感謝信，作者去世了，就寫信給認識作者的人。他要把數學弄對。讀者會拿著他的程式找漏洞，他得一遍遍重寫。

有沒有白費功夫的時候？有。他曾經花了很長時間準備一個以棒球為主題的大型例子，甚至打算做摺疊插圖。後來他想，一個從小打板球長大的人會怎麼看？一個從小踢足球長大的人會怎麼看？他在這個例子裡到底在教什麼演算法？他把整個例子刪了。後來連保齡球的例子也刪了，因為那更小眾。

## 為什麼叫「藝術」

《計算機程式設計藝術》這個書名裡，「藝術」這個詞是克努特專門想過、還在圖靈獎演講裡講過的。

他說，art 這個詞的本義是「非自然之物」，和 artificial intelligence 裡的 artificial 同一個詞根，意思是人創造出來的東西。後來這個詞引申出「美術」的意思，帶上了美的維度，**意味著一樣東西不但是人造的，而且做得優雅，帶來愉悅。**

所以當他說「程式設計的藝術」，他想說的是：你寫一個程式，可以把它寫成一件作品。

> 「藝術是人類特別擅長的那部分東西。當人們說人工智慧的時候，他們是在試圖模仿人類。但這裡面有一個美的、優雅的成分。這也是我一直想說的：你可以寫一個程式，把它寫成一件藝術品。」（唐納德·克努特）

## 1986 年的一個意外

Lex 問他，有沒有哪個想法徹底改變了他看問題的方式。

克努特說，他每次程式出 bug 都會「驚訝」，但那不是他說的那種驚訝。他講了一個具體的例子。

**BDD，二元決策圖（binary decision diagram）。**它是 Randy Bryant 在 1986 年提出的結構。克努特說自己從五十年代就開始程式設計，是老傢伙了，他以為布林函式這種東西早就被研究透了。命題邏輯是一切的基礎，我們知道的幾乎所有東西都能用它描述，他以為這塊地已經耕完了。

結果 1986 年來了個全新的想法，徹底改變了布林函式的表示方式。到九十年代，它成了設計計算機晶片的標準方法，直到 2000 年 SAT 求解器崛起才被取代。

這件事直接改變了第四卷的結構。**第四卷 B 分冊中間三分之一，三百多頁，講的全是這個東西，其中大部分材料是本世紀才發現的。**他得從零開始，去見這個領域裡的人，寫了十五套不同的程式，書裡描述了其中七套，另外八套是給他自己理解問題用的。

還有一個小插曲。BDD 火了之後，理論研究者開始研究它「做不到什麼」，於是它名聲變差，因為它不能解決所有問題。克努特說他預計，接下來十年，理論研究者會證明機器學習也解決不了所有問題。

他自己不怎麼擔心最壞情況。**他的快感來自「這個問題我以前解決不了，現在能解決了」，哪怕這個問題本身又引出了下一個問題。**他知道自己比以前強了，這就夠了。

## P 是不是等於 NP，以及那些「知道存在卻不知道長什麼樣」的演算法

克努特反覆講過同一個直覺：他傾向於認為 P = NP，但即便有人證明了 P = NP，也不會直接給你一個能解決實際問題的演算法。

他的理由很直接。**存在的演算法，比任何人能理解的、能發現的演算法都要多得多。**我們現在的處境是：我們知道某個演算法存在，卻一點頭緒都沒有，不知道它是什麼。

他舉了兩個例子。

**第一個是 Hex 遊戲。**黑白雙方輪流在六邊形格子上放石子，白方要從左連到右，黑方要從下連到上，沒有吃子，沒有和棋。遊戲有限，不存在平局，所以一定是先手必勝或後手必勝。**數學上可以證明先手必勝**，用配對策略可以推出後手不可能贏，但我們不知道那條必勝之路該怎麼走，也不知道先手第一步該下哪裡。

**第二個是圖論裡的 Robertson-Seymour 定理。**它說，任何一個在取子式下封閉（closed under taking minors）的圖類，都存在一個多項式時間的演算法，判斷一個給定的圖是否屬於這個類。取子式的意思是，你可以把一條邊縮成一個點，也可以刪掉一條邊，得到的新圖還留在這個類裡。

這個定理證明了：每一個這樣的圖類，都存在有限個「最小的壞圖」，一個圖不屬於這個類，當且僅當它包含其中一個壞圖作為子式。既然壞圖是有限的，那就可以逐個測試，每個測試都是多項式時間，加起來還是多項式時間。

> 「於是就有了一個多項式時間演算法，可我們並不知道它長什麼樣。我們只知道壞圖的數量是有限的，我們可能只知道其中一兩個，不知道到底有二十一個還是二十五個。我們只知道它有限。」（唐納德·克努特）

Lex 說，這就是你覺得 P = NP 可能也沒用的原因。克努特說，差不多。**你要排除的可能性太多了。**他講了一個頭發數的類比：一個國家的人口數遠小於一個人頭上的頭髮數，那麼必然有兩個人頭髮數一樣多。這裡面沒有巧合，起作用的是抽屜原理。組合演算法的世界裡，這種因為可能性太多而撞上的事情經常發生。

他說，有人反駁他：如果 P = NP，那麼多聰明人研究這麼多年，還有百萬美元懸賞，怎麼就沒找到？克努特說，他可以用完全一樣的邏輯反過來說：**那麼多聰明人努力證明 P ≠ NP，也都失敗了。**這個邏輯兩邊都能用，說明它撐不起一個證明。

最後他把話題拐到了外星人。Lex 問，你覺得宇宙裡有智慧生命嗎？克努特說，他不知道，也不花時間想。他不願把時間花在自己永遠無法知道答案的問題上。**但他又說，他很高興有些問題沒有答案，因為有了答案，謎就沒了，世界就太無趣了。**

## 螞蟻、生命遊戲，和「假裝理解」的界限

Lex 提到，克努特說過，理解蟻群如何完成高度組織化的任務，可能是理解人類認知的關鍵。蟻群是個分散式系統，而每一隻螞蟻在幹什麼，我們看得見。

克努特說，對，這就是蟻群的優勢。我們知道哪隻螞蟻在跟哪隻螞蟻交流，大腦內部就難得多，你不知道神經元之間傳遞訊號到了什麼程度。他傾向於把蟻群當成一個單一的認知體，而不是一堆螞蟻的集合。就像大腦裡的細胞、還有微生物組，都是互相作用的實體，但他把自己當成一個人。

Lex 又問到康威的生命遊戲（Conway's Game of Life）。克努特說，生命遊戲能模擬任何可計算過程，可這不是它最強大的地方。**它的魔力在於規則極度簡單、單元極度分散。**我們能完全看清它的原語是什麼。這仍然不意味著他理解了「生命」。

它給他的是一個視角：一個確定性的宇宙意味著什麼，自由選擇對我們意味著什麼。

Lex 問，你覺得上帝擲骰子嗎？克努特說，擲。**他不覺得有理由禁止上帝使用最高效的方法，而我們知道隨機性對很多演算法來說是必需的，有些事情不靠隨機就做不好。**

## 聖經、隨機抽樣，和「更接近」

1999 年，克努特在 MIT 做過一系列關於宗教和科學的講座，後來結集出版。他在書裡講了一個方法論：面對一個複雜到超出人類理解的主題，你怎麼辦？

他的答案是：**隨機抽樣。**不要只研究別人讓你研究的那部分，也不要因為太難就什麼都不研究。挑一個在你能力範圍內的隨機子集，深入進去。

他給自己定了一個子集：大概三千節經文裡的六十節，比例約五百分之一。然後他去圖書館，波士頓公共圖書館每週去一次，去了一年；哈佛的圖書館也去過幾次。那裡的索引做得很好，他可以直接翻到某本書的某一頁，看這一節經文有沒有被提到。這樣他不光學了聖經本身，還學了關於聖經的二手文獻，那些學者寫了什麼。

> 「這給了我一些堅固的釘子，可以把零碎的資訊掛上去。但我不會說，因此這就是真的。這只是一種隨機抽樣的方式。」（唐納德·克努特）

他讀出來的核心是什麼？他說，要點不在大多數人以為的那些戒律，而在**如何與上帝的意願和諧共處**。他假設上帝存在。他說他很慶幸這件事無法被證明，因為如果能證明，他看一遍證明，記住，然後就完了，他不會再對精神性的東西、對謎感興趣，他的人生會非常不完整。

他還提到他研究過的一節經文，可以解讀為：**做一個無神論者，也比什麼都不在乎要好。**

Lex 問他，如果你是上帝，你會怎麼向地球上的人顯現自己？克努特提到一本小說，他忘了是不是叫《Blasphemy》，講的是上帝在洛斯阿拉莫斯透過一臺計算機顯現自己。他說那是他讀過的唯一一本把點睛之筆放在最後一個詞、而且最後一個詞解釋了整本書的書。他不想劇透，但那本書恰好就在談這個問題。

他說，如果上帝覺得過去跟世界溝通的方式不適合 21 世紀，那會怎麼做？也許就是那本書裡寫的方式。

他還說，做這個思想實驗，大部分時候你會學到的是謙卑。**解出一個問題，不代表其他問題會跟著掉出來。你得意識到有些東西超出你的能力。**

Lex 說，我看到周圍全是傲慢（hubris）。克努特說，說得對。

## 0.8 是夠的

Lex 讓克努特對自己的人生做一次程式分析：正確性怎麼樣，執行時間怎麼樣，漸近意義下的資源使用怎麼樣。

克努特說，這個問題以前沒人問過他。他說他一開始裝的是庫、子程式，學著做一個聽話的自動機。他有一個巨大的優勢：**他沒有可以責怪的人。**如果他有什麼沒搞懂，他知道該停止打乒乓，那是他自己的錯，是他沒努力學，並沒有誰在歧視他。他說他不知道怎麼消除世界上的偏見，但他知道自己不必承受那份額外的負擔。

後來他從父母那裡學到了利他，學到了服務他人更重要。再後來他意識到，自己得先足夠快樂，才能去服務別人。

最後他給這套人生哲學起了個名字：「0.8 就夠了」。

> 「如果我能給幸福打分，我覺得一個生物體快樂百分之八十的時間，這是好設計。如果百分之百快樂，那就像所有人都在嗑藥，什麼都幹不成，整個系統會崩掉。」（唐納德·克努特）

他承認自己也會有低落的時候。他說他知道那是被「程式設計」成這樣的，如果情緒失調、比該有的更沮喪，他會試著想：今天該生誰的氣？然後他意識到，那只是化學反應在告訴他應該生氣。他說，那我就把它放一邊，去睡覺，會好起來的。**不百分百快樂，不意味著他要去街上找個人吼一頓。他可以接受自己足夠快樂，能夠成為可持續狀態的一部分。**

## 2006 年，和一場死亡預習

2006 年，克努特被診斷出前列腺癌。Lex 問他，這次跟死亡的照面有沒有改變他看世界的方式。

他說，有。他第一次真正面對死亡，是父親去世的時候。他花了一個月，才慢慢接受自己總有一天也會死。**那一個月裡，他覺得自己還行，可他唱不了歌，也做不了原創研究。**他記得大概三四周之後，他第一次冒出一個有意義、稍微有點創造性的技術想法，他能感覺到某個東西又開始動了。在那之前，他覺得很空。

後來他知道，哀傷有一個標準的過程，他走的就是這條路。

2006 年被診斷的時候，他的反應很平靜。他想，我這輩子運氣一直很好，沒什麼可抱怨的，也許現在就到此為止。他沒有覺得自己理應得到更好的結果，也沒有為未來做計劃。**他做了手術，術後重新學走路，疼了一陣子，然後回家了。回家之後他才意識到，他根本沒想過接下來要幹什麼。他心裡沒給自己留什麼期待，只冒出一句：哦，我還活著，那我還能再寫幾本書。**

他說，那種「這太不公平了」的情緒，他心裡沒有。他接受結果。他說，他已經拿到了超過自己份額的東西。

訪談裡他還提到另一件未了的心願：寫一部音樂作品。他腦子裡有一個想法，覺得某種音樂應該被寫出來，至少得有人試一試。他知道不容易，可他想做一個概念驗證，想知道這條路走不走得通。**他花了很多時間，最終完成了。去年他八十歲生日，這部作品做了世界首演，後來在加拿大又演了一次，據說歐洲也在談演出。**

他說，那件事做完了，它現在是世界音樂的一部分，好也罷壞也罷，他做了他想做的。

現在他日程上只剩一件事：《計算機程式設計藝術》，盡他所能寫到終點。

Lex 問，會不會有一個「1.0」的時刻？克努特說，他更願意把它看成：那場音樂會結束時，他其實已經觸到了 1.0。**2006 年他處在 0.8，被診斷出癌症時他想，也許這就是終點了，結果沒有。他接受了任何結果。**

## 兩根「2」的戰爭

如果說克努特在什麼事上追求過 0.98，那就是排版。

七十年代，他創造了 TeX 排版系統，配套的 METAFONT 語言用來描述字形，還有 Computer Modern 字型家族。今天，數學、物理、電腦科學以及大量工程領域的論文，用的還是這套東西。

Lex 問他，美很難量化，你怎麼創造出美的字母和美的公式？

克努特提到哈佛數學家 George David Birkhoff 在三十年代寫過一本《Aesthetic Measure》，書裡印著花瓶的圖片，每張圖下面標一個數字，代表這個花瓶多美。Birkhoff 還寫過音樂，克努特一度想過，能不能在作曲時把他的演算法編成程式，讓作品拿到他評分體系裡的最高分。他說，那套東西不夠嚴謹，計算機做不了。可那是人們給美賦值最認真的一次嘗試。

格什溫的老師也寫過兩卷本，講他的作曲方法。Lex 想問的卻是另一種美，字母的美，線條和曲線的美。

克努特說，那就在觀者眼裡。**你只能盡力靠近你心裡那個美的定義，儘可能靠近。**

他說，他的定義很私人：**它得讓他自己滿意。**這就是標準。這個標準曾經讓他非常痛苦。

《計算機程式設計藝術》第二卷出新版的時候，他以為那會是他人生中最快樂的一天。結果他開啟書，看到同一個封面、同樣的裝幀，可頁面上的東西不好看。**那個「2」特別醜，他受不了。任何一個畫家都會把頁碼上的「2」畫好。**他做了很多測量，用不同的方式看，技術是好的，可他還沒做完。1961 年之後的所有東西，他都得重新寫。

Lex 問，它最終讓你滿意了嗎？克努特說，當然。他說，那麼多書是因為這套系統才寫得出來。**而且現在他坐在書房裡，看到上面那些排好的頁面，如果他不喜歡，他隨時可以改。別人沒有這個能力，他們只能用他給的東西。**

Lex 又問到間距、留白，能不能更系統一點？克努特說，你永遠可以再往前走一步。**他說他在排版上並沒有停在 0.8，他大概是從 0.98 開始的。**

Lex 說，這好像違背了你自己的幸福法則。克努特說，這裡不一樣。日本有一種美學叫侘寂（wabi sabi），認為最美的作品是那些帶瑕疵的，因為觀者可以在瑕疵里加入自己的欣賞，這會帶來更多滿足感。**排版上他要的東西恰好相反，他要的是絕大多數情況下都儘可能好看。做不到的時候，他就說：好吧，作者得多花百分之二的工作量。**

他不肯把「做到百分百」當成自己的任務，那會把作者的所有工作都搶走。這就是他說的「0.8 就夠了」的意思。

## 我們對宇宙的理解，是一個極小的數

訪談快結束時，Lex 讓克努特估一個數：人類對現實本質的理解，佔多少？

克努特說，無窮小。小數點後面不知道多少個零。

他說，數學家辦公室裡坐他隔壁的那些人，從來不考慮比可數無窮更小的東西，而他幾乎不碰無窮，因為他處理的都是有限的東西。**可即便只談有限，宇宙可能只是有限個夸克組成的，而所有人類能理解的數，仍然遠遠小於幾乎所有的有限數。**

他提到自己寫過一篇論文叫《Supernatural Numbers》，講的是康威箭頭表示法（Conway chained arrow notation）。規則說穿了不復雜：沒有箭頭是乘法，一個箭頭是指數，兩個箭頭是把指數反覆迭代，三個、四個箭頭往上疊，數字會膨脹到完全無法想象。

他舉的例子是 10 加四個箭頭再加一個 3。先算 10 的三重箭頭，那已經是一摞指數塔，塔有多高你都說不清。算完這一遍，只完成三重箭頭，還得再來一遍才到四重箭頭。這個數早已超出任何人的想象。

可它和真正的有限數比起來，還是小得可憐。克努特說，他不過是用了 10、3、4 這幾個小小的引數。你要是把箭頭的數量本身設成那個超大的數，那才是有限數真實的樣子。

> 「有限與無限之間的那條界線，對人類來說本身就是不可理解的。」（唐納德·克努特）

無窮是一個好用的工具，它幫我們思考那些極大的東西，我們甚至能對它做運算。我們永遠無法確知，這個宇宙是否真的接近過它。

所以克努特說他清楚自己知道得多麼少。緊接著他又補了一句：即便在這麼小的宇宙裡，人類確實發現了很多東西，多到任何一個人都裝不下。**「我們幹得還不錯。」**這是他的原話。

## 見上帝時，他會問什麼

訪談最後，Lex 丟擲了一個常見的問題：你上了天堂，見到上帝，能問一個問題，而且一定會得到回答，你會問什麼？

克努特的回答是：「你這兒的瀏覽器是哪個？」

Lex 說，這答案真美。克努特接著說，他其實不覺得這是個有意義的問題，可他真心希望那兒網速夠好。

這個回答裡包含了他對終極問題的整套態度。前面他已經說過一遍：他不花時間思考那些自己永遠不可能知道答案的問題。他不否認神秘的價值，他甚至希望有些謎永遠不要被解開，因為一旦解開，世界就太無趣了。珍視神秘和沉迷於猜測是兩件事，他把這兩件事分得很清楚。

所以當被問及上帝、宇宙、外星文明時，他的答案永遠分成兩層：一層是「我不知道，我也不打算猜」；另一層是「這個問題本身很好，它讓我保持謙卑」。

## 他怕的是誤以為自己已經對了

把這些片段串起來看，會發現克努特的整套思維方式有一條主線。

他對人工智慧的態度就是一個例子。他說，AI 社群從六十年代起就是電腦科學最大的靈感來源，可能超過任何其他群體。他們總去啃「智慧最了不起的那些成就」，逼著整個領域把邊界往外推，也因此產生了一大批好問題，以及越來越多成功的答案。

**他真正擔心的，是人們在還沒做到的時候就開始相信自己已經做到了。**

> 「讓我不安的是，當人們開始相信自己真的成功了。因為在我看來，真正理解一樣東西，和能夠假裝理解、能夠製造出理解的錯覺，這中間有一道巨大的鴻溝。」（唐納德·克努特）

Lex 追問：你覺得可以在不理解的情況下創造出東西嗎？克努特說，他天天這麼幹，他喜歡用隨機數。可那道鴻溝還在那兒。他說，他不敢斷言真正意義上的智慧不可能被造出來，他只是沒看到任何東西在靠近他心裡那個標準。

注意他用的詞：他心裡那個標準。他不把自己的標準當成客觀真理往外推，可他也不因為別人都說「快成了」就跟著改口。

同樣的剋制出現在他對 P/NP 的判斷裡。他說自己傾向於 P = NP，緊接著補一句「這絕不是證明」。他說他也可以用同樣的邏輯推出相反的結論，說完就承認這個邏輯撐不住。

這種「先給出判斷，再自己拆掉論證的地基」的說話方式，在整場訪談裡反覆出現，跟故作謙虛沒什麼關係。這是長期訓練出來的思維習慣：**把結論和支撐結論的論證分開存放，論證不夠硬的時候，結論就只能停在「直覺」那一格，不能往上挪。**

## 非一致性，才是他真正的主題

如果只記住這場對話裡的一件事，那應該是克努特關於「非一致性」的那段話。

他說，很多純數學建立在一條或兩條普遍規則上，從規則出發，一切都能推演出來。而像他這樣的人，可以跟一個有十個步驟、每步幹一件不同事情的演算法和平共處，不覺得難受。**他甚至承認，正因為如此，他們有時候會造出比必要的更復雜的系統，因為他們不覺得「沒找到那條簡單規則」是件大事。**

這套哲學解釋了他幾乎所有的選擇。

他的書裡為什麼混著高層和低層？因為他能在層級之間跳，跳起來不費勁。

一個形式化大師為什麼會發明文學化程式設計？因為他不相信一種尺寸適合所有人，也不相信所有真理都藏在同一種專業能力裡。

他為什麼願意花一個月吸收四個日本研究者提出的新想法，把舊方法在幾十個老問題上重新跑一遍，再寫最終稿？因為他享受的是把兩撥互不相識的人的想法接上。

他為什麼能接受自己只快樂八成？因為一個百分之百運轉的系統，在他看來就是設計失敗的。

「0.8 就夠了」在他這裡有一層工程學的底子。**他做排版做到 0.98，因為那是他能控制的、能一遍遍重來的東西；他對幸福只要求 0.8，因為那裡面有一半變數不在他手上。**

他分得清哪些事該追到極致，哪些事該放自己一馬。

## 一個不查郵件的人，是怎麼把書寫完的

Lex 在開場提到，為了約到這次訪談，他得想別的辦法，因為克努特不查郵件。

這件事放在整場訪談裡看，一點都不奇怪。克努特描述的工作方式是這樣的：鉛筆、紙、一把能坐幾個小時的椅子、每天站起來打字、一週七天、每週寫五個左右的文學化程式。他儲存著從六十年代起的所有手稿。他去圖書館翻紙質索引，一頁一頁查某節經文有沒有被學者討論過。他給作者本人或作者的熟人寫信。

**每一個環節都需要長時間不被打斷的注意力。**收件箱是這種注意力最大的敵人，它每天把幾十件別人認為重要的事塞到你面前，讓你以為自己在處理事務，其實你在被別人安排。

他不查郵件，跟清高沒什麼關係，他在保護那條唯一能產出東西的時間線。他今年八十多歲，還在寫第四卷 B 分冊，還在給一本書追加上百頁的新材料。這套工作方式顯然有效。

訪談裡有一個細節。Lex 問他：寫書這麼多年，有沒有想過降低標準，別什麼都試一遍，直接把答案報出來就完了？克努特說他確實這麼想過，很多天都在想，為什麼我非得有這麼高的標準。然後他咬牙做完，樂趣會在看到好結果的時候出來。**更大的樂趣，是看到有人真的讀懂了他寫的東西，並且告訴他怎麼改得更好。**

這就是他願意繼續坐下去的原因。這裡沒有抽象的目標，只有具體的、來自真實讀者的回聲。

## 鉛筆、紙，和一種正在消失的耐心

這期訪談裡有一個不太起眼的細節，值得單獨拿出來說。克努特描述寫作流程時，把順序講得很清楚：先在紙上寫，用鉛筆和橡皮，寫完了站起來，打到機器裡，然後改。

紙上的那一遍，是想法第一次變成形狀的過程。打字的那一遍，是形狀第一次接受檢驗的過程。他說他打字速度快過思考速度，所以風格和節奏會在打字的時候自己長出來，出來的東西跟紙上已經很不一樣。

這兩遍不能合併。今天大多數人的工作方式是直接在編輯器裡從第一句話開始寫，邊寫邊改邊刪，一個下午過去，螢幕上的字數和早上差不多。**那種寫法的毛病在於，思考、表達和評判同時進行，三個動作互相打斷。**

克努特的流程把這三件事分開了：紙上只管想，鍵盤前只管說，改稿時再只管評。

他還提到一件更小的事：為了版面改句子，為了省下一行重寫整句，像寫俳句一樣。他說這大概只佔百分之三的時間，不該浪費，可他忍不住。

這百分之三，恰恰是他身上最難複製的那部分。一臺機器可以檢查語法、檢查拼寫、檢查程式碼能不能跑，它檢查不出「這句話在這個頁面上不夠好看」。**能夠對這種事產生不適感，是一個人長期跟自己較勁之後留下的印記。**

## 他給世界留下的東西，沒有一個是他計劃中的副產品

這場訪談裡有一個反覆出現的模式，值得單拎出來。

他想寫一本編譯器的小冊子，結果寫出了七卷本的《計算機程式設計藝術》。他為了讓自己的書排版好看，造了 TeX，結果整個數學、物理、電腦科學界的論文排版都靠它。**他發明文學化程式設計，初衷只是讓自己寫程式時更快寫對，結果成了一種影響深遠的程式設計觀念。**

每一次，起點都是一個具體到不能再具體的問題：這本書怎麼排才好看，這段程式碼怎麼組織我才不出錯，這個例子到底在教什麼演算法。**每一次，終點都遠超他當初的設想。**

這跟很多人的直覺相反。大家以為要做大事得先有宏大的規劃，得先想清楚十年後要成為什麼。克努特的路徑是：先把手頭這一小塊做到別人做不到的程度，然後那一小塊自己會往外長。

Te X 能統治學界幾十年，不因為他規劃了一個排版帝國。是因為他真的無法忍受頁碼上一個醜陋的「2」，然後一路追下去，追出了一整套字型、一整套排版演算法、一整套描述字形的語言。**這條路的每一站都由「還不夠好」推著走，沒有一站來自「市場需要什麼」。**

一個想法能長多大，取決於推它的人願意追多深。

## 它變成你自己的東西

克努特在這場訪談裡給出的，是一組可以今天就用起來的動作。挑一兩個開始，比全部收藏起來更有用。

- **給自己設一條 0.8 的幸福線。**接受自己有一部分時間狀態不好，那段時間別逼自己產出，也別去找一個人來承擔這份情緒。睡一覺，等化學反應過去。
- **分清「能反覆重來的 0.98」和「不在你手上的 0.8」。**排版、程式碼風格、文件質量這類可以一次次改的東西，值得追到近乎完美；行業走向、別人的評價、身體的衰老，追到八成半就該停手。
- **每次寫程式碼時問一句「三個月後我還看得懂嗎」。**看不懂就補上那段「為什麼要這麼幹」的說明。這是文學化程式設計最小可行的版本，不需要任何工具。
- **遇到複雜到超出你理解的東西，隨機抽一小塊，鑽到底。**不要因為整個主題太難就什麼都不學，也不要只學別人指定的那部分。挑一個在你能力範圍內的子集，去原始文獻裡把它挖穿。
- **把想、說、評三個動作分開。**先用紙把想法寫成形狀，再打字讓它接受檢驗，最後才回頭評判。別在同一個螢幕裡同時幹這三件事。
- **給深度工作留出整塊時間，別讓收件箱把它切碎。**克努特的做法極端，方向是對的：一天裡至少有幾個小時，別人找不到你，你也不主動找別人。
- **把結論和論證分開記。**寫下你的直覺判斷，同時標註支撐它的理由有多硬。理由不夠硬時，讓它停在「直覺」那一格，別急著對外宣佈成結論。
- **去找那個能把你兩個領域的想法接起來的問題。**克努特說，創造發生在你成為第一個同時看到 A 和 B 的人的那一刻。你在兩個圈子裡都待過，那就是你獨有的位置。
- **先把手頭那一小塊做到別人做不到，別忙著規劃全域性。**TeX 是從一個醜陋的頁碼「2」長出來的，不是從一個排版帝國的藍圖長出來的。你現在抱怨得最厲害的那個細節，往往就是入口。
- **寫完東西，想辦法讓真正讀懂它的人給你反饋。**他說最大的快樂來自有人讀懂了，並且告訴他怎麼改得更好。找這樣的人，比找一百個點贊有用。

訪談的結尾，Lex 引用了克努特的一句話：我們應該持續努力，把每一門藝術轉化為科學，而在這個過程中，我們把藝術本身往前推了一步。

這句話放在克努特自己身上最合適。他把排版從手藝變成了可以計算的東西，然後在計算之上重新做出了藝術。他把寫程式從技術變成了可以閱讀的文章，然後在可讀性之上讓程式有了被理解的可能。他甚至把自己的人生當成一個可以分析的演算法來審視，最後得出的結論是：八成，夠了。

一個不查郵件、用鉛筆寫程式、八十歲還在改稿的人，比誰都清楚兩件事的分量：長時間不被打斷的注意力，以及在沒人監督的時候，仍然願意把 i 上那一點、t 上那一橫畫好的那點倔強。前一件決定你能走多遠，後一件決定你走過的地方留下什麼。
