Node.j和Java的史詩級對決,誰纔是開發者的“真愛”?

本文最初發佈於Peter Wayner博客,經原作者授權由InfoQ中文站翻譯並分享。

在計算歷史上,1995年是一段瘋狂的歲月。首先Java出現了,隨後JavaScript也出現了。Java和JavaScript的名字看起來像是一對雙胞胎,但實際上它們差別巨大,Java是被編寫和靜態定型的,而JavaScript則是被解釋和動態定型的。但這僅僅是這兩個完全不同的語言的技術差別的一個開始,Node.js的出現使得兩種語言經歷了兩條完全不同的發展軌跡。

如果你比較早的接觸了IT技術,那麼你或許記得Java曾經風靡一時,每個人都將其視爲一項革命,認爲它將完全替代計算。但事實證明,這一預測只有一部分是正確的,Java統治了安卓手機、企業計算和一些嵌入式設備,如藍光光碟。但它從來沒有統治過桌面或瀏覽器。人們曾嘗試出售過小應用程序和Java工具的強大,但是表現平平。

同時,之前被程序員們錯認爲是Java“雙胞胎”的JavaScript,如今也能獨當一面了。在HTML和web推出Borg的幾年間,JavaScript一直緊隨其後,AJAX的出現使得JavaScript突然之間擁有了力量,打破了之前的局面。

隨後Node.js誕生了,大大提高了開發速度。JavaScript不僅在服務器上比大多數人預期的要快,甚至與Java或者其它工具相比,速度也要快。JavaScript能夠更加穩定地處理小的、快速的和無休止的數據請求,因此,當網頁變得更加動態時,Node.js就變得更加常用了。

雖然這在20年前可能是無法想象的,但是現在Java和JavaScript正在爭奪編程領域的“統治權”,它們一個強調以堅固的工程和架構爲深層基礎,另一個強調簡潔和普遍性。到底是老式的編譯器驅動的Java會立於不敗之地,還是在Node.js幫助下的JavaScript將所向披靡呢?

Java獲勝之處:堅如磐石的基礎

看到這個小標題,可能有些開發者會有質疑。當然,我們不否認Java還存在一些小Bug,但是相對而言,Java已經算是很“堅固”的了,Node.js想要讓我擁有這樣的信心,還需要許多年。

事實上,要寫出與Sun/Oracle在測試Java虛擬機時所寫數量相同的迴歸測試,JavaScript開發者或許要花上幾十年。當你啓動JVM時,你將獲得來自一個質量可靠的管理者的20年經驗,而這個管理者一直決心要統治企業服務器領域。

不過,JavaScript也在迅速迎頭趕上。當Web的大部分依賴於JavaScript執行引擎時,開發者的時間大部分花在了打磨邊邊角角上面。然而,所有的創新都有一個缺點,那就是新的功能可能擴散太快,以至於開發者們來不及吸收這些功能。一些老派的開發者經常會對充斥着最新ECMAScript句法的增強特性感到困惑。另外,這些新代碼可能還會導致某些舊版瀏覽器崩潰。

創新性的預處理器,如CoffeeScript和JSX等,源源不斷地出現,對於需要這些功能的開發者來說是件好事,但是對於不需要的開發者來說增加了難度。

儘管Java也在不斷推出新的功能和選項,但總體而言,它是一個穩定的平臺,它給那些需要開發更長久的東西的開發者帶來了便利。

Node.js獲勝之處:普遍性

多虧了Node.js,JavaScript在服務器以及瀏覽器領域找到了一席之地。你給服務器寫的代碼很可能在瀏覽器上也能運行。很明顯,比起在Java和JavaScript中分別寫代碼,直接使用JavaScript更簡單。

如果你決定要把Java中的服務器業務邏輯遷移到瀏覽器中,或者老闆執意要你把給瀏覽器寫的邏輯遷移到服務器上。在這兩種情況下,Node.js和JavaScript都能讓代碼遷移變得更簡單。

不僅如此,Node.js的領導地位似乎還在擴大,例如比較複雜的Web框架,類似React,是要把代碼運行在服務器還是客戶端上呢?另外,還有可能出現這種情況,代碼前一天是運行在客戶端上的,但是後一天可能就運行在服務器上。某些智能的邏輯將在運行時根據負載、閒置RAM容量和其它因素來決定究竟代碼運行在什麼上面。有些框架會把JavaScript作爲一條查詢,輸入到數據庫,並在那裏執行。你的代碼可能在任何地方運行,所以,你很難了解究竟是在什麼地方,因爲代碼根本不會返回任何東西。但是也無需擔心,因爲你不需要考慮太多細節。

