顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2009年7月22日 星期三

學程式語言的樂趣

國三時為了做北市數學科展,實習老師教我使用 Microsoft Word,這是我首次體會到電腦在遊戲之外的樂趣。為了學會怎麼灌 Windows,高一時參加了社團,結果社團學長 Scott 說:「灌 Windows 太簡單了,你來學 C 吧。不過我們這裡只有 Red Hat Linux,就邊學 C 邊學 Linux 吧。」傻傻的我,以為 Linux 裡只有 Vi,就四處翻 Linux 入門書,看完各本書裡 Vi 部份,還寫了篇 Vi 的教學。日漸熟悉 Vi、bash 指令後,覺得玩系統、寫程式真有趣。於是上課無聊就偷看電腦書,下課耍自閉繼續看書,中午放學都跑去社團混,就這樣渡過我的高一。不知不覺,我打下日後學習能力最重要的基礎。

高一一時想不開,同時學 C 和 Perl,用 Perl 寫東西頗有趣的,特別是費盡心思把程式擠到一行作完一件煩人的小工作時,有說不出來的成就感。可是我基礎太弱,無法明白兩者更深層的差異,只能當作兩個不同工具看。兩者同時學的下場,學一陣子仍不熟兩邊的語法。於是我先專心學 C,之後 Perl 也忘光了。那段日子最大的收獲是,不要一次同時學兩個語言。另外,多虧 Scott 心理不正常,用 K&R 的《C 程式語言》當入門書,我直接學會標準語法,和 C 的典型寫法。這個習慣一直伴隨我到現在,每學一個新語言時,我傾向直接找能教我典型寫法的書,省去先花時間學一堆語法,再去蕪存菁地寫出典型風格。

寫了三年的 C,大一接觸到 Java 後,覺得 OOP 很有趣,這麼簡單又優雅地,讓我能同時使用兩個 Stack!雖然一開始寫著滿滿的 C-like Java,程式裡都是 static method,看了些 OOP 的書,開始轉型寫著自以為是 OOP 的怪東西。時至今日,我仍然不明白要怎麼寫出真正的 OOP。至少我發現自己寫得不是 OOP,和大學時相比,算是進步不少。

有些課要求用 C++,我就會用 Java 學到的 OOP 觀念和 C 的經驗來寫。每次要寫 C++ 就重翻一下 C++ 快速入門的書,寫完後又忘光一切。大三做專題時,我和朋友們打算參加一個國外的比賽,由於主要贊助商是 Microsoft,我們決定用 .NET Framework 開發。就這樣,我有個好機會寫 C#。亂翻一些 ASP.NET 的書把殼刻一刻後,我找了《C# Essentials》來看。這本書如其名,薄又都是重點,很快地明白 C# 的特色,讓我覺得 C# 挺漂亮的。不過寫完專題後沒繼續寫 C#,現在什麼也不記得了。而且,當時我的底不夠深,仍無法感受到各語言的特色。

除 C++、C# 兩個插曲外,大學時主要用 Java 和 PHP。用途很簡單,接網站案子用 PHP,其它用 Java。我練習 PHP 的方式是不斷改寫自己的網站,還有接些小案子,可是我覺得 PHP 實在不怎麼美,沒動力學好它,能用就好。

大學中途有試著寫了一點 Python、Scheme,可惜無法持續。一直到碩一一時興起,一方面是厭煩了用 PHP 寫重覆的東西,另一方面想試看看當紅的 Ruby on Rails,就邊查邊寫完成一個小案子。寫得過程裡,覺得 Ruby 很奇妙,於是在寒假花了一週讀完《Programming Ruby》第一部份,這才正式開始我學的第三個語言。

自那之後,我只有寫 Ruby,Java、PHP和其它語言碰也沒碰,這樣直到碩士畢業。沒錯,我的碩士論文也是用 Ruby 寫的,這才深深體會到 Ruby 有多慢有多肥,幸好實驗室的機器很壯,不然我得改用 Java 完成碩論。這段期間,把一個論文裡用到的程式零零總總地加起來,大概有兩千多行,也驚覺 Ruby 幫我省了不少寫程式的時間,相信用 Java 的話,我無法在不到一個月的時間裡寫完自己的演算法、數個比較對象的演算法、前置處理、評估分數等程式。不過卻辛苦交接的學妹,這樣瘋狂用一個不熟語言趕出來的程式碼,原以為不會繼續用的說。

