速讀原著-Java 20 年:歷史與未來
- 2020 年 2 月 14 日
- 筆記
Java 20 年:歷史與未來
作為最受歡迎的程式語言之一,Java 已經走過了 20 個年頭。從已經落寞的諾基亞到現在火熱的電商系統,我們都能看到 Java 語言的身影。從 1995 年的第一個版本到現在的 Java 1.8,我們甚至能從Java 的版本迭代中看到不同時代程式語言關注的重點。經過了過去 20 年的發展,Java 已經成為如今使用最為廣泛的企業級語言。為了慶祝 Java 的第 20 個生日,InfoQ 為此採訪了 Java 技術專家彭晨陽(網路 ID:板橋)。
InfoQ:您是哪一年開始接觸 Java 的?還記得當時『世界』是怎麼看這門語言的嗎?
板橋:我大概是 2000 年之前開始接觸 Java,當時大家都認為 Java 慢,幾乎沒有幾個人看 得上眼,那時使用Perl/C 實現CGI 比較快,PHP 很方便。
InfoQ:能回憶下你的職業生涯中與 Java 相關的經歷嗎?
板橋:2000 年之前使用 Perl 開發過一個類似西祠、西陸社區網站,隨著功能日益複雜, 維護拓展比較麻煩,打算使用 Java 改造升級。但是 Java 比較複雜,當時有 EJB 等規範, 因此誤用過 EJB 來做產品,其實 EJB 更適合做企業中可靠性要求比較高的項目。而對於社區項目來說,性能是關鍵,這個道理後來我從 CAP 定理中才得到答案,當然當時也沒有聽說過 CAP 理論,這段教訓是相當深刻的,EJB 很難掌握,運行起來更慢,最後也以失敗告終。 之後研究學習了 Jive 開源 Java 論壇,對其設計模式與快取兩個優點進行了綜合學習與應用。有一段時間參與過手機遊戲的開發,那時客戶端是 J2ME,但是遊戲邏輯不載入在客戶端,而是將客戶端只作為介面展現,類似今天的瀏覽器+Angular.js 這樣富客戶端。當然,這個系統對網路要求比較高,但是當時無線網路 3G 還沒有推出,後來放棄了,從該項目中我意識到高性能的大型並發系統使用 Tomcat 這樣的普通 Web 伺服器已經無法承擔,於是對非同步消息JMS 等技術產生了興趣。 之後,陸陸續續參與過一些項目的諮詢和設計,大部分都比較普通,無非是 CRUD 增刪改查。於是萌生了做一個快速開發框架,在不丟失多層架構的基礎上能有Delphi等二層架構的開發效率,這大概是JDON 框架的原型。當然,該框架後來從快速開發為首要目標轉移到靈活性為首要目標。 做了不少項目後,需要尋求理論指導,原來的資料庫+Java 路數已經不能包打天下,後來逐步開始引入 DDD 領域驅動設計 CQRS 和EventSourcing。
InfoQ:很多人都在唱衰 Java,您能結合 Java 的發展現狀和趨勢談談 Java 的前景嗎?
板橋:Java 發展到今天已經 20 年了,作為一個程式語言確實不簡單,想當初人人受懷疑 的慢語言到今天通用的健壯語言,真是大智若愚啊。Java 代表的面向對象思想確實給工程領域帶來了革命性的變化,當然思想是不斷進化發展的,如今人們開始看好函數式編程語(FP)。儘管 Java 8 也加入了函數語言的特點,但是 OOP 和 FP 兩者到底是不同的編程範式,不過掌握 FP 有一定門檻,這也是造成很多人觀望的一個原因。 Java 在數據流處理方面還是很有競爭力的,而大數據實時流處理系統是Java 的新領域,在這個領域有Apache Kafka、Apache Samza、Apache Storm、Apache Spark 的 Streaming 模組和最新的Apache Flink。Spark 是基於 JVM 的函數語言 Scala 編寫,其餘都是Java 編寫。
InfoQ:JVM 的普及促使相關周邊語言不斷湧現,你怎麼看這些 JVM 語言?
板橋:以Scala為代表的JVM語言發展迅速,Scala語言特性是首先區分不變性和可變性, 當初使用EJB 時首先要區分是無狀態和有狀態,這說明思路是一脈相承的。可變性的狀態是造成副作用和各種Bug 的罪魁禍首,可能我們如果只是把可變狀態使用資料庫實現時沒有注意到這種問題。其實這個問題遍布在應用的每個角落,特別是使用類和對象這個OOP 概念實現時最容易發生。一個類或對象包括欄位和方法,如果這個欄位值是可變的 (可變狀態),我們使用這個對象時如果不打開它的類程式碼是無法得知它有可變狀態的,那麼就會導致各種副作用發生。 而函數編程由於函數方法是第一公民,沒有什麼東西擋在它的前面,沒有類或對象包裹著它們,因此,它們無法私藏可變狀態欄位,能夠確保應用系統每行程式碼都是基於不可變的基礎之上。 如果說 Scala 之類 JVM 的函數語言適合不斷添加功能函數的應用場景,那麼 Java 之類的 OOP 語言適合不斷增加實體物體的應用場景。前者好動,後者好靜。
InfoQ:Java 是如何擁抱雲時代的?
板橋:Java 在雲時代面臨以 Go 語言為主的容器(Docker 等技術)生態圈的挑戰。其實 JVM 也是一種容器,但是這種容器特性正在被 Linux 學習與趕超,那麼,JVM 的定位就可能比較尷尬。 Docker 之類容器可以在本地筆記型電腦或電腦上運行,然後同樣可以部署到雲上運行。當在雲上運行時,Kubernetes 能夠以一種可控的方式升級容器從而實現運行管理一批容器,如同一個大型船隊或艦隊一樣,你可以控制它們的流量訪問量,可以指定多少個容器來擴展支撐一個服務的運行,隨著訪問量提升,你通過增加容器數量能夠整個系統的負載能力。 當然,Java 的大型分散式系統越來越多,Java 在雲計算與分散式系統中還是扮演主要角色,形成一個大型的生態圈。當我們站在泰山之上,一覽眾山小,當你在全球擁有多個數據中心時,語言已經變得不那麼重要了,關鍵是架構設計。
InfoQ:Go 語言這兩年比較火熱,你怎麼看這門語言?與 Java 相比,他有哪些優劣?
板橋:Go 語言相對 Java 主要優點是其並發組件模型,Java 的並發比較低級,無非是多線 程與鎖,想搞清楚 Java 中各種鎖的用途,包括數據集合 Collection 的執行緒安全性與性能差異對比,需要花費大量時間與精力,包括使用經驗。而 Go 語言使用了 Channel/CEP 這樣的組件簡單封裝了多執行緒與鎖,將以前 JMS 的 Queue 隊列模型架構引入到了語言之中,兩個對象之間交互只要通過 Channel 通道就可以。這種模型保證了並發性,有簡化了編程模型,無疑受到很多人的歡迎。 Go 語言當前也受到更加強勁的 Rust 語言挑戰,如果說,Go 語言的 Channel 是一種有形的設計,那麼,Rust 語言的並發模型達到無形的設計,只要你編寫好函數方法,安全性與並發性就無形中得到了解決,不用專門去思考並發,有意識地去使用並發組件模型編程。
InfoQ:現在的開發語言特別多,Java、Go、PHP、Rust、Python 等,你認為未來語言的發展趨勢是怎麼樣的?
板橋:現在的開發語言如雨後春筍,主要原因是 CPU 進入多核並發時代,以及大型架構 進入分散式系統,如何使用一種語言從微觀的 CPU 多核之間並發到數萬台伺服器之間的分散式計算處理,這種大一統的願景促使人們在不斷探索。 在 Java 中,我們可以通過框架來實現這點,以我前幾年研發 Jdon 框架為例,雖然能夠勉強實現並發與分散式,但是這種實現需要很強的知識背景,不利於初學者上手。而要達到普及這個目標,必須從語言入手,讓語言初學者在學習掌握語言以後,無形中就會實現了並發與分散式。 Go 語言在這方面比較突出,其並發模型以讀寫操作為基礎。請注意,Java 等語言並發模型沒有這麼高,它們是以執行緒為基礎,再應用到讀寫場景中,而我們現實中必須以讀寫為基礎,再應用到具體業務場景中,這裡面高低層次:執行緒–>讀寫操作–>業務應用,無疑越靠近業務應用的語言越能簡化我們的開發,而分散式系統也是基於讀寫操作,著名的 CAP 定理也隱含了以讀寫操作為基礎的語境。
