国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

Java的命運(yùn)

發(fā)布時(shí)間:2011-3-11 15:44    發(fā)布者:1770309616
關(guān)鍵詞: java
本文是Common Lisp專家Peter Seibel對(duì)Google公司首席Java架構(gòu)師Joshua Bloch的訪談,談到他所遇到的最糟糕的Bug以及Java的命運(yùn)。
最糟糕的Bug

Seibel:我們聊聊調(diào)試吧。你遇到的最糟糕的Bug是什么?

Bloch:提起B(yǎng)ug我立馬就想到了一個(gè),這個(gè)Bug很嚴(yán)重,而且很搞笑。那是90年代初,我在匹茲堡的 Transarc公司工作時(shí)。我在很緊的工期下提交了一個(gè)事務(wù)共享內(nèi)存的實(shí)現(xiàn)。我在限期內(nèi)完成了設(shè)計(jì)和實(shí)現(xiàn),甚至還在過程中做出了幾個(gè)可重用的組件。但是這么匆忙地寫了很多新代碼,我還是挺擔(dān)心的。

為了測試這些代碼,我寫了一個(gè)叫做“亂撞”的很長的程序出來。它運(yùn)行了大量的事務(wù),每個(gè)事務(wù)又包含了嵌套的事務(wù),嵌套到可以嵌套的最大深度。每個(gè)嵌套事務(wù)都可能會(huì)加鎖,以遞增的順序讀取共享數(shù)組里面的幾個(gè)元素,對(duì)每個(gè)元素都加入點(diǎn)東西,保持?jǐn)?shù)組中所有元素的和為0,還是不變量。這些事務(wù)要么提交,要么取消,如90%的提交,10%的取消,其他比例也可以。多個(gè)線程同步運(yùn)行于這些事務(wù)之上,長時(shí)間地訪問數(shù)組。因?yàn)槲覝y試的是一個(gè)共享內(nèi)存機(jī)制,所以我同時(shí)運(yùn)行多個(gè)有多個(gè)線程的“亂撞”程序,每個(gè)有自己的進(jìn)程。

在一般的并發(fā)級(jí)別下,“亂撞”輕松過關(guān)。但是當(dāng)我真正調(diào)高并發(fā)級(jí)別時(shí),我發(fā)現(xiàn)“亂撞”偶爾,僅僅是偶爾,無法通過一致性檢查。我不知道這是怎么搞的。這只能是我的錯(cuò),因?yàn)樾麓a都是我一個(gè)人寫的。

我花了大約一個(gè)星期,痛苦地為每個(gè)組件寫了徹底的單元測試,所有的單元測試都通過了。然后我為每個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu)寫了詳細(xì)的一致性檢查,這樣我就可以在每次變化后調(diào)用這些一致性檢查,直到測試失敗為止。最后,我終于發(fā)現(xiàn)一個(gè)底層的一致性檢查失敗了,這個(gè)問題無法重現(xiàn),但是某種程度上可以幫助我分析問題出在哪里。最后,我得出了確實(shí)的結(jié)論——我的鎖根本不工作。兩個(gè)事務(wù)鎖定、讀寫同一個(gè)值的時(shí)候,產(chǎn)生了并發(fā)的讀—修改—寫回操作,而后一次寫入毀掉了第一次的寫入。

我編寫了自己的鎖管理器,所以我懷疑是它出了問題。但是鎖管理器輕松地通過了測試。最后,我覺得問題不在鎖管理器,而是它依賴的互斥體的實(shí)現(xiàn)!那時(shí)候操作系統(tǒng)還不支持多線程,我們需要寫自己的多線程包。原來負(fù)責(zé)互斥體代碼的工程師,不小心把我們的Solaris的線程實(shí)現(xiàn)中的lock和try- lock的匯編代碼的標(biāo)簽弄混了。所以,每次你以為你在調(diào)用lock的時(shí)候,其實(shí)調(diào)用的是try-lock,反之亦然。也就是說當(dāng)真的有爭用發(fā)生的時(shí)候 ——在當(dāng)年其實(shí)是很罕見的——第二個(gè)線程直接就進(jìn)入了第一個(gè)線程的臨界區(qū),因?yàn)榈谝粋(gè)線程也沒有鎖住。搞笑的是,這也就是說,整個(gè)公司幾個(gè)星期都在運(yùn)行沒有互斥體的程序,而且誰都不知道。