用 Ruby 讓我有了第二次衝擊,就像當年從 C 到 Java 發現可以同時有兩個 Stack 那般驚奇,沒想到 iterator、code block 這麼好用,腦裡想什麼,手就可以直接敲出來,不用寫一寫還要把游標移來移去。而且,Ruby 可以寫出很短又好讀的程式,我從來沒想過程式可以寫到這麼精簡,而寫到這麼精簡後,又更容易理解。

碩士畢業去一家公司實習時,該公司不用 Ruby,我藉機來試看看 Python。於是,對照先前一年多寫 Ruby 的經驗,我明白很多事。有時選擇某個語言,沒有什麼明確的理性依據,單純是個人偏好。高中時我一直想知道 Python 和 Perl 的差異,到底學那個比較划算,如今又多了一個 Ruby 列入抗爭。現在來看,即使我可以找到三者在語言設計、執行速度、社群、函式庫、上手度等各方面的比較,到頭來,選擇何者反而像是信仰。

附帶一提,若要推廣一個程式語言,良好的互動直譯器、快速隨手查的文件、精簡易讀的入門書,三者缺一不可。 Ruby 大概就互動直譯器弱了一些,而 Python 三者都完美無缺,非常容易上手。至於 Java,即使到現在,我仍不知道要推薦別人看什麼書入門。最後附上我對各語言入門方式的看法,入門書書單是針對已學過一種語言的人:

語言 互動式直譯器 隨手查的文件 入門書
C man page 《C 程式語言》
Ruby 設定後的 irb ri 《Programming Ruby》
Python ipython ipython 《Python Essential Reference》
Java CHM格式的 Java doc

( 待續 )

2009年3月15日 星期日

軟體開發技巧的待讀書單

經過這陣子的評估,終於列出了夢幻般 (?) 的讀書清單。我的做法是先在網上看到有人推薦,到書局翻一陣子,再回來查 Amazon 的評論,最後決定是否有必要看。附帶一提,待這書單決定後又查了一下,結果發現每本書都有得到 Jolt Award,一瞬間好像以為 Jolt Award 不值錢了 :-)。

以下依暫定的閱讀順序依序說明,除前兩本外,後三本都有中文版:

1. Test Driven Development by Examples

Amazon 評論 4 顆星,由 Kent Beck 所著。全書只有 200+ 頁,用大量的例子,一步一步說明怎麼進行 TDD,相當易讀。這裡有別人寫的詳細書評

2. xUnit Test Patterns: Refactoring Test Code

Amazon 評論 4.5 顆星,不過只有七筆評論,樣本略嫌不足。 在書店試翻的感想是:好書但不易讀,而且實在是太厚了。ThoughtWorks 專出這種書嗎?

3. Refactoring to Patterns

Amazon 評論 4 顆星,但評論兩極化落在 3 和 5,最中肯的評論為: "Good ideas, but needs refactoring",值得一讀,但不好消化。讀過 Martin Fowler 的 Refactoring 並有一段實戰經驗後的最佳書藉。本書中文版《重構-向範式前進》,且是侯捷合譯的 。

4. Head First - Head First Object-Oriented Analysis and Design

Amazon 評論 4 顆星,評論裡指出本書適合初學者,另外最多人同意的評論 (Decent Introduction to OOA&D) 指出:本書不夠簡潔,並有不少小錯,若有第二版才值得推薦。 

5. Head First - Design Pattern

Amazon 評論 4.5 顆星,且是壓倒性的一堆 5 顆星。Head First 的書以易讀出名,但通常也寫得很厚,需要花不少時間消化 。 對照過於精簡典雅的 Design Pattern Bible Book,這本書親切不少。附帶一提,在書店還有看到 Head First - Algebra,真是太有趣了!可惜是教國中代數,不是教線性代數。

