程式設計師成才的關鍵:內在興趣和善於發現

發表於2011-02-17

本文是Common Lisp專家Peter Seibel對電腦科學家Guy Steele的訪談,談到了他程式人生開啟的歷程以及程式設計師成才的關鍵。

初涉程式設計

Seibel:你是怎樣接觸程式設計的?

Steele:嗯,當我還是個小學生時,我就已經深深迷戀科學和數學了,我讀了很多這方面的書,比如 Irving Adler的Magic House of Numbers,它是我的最愛。我也喜歡兒童科幻小說,比如DanngDunn系列等等。總的來說,我對科學和數學有著廣泛的興趣。所有我能找到的關於科 學和數學的東西,我都讀了,同時我也讀到了一點關於即將到來的新奇的計算機的介紹。

Seibel:你編寫的第一段有趣的程式是什麼?

Steele:嗯,我首先學習了Fortran語言,不過在我開始學習IBM 1130組合語言之後,事情才變得真正有趣。我能想起來的最早的有趣的程式是一段能產生上下文關鍵字索引的東西。IBM為他們的使用者手冊提供一個被稱作是快速索引的東西:給定一個關鍵字,你可以從一個按字母排序的索引中查詢,關鍵字的前後是這個關鍵字的上下文的一些單詞。

Seibel:你在MIT很自在,但最終卻還是去了哈佛讀書,而同時又在MIT打工,這是怎麼回事呢?

Steele:我申請大學的時候,申請了三所學校,MIT、哈佛還有普林斯頓。我最想去的是MIT。三所學 校同時都錄取了我。波士頓拉丁學校的校長Wilfred L.O’Leary是個老派的學者。老先生人非常好,打電話給我父母說:“你們知道令郎拿著哈佛的通知書實際上卻考慮去MIT嗎?”他就這樣向我父母施 壓,我父母轉而對我施壓,最終我決定去哈佛了。

我父母繼續找我的麻煩,讓我去打一份夏季工,而不是在家待著——你知道,做父母的都會這樣。我很清楚自己的興趣是計算機,我可不想去快餐店擺弄 漢堡包。我面試了打孔工的工作,並且自以為是完全能夠勝任的。但是沒有人願意僱用我,部分原因是我還不滿18歲,可找到後才明白。他們聽了我的敘述後 說:“不要打電話給我們,我們會打給你的。”然後就杳無音信了。

大約7月初我聽說MIT的BillMartin正在尋找Lisp程式設計師。我想:“啊哈,機會來了,我瞭解Lisp啊。”我過去經常出沒於MIT 的時候,從AI實驗室搞到了一些Lisp文件的副本,我也曾偷偷溜進實驗室擺弄過計算機。那些日子裡實驗室大門是敞開的,反越戰抗議發生後門才被鎖上。我 在高中四年級時在IBM1130計算機上實現過我自己的Lisp程式。

於是,我這個不知道哪裡冒出來的小瘦猴兒,跑到BillMartin的辦公室,從門口探進頭說:“我聽說你在招Lisp程式設計師。”他並沒有嘲笑 我,只是打量了我一下,然後說:“你得先做做我出的Lisp考題。”“沒問題,現在考怎麼樣?”我就坐了下來,花了兩個小時來答題。完成後我把試卷遞給 他,他用了十分鐘瀏覽了一遍,然後對我說:“你被錄取了。”

程式設計導師

Seibel:在你起步時有沒有遇到對你很重要的導師呢?

Steele:在拉丁學校期間我的數學老師對我的適當鼓勵刺激很重要。9年級的 RalphWellings,就是在那個感恩節週末借我書的那位老師,和我做了一個交易。他說:“我注意到你在所有數學測驗中都得到了100分。我可以讓 你在每週的前4天數學課都待在計算機室,不過在第5天數學課的測試上你必須得到100分,否則,交易就自動終止。”看,這就是激勵。在那年餘下的時間中我 變成了考試高手——我特別刻苦地學習數學,因為這能讓我接觸到計算機。更好的是,第二年我的數學老師沒有與我做同樣的交易,這正好,因為我對那一年的數學 瞭解不多。他們做出了恰當的評估。我的老師都是非常好的老師,我要學什麼他們總是為我大行方便。

Seibel:在那之後,隨著你更深入地學習計算機,有沒有特別的人在這領域幫助你呢?