Java獲勝之處:更好的集成開發環境(IDE)

Java開發者擁有三大IDE,Eclipse、NetBeans和IntelliJ,這三個IDE是與調試程序、反編譯器和服務器良好地集成的頂尖工具。每個工具都經過了數年的開發,擁有忠實的用戶、堅固的生態系統和數不盡的插件。

大多數Node.js開發者會將文字輸入命令行,再編碼到他們最喜愛的文本編輯器中。誠然,市面上最好的一些文本編輯器,像Atom,都擁有琳琅滿目且幾乎無所不能的插件,但如果和Eclipse進行比較,Node.js給人的感覺要更老式一些。在不久的將來,Atari操縱桿將代替我們的鼠標。

另外,有些Node.js開發者會使用Eclipse 或Visual Studio。開發者對Node.js突然激增的興趣可能會有新工具誕生,例如IBM的 Node-RED 給我們提供了一些極具吸引力的方法,但是這些工具還遠未達到像Eclipse或IntelliJ那樣的完整度和統治地位。

但奇怪的是,開發者好像並沒有使用這些工具。命令行本該在35年前Mac到來時就消失,但卻沒人把這個消息告訴Node.js的開發者們。但是選擇一直都在那裏。例如,WebStorm就是一個可靠的由JetBrains開發的商業化工具,它集成了許多命令行構建工具。

當然,如果你正在尋找一款能夠編輯和調整代碼的集成開發環境,那麼現在支持Node.js的新工具已經足夠使用了。但如果你希望集成開發環境能夠讓你一邊操作正在運行的源代碼,一邊編輯代碼,那麼Java的工具顯然會更強大一些。

Node.js獲勝之處:數據庫查詢

一些較新的數據庫,如CouchDB和MongoDB的查詢是由JavaScript編寫的。將Node.js和數據庫調用合併不需要任何換擋,也不需要記住任何句法差異。

而許多Java開發者都在使用SQL。即使是在他們使用Java DB——前身是Derby (一種由Java編寫的數據庫)時,他們的查詢也是用SQL寫的。你可能會以爲他們會簡單地調用Java方法,但其實沒有,開發者必須要用SQL寫數據庫代碼,然後再用Derby解析SQL。 雖然SQL是很好的語言,但是它與Java完全不同,許多開發團隊需要有不同的人來分別寫SQL和Java。

更糟糕的是,許多Java程序員使用複雜的庫和模式來將SQL查詢數據轉換成Java對象,目的是讓自己能夠將這些東西重新導入到模板中。這個過程非常瘋狂,而且非常浪費。

Java獲勝之處:類型

許多入門級的編程課程都使用Java,因爲許多程序員都喜歡靜態類型編碼,靜態類型編碼很簡潔而且安全。在編譯器找出了一些明顯的bug後,代碼看起來更加嚴謹了。

不過,JavaScript也在追趕,一些開發者已經轉到TypeScript。TypeScript是一個靜態類型的JavaScript超集,首先會應用所有的類型檢查手段,然後剔除掉運行在瀏覽器上的JavaScript堆棧中的一些東西。

對於喜歡類型的開發者來說,TypeScript足以讓你喜歡上JavaScript。當然,你可以把JavaScript這種模仿視爲是對Java最真誠的恭維,並且繼續使用Java,因爲Java從一開始就是使用靜態類型的。

Node.js獲勝之處:語法靈活性

JavaScript曾經是一個簡單的語言,用於彈出警示框和雙重檢查輸入表。後來,開發者社區創造了JavaScript的許多不同版本,它們能夠被轉編譯爲瀏覽器可用的東西。例如,CoffeeScript提供了一些不同的句法,旨在使標點符號更加清晰。React/Vue羣體將HTML和JavaScript混合。此外,還有針對類型愛好者的TypeScript和針對功能語言信徒的LiveScript。

而在Java中,你會發現有很多創新,但這些創新由於某些原因,並未用預處理器進行表達。還有一些語言如Kotlin、Scala和Clojure,爲了JVM專門變成了字節代碼,但不知爲何,它們可以說是完全獨立的語言。對於喜歡嘗試不同的代碼編寫方式或標點符號的JavaScript程序員來說,所有的預處理器均使他們的生活變得更加有趣了。

Java獲勝之處:簡單的構建流程