Knuth有句關(guān)于測試的名言,Bentley和Mcllroy的精彩論文“Engineering a Sort Function”中曾經(jīng)引用過,大概意思是說,做測試時(shí),要不憚以最大的惡意來推測所要測試的代碼的錯(cuò)誤。做這些測試的時(shí)候,我就是這么做的。但是這樣會(huì)把所有東西糾結(jié)在一起,更難找到Bug。首先,并發(fā)的時(shí)候很難這么做,往往完全無法復(fù)現(xiàn)場景。其次,到最后可能會(huì)發(fā)現(xiàn)你的核心假設(shè)是錯(cuò)的。喜歡喊“耶,這語言出錯(cuò)了”或者“系統(tǒng)出問題了”是新手干的事兒。但是在這里,我依靠的基石——互斥體,確實(shí)出問題了。

Seibel:也就是說Bug不在你的代碼中,但是同時(shí)你只能對(duì)你的代碼進(jìn)行徹底的單元測試,因?yàn)槟銢]有別的辦法,只能去檢查自己的代碼。你覺得這些測試是不是可以,或者說應(yīng)該讓互斥體代碼的作者來寫,這樣你就不用浪費(fèi)一個(gè)星期,節(jié)省了一半的測試量,而且也可以找到這個(gè)Bug。

Bloch:給互斥體代碼加一個(gè)好的自動(dòng)化單元測試肯定可以避免讓我遭受那些痛苦,不過注意那可是90年代初。我想都沒想過要抱怨那個(gè)工程師沒寫個(gè)好的單元測試。即使是今天,為并發(fā)工具寫單元測試還是一種藝術(shù)形式。

Java的命運(yùn)

當(dāng)你改進(jìn)一個(gè)成熟語言的時(shí)候,你必須更加仔細(xì)地考慮能力和復(fù)雜度之間的平衡。

Seibel:既然你說到這里,Java是否逃脫了滅亡的命運(yùn)了?它變復(fù)雜的速度是不是比變好的速度更快呢?

Bloch:這個(gè)問題不好回答。具體說來,Java5加入了比我們?cè)O(shè)想的更多的復(fù)雜度。將泛型特別是通配符加到語言中到底有多復(fù)雜我也說不好。我得為有功勞的人說句話,GrahamHamilton真是了不起,那時(shí)候他就想明白了一切,而我不明白。

有趣的是,他抗?fàn)幎嗄辏M柚狗盒瓦M(jìn)入Java語言中。但是在泛型被成功地阻擋在Java外的這些年里變體的概念,也就是通配符的隱含意義流行了起來。如果它們來得更早,沒有變體,也許我們現(xiàn)在可以有一個(gè)更簡單的、更容易跟蹤的語言。

引入通配符有實(shí)際的好處。子類化和泛型之間根本就是阻抗不匹配的,通配符盡力在彌合這種不匹配。但是這么做又顯著地增加了復(fù)雜度。有些人認(rèn)為在聲明空間,而不是用戶空間,變體是更好的解決方案,但我不太相信這一點(diǎn)。

這仍舊懸而未決,因?yàn)樗鼈兌歼沒經(jīng)過在真實(shí)世界里海量的程序員們的測試呢。一些語言經(jīng)常只在小范圍內(nèi)獲得成功,人們會(huì)說:“噢,這些語言很不錯(cuò),只是可惜沒有成為世界范圍成功的語言。”但是這往往是有原因的。希望使用Scala或者C#4.0,這樣的聲明空間變體的語言可以徹底解決這一疑問。

Seibel:那么是什么推動(dòng)Java引入泛型呢?

