The Perils of JavaSchools

From The Joel on Software Translation Project

Jump to: navigation, search

The Perils of JavaSchools

JavaSchools的危機

懶惰的孩子。

辛勤的工作究竟會發生什麼事呢?

這些日子以來對於孩子們的牢騷與悲歎,以及他們不願亦不肯將事情作的更嚴謹,是我逐漸地步向衰老的一個明確預兆。


你們是相當幸運的,過去我們會在化糞池的一個棕色的紙袋裡住三個月,早晨六點起床、清潔這個袋子、吃一層走了味的麵包皮、坐下來開始工作、一天十四小時、日復一日,回到家後,父親拿著他的腰帶把我們轟去睡覺。

--Monty Python的飛行馬戲團, Four Yorkshiremen


當我還是個孩子的時候,我使用打孔卡片來學習編寫程式(譯註:最早的編程是先在卡片上打孔,然後讓電腦一一讀入處理),假若你發生了一個失誤,很抱歉,你沒有任何現代才有的一些功能,像是使用倒退鍵來加以更正,你只能扔了這張卡片然後重新開始。

當我在1991年開始面試程序員時,一般來說我會讓他們自行選擇使用的語言,來解決我給他們的編程問題。99%的機會他們會選擇C。

現在,他們傾向於選擇Java。

現下,不要誤解我:身為一種實作語言,Java並沒有任何問題。

稍待一會兒,我要修正一下。在這篇文章中,我並沒有宣稱從實作語言的角度來看,Java沒有任何的問題,實際上有許多的事是不對勁的,但那要等到另外一個主題再來談了。

相反地,基本上我認為Java不是夠困難到足以區分偉大的程式員跟平庸的程式員。在工作上,它或許是個好語言,但這不是今天的主題。我甚至會說事實上Java不夠困難是個特徵、而非一個缺陷,但它的確有這個問題。

請原諒我的無理,在個人不甚成熟的經驗裡,指標跟遞迴是大學計算機科學傳統教授的課程中,讓許多人無論如何就是無法完全理解的兩件事。

你們過去常常以資料結構這堂課開始了院校的課程,這堂課包含了鍵節表(linked lists)、雜湊表(hash tables)等等雜七雜八的東西,都廣泛的使用指標。這些課程常被用來當成大刀的課程:它們是如此的困難,導致於無法面對CS(資訊科學,後面都簡稱CS)學位這種心智挑戰的人會選擇放棄。這是件好事,因為假若你認為瞭解指標是困難的,那就等吧,直到你試著去證明固定點定理(fixed point theory)的一些事情。(譯註:作者應該是說,直到你開始動手去做某件事,不然你永遠都不會瞭解它的。)

那些在高中時期,就能在他們的Apple II電腦上使用BASIC語言寫出完美的乒乓遊戲的孩子們,當他們上了大學修習了CompSci 101:一門資料結構的課程,觸及了指標這玩意之後,轟!他們的大腦馬上被炸成一堆豆腐渣,如你所知,接下來他們都跑去修政治學,因為法律學校看起來是個更好的主意。我看過各單位關於CS學位被死當的統計圖表,它們的值通常在40%到70%之間。不少大學視這種情況是種浪費,我則認為這是必要的,讓那些無法在編程工作上獲得快樂或成功的人及早出局。