複雜的構建工具如Ant和Maven使Java編程發生了革命。但還是有一個問題,開發者需要將說明用XML寫出來,而XML並不是一個支持編程邏輯的數據格式。

當然,使用嵌套標籤來表達分支相對而言比較簡單,但是僅僅是爲了構建,就要從Java切換到XML,有些令人討厭。有了JavaScript後,你就不需要再切換。

之前,Node.js的構建很簡單,只需要編輯代碼,點擊“運行”就可以了。但是隨着Node.js開發者不斷改進流程,添加了一些預處理器來抓取你最喜歡的JavaScript方言,並將這種方言轉換成可以運行的東西。然後,Node包管理器需要找到正確的庫,因爲有時可能會找不到,所以需要花時間尋找某個工件正確的版本號,而這個工件必須在單獨的步驟中自行構建。而且,如果你在工件庫中引入了一些錯誤,那麼,這個版本號便無效了,需要重新做。

Java也有與Node.js方法類似的複雜的構建過程,但給人的感覺不會比Node.js更復雜,從某種意義上說,Maven和Ant貌似已經成爲了Java基礎的一部分,許多粗糙的邊角已經被去除了,因此構建的工作成功率更高了。

如果非要對它們的構建難度進行衡量的話,它們可能不分伯仲,但如果從JavaScript快速增加的複雜度的角度來看,Java在這方面獲勝了。

Node.js獲勝之處:JSON

當數據庫給出答案時,Java需要花費大量時間把結果變成Java對象。開發者會就POJO映射、Hibernate和其它工具爭辯上好幾個小時。配置這些東西耗費數小時甚至數天時間。最終,在所有的轉換之後,Java代碼獲得了Java對象。而來到配置階段時,Java使用的仍然是XML,並且提供了2個主要的解析器,這給開發者帶來了更多的煩惱。

如今,許多Web服務和數據庫都以JSON的形式返回數據,JSON是JavaScript天然的一部分。JSON現在非常常見和有用,以至於許多Java開發者都在使用這種格式,而且還有一些非常好的JSON解析器可以作爲Java庫被使用。相比之下,JSON本身就是JavaScript基礎的一部分,不需要庫,直接使用就可以了。

Java獲勝之處:遠程調試

Java擁有許多非常棒的監控機器集羣的工具。JVM有深層的鉤子和精細的剖析工具來幫助我們識別瓶頸和故障。Java企業堆棧上運行着全世界最複雜的服務器,而使用這些服務器的公司對遙測的要求非常之高,所有這些監控和調試工具都較爲成熟,並且可以立即部署它們。

Node.js獲勝之處:桌面

也許有人在使用Java小程序,但我仍然保留了一些可以點擊運行的Java JAR文件。總體來說,桌面領域大體上是不用Java的。另一方面,隨着瀏覽器取代了桌面的大部分角色,JavaScript的作用也越來越大。當微軟重寫了Office並使其能夠在瀏覽器上運行時,一切就註定了。如果你還想了解更多,那麼市面上還有許多有趣的選擇,比如Electron,它能夠抓取你的Web代碼,然後轉換成獨立的桌面app。

Java獲勝之處:手持設備

安卓app大多都是用Java寫的,而且90%的新手機都運行着各種版本的安卓系統。很多人根本就不使用桌面了,因爲手機已經可以做任何事情了。

許多開發者都在編寫Node.js Web應用,這些應用主要用在iPhone和安卓手機上的移動瀏覽器上。如果這些應用寫得比較好,性能通常會比較好。但Java正以另外的一種方式入侵。最新的Chromebook將支持安卓應用,從而給Java開發者進入Chromebook用戶的桌面開闢了道路。那麼Java是否仍有機會征服桌面呢?

Node.js獲勝之處:庫

Java提供了大量的庫,而且這些庫做得都非常好,文本索引工具如Lucene和計算機視覺工具包如OpenCV都是非常好的開源項目,它們都將成爲其它重大項目的基石。JavaScript程序員也在追趕,創造出了很多了不起的項目。

在某些領域,Java就是一個遠程的存儲器,市場上可能有無數不同的Web框架,所以Java不能在這個新興市場中參與競爭。

Java獲勝之處:堅固的工程

雖然這點很難量化,但是因爲Java的數據基礎非常強大,許多重大的科學工作中使用的許多複雜的程序包均是用Java寫的。Sun公司花了大量的時間來獲取工具類的詳情。市場上有BigIntegers、精巧的IO例程和複雜的日期代碼,它們均實現了格里高裏和羅馬儒略日曆。