Steele: 有,當然就是僱用我的Bill Martin。還有Joel Moses,他領導著Macsyma專案,我受僱於MIT期間就在這個專案組裡。

Seibel:在整個大學期間,你一直在做這個專案嗎?

Steele:是的,我在哈佛讀書的時候就一直是MIT的一名僱員。在暑假時是一份全職工作,開學後它就變成了一份下午的兼職工作。我儘可能地把哈佛的課程安排到早上,這樣我就可以搭乘地鐵去MIT,用兩三個小時來程式設計,然後再回去。

Seibel:一直用Lisp做Macsyma專案嗎?

Steele:是的。具體說就是當Maclisp直譯器的維護人員。Jon L.White原本同時負責直譯器和編譯器的工作。他後來成為了一位相當厲害的編譯器大師,而我則負責直譯器,這個分工不錯。就這樣,Jon L.White成了我的導師。Macsyma專案組裡所有的人都很關照我。我也得以結識一些AI實驗室的人,所以當我申請讀MIT的研究生的時候,很容易 就被錄取了,因為他們已經瞭解我,並且知道我在幹什麼。

Seibel:你得到了電腦科學學士學位?

Steele:是的,我本來打算主修純數學,並且都安排好了我的課程。後來發現我對什麼無窮維巴拿赫空間完 全沒有感覺,簡直要害死我了。幸好,我已經在業餘時間學習了足夠多的計算機課程,這讓我可以在專業的時候很主動。確切地說,我轉去修應用數學專業,而計算 機科學是應用數學的一個分支,在哈佛應用數學又屬於工程學的一部分。

Seibel:如果有可能讓你重新學習程式設計,你會有什麼不同嗎?有什麼事情你希望更早一點完成的嗎?

Steele:並不是一開始在我的腦海裡就有特定的目標。我對我選擇的這條路也不後悔。回首往事,我想我是一個幸運兒,受惠於一系列有趣的巧合,或者說,恩賜。

現在我意識到,實際上同時在MIT和哈佛的經歷是很不尋常的。我可以跑來跑去,然後說:“這條河(編者注:哈佛大學與MIT只有一河之隔,即查爾斯河)那一邊的教授是這樣說的。”而這一邊的教授就會說:“哦,別信他,你應該這麼想。”這很快讓我的視野更開闊。

作為高中生就能進入MIT是另一個相當不尋常的經歷。我15歲時就可以擺弄那些價值數百萬美元的機器,在那時1百萬元可真是一筆相當大的錢。所以,我當然沒有抱怨,沒有後悔,也不會有任何得隴望蜀的想法。我本性也是個隨遇而安的,既來之,則安之。

Seibel:與那時相比,對於程式設計的思維方式,有哪些大的改變?除了認識到氣泡排序不是最好的排序演算法之外。

Steele:我想對我來說,最大的變化是認識到你不可能瞭解執行在你計算機上的所有一切。有些事情絕對超 出了你的控制,因為不可能瞭解所有軟體的一切細節。而在上世紀70年代計算機僅僅有4K位元組的記憶體,你完全可以做一個記憶體轉儲,然後一個字一個字地去檢查 是不是你期望的。閱讀作業系統的原始碼,瞭解它是如何執行的自然也正常。我也確實這樣幹過——我研究過磁碟管理程式和卡片閱讀機程式,然後實現了我自己的版 本。我覺得我自己瞭解整個IBM 1130是如何運作的,或者至少可以說我瞭解我自己想了解的所有事情。不過現在你再也不能這樣幹了。

程式設計參考書

Seibel:在你學習程式設計的時候,有沒有什麼書對你特別重要?

Steele:在70年代的書當然是Knuth的TAOCP《計算機程式設計藝術》。

Seibel:你從頭到尾地讀過嗎?

Steele:差不多每頁都讀過,差不多。我做了幾乎所有我能做的習題。一些被稱作是高等數學之類的東西我不太明白,我做了些註釋或跳過了那些我不懂的。不過頭兩卷和第三卷的大部分我都很認真地讀過。還有Aho、Hopcroft和Ullman編著的那本演算法書(編者注:是指The Desing and Analysis of Computer Alogorithms(《演算法分析與設計》)一書)—— 我想我是從這裡面真正學到如何排序的。我得從我的書庫裡查詢一下,看看能不能還記得有什麼別的書。我是個收集狂——這類書我都有。不過這兩本是我首先想到 的。還有Lisp的書。Berkeley和Bobrow編輯的III Lisp(編者注:III指IntformationInternational,Inc.):是主題各異的論文集,不過我從中學到了很多有意思的東西。 然後我開始讀《SIGPLAN公報》和《ACM通訊》。那些日子裡的《ACM通訊》可是有很多真正的技術內容,非常值得一讀。

