訪談Brad Fitzpatrick——《編程人生》精彩樣章
丁雪豐/譯
Brad Fitzpatrick 是所有受訪者中最年輕的一位,也是其中唯一一位從未在沒有因特網或個人電腦的世界里生活過的。他出生于 1980 年,很早就開始了自己的程序員生涯, 5 歲時就在一臺自制的 Apple II 克隆機上學習編程。在十幾歲時,正好趕上因特網革命的大潮,他一頭扎入其中,在高中時就建立了自己的第一個商業網站,在進入大學前的那個夏天創立了著名社區 LiveJournal 。
LiveJournal 的日漸流行迫使 Fitzpatrick 走上了學習構建可伸縮網站的艱難之旅,期間他和他創辦的 Danga 交互技術公司里的程序員們開發了幾個開源軟件,其中包括 memcached 、 Perlbal 和 MogileFS ,現在被用于很多世界上最繁忙的網站的服務器上。
Fitzpatrick 是個典型的極有才華的世紀之交的 Web 程序員,他的主要編程語言是 Perl 和 C ,需要時也會用 Java 、 C++ 、 Python 、 JavaScript 和 C# 。他做的所有編程工作基本都與網絡相關,比如為網站構建更好的后端基礎設施,設計協議和軟件來讓博客閱讀軟件獲知博客更新,甚至為他的手機編寫代碼以便在摩托車上就能自動打開車庫門。
我們將談到他在讀著名兒童系列叢書 Clifford the Big Red Dog 的年齡就開始學習編程,為什么能夠很高興地一邊念大學,一邊運行 LiveJournal ,以及他是如何學會不懼怕去閱讀他人的代碼的。
Seibel : 你是怎么成為一個程序員的?
Fitzpatrick :我父親曾在 Mostek [1] 工作。這個公司是制造內存的,他對電腦很感興趣。他做了臺 Apple II 電腦,材料幾乎都是多余的廢棄部件。他和我母親坐在電視機旁把部件焊起來,這個工作花了他們好幾個月,只是把它們焊起來而已。然后我父親從公司里拿了些不能賣的ROM ,這些 ROM 有一位或幾位不能用,有的在高位,有的在低位。后來不知怎么著他們弄到了 Apple II ROM ,接著就不停地將 ROM 燒到無法工作的芯片上,直到找到一塊能用的為止,損壞的那位正巧是好的。最終,他和他的一幫同事終于做成了自制 Apple II 。我差不多從兩歲起就在上面玩或者看他編程。
Seibel : 他是個程序員還是個硬件工程師?
Fitzpatrick :他是個電氣工程師,偶爾也寫寫程序。我五歲時他就教我編程,搞笑的是我六七歲時就超過他了。我母親說我是一邊讀 Clifford the Big Red Dog , 一邊讀從圖書館借來的 Apple II 程序員手冊。我會把 “ 變量”念成 “ 貝量”。我早期的一些記憶就是和父親一起編程。比如他把我拖進廚房,在紙上寫下一段程序,問我: “ 你覺得這段程序是什么意思?”我記得那程序好像是 “ 10 PRINT HELLO, 20 GOTO 10” 。
Seibel : 那么說你是從 BASIC 開始的?
Fitzpatrick :是的,就是 BASIC 。我當時還不能使用鼠標、高級圖形模式和彩色,直到我們家的一個朋友向我介紹了 C 并給了我 Turbo C。那年我大概八歲或者十歲。我父親在 1984 年去了 Intel ,我們就搬去了波特蘭。他幫助設計了 386 和 486 ,現在仍在 Intel 。我們總是能有新的有趣的電腦。
Seibel : 那你有沒有試過匯編語言呢?
Fitzpatrick :我在計算器上做過些匯編,比如 TI 計算器上的 Z80 ,但僅此而已。
Seibel : 你還記得是什么吸引你開始編程的嗎?
Fitzpatrick :我不記得了,只是好玩吧。我母親不得不限制我使用電腦,好讓我出去和朋友們一起玩。我的朋友們會跑過來說: “ Brad 又在玩電腦。他太無聊了。”我母親則會對我說: “ 到外面去玩吧。”
Seibel : 你還記得寫的第一個比較有意思的程序嗎?
Fitzpatrick :我們以前有臺 Epson 打印機,它配有幾本又大又厚的手冊,手冊最后是程序員指南。我就在 Apple 上寫了點東西,我可以在高級圖形模式下畫些東西,當程序完成繪制(線段、圖案或別的什么)之后,按下 Control C ,在后臺一個不會顯示的幀緩沖區里鍵入一段內容,加載另一個程序,它會讀取屏幕并打印出來。
在那之前,我記得還寫過一個程序,每當我敲擊一個鍵,它就移動稿面,我按退格稿面會向回退,這樣打字時就感覺像是在用打字機一樣了。
這是我的第一個程序,好比方 K 是抓取的下一個字符,如果 K 等于 a ,打印 a ;如果 K 等于 b ,打印 b 。我幾乎處理了每個字母、數字和一些標點。后來一個念頭一閃而過: “ 等等,我可以說‘打印一個變量!’”然后用 1 行代碼替換掉了 40 行。 “ 天啊,這太棒了!”對一個六歲的孩子來說,這已經是抽象能力的極限了。
那些都是比較有意思的早期作品。到了中學,我開始開發游戲,為朋友們制作圖形編輯器和關卡編輯器,他們會把圖形做進關卡中,隨后我們再把它賣給其他同學。我記得我不得不檢測 EGA 和 VGA 。如果 VGA 跑不了,就退回到 EGA 模式,使用另一組適合當前屏幕的貼圖,為此我們必須為所有的東西做兩組圖形。學校的人會出大概 5 美元買它,然后安裝,接著發現它不能用,他們的家長就會給我爸媽打電話大喊:“ 你兒子拿那沒用的東西從我孩子那里騙了 5 美元。”我母親就開車帶我過去,坐在死胡同里等我進同學家調試并修復我的程序。
Seibel : 那段日子里你有沒有上過關于編程的課?
Fitzpatrick :沒有。就是從圖書館里借了一兩本書,然后隨便玩玩。當時沒有真正的論壇或因特網。后來我連上了一個 BBS ,但上面并沒什么內容,它沒有聯上因特網,只是一群人在玩棋類游戲而已。
Seibel : 你的學校有 AP [2] C.S. (計算機科學)或類似的課程么?
Fitzpatrick :呃,我們沒有 AP C.S. 課程,但我們有計算機程序設計課。有一個老師在上這門課,不過我都可以在教室后面講高級課程了。他們還在用我寫的圖形編輯器和圖形庫,他們要做的項目是開發一個游戲。我偶爾還會碰到那個計算機老師,他是我家的一個朋友,我會在我哥哥的足球比賽上看到他,他會說: “ 是啊,我們還在用你的庫呢。”
我的確參加了 AP C.S. 考試,那是在考試從 Pascal 換成 C 語言前的最后一年,一年后又從 C 換到了 Java 之類的語言。我不懂 Pascal ,所以去附近有 AP C.S. 課程的高中上了一些夜間班,大概三四次吧。后來我找了本書來學 Pascal ,我把大多數時間花在用 Pascal 畫星形線上,因為那時我剛學三角學。我會說: “ 哇哦,正弦和余弦太有趣了。我又可以一顯身手了。”
Seibel : 那你考得怎么樣?
Fitzpatrick :我得了 5 分 [3] 。考試內容是寫一個大整數類。現在這是我招聘人員的一道面試題: “ 寫一個能夠進行任意大整數乘法及除法的類。”既然我能在高中的一次 AP 考試中做出這道題,那么他們在這兒應該也能做得出來。
Seibel : 你大學第一年的夏天在 Intel 工作,那在高中時期有沒有做過程序員的工作呢?
Fitzpatrick :是的,我在 Tektronix[4] 工作過一段時間。在正式工作之前,我有幾個主機賬號。我寫了些機器人程序,往聊天室里灌水,把AOL 惹翻了,這么做確實讓人討厭。我在另一個 Windows 程序中編寫 AOL 客戶端腳本,還寫機器人程序猛提交 AOL 的線上表單,獲贈 CD 。因為不想讓他們發現這是重復表單而只寄一張 CD ,我用了自己名字的各種變體。這些賬戶有 100 個免費小時,或者是 5000 個免費小時。在這幾千次表單提交后,整整一個星期,郵遞員會天天帶著很多 CD 過來。
我媽媽說: “ 見鬼, Brad ,你會有麻煩的。”我回答: “ 呃,這是他們的錯,對嗎?”后來有一天,有一個找我的電話,我接了(通常我不去接電話),電話那頭是一個 AOL 的人,他對我大叫: “ 別再向我們提交表單了!”我平時的反應并不敏捷,但這次我立刻回敬了他:“ 為什么你們會寄給我這些廢物?每天都有郵遞員過來,扔下這些 CD !”他說: “ 對不起,先生。不會再發生這樣的事情了。”然后我把這些 CD 都用來布置大學宿舍了,它們現在還放在我家車庫的一個盒子里呢。我記得它們曾是很好的裝飾品,所以沒有扔掉。
惡搞完 AOL 后,我得到了一個當地 ISP 的 shell 賬號。大概上我就是在那時學的 Unix 。雖然不能運行 CGI 腳本,但我可以用 FTP 上傳東西,所以我就在家里的臺式機上運行 Perl 程序來生成整個 Web 站點,接著再上傳到服務器上。后來我在 Tektronix 得到了一份工作,類似暑期實習。當時我已經很懂 Perl 和 Web 了,但還沒有做過動態 Web 。在 1994 年、 1995 年時, Web 還是個很新的東西。
我去 Tektronix 上班的第一天,他們給我介紹我的辦公用品: “ 這是你的電腦。”那是一臺大的 SPARC 工作站,也可能是別的什么運行了X 和 Motif 的機器。 “ 這是你的瀏覽器。”可能是 Netscape 2 ,我記不清了。 “ 如果你有 CGI 的東西,放到這個目錄里。”我記得那天晚上我寫了個最基本的 Hello World 的 CGI 程序,大約就三行吧,我感嘆道: “ 天哪,這太有意思了。”第二天早上六點我就來工作了,繼續瘋狂地寫 CGI 。
后來我開始自己做動態 Web 編程。當時我找了臺支持 CGI 的 Windows Web 服務器。我最終說服了我的 ISP (也許是和他們交情不錯,或者之前給了他們不少幫助讓他們信任我): “ OK ,我們會運行你的 CGI ,但開始前會對它們做審核。”他們仔細查看了代碼,然后把那些代碼扔到他們的目錄里。那是一個投票站的腳本,你可以用它來創建投票程序,例如: “ 你最喜歡的電影是哪部?”添加完選項后就能開始投票了。后來的幾年里它變得越來越流行了。
Seibel : 是 FreeVote 嗎?
Fitzpatrick :是的,在弄爆我的主機后它變成了 FreeVote 。那時 Banner 廣告真的很流行,也許就是那段時間開始流行起來的,我通過它賺到了越來越多的錢,得到越來越好的合同,每次點擊的收益也越來越高。最高時每點擊一次廣告我就能賺到 27 美分,就算是按今天的標準,我覺得也是相當夸張的。有了它,我每個月在 Banner 廣告點擊方面能有 2.5 萬~ 2.7 萬美元的收入。
這些都是在高中時做的,我整個高中時期都在私下做這事。我還在 Intel 做了兩個夏天,隨后在進入大學前的最后一個夏天,我辦起了 LiveJournal 。為此,在進入大學的第一年,我賣了 FreeVote ,基本上算是送給一個朋友的,大概只要了 1.1 萬美元,因為我想擺脫它,還有相應的法律責任。
Seibel : 你有了 ISP 并開始使用 Unix ,這有沒有對你編程帶來什么變化?
Fitzpatrick : Unix 并沒讓我抓狂。我沒辦法理解 Windows 上都發生了什么,也許你看過 Windows API — —每個函數都有差不多 20 個參數,它們都是標志位,而且一半都賦了 0 值。完全不知道發生了什么。當有東西無法正常工作時,你根本沒辦法知道究竟是怎么回事。
Seibel : 你早期的編程方法或編程風格和你現在所想的有什么明顯的不同之處嗎?
Fitzpatrick :我用過很多種編程風格,面向對象的、函數式的,現在用的這種有點怪異,混合了面向對象和函數式編程。這是我熱愛 Perl 的原因,雖然語法很丑陋,有很多歷史包袱和瑕疵,但它從不限制我寫代碼的風格。用你喜歡的風格去寫就是了。你能讓代碼優雅一致,卻沒有和特定語言相關的風格。直到我進入 Google ,我寫的 Perl 代碼才慢慢少了下來。
運營 LiveJournal 后,我也做了很多測試工作。尤其是當我開始和他人共事時,我意識到永遠也甩不掉自己寫的代碼,要一輩子維護它們時,我開始寫測試了。在十年前的博客文章上,我收到了這樣的評論: “ 嘿,我看到這段代碼,發現了一個問題。”然后我立刻著手維護代碼。
我現在維護著很多代碼,還有其他很多人在和它們打交道,如果有什么地方不清楚,我會假設有人理解不了我寫的某些不變式。因此,當我要搞些小聰明時,通常我都會保證在代碼出現問題時有測試及時跳出來。我也強迫其他人寫測試,他們基本上都為我工作。我會為自己的代碼寫測試,當別人寫代碼時我會告訴他們: “ 你確定這段代碼能工作嗎?寫個測試證明給我看。”有時,他們會意識到 “ 天哪,這么做太有用了”,尤其是在后期維護的時候。
Seibel : 你是從什么時候開始和他人一同共事的?
Fitzpatrick :差不多是在大學結束的時候,我開始雇用其他人,尤其是畢業搬回波特蘭后。
早期的雇員是客戶支持,所以他們不用寫任何代碼。慢慢地,我開始雇用程序員。我雇傭的第一個人是我的一個網友,他的名字是 Brad Whitaker ,我們都有名為 BradleyLand 或 BradleyWorld 的網站,因此我們找到了對方的網站。我比他早幾年開始 Web 編程,也可能是早一年,他問我: “ 嘿,你的網站是怎么做的?”就是說它到底是 HTML 、 Frame 、 CGI 還是 Perl 的。后來我開始接很多合同項目,我就把一些我不做的項目給他。有一次我們有個大項目,誰都沒有辦法獨自完成,我找到他說: “ 這個項目需要兩個人來做。”他讓我飛去賓夕法尼亞,也許是匹茲堡?我對東海岸完全沒概念,我是個生活在西海岸的人。也許是費城?有牛肉奶酪三明治 [5] 的地方。
Seibel : 是費城。
Fitzpatrick :是的,我們第一次見面是在一家便宜的旅館里,我感覺好像早就認識他一樣。他和我打招呼: “ 嘿,最近怎么樣?”他走了進來,在我旅館的衛生間里上了個廁所,當時我就站在那兒,可他連門都不關。我回答道: “ 還不錯。你還真愜意。”雖然我們從未謀面,可就像認識了四五年一樣。然后,我們就開始干活了。
他住到我空余的一間臥室里,我們差不多把廚房給搬空了,架起幾張桌子,放上電腦就開工了。我們通常 10 點或 11 點起床,干到中午,看會兒電視(穿著短褲坐著看電視),然后不間斷地工作到早上三四點鐘。后來,我的另一個朋友從華盛頓大學過來度暑假。他是我大學一年級后認識的,我們三個在一起忙碌著。這個朋友住在市區,早上坐輕軌過來,然后滑滑板到我家。他就坐在外面用 Wi-Fi 上網、寫程序,直到我們醒過來去給他開門,讓他進來。
一起有了三個人,房子就有點擠了,我就說: “ 哦,好吧,我們搞間辦公室吧。”于是我們弄了間辦公室, “ 我們既然有了這些空間,不如再雇點人吧!”在隨后的兩年里,我們慢慢擴大到了 12 個人,而 LiveJournal 也逐漸流行了起來,當然壓力也更大了,因為我還得處理人事問題。
后來,我媽媽來處理人事,隨后我們的關系就有點緊張了,因為她為我工作。我給她定了幾條規矩: “ 如果你給我打電話,要分清楚是私事還是公事。要么只談私事,要么只談公事。你不能在工作與私人問題間換來換去的。”如果她轉變話題,我就會掛電話。然后她再打回來,我會說 “ 你搞混了”。這真的搞得很緊張,當我把公司賣掉時她真的很高興,她不用再為我工作了,我們也不用爭吵了。
Seibel : 那時你的公司還接合同工項目嗎,還是說這就是整個 LiveJournal 了?
Fitzpatrick :差不多這就是整個 LiveJournal 了。我們還打算開個照片托管服務,這方面 Flickr 做的比我們好,我們的那個有些過度設計了:漂亮的抽象,能結合到任何東西中。為 LiveJournal 做的每個新的基礎設施,我們都會問自己: “ 它怎么和 FotoBilder 結合到一起?”為此,我們把每樣東西都抽象出來。 Memcached 是抽象的,因為沒有必要把它和 LiveJournal 綁在一起。隨后我們還做了個類似 GFS 的文件系統,還有一個任務隊列。為了提高可擴展性,我們不停地開發基礎設施組件,它們能被應用于我們的各項產品之中,由于沒有復雜的依賴關系,它們的維護也更方便了。雖然可能會增加一些工作量,但如果能減少依賴,那還是很值得的,所以我們開發了所有這些通用基礎設施。
Seibel : 我對于你擴展 LiveJournal 的過程有些好奇,你是從什么地方開始的,一路上又是怎么學到你需要的東西的?
Fitzpatrick :我們和其他客戶共享一個 Unix 主機,差點把它搞掛了。
Seibel : 以 CGI 的方式運行的嗎?
Fitzpatrick :是的。我想從嚴格意義上來說那應該是個 CGI ,派生出所有的東西然后終止掉。 ISP 分配給我一個家伙。我的服務器當時總是死機,我對他說: “ 我每月為這臺服務器付 10 美元,它為什么不能工作?”他告訴我: “ 哦,你該這么做。”很快我就學會了 Unix ,知道正在發生的事情。
我從 CGI 轉到 FastCGI ,調整了 Apache ,關閉反向 DNS 查詢功能。經過了這些步驟,性能有了好轉。最終,我遇到了 IO 和 CPU 的瓶頸,我買了自己專用的服務器,但那也只是一臺機器,它經常死機,而且我的硬盤快沒有空間了。起先這臺服務器只對我的朋友開放,我沒有取消注冊頁面。他們邀請了他們的朋友,而這些朋友又邀請了其他朋友,但我并沒想過把這個站點變成公開網站。它只是正好有個開放的注冊頁面。于是,我在 LiveJournal 的新聞頁面里寫了點東西: “ 我們需要大家的幫助,我們需要購買服務器。”
我記得那次大概募集了六七千美金,我買了兩臺大的 Dell 服務器,托管在西雅圖市區的 Speakeasy[6] 里。有人推薦了一些 Dell 服務器,這些 6U 的大家伙差不多有 90 磅 [7] 一臺。數據庫服務器和 Web 服務器從邏輯上是獨立的。因為我運行了一個 MySQL 進程和一個 Apache進程,所以我只知道這樣去分離。
就這樣過了一陣子。 Web 服務器直接面向大眾,服務器上有兩塊網卡,通過交叉線纜( crossover cable )連接數據庫服務器。后來 Web服務器過載了,但那還比較好對付,那時我有了幾臺 1U 的服務器。之后我們有了 3 臺 Web 服務器和 1 臺數據庫服務器。這時我先后用了三四個 HTTP 負載均衡器— — mod_bachhand 、 mod_proxy 和 Squid 。這些我一個都不喜歡,我就是從這時開始討厭 HTTP 負載均衡器的。
接下來過載的就是數據庫,那時我抱怨道: “ 哦,見鬼。” Web 服務器可以很好地擴展,它們都是無狀態的,只要投入更多的機器,分散負載就可以了。那段時間很難熬, “ 我可以優化查詢來應付一下,”但那只能堅持一周,一周后它又會過載。那時我就開始思考一個獨立的請求到底需要什么。
那時我認為自己是世界上第一個想到這個方法的人,我們可以切分數據庫,將它分區存放。我畫了幾張圖來做設計文檔,簡單說明我們的代碼會是如何工作的。 “ 我們的主數據庫只存放全局相關的元數據,這些是低流量的。各個博客和評論相關的東西會分別存放到每個用戶的數據庫集群里。每個分區都有自己的用戶 ID 。”現在看來,每個人都會這么做。但那時候在不間斷服務的情況下遷移代碼 著實是件很費力的事。
Seibel : 在你遷移時有沒有暫停服務?
Fitzpatrick :沒有。每個用戶都一個標志位,標明他在哪個集群上。如果標志位是 0 ,說明他在主數據庫上;如果非零,則說明他已經被分區了。有個版本號是 “ 你的賬號正被鎖定”。這時該賬號處于鎖定狀態,嘗試遷移數據,如果在這時你做了什么變更則需要重試。基本上在我們完成遷移前你在主庫上不能進行寫操作,遷移完成后聲明: “ OK ,現在你的賬號可以使用了。”
遷移程序在后臺運行了兩個月。我們計算過,如果只是把數據導出來,寫點程序拆分 SQL 文件隨后重新加載,可能要花一周左右。擺在我們面前有兩個選擇——停機一周或者緩慢遷移兩個月。我們先遷 10% 的用戶,這時對其他用戶而言,整站的可用性提高了,隨后我們再慢慢提升遷移到集群的用戶比例。
Seibel : 這就是 memcached 和 Perlbal 的前身了吧。
Fitzpatrick :是的,那確實是 Perlbal 的前身。 memcached 是在那之后的事情了。在大學結束離開學校前,我都沒想過要做 memcached。站點越來越慢,一天我在浴室里洗澡的時候靈光乍現,突然意識到我們有這么多空閑的內存可以利用。那晚我寫了個原型,服務端和客戶端都是用 Perl 寫的,服務端很快就崩潰了,因為對于一個 Perl 服務器而言 CPU 的使用率太高了。于是我們著手用 C 來重寫它。
Seibel : 這樣就省去了購買更多數據庫服務器的開銷了。
Fitzpatrick :是的,數據庫服務器又貴,遷移又慢。 Web 服務器非常便宜,把它們加上馬上就能見效。如果你買一臺新的數據庫服務器,差不多要花一周來進行配置和驗證:測試磁盤、配置和調優。
Seibel : 這么說來,你所開發的所有這些基礎設施,比如 memcached 和 Perlbal ,都是為了響應 LiveJournal 的實際擴展需要?
Fitzpatrick :是的。我們開發這些東西都是因為 LiveJournal 承受不了負載,我們挑燈夜戰開發新的基礎設施。我們甚至還買過 NetApp[8]。我們問: “ 這要多少錢?”他們回答: “ 說說你們的商業模型。” “ 我們有付費賬戶。” “ 你們有多少客戶?怎么收費?”你就能看到他們在那里做乘法。 “ 價格是你們在不破產的情況下的所有可支配收入。”我們心說: “ 去你的。”但我們確實需要它,所以還是買了一臺。我們對它的 I/O 性能并不滿意,它不僅很貴,還會形成單點故障。他們試圖賣給我們一套高可用配置,我們想: “ 去你的!我們不會再買這種東西了。”
后來我們開始寫自己的文件系統。我不確定當時 GFS 的論文是不是發表了,我覺得我應該從誰那里聽到過。那時我的內存很分散,取個散列的鍵,從分區里取值。為什么不能把這招也用在文件上呢?文件是永久性的。因為增加存儲節點時配置會發生變化,所以應該記錄下文件的實際位置。那用不了多少 I/O ,只需跟蹤文件的位置就可以了,但如何保證高可用性呢?我們想出了一個解決方案,我提出一個計劃: “ 這是我們確定文件位置所需的全部的讀和寫。”我先寫了主控的 MySQL Schema 和文件位置追蹤器。隨后,我發現: “ 上帝啊!這部分用 HTTP 就能搞定了。它根本不難!”
我記得在想了整夜之后,我們就投入工作了。我們在公用辦公樓下面有個會議室— —一間昏暗的大會議室。 “ 好了,各位,停下你們手頭的事情。我們下樓去畫圖。”每次我有設計思路時差不多都會這么說,我們應該找塊白板把它畫出來。
我解釋了整個設計,誰和誰交互,誰處理請求。然后大家就上樓了,我先預定了所有的硬件,因為差不多要兩周左右它們才能到貨。然后開始編碼,我們希望能在機器到貨前完成編碼工作。一切總能挑出毛病,總有東西出問題,因此我們總在寫新的基礎設施組件。
Seibel : 有沒有這樣的情況,某人在開始時讓你坐下,告訴你 “ 你需要知道 X 、 Y 和 Z ”,你的生活會不會更容易些?
Fitzpatrick :從一開始就把事情做好總是比遷移一個線上服務要容易很多。這一直都是最讓人頭痛的。我所說的每件事,你都能在一臺機器上做到。開始時就這么設計,你就不需要假定能把這兩個用戶數據關聯起來或是別的什么了。假設你想加載這 20 條數據——你的實現可以把它們從同一張表里加載上來,但在更高層次的代碼里只需要說一句 “ 我想要這 20 個對象”,就能實現從一組機器中收集數據的工作了。如果從一開始我就這么做,可以免去不少遷移的痛苦。
Seibel : 這么說,基本上你學到的就是 “ 要為數據無法容納進一個數據庫的那天做準備”。
Fitzpatrick :我認為這已是 Web 社區中的常識。人們總是假定他們的站點會變得很大,有些想過頭了。但在那時,常識卻是, Apache 和MySQL 就是你需要的一切。
Seibel : 看起來你寫這些組件是因為你需要它們,同時你也樂在其中。
Fitzpatrick :哦,當然!我確實是在找理由去使用各種東西,去學習它們。因為如果不實際用它寫點什么,不和它生活在一起,你永遠學不到東西。出于興趣去學一門語言和學會它是兩回事,如果不用它寫些大的、復雜的系統,那你不能算是真的學會了。
Seibel : 那你覺得對你而言,你和哪些語言生活在一起呢?
Fitzpatrick : Perl 、 C 。以前的話,還有 BASIC ,不過我不確定 BASIC 算不算。我還寫過很多 Logo 。在小學的 Logo 課上,大家都在提筆、落筆,而我不在圖形模式里——有些鍵能跳出圖形模式,我在寫函數。老師會走過來說: “ 你在干什么?你做的不對,你應該在畫房子。” “ 不,我在寫 Logo 。你看。” “ 不,你弄錯了。”在課程結束的時候,我做出了些東西,我寫了個類,能以任意尺度和任意方向畫出所有字母。有了它,我能在波狀橫幅上打印整條消息,并加入距離和填充。每個人都很吃驚: “ 這是什么?”我也不知道這個算不算。
現在在用很多的 Perl 和 C ,在大學里還為工作和 Windows 程序寫了很多 C++ 。后來我的 C++ 忘得差不多了,或者說是退化了。現在我在 Google ,去年我寫了很多 C++ 、 Python 和 Java 。在 Java 剛出來的時候我也寫過不少,但后來厭倦了。現在我又開始寫 Java ,又開始有些不爽了。
Seibel : 使用何種語言很重要嗎?
Fitzpatrick :目前還沒找到能讓我滿意的語言。我還不太清楚究竟什么才能讓我完全滿意。我討厭在一個項目里一直切換語言。我想要的語言要在我需要時擁有靜態類型,在編譯時檢查所有內容。 Perl 比較接近這個要求,我能用各種喜歡的方式來寫代碼。它在編譯時沒有足夠的靜態檢查,但我可以在運行時對其進行補充。不過 Perl 還是不夠好。
我想要可選的靜態類型。在 Perlbal 里,除了核心(要復制字節),沒理由讓半數的東西都有這么高的性能。我希望在特定的部分代碼和類型聲明時能給運行時一些提示。但如果想使用惰性求值或模擬一些東西時,我可以采用另一種方式。
Seibel : 這么說來,你主要就是希望語言能有靜態類型,這樣編譯器能更好地進行優化?
Fitzpatrick :不是這樣的。我還希望在編譯時它能告訴我 “ 你正在做傻事。”有時我并不關心編譯時的情況,我希望它能在運行時有些強制措施,能做任何事。我并不想對 Perl 6 過于樂觀,他們的確在討論很多我希望看到的東西。但我并不認為它們最終能實現出來。
Seibel : 你喜歡 C++ 嗎?
Fitzpatrick :我并不是很喜歡它。 C++ 的語法很糟糕而且并不一致,它的錯誤消息也很可笑,至少 GCC 的錯誤消息是那樣的,往往會因為漏了一個分號而顯示 40 頁的錯誤信息。但和別的東西一樣,你很快能記住各種模式,之后甚至不用看那些信息就能知道 “ 哦,我大概忘記在頭文件里關閉名字空間了。”我認為新的 C++ 規范,盡管加入了很多復雜性,但還是添加了不少能減少打字痛苦(擊鍵次數)的東西。例如,自動變量和 for 循環,它的風格變得更像 Python 了。還有 lambda 表達式,盡管用的是 C++ ,但這足以讓我誤以為自己在寫 Python了。
Seibel : 你是出于性能目的使用 C++ 的嗎?
Fitzpatrick :是的,差不多吧。我在 Google 主要使用 C++ 。各種有性能要求的東西都會用 C++ 來寫。我在 Google 還寫了不少 Java。
Seibel : 據我所知, Google 有以 C++ 為中心的文化,因為那是 Google 最早使用的語言,而且他們圍繞它構建了整套軟件基礎設施。你不能改變歷史,但在 Google 可能有很多 C++ 代碼對提升性能而言并不是必需的。
Fitzpatrick :原因是這樣的,隨著時間的推移, Java 越來越快了, JVM 越來越聰明了。關于 Java ,有件事讓我很不爽,那就是每個人都很討厭 JNI 。有時一個庫是用 C++ 寫的, Python 開發者(不管 Google 里的還是外面的)并不在乎,他們會說: “ 哦,我們會用 SWIG 包裝它。”他們繼續自己的工作,做得很開心。 Python 能很快從用 C++ 寫的東西中獲得支持,因為 Python 開發者并不介意它到底是用什么語言寫的。
Java 的人卻會說: “ 這必須得是純 Java 的。我們不用 JNI ,否則若 JVM 崩潰了,我們根本不會知道是為什么。”這個問題最后會導致所有的東西都要寫兩次,一次為 C++ 、 Python 和所有其他語言,另一次專為 Java 而寫。如果他們能討論出一個好的嵌入方案或者克服對 JNI 的恐懼,那我就沒什么好說的了。
[1] 集成電路制造商,成立于 1969 年,在其巔峰時期曾占據全球 85% 的 DRAM 內存芯片市場份額。
[2] Advanced Placement 項目,在美國和加拿大的高中提供大學級別的課程。
[5] cheesesteak ,費城牛肉奶酪三明治,這是費城及其附近地區的食品。用一種細長的意大利面包,里面有切得很薄的肋眼牛肉片加炒過的洋蔥及蘑菇,然后淋上融化的奶酪醬,也可加上紅椒或者是很辣的小尖椒。(摘自維基百科。)