Joshua Bloch訪談:選擇編程語言就像選擇酒吧

本文是Commmon Lisp專家Peter Seibel對Google公司首席Java架構師Joshua Bloch的訪談,談到程序員應該看什麼書、如何能快速熟悉一種新語言以及爲什麼說選擇編程語言就像選擇酒吧。

Joshua-BlochSeibel:你是怎麼開始編程的?

Bloch:我想這是受益於我的家庭影響。我父親是Brookhaven國家實驗室的化學家。當我上小學四年級的時候,他參加了一個程序設計培訓班。當然在那個時候,電腦都是放在玻璃窗背後的大型機,你只能把寫好的程序卡片交給操作員。雖然沒法兒親自動手,但我還是被電子計算機可以幫助你做事兒這一點震撼了。所以,我在父親上課的那段時間,跟他學了一點兒Fortran。

Seibel:那大概是哪一年?

Bloch:我想是1971年。直到很多年以後我才真的對程序產生了強烈的興趣。讓我產生興趣的當然是分時系統。長島有一臺DEC system-10電腦,供Suffolk縣內所有的學校使用。Nassau縣也有一臺。很神奇的是,很多著名人物的事業都是從這兩臺DEC system-10電腦開始的。

你的程序一旦有交互,就會有Bug。大概是從1973~1976年,那時候我跟其他人一樣,在寫BASIC程序。我就是從那時開始正式寫程序的。你知道嗎,我還保存着當年寫的程序,是印在電信打印紙上的。如今回頭再看這些程序的時候我發現,我代碼風格中的某些部分從那個時候起就一直沒變過。

Seibel:你還記得你寫的第一個有趣的程序是什麼嗎?

Bloch:噢,我記得那是1977年7月4日,我爲經典的二十問遊戲寫了一個程序,叫“猜動物”。這個程序包含一個二叉樹,是非題位於它的內部節點,動物位於它的葉節點上。如果用戶所提的動物是葉節點上沒有的,它會向用戶提出是非題,通過區別新動物和它猜出的錯誤動物之間的差異來了解新動物。二叉樹保存在硬盤上,這樣程序可以越來越“聰明”。

我當時想,“天啊,真酷,程序真的能學習。”這是我一生難忘的瞬間。我還記得另一件事。當時我在高中,應該是10年級吧。是關於DEC system-10的。當時不允許我們編寫現在叫做即時消息軟件的東西,因爲它們對系統資源的消耗實在太大了。

Seibel:如果時光能夠倒流,可以一切從頭來過,有什麼東西是你真的希望改變的?Basic對你來說太簡單了?其他還有什麼?

Bloch:我沒什麼遺憾的,實際上Basic很有趣。我覺得Dijkstra對Basic的看法是完全錯誤的。原諒我這麼評價已故的人,願他在天堂安息。我知道很多非常好的程序員,他們是從BASIC編程開始的,因爲那是他們能找到的唯一的語言。

然而我覺得使用多種語言是件好事。上大學的時候,我用很多語言編程。每門課都可以用一門語言。在數學課或者理工科課上,應該用Fortran。那時候編程課學的都是Pascal、SAIL、Simula或者類似的東西。在人工智能課上,用LISP。

不過也許我應該學更多的語言。有意思的是,一開始我對面向對象並不感冒,直到那個二十問遊戲開發快結束了,我才真正對面向對象有了感覺。嚴格來說,Java纔是我真正使用的第一種面嚮對象語言,某種程度上是因爲我不太想用C++。

Seibel:那是什麼時候?

Bloch:那是我1996年加入Sun公司時。我覺得要是我能更早學習這些概念就好了。我不認爲這些概念都是好的。面向對象很有意思,它有兩層含義。第一,它意味着模塊化。模塊化是非常好的。但是我不認爲這是創造面向對象的人們的專利。你可以去看以前的文獻,例如,Parnas關於信息隱藏的論述,就會發現這種概念可以看作面向對象編程中類概念的一種抽象的原型。第二,它意味着繼承,我認爲繼承有利也有弊,這跟如今很多人的使用感受一致。

另外,我應該進入更多的領域,計算機科學領域內外都應涉獵。你學的東西越多,開始得越早,對你越好。我一直沒有真正做過的就是GUI編程,在某種程度上說我應該強迫自己做做看。但是由於種種原因,如這些年來開發庫代碼,構建他人可以使用的代碼塊,這些事情已經佔據了我的大部分時間。這樣算來,我做數據結構和算法等方面的工作已經有幾十年了。