我要提及兩件事。第一件,當我在拉丁學校開始對科學感興趣的時候,我決定從事電腦科學相關的事情。有一天有個導師問我:“你考慮過成為ACM的學生會員嗎?”我不知道他的名字。不過我從那時起就非常感謝他,這給了我很大的鼓勵。

而我上哈佛以後,每當早晨有點空閒時間,我就會去Lamont圖書館做兩件事:按照我的方式,從後往前閱讀《科學美國人》,或者從前往後閱讀 《ACM通訊》。對《科學美國人》,我特別注意MartinGardner的所有數學遊戲專欄。對《ACM通訊》則閱讀所有我感興趣的文章。在1972年 這本期刊還只有15年的歷史,所以不難把它們全部都過一遍。

Seibel:閱讀所有文章在那時比在今天要容易得多,一個人還是希望瞭解整個領域的。

Steele:是的,你有希望瞭解這個領域。有很多隻有一頁長短的文章,讓你知道:“這兒有一項新的散打技術。”我讀了很多這類的文章。

Seibel:舊的文章我個人常常覺得不太容易理解,因為它們和一些舊硬體或者舊語言聯絡得比較緊密。

Steele:是這樣的,需要是創新之母——一個想法的出現是因為在一個特定的環境下需要它。過了一段時 間,大眾認識到這個想法很重要。然後你需要擺脫環境的侷限,展現出核心思想本身凸顯出來,這樣就可以流行好幾年了。“這個神奇的技巧可以按位逆轉字。”他 們給出了7090組合語言的一些東西。有些很有趣的數學思想在裡頭,不過他們還不能從中抽象出來。

Seibel:的確很多人從學校裡開始,在指導下學習電腦科學知識。但是還有很多程式設計師是沒有正規學歷背景的,只是邊幹邊學。對這個你有什麼建議嗎?你怎麼開始閱讀那些技術論文,如何抓住要點並理解它呢?應該從ACM最初讀起,一直讀到現在嗎?

Steele:嗯,首先,我得說通讀《ACM通訊》並不是我刻意博覽群書成為一名偉大的電腦科學家的計劃。我閱讀是因為我有興趣,有內在的動力去學習那些資料。所以我覺得這裡有兩個因素:第一是有內在的動力,想要閱讀它們,因為你有興趣或者說你覺得能提高你的技能。

另一個問題是你怎樣才能發現好的東西?當然,對“好”的認識也是三十年河東,三十年河西。今年你覺得是真正好的十年後說不定過時了。我覺得你可 以拜訪一位曾經經驗豐富的前輩,問他覺得什麼才是好的東西。對我而言就是Knuth,就是Aho、Hopcroft和Ullman。還有 GeraldWeinberg《程式設計心理學》,那本書今天還是非常值得讀一讀的。Fred Brook的《人月神話》也給我一些啟示。

那時候我流連於MIT書店的電腦科學書架,下決心每個月到那裡去一次,去翻翻那些書架。今天你再去一個書店,它的計算機書架規模可能是那時的10倍了,不過其中大部分圖書都是如何使用C或者Java的。但還是會有一部分理論背景、演算法這類書。

程式碼閱讀

Seibel:另一種閱讀——我知道你認為很重要的——是程式碼閱讀。你是怎麼樣以你的方式切入不是你編寫的一大段程式碼的呢?

Steele:如果那個軟體我知道如何使用,但不瞭解內部的工作機制,我通常會選擇一個特定的命令或者互動行為然後追蹤下去。

Seibel:執行路徑嗎?

Steele:是的。如果我要開始閱讀Emacs原始碼的話,我會說:“讓我們看看‘向前移動一個字元’的那部分程式碼吧。”即使我不能完全理 解,我至少會知道它使用的一些資料結構以及緩衝區是怎麼表示的。如果我足夠幸運,我能找到緩衝區增加一個的地方。一旦我理解之後,我接下來會嘗試“後退一 個字元”、“刪除一行”。通過我的方式就瞭解越來越多的使用方法或者互動,直到我覺得我能夠按照這種方式追蹤程式碼的其他更重要的部分。

