[原]《程序員的吶喊》讀書筆記(上)
《程序員的吶喊》是Google一位老程序員的經驗總結,文中展現了他對各大語言如Java、C/C++、Lisp、Python、Ruby、 Perl等的極端觀點,比如大力吐槽C++,極力推崇C、Lisp、Ruby。他的觀點只是他個人經驗所得,也不一定符合實情,僅供參考,有任何想法都可以說出來一起討論。
-
程序員和司機一樣,總是自我安慰說等到需要的時候再去學新技能也來得及。但是在內心深處他們都明白,其實當需求出現的時候就已經太晚了。因此現實情況是這樣的,旱鴨子會和水保持距離,司機會繞開泥濘的路段,而程序員會躲在舒適區里,搭建圍欄把自己保護起來,然后祈禱世界和平。
me:其實喜歡躲在舒適區里是每個人都或多或少存在的性格弱點,誰能克服它誰就能學到新技能,誰就能站的比別人高。對于偶爾努力經常懶惰的我來說,技術也是學的廣而不精,對新技術都有興趣但學不到精深處,希望剛工作的我可以改善這個弱點。
-
當時04年亞馬遜正飽受其龐大代碼庫的困擾,我曾經一度認為它的代碼庫失控是因為語言問題,后來才意識到企業文化是主因。首當其沖的是,亞馬遜的主流語言里有兩門非常哆嗦的語言C++中和Java,外加一門精練的語言Perl。但是Perl正受到排擠,漸漸退出主流。我覺得這是因為 Perl程序員能用更少的人力完成和Java/C++程序員同樣的工作量,所以要是比人多的話,他們注定是贏不了的。根據我們的估算,亞馬遜的代碼量比它的功能數量膨脹得更快。第二個因素是,亞馬遜的很多技術問題完全可以用自定義領域語言(DSL的方式來解決),比如大規模的查詢、分布式計算、產品配置等,他們寫了太多不必要的代碼了。我后來跳到Google,發現他們為這些完全一樣的問題專門編寫了強大的自定義DSL。這證實了我心中的疑慮,亞馬遜的工程師在這些問題上和無頭蒼蠅沒什么兩樣。我敢說這句話誤傷的概率極低。最后一點就是,和絕大多數公司一樣,亞馬遜非常抗拒用新語言來解決問題。他們會避免使用表達能力更強的通用語言,比如Ruby或Erlang。他們也幾乎從來不會想到自己去寫DSL。
me:龐大代碼庫是很多公司都有的弊病吧,可又有多少能想到用DSL來解決呢。害怕變動、拒絕新技術的公司注定是失敗的。
-
為什么C是必修課?一個原因是現在的電腦都是馮諾·伊曼結構的,而C以精悍的語法展現了馮·諾伊曼機的能力,其他類型的機器也是存在的,比如Lisp機。還有一個原因就是,Unix是用C寫的,不僅如此,包括Windows等在內的幾乎所有的操作系統都是用C寫成的,因為它們全部屬于馮諾伊曼機操作系統。你覺得自己還有其他選擇嗎?至少在操作系統領域里,任何與C迥異的語言都發揮不出硬件的實際能力,至少這句話放在近一百年里都是對的這些系統都誕生于這段時期內。
-
計算機編程語言里沒有所謂的“親近生侮謾“,只有在掌握更優秀的語言前提下,才會懂得怎么批判自己最熟悉的那門語言。因此,要是你不喜歡我批評C++,我建議你去了解一下更優秀的語言是什么樣子的,然后你才有資格否定我的話。不過到那時你就不會來否定我了,我忽悠成功了。那時你不會再喜歡C++,可能會有點生我的氣,忽悠你討厭自己之前最愛的語言。所以你還是別管我說什么了。C++很出色,非常優秀。別在意我的話。它是門很棒的語言。
me:作者是有多么討厭C++啊!“親近生侮謾“的意思是當你對一個人或事物越親近越熟悉,你就會越討厭越忽視TA。而作者認為計算機語言里不會發生這種事情,除非你知道了其它更優秀的語言。我贊同這個觀點。
-
亞馬遜的偉大元老們只用兩種語言:C和Lisp。顯然,他們都是Emacs的擁躉。
me:的確很多編程界的大佬都愛這兩門語言,比如《黑客與畫家》的作者。
-
杰米·扎溫斯基曾經寫過一篇非常有名的文章來批判Java有多糟糕,但他還是這樣寫道:“ 先說好的地方:Java沒有free(),我必須承認這一點,其他錦上添花而已。光這一點就足以讓我忽視其他缺點了,不管它們有多糟糕。 有鑒于此,本文接下來的內容都可以說無足輕重。”杰米的這篇文章寫于1997年,那時的Java還在襁褓之中,如今Java早已今非昔比,他當時抱怨的有些東西現在都已經修復了。但也不是全都改好了。就語言層面,Java仍然算不上優秀。但正如杰米所言,它“依然是今天最好的語言,遠遠比我們在實際工作中用的那些徹頭徹尾的垃圾語言要好得多”。 不過Java也缺了一些C++的優點,比如(在棧上)傳引用、typedef,宏,還有重載操作符。 這些東西并非必不可少,但是需要的時候就很方便。對了還有多重繼承,說得我都開始懷念從前了。假如你要用我自己的“固執己見的精靈”來反對多態,那么我還可以舉出更多為什么多重繼承是必需的例子。有時間我們可以討論一下“火焰劍”或者“盜賊披風”的問題,你就會明白接口是多糟糕的東西了。幾年前,高斯林自己也承認,要是有機會重來的話,絕對不會考慮接口。而這正是Java的問題所在。
me:Java好在垃圾自動回收,壞在臃腫不堪,語言本身設計的不好。
-
總之,Ruby對Perl充分實行了拿來主義。Ruby的作者Matz(我沒記錯的話,他的本名是松本行弘,不過通常都自稱“Matz”)甚至可能有點借鑒過頭了,連些不好的東西也拿了過來。好在不多,只有一點點而已。 基本上Ruby照搬了Perl的字符串處理和Unⅸ集成,語法完全一樣,只此一點,Perl的精華就全都有了。這可以說是開了個去蕪存菁的好頭。接著 Matz從Lisp那里吸收了列表處理的精華,從Smalltalk那里拿來了OO,迭代器則是取自CLU,基本上各個語言里的優點都吸收進來了。 所有的這些東西被完美地糅合在一起,你壓根注意不到斧鑿的痕跡。
me:Ruby本質上就是各種語言精華的大雜燴,去蕪存菁,作者精通這么多語言的精華非常值得敬佩。現在的框架也是的,都是互相之間借鑒精華,按需索取,無可厚非。
-
Python本來是有機會一統江湖的, 但是它有兩個致命的缺陷:一個是空白符,另一個是死腦筋。 所謂空白符的問題就是Python的嵌套是通過縮進來完成的。它強迫你用特定的方式來縮進,這樣大家的代碼看起來就是一樣的了。可惜,很多程序員都討厭這個規定,感覺好像被剝奪了自由一樣;他們覺得胡亂排版和和編寫那種精簡到一行沒人看得懂的小程序是自己的權利,而Python卻侵犯了這一點。 Python之父吉多·范羅蘇姆之前也出過幾次昏招,雖然不如拉里那么驚世駭俗,但也真的是夠小兒科的了。比如,Python原本是沒有詞法作用域的。可問題是它連動態作用域也沒有,雖然說動態作用域也有自身的問題,但至少還勉強可以用。Python最早只有全局和局部(函數)作用域,所以雖然它擁有一個 “真正的OO系統,可是—個類卻連自己的實例變量都沒法訪問。你只能給每個實例方法帶上一個self參數,然后通過self來訪問自己的實例數據。所以你在Python里看到一堆self ,哪怕你忍了空白符,這些self也能把你給逼瘋了。
me:用空格縮進的確讓人不爽,不過提升了規范性。
-
Java 其中特點之一就是凸顯了“架構”。Java國王授予了架構尊崇的地位,因為架構完全是由名詞組成的。我們都知道,名詞就是事物,而在Java里,事物的地位遠勝一切動作。建筑是由看得見摸得著的事物構成的,譬如高聳入云的龐然大物,又如用棍子敲打時發出低沉悅耳聲音的東西。Java國王特別喜歡這種沉悶的聲音,每次換新馬車的時候,他都特別喜歡從踢輪子中獲得快感。不管上述的兒歌有何瑕疵,它就是不想要任何東西。me:的確,Java最讓人受不了的就是一堆架構,一層層封裝致死,調試起來也麻煩。
-
福勒告訴我們所謂重構,就是通過迭代,將惡心的代碼變成優質代碼的藝術和科學,是能妝點代碼卻不會在操作過程中產生破壞的算法,而且正確性都是能證明的。
me:作者認為福勒寫的重構這本書非常不錯,值得一讀。
-
那么這些代碼一開始是怎么變爛的呢?首先當然是由于過早優化造成的,為了避免重復計算而保存了太多的中間變量。因為害怕方法調用會造成虛幻的負擔,而刻意回避編寫短小的函數。我們還弄出一大堆類的繼承關系,僅僅是為了想象中可能存在的復用,為了避免分配器對象而弄出一個巨大的參數列表。濫用null,把它當成成具有語義的符號。放任簡單的布爾邏輯表達式變成錯綜復雜、無法閱讀的漿糊。不用訪問方法來封裝數據結構。還有其他很多亂七八糟的問題。正是因為各種各樣的小錯誤別類,加以命名,并歸類成嚴重錯誤。
me:這是福勒重構這本書告訴我們的。
-
那我們的代碼是怎么變成那樣的呢?因為寫得爛。這時重構就能救命。再優秀的設計也會出紕漏,但我們仍然可以補救,反正有自動化的奴仆來幫我們修復這些:小問題。它們不知疲倦,我們只要點個按鈕就行了。既然如此,誰能離得開自動化重構工具?還有誰能協調Java那些數以百計的小腿,讓它們像毛毛蟲一樣統一行動呢?讓我來告訴你答案:Ruby是蝴蝶。(意指Ruby是完全不同的物種,Java中自動化重構工具所要解決的問題在Ruby中根本不存在。)
me:作者喜歡Ruby,覺得Java需要重構是因為代碼寫的爛,要是用Ruby寫的話根本不需要重構,也就沒有自動化重構工具。
-
首先,再垃圾的語言和技術也一樣有機會贏。甚至贏面可能還會大一點,因為改正起來會更快。Java擊敗了smalltalk , C++擊敗了Object-C,Perl擊敗了Python,VHS擊敗了Beta,諸如此類。并不是說一項技術(特別是編程語言)比較優秀,它就一定會勝出。營銷才是關關鍵。追求公平競爭只會導致你的語言無人問可津。
me:原來一門語言的流行起關鍵作用的不是這門語言有多優秀,而是它的營銷做的有多好。嗯,我記得Java就是營銷搞起來的。
-
注意,罵誰也不能罵Python。相反,罵Ruby罵得最兇的人可能就是Matz自己了。他在自己的演講“為什么Ruby很爛”里,自陳了Ruby的各種問題,當時看得我汗都下來了。不可否認,任何語言都有缺點。相比之下,我更喜歡Ruby眾的坦誠,Pyhon那種一味指責別人,回避問題,過分地自我標榜的行為令人感到惡心。
me:作者的意思是Python眾狂妄自大,而Ruby相對比較坦誠,這是作者通過經過逛兩個社區得出的結論,也不一定準確。