Seibel:有什麼書是所有程序員都應該看看的?

Bloch:《設計模式》無疑是一本,雖然我對它的感情有點複雜,但是我還是認爲每個人都應該讀一下。書中列出了通用的詞彙,也提出了很多好的創意。另一方面,這本書有點兒像方法和語言的大雜燴,內容也有些過時了。但是我認爲它絕對值得一讀。

另外一本書是《Elements of Style》,它甚至不是一本編程書。爲什麼要看這本書呢?理由有兩條。首先,每個軟件工程師工作中很大一部分是寫文檔。如果你無法寫出精確、統一、易讀的說明書,那麼沒人會去用你的產品。所以說可以改善你寫作風格的東西都值得借鑑。其次,該書裏面的大部分思想都適用於編程。

我的荒島列表有點古怪。例如,最重要的書是Herry Warren寫的《高效程序的奧祕》(Hacker’s Delight)。

Seibel:這是一本位操作(bit-twiddling)書?

Bloch:是的。我愛位操作,這跟我的工作有關聯。如果你寫庫、編譯器、底層圖形代碼或者加密代碼,這本書是不可或缺的。Warren把曾經口口相傳的東西放在一起,用嚴謹的數學去進行驗證。這本書出版的時候,我被震驚了。

當然還有Knuth的《計算機程序設計藝術》。事實上,我從來沒有讀完這一套書,至少沒有從頭到尾看過。但當我研究某個具體算法的時候,我就去看他會怎麼說。往往可以得到我想要的東西,這套書太全面了。

但是我沒有能力、也沒有時間去讀完整套書,所以如果我告訴你我讀完了,那麼我就是在說謊。我覺得還有一本非常好的老書,是Kernighan和Plauger寫的The Elements of Programming Style。書裏面的例子都是用Fortran IV和PL/I寫的,所以有點過時。不過,雖然這本書這麼老,但裏面的思想卻從未過時。

另外一本老書是Frederick Brooks的《人月神話》。這本書都出版40年了,裏面的思想仍舊同出版時一樣有影響力。閱讀它是一種快樂,每個人都應該讀一下。這本書的主要信息是“給一個延期的項目加人,會讓它延期得更加厲害”,今天這一點仍舊是正確的。裏面還有其他很多重要的觀點。有些細節雖然過時了,但仍值得一讀。

現在每個人都必須要學習併發編程。所以應該看看《Java併發編程實踐》這本書。雖然標題中有Java,但是很多內容並不限於任何具體的編程語言。

Seibel:這就是你和Brian Goetz合著的那本書?

Bloch:我的名字是印在封面上的,但是我提到它的原因恰恰是因爲這不是我寫的書。第一作者是Brian,第二作者是Tim Peierls,制定Java併發標準JSR-166的每一個人也都是這本書的作者。把我的名字印在了封面上僅僅是出於禮貌,我貢獻了些材料,但是沒有正式參與編寫此書。

噢,還有一本:《韋氏學院詞典(第11版)》。我去哪裏都帶着它。這倒不是你實際上要讀的東西,但是我說過,寫程序的時候,必須能命名好變量。你的文筆必須好。沒有好的字典,我就會覺得少了點兒什麼。

Seibel:除了命名好變量,儘量少的複製粘貼以外,你經驗豐富後,還有哪些寫程序的習慣改變了?

Bloch:隨着年齡的增長,我逐漸意識到編程不僅僅是讓程序運行而已;編程是創造一個易於理解的、可以維護的、高效的作品。一般來說,我發現,乾淨整潔的代碼,往往運行起來更快。這與流行觀點正好相反。而且即使它們不快,也可以很容易地讓它們變快。正如人們所說的,優化正確的代碼比改正優化過的代碼容易多了。

我的一些改變是跟具體語言相關的。每種語言都提供了一個工具箱。你要使用正確的工具,在這種語言中正確的工具在另外一種語言中可能不是最好的。舉一個簡單的例子:如果你用Java 5,使用枚舉來代替整數常量或者布爾常量可以大大簡化程序,讓它更安全,更可靠。

Seibel:說到這兒,你能否談談如何能快速熟悉一種新語言?

Bloch:這跟人類的語言很類似。一種方法是學會很多語言。如果你已經熟悉意大利語和西班牙語,那麼學葡萄牙語就不需要花太多時間了。你知道的越多,你能吸收的就越多。