Seibel:“追蹤”是指檢視原始碼在心裡執行它呢,還是要在偵錯程式中啟動它,然後單步執行進去呢?

Steele:兩種方式我都會做,我會用單步偵錯程式對付那些70年代或者80年代的小一點的程式。今天的問題是從啟動程式到它真正可以做點什麼,這中間有一段很長的初始化過程。所以更好的辦法是找到主命令迴圈或者中央控制子程式,從那裡開始追蹤。

Seibel:當你找到了那些以後,你是設定一個斷點然後單步跟進去呢,還是僅僅在腦海中想象它們的執行過程?

Steele:我更願意做桌面檢查——就是閱讀程式碼想象它會做什麼。如果我確實需要理解整段程式碼,我會坐下 來試圖按照我的方式來通讀程式碼。不過你不能一上來就這樣做,應該先在腦子中有了事情的組織框架。現在,如果你足夠幸運,程式設計師會留下一些文件或者規則的命名,或者合理組織檔案的順序,方便你快速閱讀他們的程式碼。

(推薦閱讀:《微軟資深軟體工程師:閱讀程式碼不容易》、《閱讀優秀程式碼是提高開發人員修為的一種捷徑》)

合理組織檔案的順序

Seibel:什麼是合理組織檔案的順序?

Steele:很好的問題。使我想起了諸如Pascal這樣的程式語言的一個問題,Pascal是為只過一 遍的編譯器設計的,原始檔中的過程傾向按照自底向上的方式組織,因為在使用過程之前你必須定義過它們。也就是說,閱讀Pascal程式最好的方法實際上是 從後面讀起,因為這樣你就會看到程式自頂向下的結構。現在(編譯器)形式如此多樣,你也就不能指望什麼了,除非程式設計師有一顆很強的責任心,將一切事情安排 得井井有條,有助理解。不過,第三點,我們現在也有很棒的IDE來幫助你檢視交叉引用,也許程式的線性組織也不再是那麼重要了。

第四點,我個人非常不喜歡IDE的一個原因是,你看完了所有內容後,還是很難理解。在圖形迷宮裡亂竄,很難知道所有地方都走到了。但如果你得到的是線性順序,就會確保所有事情都會梳理到。

Seibel:那麼在你寫程式碼的這些日子裡,你是不是儘量按照自頂向下來組織程式碼呢?高層函式出現在它們依賴的低層函式之前?

Steele:我儘量表現高層的想法。最好的表現方法可能是展示一箇中心的命令,控制的過程,以及向下面分發的事情。或者,重要的事情可能是首先要展現資料結構,或者說較重要的資料結構。重點是要像講故事那樣去表現想法,而不是隻羅列一堆程式碼在那裡。

在MIT工作時,一件很棒的事情是可以隨意訪問到沒有加密的程式碼,它們全是非常聰明的黑客作品。於是我讀過了ITS作業系統,也讀過了TECO 的實現和Lisp的實現。還有第一個相當漂亮的Lisp格式列印程式,是BillGosper編寫的。事實上,我在讀高中的時候就讀過它們,還試圖複製一 些到我個人的1130實現當中。

如果沒有接觸到在其他機型上的現有Lisp實現,我一定不能為1130實現Lisp的,我根本就不知道怎麼做。這是我個人教育的一個很重要的部 分。時至今日,我們面對的部分問題是軟體已經變得很有價值了,大部分軟體都是商用的,也就是說我們不再有可作為免費例子的優秀程式碼來參考了。開源運動在某 種程度上扭轉了這一點。如果你願意,你可以深入閱讀Linux的程式碼。在我那個時候閱讀TeX的程式碼是一項很有意義的練習,因為它是一大塊良好組織的、易 於除錯的程式碼。

本文節選自人民郵電出版社北京圖靈文化發展有限公司出版的《程式設計人生》一書。該書是當今15位大師級計算機程式設計師的訪談錄,重點介紹了他們的程式設計感悟。特此感謝圖靈公司授權。

來源:《程式設計師
文/ Peter Seibel   譯/葉淮光

 

相關文章