依目前心得來說,有四件事要學:

  1. 寫出良好的測試程式 - book 2
  2. 寫出良好的 OOP- book 4, 5
  3. 提昇重構技巧 - book 3
  4. TDD (其實就是上述三者的綜合體) - book 1

前往軟體開發聖殿之路是很遠的,希望一個月至少能解決一本,並持續地應用到實戰中,半年後就出師啦!

備註

這裡補充我曾看過且大力推薦的書藉:

2008年2月16日 星期六

Java Puzzlers

書藉基本資料: Java Puzzler中文版-陷阱、錯誤與死角

《Effective Java》類似,這本在講Java的特性。不同的是,這本著重在以易犯的錯誤例子來說明正確的準則,而《Effective Java》是直述守則。本書在說明錯誤時,常引用別處文獻說明進一步資訊上那找,其中大部份的參考文獻出自《Effective Java》。另外不同的一點,本書的述說語氣比較風趣,偶而還有有趣的爛解答。哦,還有附一堆相當傷眼的錯覺圖,我時常用手遮住它們,以方便我能舒服地閱讀文字。然而兩本相較之一下,《Effective Java》較值得看。

不過相較於《Effective Java》直接說怎麼做較好,這本書到是相當成功地說服讀者,為什麼不要那麼做,例子舉得相當漂亮,帶來不少衝擊。本書不宜長時間連續閱讀,讀起來相當傷腦,一堆看似正常的程式碼,卻常發生不可思議的結果,或是不知所云的編譯錯誤訊息。或許,當Java寫到一定程度時,看這本書可以協助除錯。以下簡單直述部份心得,若對解謎有興趣的話,就別看下面的心得,自己慢慢翻書也是種樂趣。

  1. final對於method和field的含意不同,field的final是指只能設值一次,所以
    final int a;
    a = 3;

    是合法的。但也因這個特性,會有些潛在問題,例如:物件因為初始化順序不同,而讀到未初始化的final field。解法:lazy initialization。

  2. 除非之前有執行 System.exit(),finally一定會被執行到,這意味著在finally之前的return和throws exception會被finally給蓋過!
  3. constructor內不要呼叫被覆寫的method,有可能因物件初始順序而讀到未初始化的欄位。可用lazy initialization解決。
  4. 一些計算機組織的知識,像是 IEEE 754對浮點數的定義,使得太小的小數無法加進去,例如:

    float a = 2.0E20f;
    a += 1.0; // 結果仍是2.0E20f

    還有因為負數用二補數表示,負的MIN_VALUE不存在對應的正數,abs(MIN_VALUE)結果仍是負的MIN_VALUE。

  5. 要分清楚overriding、overloading、hiding、shadowing、obscuring。Java 5.0後,override時記得加 @override 避免 method 寫錯宣告時變成 overloading。還有別用參數數同一樣且有父子關係的 overloading,例如下面是個不好的 overloading,由於 JVM 會找最接近型態的,而可能呼叫到非你想要的:

    public boolean equals(Object o) {return true; }
    public boolean equals(String o) {return true; }

  6. method的覆寫 (override)不能變得更限制(例如public不能變protected),但field可以,此時稱為 hiding(亦有其它情況會發生 hiding),例如下面的例子是合法的:

    class A { public static String s = “A”; }
    class B extends A { private static String s = “B”; }
    A o = new B();
    System.out.println(o.s); // 結果為:A

  7. 用class method時,使用class名稱呼叫,避免呼叫錯誤。注意:((Math)null).PI 是合法的,JVM不會理會object,而會直接找它的class。
  8. Java 5.0支援泛型後,盡量不要使用原始類型(例如 List),那是向下相容的必要之惡;改使用參數化類型(例如 List<T>)。千萬不要混用原始類型和參數化類型,#88會給你滿意的理由,為何不要這麼做。
  9. 不要在一個運算式裡改變一個變數多次,這牽涉到實作細節,比方 x^=y^=x^=y 這個有名的例子,在 Java 裡不會成功的 swap。
  10. 不要在一個運算式裡將型態自動向上向下轉型(例如 int 變 long或反過來),這之間有很多潛在問題,詳情參閱前面的puzzles。
  11. char是無號型態,其它byte、int等都是有號的;16進位沒有正負號,它直接以二補數解讀;< <、>>等只看最低的5 bits數,a < < 31和a << 63意思一樣(小心負數的情況)。