Bloch:沒看起來那么精彩啦,我們的新聞報(bào)道是可信的。我的思維模式是,“嗨,集合多半都應(yīng)該是同質(zhì)的 ——一組字符串,一個(gè)從字符串到數(shù)字的映射,等等。而現(xiàn)在默認(rèn)情況下集合是異質(zhì)的:它們都是對(duì)象的集合,取出時(shí)都需要類型轉(zhuǎn)換,這簡直是胡鬧。”如果我可以告訴系統(tǒng),這是一個(gè)從字符串到數(shù)字的映射,它會(huì)幫我做類型轉(zhuǎn)換,而且會(huì)在編譯期間幫我盯著,防止我做錯(cuò)什么,那不是挺好的嗎?它可以抓到更多的錯(cuò)誤—— 它可以包含高層的類型信息,看起來是件好事兒。

我認(rèn)為泛型和其他加入到Java5的語言特性一樣,我們只是讓語言去做以前我們要手工去做的事情而已。某些情況下我堅(jiān)信:foreach就是好。它所做的就是對(duì)你隱藏遍歷器和索引變量帶來的復(fù)雜性。代碼更短,概念也不復(fù)雜。從某種意義上說,它的概念更簡單,因?yàn)槲覀優(yōu)閿?shù)組和其他的集合創(chuàng)建了這種偽多態(tài)機(jī)制,你可以遍歷一個(gè)ArrayList或者一個(gè)數(shù)組,而無需關(guān)心你遍歷的是什么類型。

這種思想不能適用于泛型的主要原因是,它是對(duì)已經(jīng)很復(fù)雜的類型系統(tǒng)的大擴(kuò)展。類型系統(tǒng)是很微妙的,修改它們可能對(duì)語言帶來深遠(yuǎn)的、難以預(yù)期的影響。

我認(rèn)為得到的教訓(xùn)是,當(dāng)你改進(jìn)一個(gè)成熟語言的時(shí)候,你必須更加仔細(xì)地考慮能力和復(fù)雜度之間的平衡。而且,實(shí)際上,復(fù)雜度跟語言的功能數(shù)量間至少是平方級(jí)關(guān)系。為一門老語言加上了一個(gè)新的功能,通常就意味著為它加入了一大堆復(fù)雜度。當(dāng)一種語言已經(jīng)達(dá)到或接近程序員理解能力的極限時(shí),那么你加入任何復(fù)雜性進(jìn)來都會(huì)加劇理解的難度。

語言更復(fù)雜后就會(huì)消失嗎?不會(huì)。我認(rèn)為C++早已超越了它的復(fù)雜度極限,但還是有很多人用它編程。可這實(shí)際上是逼人們只使用其中一個(gè)子集。所以我認(rèn)識(shí)的每個(gè)用C++的公司都說:“對(duì),我們用C++,但是用的是多繼承,不用操作符重載。”有很多功能你完全不用,因?yàn)槭褂盟鼈儠?huì)造成代碼太復(fù)雜。即使不得不用那些功能,我認(rèn)為也實(shí)在沒什么好處。那樣的話,程序員就讀不懂別人的代碼,也就不存在“程序員的可移植性”了。

Seibel:如果去掉泛型,現(xiàn)在Java會(huì)變得更好用嗎?

Bloch:我不知道。我還是喜歡泛型。泛型能幫我找到代碼中的Bug。泛型可以讓編譯器強(qiáng)制做一些限制,之前這些限制我只能放在注釋中。另一方面來說,當(dāng)我看到那些瘋狂的參數(shù)類型相關(guān)的錯(cuò)誤信息,當(dāng)我看到像 classEnum>這樣的泛型類型聲明時(shí),我就會(huì)想,顯然泛型的設(shè)計(jì)還沒成熟到可以放到 Java中的水平。

