成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Google首席架構(gòu)師談Java的命運(yùn)

開(kāi)發(fā) 后端
本文是Common Lisp專家Peter Seibel對(duì)Google公司首席Java架構(gòu)師Joshua Bloch的訪談,談到他所遇到的最糟糕的Bug以及Java的命運(yùn)。

                   

文 / Peter Seibel 譯 / 郝培強(qiáng)

本文是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),甚至還在過(guò)程中做出了幾個(gè)可重用的組件。但是這么匆忙地寫(xiě)了很多新代碼,我還是挺擔(dān)心的。

為了測(cè)試這些代碼,我寫(xiě)了一個(gè)叫做“亂撞”的很長(zhǎng)的程序出來(lái)。它運(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ù)之上,長(zhǎng)時(shí)間地訪問(wèn)數(shù)組。因?yàn)槲覝y(cè)試的是一個(gè)共享內(nèi)存機(jī)制,所以我同時(shí)運(yùn)行多個(gè)有多個(gè)線程的“亂撞”程序,每個(gè)有自己的進(jìn)程。

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

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

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

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

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

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

Java的命運(yùn)

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

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

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

有趣的是,他抗?fàn)幎嗄?,希望阻止泛型進(jìn)入Java語(yǔ)言中。但是在泛型被成功地阻擋在Java外的這些年里變體的概念,也就是通配符的隱含意義流行了起來(lái)。如果它們來(lái)得更早,沒(méi)有變體,也許我們現(xiàn)在可以有一個(gè)更簡(jiǎn)單的、更容易跟蹤的語(yǔ)言。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Bloch:有沒(méi)有工程師大罵泛型的缺點(diǎn)?不,沒(méi)有,他們沒(méi)有抱怨過(guò)。如果因?yàn)榉盒秃?jiǎn)潔就把它們加進(jìn)來(lái),那我會(huì)內(nèi)疚的。因?yàn)楫?dāng)時(shí)我們以為這么做是對(duì)的。

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

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

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

思考Java帶來(lái)的編程經(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ì)的就是在愚弄自己。程序里有大量沒(méi)解決的Bug,當(dāng)然是不對(duì)的。多數(shù)情況下,程序里的Bug都不少,它們只能免費(fèi)完成任務(wù)。

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

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

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

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

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

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

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

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

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

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

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

我還想用用Python。Scheme不是新生物,不過(guò)我也想試試。我想花幾個(gè)月,跟我兒子一起過(guò)一遍《Structure and Interpretation of Computer Programs》一定很有意思。每個(gè)人都說(shuō)這是一本偉大的書(shū)。我已經(jīng)買(mǎi)了,算是開(kāi)了個(gè)頭??赐晁枰恍r(shí)間。我想這就是我目前想學(xué)的。

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

Bloch:我想說(shuō)得更深入一些。我認(rèn)為Java是現(xiàn)有語(yǔ)言中最好的。但有趣的是,現(xiàn)在很流行談Java是否即將死去。我覺(jué)得這基本上是扯淡。我認(rèn)為現(xiàn)在最好的多線程構(gòu)件就在Java里。我認(rèn)為Java將迎來(lái)復(fù)興。我不是說(shuō)它是未來(lái)20年內(nèi)最先進(jìn)的,也不是說(shuō)它是處理多核的最好方式。但是我認(rèn)為從現(xiàn)有的東西來(lái)看,我們是足以傲視同儕的。

 原文鏈接:http://www.programmer.com.cn/5200/

責(zé)任編輯:金賀 來(lái)源: 《程序員》雜志
相關(guān)推薦

2010-12-16 11:05:36

數(shù)學(xué)程序員Google首席Jav

2014-10-28 09:56:56

Hadoop

2012-04-26 10:22:27

豆瓣網(wǎng)洪強(qiáng)寧Python

2009-12-18 10:22:50

Ray Ozzie架構(gòu)師

2010-11-25 15:18:01

Windows Emb微軟架構(gòu)師

2011-04-28 10:12:13

海量數(shù)據(jù)分析平臺(tái)

2009-07-17 15:18:46

Windows Emb

2009-07-17 15:31:18

Windows Emb

2009-07-17 15:34:13

Windows Emb

2010-08-05 13:51:13

軟件架構(gòu)師

2012-03-21 17:30:21

百度架構(gòu)師

2009-06-30 16:34:44

微軟

2017-07-20 10:31:33

2012-02-02 10:23:07

2010-04-20 09:18:00

架構(gòu)師

2011-11-01 09:02:26

系統(tǒng)架構(gòu)師

2011-10-31 09:22:07

系統(tǒng)架構(gòu)

2010-03-02 09:44:32

首席架構(gòu)師趙亮

2017-06-01 09:34:53

公有云數(shù)據(jù)遷移

2010-10-19 10:39:45

鮑爾默軟件架構(gòu)師
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久草免费在线视频 | 国产激情精品一区二区三区 | 99福利在线观看 | 国产美女视频一区 | 草久久久| 罗宾被扒开腿做同人网站 | 免费一看一级毛片 | 国产亚洲精品久久久久动 | 99这里只有精品视频 | 一级毛片免费看 | 日日摸天天添天天添破 | 久久久久国产一区二区三区 | 蜜桃视频成人 | 亚洲小视频在线播放 | 狠狠操狠狠操 | 伊人春色成人网 | 视频一区中文字幕 | 在线观看免费高清av | 一区二区三区四区av | 免费一级黄色录像 | www.国产 | 国产精品爱久久久久久久 | 欧美福利在线 | 国产精品久久久亚洲 | 欧美激情国产日韩精品一区18 | 久久精品视频在线播放 | 亚洲一区二区视频 | 国产精品亚洲精品 | 波霸ol一区二区 | 亚洲视频不卡 | 一级视频黄色 | 亚洲永久精品国产 | 99自拍视频| 成人在线免费网站 | 成人免费精品 | 黄色片av | 日本成人三级电影 | 看一级黄色毛片 | 在线成人免费视频 | 日本一二三区高清 | 国产精品一区二区在线播放 |