2007年8月23日 星期四

試用JRuby失敗,只好用Java讀圖檔

Ruby查不到怎麼讀圖檔,只好從Java下手,原本想用jruby來搞定的,結果碰上jruby的bug,jruby還未成為完全體嗎?Java的解法見這裡,寫好的code在這裡。以下是用jruby的測試情況:

# jruby -v ruby 1.8.5 (2007-06-07 rev 3841) [amd64-jruby1.0] # cat read_bmp.rb include Java import java.awt.image.BufferedImage; import javax.imageio.ImageIO; f = File.new("test.bmp"); img = ImageIO.read(f) # jruby read_bmp.rb RubyFile(test.bmp, 0, 3) :-1: no read with arguments matching [class org.jruby.RubyFile] on object JavaUtilities (NameError)

ImageIO.read()無法讀出BufferedImage,只好重操老本行寫Java,輸出的method打成puts…,幸好Java的compiler很強,就算很久沒寫Java,想寫出能動的code還是很快,大不了多compile幾次罷了。

2007年1月26日 星期五

超越Java(Beyond Java)

書藉基本資料:超越Java(Beyond Java)

讀完全書後,回頭來補寫這是什麼樣的書。

這本書穿插資深programmer的訪談,融合作者的經驗,從實務和理論層面分析好的語言該有的特性,再說明各個語言的情況。我對語言的實務能力較理論能力好,讀起來感覺作者的介紹以實務層面居多(不懂的東西自然略過...),可能有些偏頗。

作者本身是 Java 長期支持者,並寫了幾本暢銷書,在本書裡用大量篇幅說明為什麼 Java 不行了,為什麼 Ruby 是他最看好的接班人。另外有一章介紹「延續伺服器」(continuation server),說明在 stateless server 上開發 web 的瓶頸,該用什麼樣新的 server 和 framework 來改善。

對學語言有興趣的人、 Java 的愛好者或寫網站的工程師可以看看這本書。我的背景則是七年前學會C,認真寫了三年,四年前學會Java,這四年內以寫Java和C居多,這七年來有寫些 PHP,用 C# 寫大學專題,和一點點的C++、Perl 、Scheme、Python。既對學語言有興趣,也喜歡寫Java,並且以寫網站賺生活費 XD

看這本書時,我的心態挺爽快的,沒任何抵抗就想試別的語言,我一直都覺得不同場合要用不同語言,沒有萬能的語言。

超越Java(Beyond Java) - 4 (Java以外的語言)

書藉基本資料:超越Java(Beyond Java)

ch9討論其它語言,決定一個語言是否成為主流(或著說,取代Java),可分成話題性、時機、語言特性、殺手級應用來看,比方Smalltalk一直被認為是很美的語言,但30年過去仍未能成為主流,它的時機已過,未來也難以流行。Ruby興起很快,話題性夠、時機也對,語言特性好,近年來的Rails更是Web開發的殺手級應用,所以作者在本書花了大幅篇幅說明Ruby、說明Ruby on Rails,我經驗不足,看不懂Ruby更強的功能,不過寫個一陣子後會有所體會吧。

對語言有興趣的人,可以直接翻ch9看幾位專家的看法,很有意思。除了語言外,平台也需要討論,Ruby只是語言,不是平台,降低它的推廣力。提及Java時,或多或少在指JVM、J2EE、J2SE、J2ME,提及C#時也多少涉及.NET Framework、.NET Compact Framework。換句話說,我們說Java好時,其實同時指語言特性好(OOP、安全、規範多)和平台好(write once, run everywhere),JVM成功和重要的原因,可以參閱之前寫的”談JVM跨平台,卻不談scripting language跨平台的原因”

這代表其它語言也有機會參與這些優秀的平台,Microsoft一直積極(?)強調CLR(Common Language Runtime),Java也有些案例,但都不太成功,像是JythonJRuby,如果有組織積極推廣語言和Java平台、.NET平台整合,對這些語言是一大優勢。