我們總是太樂觀,然后搬起石頭砸自己的腳。所以我們說:“耶!我們當(dāng)然可以把泛型放到Java中。在CLU的時(shí)候我們就知道泛型了。這技術(shù)25年前就有了。”最近我聽到關(guān)于閉包的類似言論,不過那是50年前的技術(shù)了。“噢,閉包很簡單,不會(huì)給語言加入任何新的復(fù)雜性。”

嗯,沒錯(cuò)。但是我覺得我們從泛型這件事兒得到了教訓(xùn)。在你懂得這個(gè)改動(dòng)會(huì)對(duì)概念層面帶來什么影響之前,在你可以確保軟件行業(yè)從業(yè)人員可以高效地使用新特性,而且這一新特性會(huì)讓他們活得更好之前,你不應(yīng)該給語言加入這一特性。

如果早知道程序員們對(duì)泛型是這個(gè)反應(yīng),我們肯定不會(huì)把它加到Java里。這是不是說我們就完全不會(huì)搞泛型?不,我不這么認(rèn)為。我認(rèn)為泛型確實(shí)很好。主要是因?yàn)榇蠖鄶?shù)集合是同質(zhì)的,而不是異質(zhì)的,同質(zhì)的集合處理起來是比較方便的。多數(shù)情況下類型轉(zhuǎn)換都不合適。轉(zhuǎn)換可能會(huì)失敗,而且讓你的程序不再優(yōu)雅。我想你知道這是什么集合,它應(yīng)該自動(dòng)符合你的這些需求。但是,是不是這就意味著你應(yīng)該承受我們現(xiàn)在承受的這種復(fù)雜度?不,我想我們只是沒有處理好泛型。

Seibel:關(guān)于泛型有來自于用戶的壓力嗎?有人抱怨泛型的缺點(diǎn)干擾他們寫程序了嗎?

Bloch:有沒有工程師大罵泛型的缺點(diǎn)?不,沒有,他們沒有抱怨過。如果因?yàn)榉盒秃啙嵕桶阉鼈兗舆M(jìn)來,那我會(huì)內(nèi)疚的。因?yàn)楫?dāng)時(shí)我們以為這么做是對(duì)的。

有人說,很多工程都是扯淡。有人要求我們加入foreach嗎?沒有。他們沒有要求我加入。但是我就知道這是應(yīng)該做的。我對(duì)了——每個(gè)人都喜歡它。但是我覺得我們行業(yè)內(nèi)的一大問題就是,在工程領(lǐng)域,做一個(gè)東西,僅僅因?yàn)樗啙崳瑑H僅因?yàn)樗且粋(gè)好的工程項(xiàng)目,等等。如果你不能解決真實(shí)用戶——在這里就是Java程序員——的真實(shí)問題,那么你就不應(yīng)該加入新的特性。

James Gosling曾做過一個(gè)非常了不起的演講——“Java的感覺”。他說,給Java加入任何東西之前,都需要三個(gè)真實(shí)的用戶。不應(yīng)該因?yàn)橐粋(gè)東西簡潔就把它放進(jìn)來。

但是人們就是想把什么東西都放進(jìn)去。工程師是做什么的?他們就是寫代碼的。而當(dāng)他們寫一個(gè)庫,或者一個(gè)語言的時(shí)候,他們就是想放各種東西進(jìn)去。你需要他人的參與,需要指導(dǎo)的聲音,需要這些東西來幫助你完成產(chǎn)品,幫你在放與不放之間做出最好的權(quán)衡。因?yàn)槟憧梢苑胚M(jìn)去的東西總比你應(yīng)該放進(jìn)去的東西多。那么是不是說所有的這些東西都不好呢?那也不是。只是你需要做出決定,某些東西是不應(yīng)該放進(jìn)去的。

思考Java帶來的編程經(jīng)驗(yàn)

Seibel:思考Java的設(shè)計(jì)并實(shí)現(xiàn)它,是否讓你學(xué)到了什么跟編程有關(guān)系的東西?

