《程式設計師》VS 一代演算法大師高德納

2021-04-23 05:30:34 字數 4474 閱讀 2965

具有實踐精神的理論家;我們時代的達文西

——高德納訪談錄

文/丁力

譯/趙斯思

審校/高昂

《程式設計師》雜誌的一位作者袁泳先生,曾經說過高德納是一位文藝復興時期式的天才人物,這說的是他的博學,以及他同時具備的靈巧的程式設計能力。在分工越來越細緻的現代社會,這確實非常罕見, 就像乙個人自己製造一架飛機,他既要考慮空氣動力學問題,也要考慮飛機上的每棵螺絲釘的固定方式。也確實使我們想到達文西,後者創造了享譽後世的《蒙娜麗 莎》,《計算機程式設計藝術》在計算機領域的影響可以與之媲美,同時也是機器設計方面的專家。從計算機科學史上說,高德納正是生逢其時。2023年,圖靈發表了《論可計算數及其在判定問題上的應用》一文,確立了可計算模型。2023年,巴克斯發明了fortran語言。從2023年代起,高德納以他的博識與耐心開始了《計算機程式設計藝術》的寫作,該書旨在對電腦科學理論的數學背景與歷史,做一梳理和總結。現在大學計算機系的《資料結構》課程的內容基本來自該書。有人更是把它與牛頓的《自然哲學和數學原理》並列,選為對世界歷史發生影響的十大科學著作,這不無理由。高德納本人在36歲時,獲得了電腦科學的最高榮譽---圖靈獎。從2023年起,他主要專心致力於完成七卷本的《計算機程式設計藝術》一書。幾個星期以前,我們採訪了他。使我們特感幸運與欣悅的是,高德納先 生對我們的採訪表現出極大的熱誠,在繁忙工作中抽出寶貴時間,細緻地回答了我們的問題,並在通訊中特別強調希望用他的中文名字。從這裡,不難看出他對中國 和中國文化的熱愛。這在採訪的本文中也有所體現。當我們談到最早的演算法時,他特別提到《九章算術》,這本即使中國人也很少讀過的書。或者我們可以將此看作 一種激勵,正如高德納在採訪中所說,電腦科學的思想來自世界各個地域、各種文明。可以期待,今天的中國也會產生如劉徽、秦九韶那樣的數學高手,對計算機 科學與技術做出獨特的貢獻。以下是採訪的本文:

當然,這些早期的演算法並不是很精巧。它們解釋了如何以計算的方式解決這些問題,但後來發現使用代數方法能更好地解決它們。最早的「有意義的」演算法,它對於今天的程式設計師們仍然很重要,是最大公約數的求解。其中乙個演算法被稱為歐幾里德演算法,它被記載於歐幾里德幾何原本上,儘管它來自於歐多克索斯和其它一些更早期的人物。這種演算法基於輾轉相除法。另乙個演算法僅需要除以二,因此非常適合當前的二進位制計算機。這個演算法可能發源於2023年前的中國——這要取決於我們如何理解經典的《九章算術》中一些句子的隱藏的含義(我在我的書《半數值演算法》的340到341頁和中文版的309頁討論了這個問題)。

高德納: 希臘數學家發明的最偉大的東西是嚴格證明的概念。這個概念將數學與其它知識區別開來,其它知識往往是基於事實的累計、由老師傳授給學生的並由社會共識所評 估(舉個例子,物理中,並不知道乙個假設的真假,而只能等著所謂專家們的想法越來越趨於統一。但是在數學中,很多事情都是無可辯駁的,或者說不存在不同的 觀點),縱觀人類歷史,那些沒有遵從希臘方式理解數學的文明把數學認為是應該記憶的規則而不是可以由邏輯推演而來的事實。在這些文明(例如古代中國、日 本、印度和哥倫布發現之前的美洲等)中,人們發現了很多重要的數學原理但是也犯了很多錯誤,因為學生否決老師是不明智的!這也是為什麼我如此感激史前的希 臘數學家教會其他人如何真正的證明問題。

另一方面,我希望澄清一點,我相信所有文明之間都是相互學習的。我為電腦科學這個全世界成千上萬的人的共同成果而慶祝,每個人都為此貢獻了他們從經驗中而來的重要觀點。

高德納:你可以參照我對第二個問題的回答,我認為數學對於程式設計師最重要的意義在於它告訴我們如何證明我們的程式將會在所有情況下正常工作。若非如此,我們就得為此擔心,儘管我們的程式通過了已有的所有測試,但或許明天它在處理另外一些新資料時就會出錯。

當然,僅僅知道程式能正常工作這一點並不夠。有了數學,我們可以證明乙個程式比另乙個程式快成千上萬倍。某些時候,我們甚至能證明程式是「最好的」(best possible)——根據某些標準,沒有其它程式會比它好。

the art of computer programming

)》,寫這本書的主要目的是什麼呢?您是否試圖構建乙個演算法體系?您是如何選擇主題呢?

高德納:我寫《計算機程式設計藝術》的主要目地是組織和理解一些廣泛被各種程式使用的最基礎的想法。只要可能,我使用數學給出對於每種基礎的方法的對於精 確效率的計量的理解。此外,我盡量敘述每一種方法的歷史,因為理解這些方法是如何被發現的有助於我們在現時和今後發明新的方法。

高德納:《計算機程式設計藝術》不是為所有人寫的。大約每50個人中就有乙個能發展出獨特的看問題的方式,這使他們成為真正的程式設計師。像你我這樣的人,傾向於將知識用特殊的形式在腦中組織以便於更好地利用電腦。每50人中的另外49人不該從事程式設計這一行,儘管他們可以使用計算機完成一些不需要程式設計的任務。