下面節錄ch9一些有趣的內容:

Lisp

這是一個不簡單的傢伙。Lisp是世界級僅存的古老技術,人們不斷地重新發明或重新發現它,但是Lisp也是一大群家族,許多彼此不相容的設計和實踐,沒有任何一個看起來像是我們的家。當然,Common Lisp需要大修,但是由委員會來重新計計 Common Lisp 在此刻來說相當不恰當。Lisp需要一個仁慈的獨裁者,具有好的偉大的執行力,以及偉大行銷,才可能成功。
p168, by Steve Yegge 

作者另在p172提到 Lisp 的社群總由聰明的programmer組成,校園內也很流行,像MIT就強調用Lisp學習可以讓學生快地抽象思考。也許最後的語言都會回歸 Lisp,但Lisp太與眾不同,需要很多時間和精力學習。

PHP

2005 年最不可思議的一件事之一是,IBM 宣稱要支援 PHP,此舉無疑是針對意圖擁抱 PHP 的中小企業而來。
...
就和 Visual Basic 一樣,隨著開發者在錯誤的地方尋找簡單性,PHP 將會被利用在某些不適合的地方。
p170, by Bruce A.Tate (book author) 

相信許多人深有體會,我懷疑在資工學生裡,課餘寫PHP的機會搞不好比其它語言多,寫PHP是賺外快的最好機會。

Perl

某些 Perl 編程員寧願斷掉手指也不願意多打四個字元,才不管這些字元是否可以提升可讀性,畢竟難寫的程式應該也會難讀。
...
而 Perl 具有相當多火星文般的語法捷徑,簡直是神祕的溝通方式 (secret handshake )
...
說來有趣,但是對照起 Java 則是截然不同,還是別去用 Perl 吧 !
p170, by Bruce A.Tate (book author) 

這裡應該是比較開發大型多人專案的情況,有用過Perl的人都很享受快速用Perl解決瑣碎雜小事吧。

Smalltalk

早在 Java 尚未在 James Gosling (Java之父) 的眼中閃爍時,聰明的開發者就已經使用 Smalltalk建立成功的物件導向應用了。而「不是很聰明」的開發者用 Smalltalk 建立某些有史以來最醜的物件導向程式。
p171, by Bruce A.Tate (book author) 

作者認為Java的成功造成Smalltalk元氣大殺,它們都是良好的OOPL,Smalltalk語法特殊,主流的C++不願嘗試,選擇改良C++的Java則成為贏家。

Functional Language

用Haskell寫費氏數列(Fibonacci series):

fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib(n-2)

Java

我沒說 Java 已死,或著 Ruby 即將接班,或著延續伺服器將會支配一切。我只知道:

  • 我現在很受傷,我的顧客也是。我愈來愈難叫我的顧客要滿意 Java 的一切。
  • ...

p174, by Bruce A.Tate (book author) 

讀了「Beyond Java」後,我覺得我又想學Common Lisp,但之前挑戰多次(包含Scheme在內)失敗,我真不懂為什麼Lisp要用這麼多括號,讀寫都很麻煩,最近會先玩Ruby和Haskell吧,哦,還有Python,別忘了Google內部喜歡用Python寫system management。

2007年1月14日 星期日

超越Java(Beyond Java) - 3 (用code來看)

書藉基本資料:超越Java(Beyond Java)

作者提到Strong Typing、Dynamic Typing的比較,背景知識可以參閱這裡

Static Typing的優點是給compiler許多資訊,可在編譯期抓出錯誤,比執行時發現來得省時,也方便IDE做Code Completion(ex:列出class下的所有method)和Refactoring。缺點是programmer要打一堆冗長的資訊給compiler,這正是Java的情況。Static/Dynamic Typing都可以具有Strong Typing,像本書作者提倡的Ruby,作者認為它是Dynamic Typing and Strong Typing。Dynamic Typing適合快速開發,讓programmer更能專注在抽象思考,把想法轉為程式碼。比方取出陣列裡的每一元素做些事,Java裡常見的笨重程式如下:

ArrayList list = ...; ... for (i=0; i<list.size(); i++0) { MyNumber n = (MyNumber)list.get(i); int x += n.number; ... }

Java 1.5引入了泛型(generic type),可以省掉中間轉型(cast)那行,但使得宣告可讀性降低,並且不能存兩種以上的型別,比方同時存MyNumber和HisNumber。更大的問題是泛型是語言層級的實踐,不是JVM層級的實踐,破壞許多Java固有的優點。

前面提及Static Typing的優點,是否能在Dynamic Typing裡做補救呢?Code Completion和Refactoring目前仍有難度,但編譯期抓出錯誤的影響較小,作者認為Unit Test才是最重要的,目前Test Driven Development的概念已漸漸普及,有良好的Unit Test,測試成本很低,編譯期抓不出錯誤也無妨。

這裡引用修改書上的例子,以寫費氏數列為例,進一步指出Java笨重之處。

Java Version:

class Fib { public static void main(String args[]) { int x1 = 0; int x2 = 1; int total = 1; for (int i=0; i<10; i++) { System.out.println(total); total = x1 + x2; x1 = x2; x2 = total; } } }

Ruby Version:

x1 = 0 x2 = 1 10.times do puts x2 x1, x2 = x2, x1+x2 end

for loop的index variable有時是不必要的,foreach是不錯的替代方案,但有時不夠直接,不恰當的for loop寫起來有點冗,會降底可讀性( ex:for loop的 i 到底用處為何?)。

簡單的例子容易懂,但突顯的現象可能不夠強,冗長的程式碼降低可讀性和撰寫速度,程式碼的字數不是絕對的指標,但不可忽視它和思維之間的關聯,就像數學總是如此精簡。

Java為了安全性、擴充性、可讀性做了許多規範,像是static typing和exception,浪費太多時間在刀口之外,有時沒必要寫exception,乾脆草草了事:

try { ... } catch (Exception e) { e.printStackTrace(); }

相較於C++,Java做得不錯,但要小心這也許是錯誤前提下的最佳解法,是該換個起跑點了。

延伸閱讀:Omega

從大中那看來的,類似Haskell的language,大中寫了篇介紹Omega的文章:”Switch between static and dynamic type checking”,看不懂但看起來很神。

超越Java(Beyond Java) - 2

書藉基本資料:超越Java(Beyond Java)

我的眼界不廣,心得可能有錯,還請大家指正。ch3、4分析Java的成功原因和隱憂,作者一邊寫自己的看法,一邊引用數位資深Java Progarmmer的訪談做為引證,這本書的宣傳手法真的很高明,如果不是名為Beyond Java,很難吸引一堆Java支持者來看,並扭轉他們的看法,了解這世界上還有很多可能。


Java成功的一大原因是和Open Source族群合作良好,Open Source帶來大量使用者和library
,比方IDE eclipse、Ant、Tomcat。做為下世代的語言霸者,作者認為非政治性是語言的必要性,比方Ruby,反之C#具政治性,會阻礙和Open Source族群的合作。不過就算Java淡出市場,JVM仍會存活許久,JVM已建立良好平台和大量library,適合其它語言使用。

”簡單就是美”、”多個解決方法裡,最簡單的最好”,如果我們相信這樣的原則,那漸漸變笨重的Java,看來不適合開發application / web application,雖然以一個承接C++的角色來說,Java已盡善盡美了,Java確實展現許多優點,但錯誤 前提/架構 下的最佳解法沒有意義。例如Design Pattern,繼Paul Graham後,第二次看到書裡質疑Design Pattern的正確性,這可能是語言本身的缺陷,而使programmer要在實作層面用特定技巧彌補,增加維護的複雜度。我滿喜歡Design Pattern的思維,但一直覺得很難上手,進而懷疑學Design Pattern的方向是否有誤,問題可能在更根本的地方。