Bloch:我學(xué)到的東西太多了。比如我知道了即使是想把一個(gè)很小的程序?qū)憣?duì)也是非常難的。我把這個(gè)想法發(fā)表在了博客里,題目是“幾乎所有的二分搜索和歸并排序都是錯(cuò)的”。認(rèn)為自己程序是對(duì)的就是在愚弄自己。程序里有大量沒解決的Bug,當(dāng)然是不對(duì)的。多數(shù)情況下,程序里的Bug都不少,它們只能免費(fèi)完成任務(wù)。

我知道,既然寫正確的程序那么難,我們就應(yīng)該盡力去幫助大家。所以能減少Bug的所有東西都是好的。這就是我是靜態(tài)類型和靜態(tài)分析的信徒的原因,任何可以減少某個(gè)特定類別Bug的東西都是非常好的,任何可以讓程序員的工作更輕松的東西都是好的。

我更加確信有好的API文檔是很重要的。人們很少提及Javadoc對(duì)這個(gè)平臺(tái)的成功所起的作用。好的API文檔永遠(yuǎn)都是Java文化的一部分,也許是因?yàn)镴avadoc從一開始就存在吧(譯者注:所以人們低估了Javadoc的作用)。

我一直信奉“簡單就是美”這句話,現(xiàn)在更是如此。我不斷看到更復(fù)雜的東西最終被證實(shí)是有害的,只是有的時(shí)間長點(diǎn)兒,有的時(shí)間短點(diǎn)兒。我設(shè)計(jì)的時(shí)候,會(huì)仔細(xì)看著我的“復(fù)雜度計(jì)”,一旦復(fù)雜度要到紅線了,就需要重新設(shè)計(jì)了。

偶爾我會(huì)遇到不相信這些的人們,他們會(huì)說:“Josh你太傻了,你怎么就是不明白;這才是應(yīng)該做的,可惜你就是搞不懂。”我就是不信這些。我覺得事情一旦復(fù)雜起來,那么一定有什么地方錯(cuò)了,也許到了尋找更簡單的方法的時(shí)候了。

Tony Hoare的圖靈獎(jiǎng)獲獎(jiǎng)感言中有一句充滿了大智慧的話,講的是設(shè)計(jì)一個(gè)系統(tǒng)的兩種方式:“一種是盡量簡單,這樣顯然不會(huì)有什么問題;另外一種是,盡量復(fù)雜,這樣沒什么問題會(huì)很顯然。”

后面的內(nèi)容同樣飽含智慧,但是知道的人不多:“第一種方法其實(shí)更難。它需要從復(fù)雜的自然現(xiàn)象發(fā)現(xiàn)簡單物理規(guī)律的那種技能、投入、洞察力,甚至是那種靈感,同時(shí)還需要你能接受你的目標(biāo)受限于物理、邏輯和科技的約束,以及在目標(biāo)間有沖突的時(shí)候可以妥協(xié)。委員會(huì)無法做到這些,除非已經(jīng)完全來不及了。”

Seibel:你是否想過在職業(yè)生涯中再次更換你的主要語言,還是準(zhǔn)備退休前一直做Java?

Bloch:我自己也不知道。我從C語言轉(zhuǎn)向Java有點(diǎn)突然。從研究生畢業(yè)時(shí)起,到1996年,我主要使用 C語言編程,然后一直使用Java直到現(xiàn)在。我已經(jīng)預(yù)見到我可能要更換到其他語言了。但是我不知道是什么語言。也許它還不存在。我覺得產(chǎn)生一個(gè)新編程語言的時(shí)機(jī)已經(jīng)成熟,但是同時(shí)我又覺得平臺(tái)的慣性也比以前更大了。現(xiàn)代的平臺(tái)不僅僅是一個(gè)語言和一些庫,它包括很多工具,是一個(gè)虛擬機(jī),一個(gè)龐然大物。創(chuàng)建一個(gè)完整的新平臺(tái)的前景比以前更不樂觀。

我不知道將出現(xiàn)什么。但是我認(rèn)為如果改變我的主要語言是對(duì)的,那么我就會(huì)這么做。我想盡力保持開放的心態(tài)。我想嘗試更多的語言。我最近沒時(shí)間做,但是以后還是會(huì)做的。