對程式設計師來說,擁有非程式設計師的朋友是非常重要的,所以對於你所說的你有朋友閱讀《計算機程式設計藝術》非常困難,我並不覺得奇怪。當然,你的朋友也許不應該閱讀你看過的所有書籍,你也不應期待能輕易看懂他們的書籍!最好的方法是團隊合作,用天分和技巧作為補充。

總 的來說,我認為我期待的主要進步來自於程式設計師和非程式設計師的合作。比如,人類能更好地理解動作。我相信很多針對醫生、化學家、物理學家、生物學家等的將資料 以動畫形式表現出來的工具應該被開發出來。要實現它們,需要優秀的程式設計師實現動畫,與能夠理解人類視覺能力的優秀的圖形設計師一起工作,與知道哪些資料需 要被理解的優秀的醫生、化學家、物理學家和生物學家一起工作。

高德納:在我回答第二個問題的時候,我提到使用數學去證明(不是重複地測試直到你找不到錯誤)的重要性。狄克斯特拉和其他人都發展了驗證正確性方法,這些方法可以放大,以驗證「大」程式。但是,如你指出的,軟體工業界並沒有真正遵從他們的建議。部分的問題在於——「大」的含義一直在變:當我們有乙個可以工作的大程式,人們常常就想寫乙個更大的,這也就更加難以驗證。驗證技術從沒有跟上人們對於**體積越來越大的胃口。

我將會試著同時從理論和實踐上解釋我的態度。拿我的程式tex做例子,它按照今天的標準來說並不「大」,它只有500頁的**。我並沒有完成對於tex完全的形式化的正確性證明,儘管我非常喜歡數學證明。但是,我已經非常熟悉驗證的基礎,我知道如何非形式化地使用它們——大體上我知道如何證明正確性,如果我有時間去研究每乙個瑣碎的細節(grind through the gory details)。

沒有這些基礎知識,我的程式可能會經常崩潰,像你我知道的一些商業軟體一樣。有了這些知識,我就能寫出非常穩定和好用程式,但也僅是在我測試了它之後!

讓我從另乙個不同角度再說一遍:沒有理論,我不知道程式可被證明的正確是什麼意思,我掙扎前進(flounder)。但是儘管有了理論,我也不能確定我的程式是好的,除非我進行了廣泛的測試!

為什麼?因為在現實中,沒有程式能被真正被證明是正確的:假定的「證明」可能包含錯誤。如果某人給我看乙個經過形式化證明的程式,我不得不檢查一下驗證過程有沒有錯誤。驗證過程也許由機器完成,但是機器邏輯也許是錯誤的,如此這般。這是乙個永無終點的迴圈。

數學展示給我們理想,我們可以檢查證明,直到我們認為它們是合理的。但是只有不會犯錯的超人能真正得出證明是正確的結論。

進一步來說,證明程式是否滿足它的規格說明(specification)的想法也是值得懷疑的,因為規格說明本身可能是不正確的。實際上tex並沒有精確的規格說明,如果有,我也認為它完全沒有用處!(不是每個人同意我這個觀點,但他們應該設計並實現乙個完美排版軟體,在我已完成了tex這個排版軟體的時候。)

總之,我認為將「形式證明」和「測試」**開來是危險的。最好的做法是正確地同時使用兩種方法。我在我的著作《literal programming》的第十章和第十一章詳細地討論了tex的除錯(在《digital typography》的第三十四章中討論了後續開發)。

高德納:程式設計師選取乙個抽象的演算法,並將其轉化為以某種定義良好的語言寫成的程式中的具體形式,程式才可以被機器執行。「演算法」之於「程式」就類似於「資訊」之於「資料」: 資訊是理想化的抽象的概念,它或多或少可以由某種精確的方法將其編碼為資料,以完美地表達。乙個演算法是一種理想化的可計算的為某些任務服務的過程,它或多 或少可以由某種精確的方法將其編碼為程式,以完美地表達。但是程式設計師事實上不僅僅是寫程式的人。真正的任務是編寫可以被人們閱讀的程式,而不僅僅是編寫可 以被機器分析的程式,因為人們會需要驗證它(非形式化的)、修改它和維護它。這就是為什麼我堅信「作文式程式設計(literate  programming)」——像文學創作那樣寫程式,寫出自己的風格,為他人所欣賞。

深圳夜場高手 新一代程式設計師的night life

深圳夜場最熱鬧。大家都知道金光華圈子 永珍城圈子 海岸城圈子,最近1年,歡樂海岸的圈子也起來了,簡稱 jmch 圈子!圈子多 圈子大 亮燈早 熄燈晚,人所共知呀。但是深圳的南山科技園的圈子裡面一直流傳這樣乙個傳說 聽說燈深圳最後熄滅的地方不是 圈子發達的 jmch 地帶呀,而是新一代核心區後海的新鵝...

現在的「新程式設計師」在想什麼?缺乏夢想的一代!

入職第一天,我在跟他們的溝通中乙個問題是 你的夢想是什麼?你想要什麼?三十個人裡,只有三個人有著開遊戲公司的夢想,源於他們對網路遊戲的熱愛 有兩個人有環遊世界的夢想,他們聽說程式設計師的生活加班每天加班太多太煩悶 還有乙個孩子的夢想是開畫廊,他不會畫畫,只是欣賞繪畫的人,有可能的話能開一家畫廊很好,...

程式設計師高階之演算法練習 一

可能很多移動端程式設計的同學聽到演算法就感到恐懼,認為我不會演算法也能開發呀。確實,不會演算法,也能應對一般的工作。但是和大牛之間的差距就是,可能別人3行 實現的東西,你卻要寫10多行,並且效能比別人差。那麼,讓我們來學習一些演算法吧。演算法的學習最簡單的方式就是多練習,找乙個提供演算法練習的 思考...