一 、靜態(tài)語言的優(yōu)勢到底在哪?
轉(zhuǎn)自http://www.cnblogs.com/spmxlBlog/archive/2010/06/28/1766832.html
引用
是像Java或者C#這樣強類型的準(zhǔn)靜態(tài)語言在實現(xiàn)復(fù)雜的業(yè)務(wù)邏輯、開發(fā)大型商業(yè)系統(tǒng)、以及那些生命周期很長的應(yīng)用中也有著非常強的優(yōu)勢
這是一個存在于大家心里常識了。我承認我自己在潛意識里面也覺得靜態(tài)強類型語言適合開發(fā)復(fù)雜,大型系統(tǒng)。而弱類型腳本語言不適合開發(fā)太復(fù)雜,太大型的項目。但是在參與這個討論過程中,我突然開始置疑這個觀點,事實究竟是不是這樣的呢?
先定義一下標(biāo)準(zhǔn):
強類型語言(靜態(tài)類型語言)是指需要進行變量/對象類型聲明的語言,一般情況下需要編譯執(zhí)行。例如C/C++/Java/C#
弱類型語言(動態(tài)類型語言)是指不需要進行變量/對象類型聲明的語言,一般情況下不需要編譯(但也有編譯型的)。例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。
引用
觀點一:靜態(tài)類型語言因為類型強制聲明,所以IDE可以做到很好的代碼感知能力,因為有IDE的撐腰,所以開發(fā)大型系統(tǒng),復(fù)雜系統(tǒng)比較有保障。
對于像Java來說,IDEA/Eclipse確實在代碼感知能力上面已經(jīng)非常強了,這無疑能夠增加對大型系統(tǒng)復(fù)雜系統(tǒng)的掌控能力。但是除了Java擁有這么強的IDE武器之外,似乎其他語言從來沒有這么強的IDE。C#的Visual Studio在GUI開發(fā)方面和Wizard方面很強,但是代碼感知能力上和Eclipse差的不是一點半點。至于Visual C++根本就是一個編譯器而已,羞于提及Visual這個字眼。更不要說那么多C/C++開發(fā)人員都是操起vi吭哧吭哧寫了幾十萬行代碼呢。特別是像Linux Kernel這種幾百萬行代碼,也就是用vi寫出來的阿,夠復(fù)雜,夠大型,夠長生命周期的吧。
引用
觀點二:靜態(tài)語言相對比較封閉的特點,使得第三方開發(fā)包對代碼的侵害性可以降到很低。動態(tài)語言在這點上表現(xiàn)的就比較差,我想大家都有過從網(wǎng)上下載某個JS包,然后放到項目代碼里發(fā)生沖突的經(jīng)歷
也就是說靜態(tài)類型語言可以保障package的命名空間分割,從而避免命名沖突,代碼的良好隔離性。但是這個觀點也缺乏說服力。
靜態(tài)類型語言中C,VB都缺乏良好的命名空間分割,容易產(chǎn)生沖突,但是并沒有影響他們做出來的系統(tǒng)就不夠大,不夠復(fù)雜。
而Visual C++開發(fā)的DLL版本沖突也是臭名昭著的,似乎C++的命名空間沒有給它帶來很大的幫助。
而動態(tài)類型語言中Ruby/Python/Perl都有比較好的命名空間,特別是Python和Perl,例如CPAN上面的第三方庫成噸成噸的,也從來沒有聽說什么沖突的問題。
誠然像PHP,JavaScript這樣缺乏命名空間的動態(tài)語言很容易出現(xiàn)問題,但是這似乎是因為他們?nèi)狈O機制導(dǎo)致的,而不是因為他們動態(tài)類型導(dǎo)致的吧?
說到大型系統(tǒng),復(fù)雜業(yè)務(wù)邏輯系統(tǒng),Google公司很多東西都是用python開發(fā)的,這也證明了動態(tài)類型語言并非不能做大型的復(fù)雜的系統(tǒng)。其實我個人認為:
動態(tài)類型語言,特別是高級動態(tài)類型語言,反而能夠讓人們不需要分心去考慮程序編程問題,而集中精力思考業(yè)務(wù)邏輯實現(xiàn),即思考過程即實現(xiàn)過程,用DSL描述問題的過程就是編程的過程,這方面像Unix Shell,ruby,SQL,甚至PHP都是相應(yīng)領(lǐng)域當(dāng)之無愧的DSL語言。而顯然靜態(tài)類型語言基本都不滿足這個要求。
那靜態(tài)類型語言的優(yōu)勢究竟是什么呢?我認為就是執(zhí)行效率非常高。所以但凡需要關(guān)注執(zhí)行性能的地方就得用靜態(tài)類型語言。其他方面似乎沒有什么特別的優(yōu)勢。
若干評論:
1??纯磞ahoo吧,它是用PHP寫的。給你用JAVA也可能做不出來那樣的性能。
2。我的一點感覺,動態(tài)語言足夠靈活,因此雖然它能夠讓人更集中精力思考業(yè)務(wù)邏輯的實現(xiàn),同時也向人工智能的方向走得更近一些,但因此它也更依賴于開發(fā)人員本身的技術(shù)功底,初學(xué)者、中級開發(fā)者,難以很好的利用它。 而靜態(tài)類型語言,與我們計算機教學(xué)的基本科目(c/pascal/basic)延續(xù)性比較好,所以對于剛畢業(yè)的學(xué)生而言,更好接受和學(xué)習(xí)。因此我覺得還是學(xué)習(xí)/培訓(xùn)/開發(fā)成本占主要因素。一個不太恰當(dāng)?shù)睦樱簀avascript的正則表達式,雖然功能強大,但并不易理解和學(xué)習(xí)。一般只能copy/paste來用。所以很多情況下,還是寧愿手寫標(biāo)準(zhǔn)js來處理。
3。我感覺類似Java這樣的強類型的準(zhǔn)靜態(tài)語言還有一個重要的特點。一旦程序員基本掌握了語法規(guī)則和書寫規(guī)范,寫出來的程序的可讀性會強很多,因為它本身的限制更多。在一個大型系統(tǒng)中,Team成員之間互相可以知道對方在寫什么是非常關(guān)鍵的,這也成為了交流的重要基礎(chǔ)。
然而Ruby這樣的語言,雖然看上去更加符合“描述問題即解決問題”,但是對于同一段邏輯,同樣可以滿足要求,寫法上卻差別很大。我曾經(jīng)見過用1行寫出來的解決數(shù)讀算法的Ruby解法,誰能看懂?
4。我更經(jīng)常見到的是Java程序員屁大點事寫幾百行,Ruby幾行就搞定了
5。靜態(tài)類型語言是指在編譯時變量的數(shù)據(jù)類型即可確定的語言,多數(shù)靜態(tài)類型語言要求在使用變量之前必須聲明數(shù)據(jù)類型,某些具有類型推導(dǎo)能力的現(xiàn)代語言可能能夠部分減輕這個要求.
動態(tài)類型語言是在運行時確定數(shù)據(jù)類型的語言。變量使用之前不需要類型聲明,通常變量的類型是被賦值的那個值的類型。
強類型語言是一旦變量的類型被確定,就不能轉(zhuǎn)化的語言。實際上所謂的貌似轉(zhuǎn)化,都是通過中間變量來達到,原本的變量的類型肯定是沒有變化的。
弱類型語言則反之,一個變量的類型是由其應(yīng)用上下文確定的。比如語言直接支持字符串和整數(shù)可以直接用 + 號搞定。當(dāng)然,在支持運算符重載的強類型語言中也能通過外部實現(xiàn)的方式在形式上做到這一點,不過這個是完全不一樣的內(nèi)涵
通常的說,java/python都算是強類型的,而VB/Perl/C都是弱類型的.
不過相比于動態(tài)/靜態(tài)語言的分類,強類型/弱類型更多的是一個相對的概念。
6。如果采用動態(tài)語言,單元測試上的工作量要比靜態(tài)語言的多很多
robbin 回這一條。其實你忽略了一點,當(dāng)使用類似RoR這樣的框架的時候,應(yīng)用代碼量是很少的,所以相應(yīng)需要測試的部分也很少,比使用靜態(tài)類型語言需要測試的部分少了很多。
另外,缺少單元測試沒有你說的那么恐怖。我們現(xiàn)在就沒有寫單元測試,ruby代碼都已經(jīng)有6000多行了,編程也好,排錯也好,一樣很輕松,哪有你吹的那么恐怖。
7.商業(yè)系統(tǒng)的復(fù)雜在于組織上交流的困難,一個大公司,內(nèi)部有個人能把商業(yè)流程搞得一清二楚就不錯了,這個人還能把過程給軟件人員講清楚那簡直是可遇不可求的事。這樣用ruby反而有優(yōu)勢了,可以快速開發(fā),促進交流,開發(fā)出個模型出來給商務(wù)人員看看,用用,自然交流起來就容易多了。
現(xiàn)在一個開發(fā)人員的開發(fā)效率比以前高多了,主要原因是因為開發(fā)語言和編譯器的進步,這個趨勢,只會繼續(xù)下去,不要抱著過去的教條不放,java也是在不斷改進的,加了reflection, 加了assert,加了泛型,下個版本,也要加腳本支持了。
8.其實靜態(tài)類型語言,除了性能方面的考量之外,最大的優(yōu)勢就是可以提供靜態(tài)類型安全,編譯器可以檢查你的每一個函數(shù)調(diào)用是不是書寫了正確的名字,是不是提供了正確類型的參數(shù)。這樣一個系統(tǒng),配合自定義類型的功能,可以讓很多錯誤(比許多人想象的要多)在編譯時就能被發(fā)現(xiàn)和定位。
9.我在slashdot上類似話題的討論上曾經(jīng)看到過有人抱怨動態(tài)語言,那個哥們是從事銀行系統(tǒng)的,大概有10萬行的python代碼,最后因為細小隱錯不斷而覺得無法維護,貌似要轉(zhuǎn)到j(luò)ava平臺。(如果把slashdot上近兩年來關(guān)于ruby和python的帖子和評論看一邊,大概還能夠找到這個跟貼)
從這哥們的描述來看,他的主要問題是沒有單元測試或者單元測試沒有達到語句覆蓋或者更強的弱條件組合覆蓋,從而導(dǎo)致某些非正常流程發(fā)生時,流經(jīng)這些未被測試的語句導(dǎo)致語法錯誤而最終整個程序都掛掉.對于業(yè)務(wù)系統(tǒng)來說,這是非常嚴(yán)重的事情。就像我前面說的那樣,我自己的程序就曾經(jīng)不止一次死在logging語句上,因為最初我也不測試這類語句的可通過性。
至于單元測試有沒有用,三五人的項目幾千行的代碼是看不出來的。其實,作坊式開發(fā)照樣能夠做出很多東西來,5年前國內(nèi)的開發(fā)方式基本上是沒有單元測試的,照樣也能玩得轉(zhuǎn)。
但是,就我自己的體驗而言,雖然我并不遵循TDD,但單元測試是足夠詳盡的,而這個測試網(wǎng)給我的置信度(尤其是在修改代碼和較大規(guī)模重構(gòu)時)是之前不可想象的。我估計上千行的程序,就能夠在漸增式的單元測試中嘗到好處。
10.編譯器對程序員的幫助到底有多大,這個還是要應(yīng)人而異的。編譯器能查出來的很多都屬于打字錯誤,拼寫錯誤。對于robbin來說,即使沒有編譯器,檢查這種錯誤也是小菜一碟。可是對于經(jīng)驗不是很豐富的程序員來說,情況恐怕就大大不同了。畢竟程序員經(jīng)驗方面差異的一個重要方面就是Debug能力和經(jīng)驗的差異。對高手來說仔細讀上兩遍程序就能發(fā)現(xiàn)的錯誤,對一些新手來說可能會花上一兩小時,這種情況我在實際項目中碰到很多次了。