學習一種新語言的時候,要利用以前所學的語言的功底,但是也要保持開放的心態。有些人執著於一種理念:“這就是寫所有程序必須遵循的方法。”我不說是哪種語言,但是某些語言,出於某種原因,令人執著於這樣的理念。當他們開始學習新的語言的時候,他們批評這種語言跟真正的神的語言的所有不同之處。當他們使用新的語言時,他們極力使用真正的神的語言的方法去寫。這樣,你就會錯過這個新語言真正的獨特之處。

這就像你本來只有一個榔頭,有人給了你一個螺絲刀,你說:“唉,這不是一把好榔頭,但是我應該可以倒着抓住螺絲刀,用螺絲刀把來砸東西。”你得到了一個很爛的榔頭,但事實上它是一把很不錯的螺絲刀。所以你應該對所有事物保持開放和積極的心態。當然,最重要的是代碼!代碼!代碼!要多用語言,這樣才能學得更快。

Seibel:爲什麼人們對所選的計算機語言那麼虔誠?

Bloch:我不知道。但是選擇一種語言時,所考慮的不僅僅是一系列技術上的權衡,而是在選擇一個社羣。這就像選擇一個酒吧。沒錯,你希望去一個提供美酒的酒吧,但是美酒不是最重要的。主要是那個酒吧裏都有什麼樣的人,他們在談論些什麼。選擇計算機語言也是這樣的。時間一長,就這門語言也形成了一個社羣,社羣裏不僅僅有人羣,還有他們的軟件成果,如工具、庫等。這就是有些理論上看起來更好的語言無法成功的原因,他們無法在周圍構建成功的社羣。

Seibel:要是這麼理解的話,Java非常有趣,它有兩個社羣。一個是實現者和系統開發者,也就是在Javasoft、Weblogic或者類似地方工作的人們。另一個是所有用Java、應用服務器、構建好的框架來構建商業應用的人們。這兩個酒吧差別非常大。

Bloch:與Java或者其他語言關聯的社羣很多。如果語言周圍沒有形成社羣,這通常表明,要麼這個語言無人問津,要麼就還很不成熟。語言繁榮發展,就會自然地表現爲出現越來越多各式各樣的社羣。同時,如果對一門語言的投入總額增長了,那麼它的價值也會相應地增長。

這就像梅特卡夫定律(編者注:一種網絡技術發展規律,由3COM公司創始人、計算機網絡先驅羅伯特·梅特卡提出。):網絡的價值與用戶數量的平方成正比。這對於編程語言也適用。所有使用這種語言的用戶構成社羣,然後突然間出現了Eclipse,出現了FindBugs,出現了Guice。即使Java對你來說不是最好的語言,但是使用它有這麼多附加的好處,所以你還是會創建社羣,解決如何在Java中進行數學編程,或者你需要的其他類型的編程方法。

Seibel:你有沒有過這樣的感覺:你越來越清楚那程序就是搞不定,到處都是這樣那樣的問題,幾乎令人絕望?

Bloch:當然有過。寫書也是這樣的。每次開始一件事情的時候,我總想逃避。開始是最艱難的,有時候我會鼓勵自己:“加油Josh!這行你都幹了三十多年了,你知道怎麼能做到跟別人一樣好,不必瞻前顧後,動手吧。”或者對自己說:“你瞧,以前的一切你都做的挺好的,這次也錯不了。”

Seibel:你剛纔提到你的生活體驗變寬廣了,這可能會影響編程,但是有沒有什麼東西,是編程以外的體驗,但是幫助你成爲了一個更好的程序員呢?

Bloch:當然有。我認爲你能做好的每件事情都有這個作用。思想是沒有學科限制的。我想到了一個例子。我寫論文的時候,要對一種分佈數據結構,RSM(Replicated Sparse Memory,複製型稀疏內存)做一個分析。而做這個分析的基礎思想來自於我所上的化學課。那是一個動態平衡公式:如果系統裏有一個動態的平衡關係,就可以寫出一個等式,“事物進入一個特定狀態的速度,和他們離開這個狀態的速度相等。”這樣就得到了三個變量的三個等式,求解這三個等式,計算出來的結果和觀察到的這種複雜的分佈數據結構的行爲恰好匹配。這就是我直接從化學裏偷來用於計算機科學的思想。

你在生活中看到的很多東西,不管是架構上的,即建築物構建的方法,還是在語言上的,即人們進行溝通的方法,很多思想都是可以借用的。當然包括數學。數學和編程相當類似。所以要睜大雙眼,積極地吸收重組各種思想,這樣做絕對錯不了。

(本文來自《程序員》雜誌10年11期)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章