對許多年輕的CS學生來說,另外一個困難的課程是functional programming,包含了惡名昭彰的遞迴編程在內。MIT在這類的課程上,設定了相當高的水平要求,建立了必備的課程(6.001),和一本實體書(Abelson & Sussman's Structure and Interpretation of Computer Programs),在成打上百的高等CS學校裡,被使用來當成CS的入門。(你可以、應該來這裡看看舊的教材online

這些課程的困難度之高,在第一章節,你就已經幾乎學習到Scheme所有的內容(譯註:Scheme是一種古老的程式語言,常見於AI領域),包含了如何讓一個固定點函式將另外一個函式當成輸入參數。當我還在與這樣的課程(CSE121在Penn)奮鬥之際,我注意到幾乎沒有多少學生可以達到這樣的程度。這些課程是如此的艱澀。我寫了一封聲淚俱下的信給教授,控訴這一點都不公平!在Penn的某個人一定是聽到了我的心聲(或者是其他抱怨者的心聲),現在這堂課已經改用Java了。

我希望他們那時候沒有聽到。


你能瞭解其中的意義嗎?在這兒測測你自己


好好思考一下,結合多年來像我這樣的懶學生的抱怨,與業界抱怨從美國大學畢業的CS學生不足等兩個因素,已經對整個環境造成了極大的影響,在過去十年間,大量其他相當優秀的學校已經完全地轉向Java。對於徵人的單位來說,當他用grep(譯註:這是UNIX環境上常見用來過濾/搜尋檔案內容的程式)去過濾所有的履歷時,會讓他興奮不已(譯註:因為有一堆人可供他們選擇了);而且最棒的是,在Java沒有任何事足以剔除掉那些腦袋裡沒有指標跟遞迴腦細胞的程式員,所以被二一的人變少了而CS學院有更多的學生、更多的預算、一切是如此的美好。

從JavaSchools出來的孩子是如此的幸運,他們從未需要去實作以指標為基礎的雜湊表,因此從未遇到segfaults這種火星文錯誤訊息(譯註:segfaults是segmentation faults縮寫,當你程式的記憶體指標使用不慎導致程式掛點時,作業系統就會賞你一個)、他們從不需要戰戰兢兢、語無倫次發瘋似地試著把東西塞進bits裡、他們也永遠不需要去動動頭腦,看為何在一個純functional程式裡,一個從未改變過內容的變數,實際上它卻一直在變化!這真是荒謬的事!

他們不需要可以讓他們在學位上獲得4分的那部分腦細胞。

我是那種守舊的老學究,像是Four Yorkshiremen一樣,自誇有多麼堅韌足以從困難的課程裡生存下來嗎?

嗨!在1900年,拉丁跟希臘語是大學必修的課程,不是因為它們能做甚麼,而是它們是被有點受過教育的人認為是必要的,在某些概念上,我的論調跟支持拉丁的人沒甚麼不同(四個理由都是):「(拉丁)訓練你的心、訓練你的記憶力、闡明一個拉丁語句子可鍛鍊思考能力,是一個真正智力上的考驗、和一個良好的邏輯思考」Scott Barker如是。但我並不能找到任何一所大學還需要拉丁語。指標跟遞迴是CS的拉丁與希臘語嗎?

現在,我絕對承認指標編程在今日90%的地方派不上用場,而且事實上,當用在產品上時是相當具有危險性的。OK,沒關係,functional programming在實際編程時幾乎都沒人在用,這我也同意。

但它在某些最讓人激動的編程作業上依然有其重要性。舉例來說,沒了指標你根本無法在Linux核心上工作、你無法瞭解Linux任何一行的程式碼,或者,更進一步說,你無法瞭解任何一個作業系統,假若你並不是真的完全瞭解指標。

不瞭解function programming,你無法發明MapReduce,這個演算法讓Google具有不可思議的可擴充性。Map跟Reduce是從Lisp和function programming來的,任何還記得他們的6.001同等編程課程的人,都能回想起,MapReduce是一種純functional programs,沒有任何邊際效益(譯註:side effects,表示不會去影響到別人或別的函式),而這可以讓它們完全地平行同步處理。一個明顯的事實是,Google發明了MapReduce,但微軟沒有,這可以解釋為何微軟仍然在嘗試讓基本搜尋功能能運作時,Google已經進到下個領域:建立Skynet這個世界上最大的平行處理超級電腦,我不認為微軟真正瞭解他們在這波競爭中落後了多少。 但是,除了口頭一直強調指標和遞迴的重要性,它們真正的價值在於你從它們身上學到的內心世界的靈活與彈性,這是建立大型系統的基本需求之一;還有瞭解它們的這種特殊資質,可讓你得以在課堂上不被它們所打敗。指標和遞迴需要某種能力在抽象的領域裡推論、思考,還有,最重要的,就是同時從數個不同層級的抽象領域來看待一個問題。因此,瞭解指標跟遞迴的能力和是否可成為一個偉大的程式員是有著直接而明顯的關連。

對於一個經由Java課程培育的CS學位,是否真能淘汰掉缺乏敏捷精神以致於無法處理以上所談概念的學生,實在是沒有甚麼好評論的。身為一個雇主,我看到純Java學校生產相當多的CS畢業生,他們就是不夠聰明到像一般程式員一樣,儘管他們可以勉強通過那些新的、簡化後作業,卻不足以進行任何比完成另一個Java帳戶管理程式更複雜的工作。這些學生永遠無法通過麻省理工學院的6.001或耶魯的CS 323課程,坦白說,這就是為何在雇主的心目中,從麻省理工學院或者耶魯獲得的CS學位比Duke的CS學位更有份量,而後者最近已經完全轉向Java了。Penn也不再用Scheme和ML語言(備註:此兩種語言常見於AI領域上),而改用Jave來教導將那個幾乎整死我和我朋友的CSE121課程,並不是說我不會雇用Duke和Penn的聰明孩子,我會的,只是對我來說實在是有困難去分辨他們在哪兒。過去我常常能分辨聰明的孩子,因為他們能用遞迴演算法快速的解決問題、或者幾乎花在白版上設計的時間,就可實作出鍵結表操作函式,但是對於Java學校的畢業生,我無法分辨他們卡在某些問題上的原因,是因為他們從未被教導過,或是他們腦袋中就是缺了可讓他們完成偉大的編程工作的部分。Paul Graham管他們叫做Blub程序員。

JavaSchools不能淘汰這些永遠無法成為偉大程序員的孩子,實在是很糟糕的事,但這些學校能理直氣壯的說這不是他們的問題,業界、或者至少是那些會過濾履歷的人肯定吵著學校必須教授Java課程。

另一方面,JavaSchools也無法訓練孩子們的腦袋變得有經驗、聰穎、靈活,以便去完成良好的軟體設計(這裡我不是指OO設計,也許你在這玩意上花費了無數的時間在重寫你的程式碼來調整繼承架構,只為了你擔憂的一些非「真正問題」上,像是has-a的關係。)你需要訓練同時在多個抽象層次上思考事情,當你需要去設計龐大的軟體架構時,你會很需要這類的思考。

也許你會想知道,物件導向編程(OOP)是否可當作指標跟遞迴的良好替代品,答案是:否。且不論OOP的優點,它只是不夠困難到足以淘汰平庸的程式員。OOP在學校內跟「封裝」、「繼承」等詞彙幾乎處於同等的概念上,它們只是多型跟重載的不同面向而已。不比在歷史課上記住著名的日期和名字難得多,OOP造成不適當的精神挑戰嚇跑一年級學生。據說,當你想方設法解決一個OOP 問題時,你的程式仍然能工作,只是有點難維護而已。但是當你與指標奮戰時,你的程式若產生Segmentation Falut,則除非你停下來、作個深呼吸,然後真正試著集中精神在兩個不同抽象層同時進行思考,否則你永遠不知道發生了甚麼事。


...

Personal tools