Java语言学校的危险性(译文)
生活随笔
收集整理的這篇文章主要介紹了
Java语言学校的危险性(译文)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
下面的文章是More Joel on Software一書的第8篇。我覺得翻譯難度很大,整整兩個工作日,每天8小時以上,才譯出了5000字。除了Joel大量使用俚語,另一個原因是原文涉及"編程原理",好多東西我根本不懂。希望懂的朋友幫我看看,譯文有沒有錯誤,包括我寫的注解。
====================
JAVA語言學校的危險性
作者:Joel Spolsky
譯者:阮一峰
原文: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
發表日期 2005年12月29日,星期四
如今的孩子變懶了。
多吃一點苦,又會怎么樣呢?
我一定是變老了,才會這樣喋喋不休地抱怨和感嘆"如今的孩子"。為什么他們不再愿意、或者說不再能夠做艱苦的工作呢。
當我還是孩子的時候,學習編程需要用到穿孔卡片(punched cards)。那時可沒有任何類似"退格"鍵(Backspace key)這樣的現代化功能,如果你出錯了,就沒有辦法更正,只好扔掉出錯的卡片,從頭再來。
回想1991年,我開始面試程序員的時候。我一般會出一些編程題,允許用任何編程語言解題。在99%的情況下,面試者選擇C語言。
如今,面試者一般會選擇Java語言。
說到這里,不要誤會我的意思。Java語言本身作為一種開發工具,并沒有什么錯。
等一等,我要做個更正。我只是在本篇特定的文章中,不會提到Java語言作為一種開發工具,有什么不好的地方。事實上,它有許許多多不好的地方,不過這些只有另找時間來談了。
我在這篇文章中,真正想要說的是,總的來看,Java不是一種非常難的編程語言,無法用來區分優秀程序員和普通程序員。它可能很適合用來完成工作,但是這個不是今天的主題。我甚至想說,Java語言不夠難,其實是它的特色,不能算缺點。但是不管怎樣,它就是有這個問題。
如果我聽上去像是妄下論斷,那么我想說一點我自己的微不足道的經歷。大學計算機系的課程里,傳統上有兩個知識點,許多人從來都沒有真正搞懂過的,那就是指針(pointers)和遞歸(recursion)。
你進大學后,一開始總要上一門"數據結構"課(data structure), 然后會有線性鏈表(linked list)、哈希表(hash table),以及其他諸如此類的課程。這些課會大量使用"指針"。它們經常起到一種優勝劣汰的作用。因為這些課程非常難,那些學不會的人,就表明他們的能力不足以達到計算機科學學士學位的要求,只能選擇放棄這個專業。這是一件好事,因為如果你連指針很覺得很難,那么等學到后面,要你證明不動點定理(fixed point theory)的時候,你該怎么辦呢?
有些孩子讀高中的時候,就能用BASIC語言在Apple II型個人電腦上,寫出漂亮的乒乓球游戲。等他們進了大學,都會去選修計算機科學101課程,那門課講的就是數據結構。當他們接觸到指針那些玩意以后,就一下子完全傻眼了,后面的事情你都可以想像,他們就去改學政治學,因為看上去法學院是一個更好的出路[1]。關于計算機系的淘汰率,我見過各式各樣的數字,通常在40%到70%之間。校方一般會覺得,學生拿不到學位很可惜,我則視其為必要的篩選,淘汰那些沒有興趣編程或者沒有能力編程的人。
對于許多計算機系的青年學生來說,另一門有難度的課程是有關函數式編程(functional programming)的課程,其中就包括遞歸程序設計(recursive programming)。MIT將這些課程的標準提得很高,還專門設立了一門必修課(課程代號6.001[2]),它的教材(Structure and Interpretation of Computer Programs,作者為Harold Abelson和Gerald Jay Sussman Abelson,MIT出版社1996年版)被幾十所、甚至幾百所著名高校的計算系機采用,充當事實上的計算機科學導論課程。(你能在網上找到這本教材的舊版本,應該讀一下。)
這些課程難得驚人。在第一堂課,你就要學完Scheme語言[3]的幾乎所有內容,你還會遇到一個不動點函數(fixed-point function),它的自變量本身就是另一個函數。我讀的這門導論課,是賓夕法尼亞大學的CSE 121課程,真是讀得苦不堪言。我注意到很多學生,也許是大部分的學生,都無法完成這門課。課程的內容實在太難了。我給教授寫了一封長長的聲淚俱下的Email,控訴這門課不是給人學的。賓夕法尼亞大學里一定有人聽到了我的呼聲(或者聽到了其他抱怨者的呼聲),因為如今這門課講授的計算機語言是Java。
我現在覺得,他們還不如沒有聽見呢。
這就是爭議所在。許多年來,像當年的我一樣懶惰的計算機系本科生不停地抱怨,再加上計算機業界也在抱怨畢業生不夠用,這一切終于造成了重大惡果。過去十年中,大量本來堪稱完美的好學校,都百分之百轉向了Java語言的懷抱。這真是好得沒話說了,那些用"grep"命令[4]過濾簡歷的企業招聘主管,大概會很喜歡這樣。最妙不可言的是,Java語言中沒有什么太難的地方,不會真的淘汰什么人,你搞不懂指針或者遞歸也沒關系。所以,計算系的淘汰率就降低了,學生人數上升了,經費預算變大了,可謂皆大歡喜。
學習Java語言的孩子是幸運的,因為當他們用到以指針為基礎的哈希表時,他們永遠也不會遇到古怪的"段錯誤"[5](segfault)。他們永遠不會因為無法將數據塞進有限的內存空間,而急得發瘋。他們也永遠不用苦苦思索,為什么在一個純函數的程序中,一個變量的值一會保持不變,一會又變個不停!多么自相矛盾啊!
他們不需要怎么動腦筋,就可以在專業上得到4.0的績點。
我是不是有點太苛刻了?就像電視里的"四個約克郡男人"[6](Four Yorkshiremen)那樣,成了老古板?就在這里吹噓我是多么刻苦,完成了所有那些高難度的課程?
我再告訴你一件事。1900年的時候,拉丁語和希臘語都是大學里的必修課,原因不是因為它們有什么特別的作用,而是因為它們有點被看成是受過高等教育的人士的標志。在某種程度上,我的觀點同拉丁語支持者的觀點沒有不同(下面的四點理由都是如此):"(拉丁語)訓練你的思維,鍛煉你的記憶。分析拉丁語的句法結構,是思考能力的最佳練習,是真正對智力的挑戰,能夠很好地培養邏輯能力。"以上出自Scott Barker之口(http://www.promotelatin.org/whylatin.htm)。但是,今天我找不到一所大學,還把拉丁語作為必修課。指針和遞歸不正像計算機科學中的拉丁語和希臘語嗎?
說到這里,我坦率地承認,當今的軟件代碼中90%都不需要使用指針。事實上,如果在正式產品中使用指針,這將是十分危險的。好的,這一點沒有異議。與此同時,函數式編程在實際開發中用到的也不多。這一點我也同意。
但是,對于某些最激動人心的編程任務來說,指針仍然是非常重要的。比如說,如果不用指針,你根本沒辦法開發Linux的內核。如果你不是真正地理解了指針,你連一行Linux的代碼也看不懂,說實話,任何操作系統的代碼你都看不懂。
如果你不懂函數式編程,你就無法創造出MapReduce[7],正是這種算法使得Google的可擴展性(scalable)達到如此巨大的規模。單詞"Map"(映射)和"Reduce"(化簡)分別來自Lisp語言和函數式編程。回想起來,在類似6.001這樣的編程課程中,都有提到純粹的函數式編程沒有副作用,因此可以直接用于并行計算(parallelizable)。任何人只要還記得這些內容,那么MapRuduce對他來說就是顯而易見的。發明MapReduce的公司是Google,而不是微軟,這個簡單的事實說出了原因,為什么微軟至今還在追趕,還在試圖提供最基本的搜索服務,而Google已經轉向了下一個階段,開發世界上最大的并行式超級計算機----Skynet[8]的H次方的H次方的H次方的H次方的H次方的H次方。我覺得,微軟并沒有完全明白,在這一波競爭中它落后多遠。
除了上面那些直接就能想到的重要性,指針和遞歸的真正價值,在于那種你在學習它們的過程中,所得到的思維深度,以及你因為害怕在這些課程中被淘汰,所產生的心理抗壓能力,它們都是在建造大型系統的過程中必不可少的。指針和遞歸要求一定水平的推理能力、抽象思考能力,以及最重要的,在若干個不同的抽象層次上,同時審視同一個問題的能力。因此,是否真正理解指針和遞歸,與是否是一個優秀程序員直接相關。
如果計算機系的課程都與Java語言有關,那么對于那些在智力上無法應付復雜概念的學生,就沒有東西可以真的淘汰他們。作為一個雇主,我發現那些100%Java教學的計算機系,已經培養出了相當一大批畢業生,這些學生只能勉強完成難度日益降低的課程作業,只會用Java語言編寫簡單的記賬程序,如果你讓他們編寫一個更難的東西,他們就束手無策了。他們的智力不足以成為程序員。這些學生永遠也通不過MIT的6.001課程,或者耶魯大學的CS 323課程。坦率地說,為什么在一個雇主的心目中,MIT或者耶魯大學計算機系的學位的份量,要重于杜克大學,這就是原因之一。因為杜克大學最近已經全部轉為用Java語言教學。賓夕法尼亞大學的情況也很類似,當初CSE 121課程中的Scheme語言和ML語言,幾乎將我和我的同學折磨至死,如今已經全部被Java語言替代。我的意思不是說,我不想雇傭來自杜克大學或者賓夕法尼亞大學的聰明學生,我真的愿意雇傭他們,只是對于我來說,確定他們是否真的聰明,如今變得難多了。以前,我能夠分辨出誰是聰明學生,因為他們可以在一分鐘內看懂一個遞歸算法,或者可以迅速在計算機上實現一個線性鏈表操作函數,所用的時間同黑板上寫一遍差不多。但是對于Java語言學校的畢業生,看著他們面對上述問題苦苦思索、做不出來的樣子,我分辨不出這到底是因為學校里沒教,還是因為他們不具備編寫優秀軟件作品的素質。Paul Graham將這一類程序員稱為"Blub程序員"[9](www.paulgraham.com/avg.html)。
Java語言學校無法淘汰那些永遠也成不了優秀程序員的學生,這已經是很糟糕的事情了。但是,學??梢詿o可厚非地辯解,這不是校方的錯。整個軟件行業,或者說至少是其中那些使用grep命令過濾簡歷的招聘經理,確實是在一直叫嚷,要求學校使用Java語言教學。
但是,即使如此,Java語言學校的教學也還是失敗的,因為學校沒有成功訓練好學生的頭腦,沒有使他們變得足夠熟練、敏捷、靈活,能夠做出高質量的軟件設計(我不是指面向對象式的"設計",那種編程只不過是要求你花上無數個小時,重寫你的代碼,使它們能夠滿足面向對象編程的等級制繼承式結構,或者說要求你思考到底對象之間是"has-a"從屬關系,還是"is-a"繼承關系,這種"偽問題"將你搞得煩躁不安)。你需要的是那種能夠在多個抽象層次上,同時思考問題的訓練。這種思考能力正是設計出優秀軟件架構所必需的。
你也許想知道,在教學中,面向對象編程(object-oriented programming,縮寫OOP)是否是指針和遞歸的優質替代品,是不是也能起到淘汰作用。簡單的回答是:"不"。我在這里不討論OOP的優點,我只指出OOP不夠難,無法淘汰平庸的程序員。大多數時候,OOP教學的主要內容就是記住一堆專有名詞,比如"封裝"(encapsulation)和"繼承"(inheritance)",然后再做一堆多選題小測驗,考你是不是明白"多態"(polymorphism)和"重載"(overloading)的區別。這同歷史課上,要求你記住重要的日期和人名,難度差不多。OOP不構成對智力的太大挑戰,嚇不跑一年級新生。據說,如果你沒學好OOP,你的程序依然可以運行,只是維護起來有點難。但是如果你沒學好指針,你的程序就會輸出一行段錯誤信息,而且你對什么地方出錯了毫無想法,然后你只好停下來,深吸一口氣,真正開始努力在兩個不同的抽象層次上,同時思考你的程序是如何運行的。
順便說一句,我有充分理由在這里說,那些使用grep命令過濾簡歷的招聘經理真是荒謬可笑。我從來沒有見過哪個能用Scheme語言、Haskell語言和C語言中的指針編程的人,竟然不能在二天里面學會Java語言,并且寫出的Java程序,質量竟然不能勝過那些有5年Java編程經驗的人士。不過,人力資源部里那些平庸的懶漢,是無法指望他們聽進去這些話的。
再說,計算機系承擔的發揚光大計算機科學的使命該怎么辦呢?計算機系畢竟不是職業學校啊!訓練學生如何在這個行業里工作,不應該是計算機系的任務。這應該是社區高校和政府就業培訓計劃的任務,那些地方會教給你工作技能。計算機系給予學生的,理應是他們日后生活所需要的基礎知識,而不是為學生第一周上班做準備。對不對?
還有,計算機科學是由證明(遞歸)、算法(遞歸)、語言(λ演算[10])、操作系統(指針)、編譯器(λ演算)所組成的。所以,這就是說那些不教C語言、不教Scheme語言、只教Java語言的學校,實際上根本不是在教授計算機科學。雖然對于真實世界來說,有些概念可能毫無用處,比如函數的科里化(function currying)[11],但是這些知識顯然是進入計算機科學研究生院的前提。我不明白,計算機系課程設置委員會中的教授為什么會同意,將課程的難度下降到如此低的地步,以至于他們既無法培養出合格的程序員,甚至也無法培養出合格的能夠得到哲學博士PhD學位[12]、進而能夠申請教職、與他們競爭工作崗位的研究生。噢,且慢,我說錯了。也許我明白原因了。
實際上,如果你回顧和研究學術界在"Java大遷移"(Great Java Shift)中的爭論,你會注意到,最大的議題是Java語言是否還不夠簡單,不適合作為一種教學語言。
我的老天啊,我心里說,他們還在設法讓課程變得更簡單。為什么不用匙子,干脆把所有東西一勺勺都喂到學生嘴里呢?讓我們再請助教幫他們接管考試,這樣一來就沒有學生會改學"美國研究"[13](American studies)了。如果課程被精心設計,使得所有內容都比原有內容更容易,那么怎么可能期望任何人從這個地方學到任何東西呢?看上去似乎有一個工作小組(Java task force)正在開展工作,創造出一個簡化的Java的子集,以便在課堂上教學[14]。這些人的目標是生成一個簡化的文檔,小心地不讓學生纖弱的思想,接觸到任何EJB/J2EE的臟東西[15]。這樣一來,學生的小腦袋就不會因為遇到有點難度的課程,而感到煩惱了,除非那門課里只要求做一些空前簡單的計算機習題。
計算機系如此積極地降低課程難度,有一個理由可以得到最多的贊同,那就是節省出更多的時間,教授真正的屬于計算機科學的概念。但是,前提是不能花費整整兩節課,向學生講解諸如Java語言中int和Integer有何區別[16]。好的,如果真是這樣,課程6.001就是你的完美選擇。你可以先講Scheme語言,這種教學語言簡單到聰明學生大約只用10分鐘,就能全部學會。然后,你將這個學期剩下的時間,都用來講解不動點。
唉。
說了半天,我還是在說要學1和0。
(你學到了1?真幸運啊!我們那時所有人學到的都是0。)
================
注解:
[1] 在美國,法學院的入學者都必須具有本科學位。通常來說,主修政治學的學生升入法學院的機會最大。
[2] 在麻省理工學院,計算機系的課程代碼都是以6開頭的,6.001表明這是計算機系的最基礎課程。
[3] Scheme語言是LISP語言的一個變種,誕生于1975年的MIT,以其對函數式編程的支持而聞名。這種語言在商業領域的應用很少,但是在計算機教育領域內有著廣泛影響。
[4] grep是Unix/Linux環境中用于搜索或者過濾內容的命令。這里指的是,某些招聘人員僅僅根據一些關鍵詞來過濾簡歷,比如本文中的Java。
[5] 段錯誤(segfault)是segmentation fault的縮寫,指的是軟件中的一類特定的錯誤,通常發生在程序試圖讀取不允許讀取的內存地址、或者以非法方式讀取內存的時候。
[6] 《四個約克郡男人》(Four Yorkshiremen),是英國電視系列喜劇At Last the 1948 Show中的一部,與上個世紀70年代問世。內容是四個約克郡男人競相吹噓,各自的童年是多么困苦,由于內容太夸張,所以顯得非??尚?。
[7] MapReduce是一種由Google引入使用的軟件框架,用于支持計算機集群環境下,海量數據(PB級別)的并行計算。
[8] Skynet是美國系列電影《終結者》(Terminator)中一個控制一切、與人類為敵的超級計算機系統的名稱,通常將其看作虛構的人工智能的代表。
[9] Blub程序員(Blub programmers)指的是那些企圖用一種語言,解決所有問題的程序員。Blub是Paul Graham假設的一種高級編程語言。
[10] λ演算(lambda calculus)是一套用于研究函數定義、函數應用和遞歸的形式系統,在遞歸理論和函數式編程中有著廣泛的應用。
[11] 函數的科里化(function currying)指的是一種多元函數的消元技巧,將其變為一系列只有一元的鏈式函數。它最早是由美國數學家哈斯格爾·科里(Haskell Curry)提出的,因此而得名。
[12] 在美國,所有基礎理論的學科,一律授予的都是哲學博士學位(Doctor of Philosophy),計算機科學系亦是如此。
[13] 美國研究(American studies)是對美國社會的經濟、歷史、文化等各個方面進行研究的一門學科。這里指的是,計算機系學生不會因為課程太難被淘汰,所以就不用改學相對容易的"美國研究"。
[14] 參見http://www.sigcse.org/topics/javataskforce/java-task-force.pdf。
[15] J2EE是Java2平臺企業版(Java 2 Platform,Enterprise Edition),指的是一整套企業級開發架構。EJB(Enterprise JavaBean)屬于J2EE的一部分,是一個基于組件的企業級開發規范。它們通常被認為是Java中相對較難的部分。
[16] 在Java語言中,int是一種數據類型,表示整數,而Integer是一個適用于面向對象編程的類,表示整數對象。兩者的涵義和性質都不一樣。
(完)
轉載于:https://my.oschina.net/u/136190/blog/135298
總結
以上是生活随笔為你收集整理的Java语言学校的危险性(译文)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奇异值分解及应用
- 下一篇: printf按8进制、16进制输出