JavaScript適合簡單的任務,但是其內部有很多令人混淆的地方。舉一個簡單的例子,JavaScript針對沒有答案的函數會生成三種不同的答案,分別是:undefined、NaN和null。那麼,哪一個是正確的呢?其實每個答案都有各自的作用,其中一個便是驅使程序員保持代碼統一。JavaScript更怪異的方面是雖然它在簡單的表格工作很少出問題,但對於複雜的數學和定型工作而言,JavaScript並不是一個好選擇。

Node.js獲勝之處:速度

Node.js的速度一直很受開發者的歡迎,數據輸入和答案輸出的速度如同閃電。Node.js不需要單獨設置線程,也沒有上鎖等令人頭疼的問題,也沒有拖慢速度的額外開銷,只需要寫一些簡單的代碼,Node.js就會快速地採取正確的步驟。

Node.js的回調模型已經改變了其編程方式,使程序員避免同時操作多個任務。JavaScript引擎能夠確定何時運行什麼代碼。因此,程序員可以編寫更短和事件驅動的代碼,並且關注重要的邏輯。

但是Node.js也存在一些問題,Node.js代碼要儘可能的簡單一點且工作正常,因爲如果它鎖死了,整個服務器都可能鎖死。操作系統開發者努力創建了許多安全網來抵抗編程錯誤,但Node.js會讓這些安全網失效。

此外,當程序員將回調函數如俄羅斯套娃一層又一層不斷地嵌套時,還會出現一個代碼複雜性的問題。一個回調還好,但一系列的回調令人抓狂,好消息是Promise模型很容易讀。但你需要記住,在執行代碼行期間,許多事情都可能發生。

Java獲勝之處:線程

代碼速度快雖然好,但更重要的是代碼要準確,而使用Java可以享受到一些額外功能:

Java的Web服務器是多線程的。創建多個線程可能要花費時間和存儲,但這是值得的。因爲,如果一個線程鎖死了,其它的還可以繼續用。如果一個線程需要很久的計算時間,那麼其它線程可以分擔。更重要的是,代碼一直在掌管之下,並且能夠進行調整。

如果某一個Node.js請求運行速度過慢,其它請求的速度也會降下來。Node.js只有1個線程,因此只有它準備好了,事件才能被處理。或許它看起來超級快,但是本質上它的架構就如同春節的時候,郵局只開一個辦理窗口一樣,即它不能同時處理多個請求。

人們花了幾十年構建智能的操作系統,能夠同時處理許多不同進程的操作系統。那爲什麼還要回到那個電腦只能處理單線程的年代呢?的確,處理多個線程意味着要做更多的工作,但是多線程更強大,不是嗎?

Node.js獲勝之處:勢頭

看見硅谷的開發者總是積極獻身於最新和最具顛覆性的東西,但有時清理掉遺毒也很重要。Java有新的IO例程,但是它也有一些舊的代碼,例如許多小程序和util類會阻擋你前進的道路。Node.js在Git庫中也留下了很多垃圾,但是由於Node.js出現的比Java晚幾十年,且Node.js開發者還在研發許多針對Web堆棧軟件的增強功能,所以,Node.js動力十足。

兩方不分伯仲之處:Java和Node.js之間的交叉編譯

服務器到底是用Java還是Node.js的辯論可能還會持續很多年,但與其它辯論不同的是,這場辯論可能會是雙贏的局面。Java可以交叉編譯到JavaScript中去,谷歌就經常在Google Web Toolkit中這麼做,而且谷歌最受歡迎的網站也運行着Java代碼,這些代碼就是從Java翻譯爲JavaScript的。

當然,反過來也是如此。JavaScript引擎如RhinoNashorn同樣在Java應用裏面運行JavaScript,然後你可以鏈接到這些應用。如果還不滿足的話,你還可以鏈接到谷歌的V8引擎
所有的Java和JavaScript代碼都可以和諧地彼此鏈接,因此,你不需要在兩者之間選擇。

作者簡介:
Peter Wayner 是InfoWorld 的特約編輯,並且是16本涉及不同主題的書的作者,包括《開源軟件(統統免費)》,《自動化汽車(未來出行)》,《隱私增強計算(透明數據庫)》,《數字交易(數字現金)》,《和隱寫術(密碼學的消失)》。他的書定期發佈在InfoWorld 上,並且他還爲許多大小型軟件項目提供諮詢。他關於機器人汽車的《未來出行》這本書的第二版已經出版。
查看英文原文:Node.js vs. Java: An epic battle for developer mindshare

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章