Seibel:列出幾個(gè)你想嘗試的語言吧?

Bloch:我想試試Scala,雖然我懷疑它是否能成為未來的新寵。我很崇敬MartinOdersky。我覺得他寫的語言中有很多精妙的想法。但是我同時(shí)也認(rèn)為他加入了太多復(fù)雜的東西,太學(xué)術(shù)化了,所以很難取得世界范圍內(nèi)的大成功。當(dāng)然我還沒權(quán)利去評(píng)價(jià),因?yàn)槲疫沒學(xué)習(xí)過。

我還想用用Python。Scheme不是新生物,不過我也想試試。我想花幾個(gè)月,跟我兒子一起過一遍《Structure and Interpretation of Computer Programs》一定很有意思。每個(gè)人都說這是一本偉大的書。我已經(jīng)買了,算是開了個(gè)頭。看完它需要一些時(shí)間。我想這就是我目前想學(xué)的。

Seibel:現(xiàn)在很多人在討論我們寫程序的時(shí)候,如何能把未來的多核CPU的優(yōu)勢(shì)利用起來。Java顯然是第一個(gè)內(nèi)建多線程機(jī)制的主流語言。你覺得Java的邏輯在多核的世界是否仍然可用?

Bloch:我想說得更深入一些。我認(rèn)為Java是現(xiàn)有語言中最好的。但有趣的是,現(xiàn)在很流行談Java是否即將死去。我覺得這基本上是扯淡。我認(rèn)為現(xiàn)在最好的多線程構(gòu)件就在Java里。我認(rèn)為Java將迎來復(fù)興。我不是說它是未來20年內(nèi)最先進(jìn)的,也不是說它是處理多核的最好方式。但是我認(rèn)為從現(xiàn)有的東西來看,我們是足以傲視同儕的。
本文地址:http://m.qingdxww.cn/thread-58010-1-1.html     【打印本頁】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

廠商推薦

  • Microchip視頻專區(qū)
  • 使用SAM-IoT Wx v2開發(fā)板演示AWS IoT Core應(yīng)用程序
  • 使用Harmony3加速TCP/IP應(yīng)用的開發(fā)培訓(xùn)教程
  • 集成高級(jí)模擬外設(shè)的PIC18F-Q71家族介紹培訓(xùn)教程
  • 探索PIC16F13145 MCU系列——快速概覽
  • 貿(mào)澤電子(Mouser)專區(qū)
關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 香蕉免费一级视频在线观看| 日韩无毛| 亚洲免费综合色视频| 国产专区_爽死777| 美女网站免费看| 亚洲深夜在线| 欧美亚洲激情视频| 日韩黄色三级| 色综合天天综合网国产成人| 亚洲欧洲尹人香蕉综合| 香蕉视频在线观看网址| 在线中文高清资源免费观看| 成人免费视频一区| 麻豆出品国产AV在线观看| 亚洲AV噜噜88| 午夜一级做a爰片久久毛片| 日本高清色www| 亚洲欧美无人区乱码| 伊人久热这里只精品视频| 哺乳溢出羽月希中文字幕| 麻豆精品2021最新| 亚洲精品综合久久| 欧美性极品黑人hd| 午夜看片影院在线观看| 伊人亚洲综合网成人| 艳姐李铁柱王淑兰的小说| old老男人野外树林tv| 麻豆久久国产亚洲精品超碰热| 亚洲国产欧美一区| 亚洲欧美日韩高清一区二区三区| 天堂av2014| 无人区在线观看免费观看| 中文精品久久久久国产网站 | 日韩人成免费网站大片| 香蕉视频在线观看免费国产婷婷| 一个人在线观看视频www| 国产精品国产三级国产专区53| 乳交高H糙汉宠文| 色综合综合在线| 日本卡一卡2卡3卡4精品卡网站| 亚洲天堂视频一区|