Java是很好學的語言,但要用Java真的做番事,要用許多framework和工具,但每個東西的熟悉時間都是以年為單位,我喜歡寫Java,但一直都很排斥學如J2EE、Structs這類framework,天知道真的投入開發時,這些東西是否還是最佳選擇,學習的代價太高了。兩年前還不少補習班廣告三個月十萬元學J2EE,現在卻愈來愈多人質疑它的必要性。

下篇引用一些書上的實例,說明Java language本身的不足。

2007年1月12日 星期五

談JVM跨平台,卻不談scripting language跨平台的原因

這篇的看法可能有錯,參照大三上計算機組織報告JVM的心得,重寫這篇說明,但我這方面的知識卻是不進反退 XD 。當時鍾伯伯聽完報告後,說內容有些錯誤,但沒說錯在那,我就繼續不求甚解下去啦。

點此下載報告用的slide

談到跨平台時,不知道為何大家只提JVM,卻不談scripting language也跨平台,也許是scripting language跨平台是天經地義的事吧。深入一點來分析,JVM有別於scripting language的差異為:

  • Java要用compiler轉成bytecode,再用Virtual Machine讀bytecode,而不是直接用Interpreter讀source code,少了parsing syntax的時間,效率較好。但這點在scripting language引入compiler後,不構成主要差異
  • 除了VM外,沒有廣大的library,無法流行起來,但廣大的library要都能跨平台,要下許多苦工,Java的做法是建立強大的圍牆,全部自己來,讓OS相依的功能減到最小。這種土法練剛的精神,不是想做就辦得到的。
  • bytecode是真正的instruction set,理論上可以依此做出CPU,用硬體直接執行;實際上也有這樣的CPU,只是一直沒成主流。要做到可支援硬體實作,不是隨便訂訂compiler的輸出就好,有別於單純地定義compiler的輸入輸出。
  • instruction set最主要的差異在於JVM是stack architecture,它沒有register file,因此不被單一register size和register數量所限制,效率有所犠牲,彈性卻大幅提升
  • Just-in-Time(JIT)的編譯技巧,提高JVM執行效率(正確來說,是減少效率的損失)

超越Java(Beyond Java)

書藉基本資料:超越Java(Beyond Java)

目前看到ch2,但是好書就是能讓讀者的靈感源源不絕,不用等到看完再寫想法。前面清楚的說明多學語言的好處,不同場合各有適合的語言,C/C++位在system level,拿來寫application不太恰當,很多時候我們並不在意記憶體用得有無效率,也許開發到極致時會,但用C/C++可能寫不到那個時刻就因過於複雜而結束開發。

粗略的分為system level、application、web application來看,Java適當的扮演一個有別於C/C++,又頗接近它們的好角色,libaray和framework日漸增長,各大廠持續推行,不愁找不到人材。但這些架構太複雜而不適合寫中小規模的application/web application,培訓人才學會寫Java不難,但對framework上手卻是曠日費時。用過scripting language的人可以體會快速開發的喜悅,熱門的Perl/Python/Ruby各有千秋,而《超越Java》是作者自身團隊用Java開發web application,並參用Ruby on Rail開發得來的心得,名為超越Java,介紹Ruby的意味深些。

受限於語言天生的能力,framework再怎麼強化,也會有限度,就像技巧高超的programmer可以用C寫出很OO的程式,但那只是費力成效又差的工作,也許是時候考慮看看不同語言,現在投入Ruby的時機正好,既不會太早而缺乏資源,也不會太晚而失去競爭優勢。別忘了Paul Graham所言,好的語言具有數十倍以上的競爭優勢,對他1995開創的網路公司來說,LISP就是祕密武器。

現今的application/web application,需要的是更高階、更彈性的語言,這正是PHP興起的主因,只是PHP有點髒,沒太大興趣學好PHP。作者相信Java仍是目前的霸者,但五年後就很難說,至少就我們的認知來說,Java對於更高階的開發需求,可能和C/C++對於system level以上的開發需求一樣地不適宜。Java的strong typing和許多保護措施使我相信用它來組合大程式,會愈組愈順,而不像在不穩的地基上蓋歪斜的高塔。雖然有不少實證表示Perl/Python/Ruby也能開發大型專案,但在試用寫較具規模的程式前,還是先保留看法。

相關閱讀: