日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

从Sun离职后,我“抛弃”了Java,拥抱JavaScript和Node

發布時間:2023/12/10 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从Sun离职后,我“抛弃”了Java,拥抱JavaScript和Node 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我是前Sun公司Java SE團隊的一名成員,在工作了10多年之后——2009年1月——也就是在甲骨文收購Sun公司之前,我離開了公司,然后迷上了Node.js.

我對Node.js的癡迷到了怎樣的程度?自2010年以來,我撰寫了大量有關Node.js編程的文章,出版了四本與Node.js開發有關的書籍,以及與Node.js編程有關的其他書籍和眾多教程。

在Sun公司工作期間,我相信Java就是一切。我在JavaONE上發表演講,共同開發了java.awt.Robot類,組織Mustang回歸競賽(Java 1.6版本的漏洞發現競賽),協助推出了“Java發行許可”,這在后來的OpenJDK項目啟動過程中起到了一定的作用。我在java.net(這個網站現已解散)上每周寫一到兩篇博文,討論Java生態系統中所發生的主要事件,并堅持了6年。這些博文的主要主題是關于“保衛”Java,因為總有人在預言Java的“死期”。

在這篇文章中,我將會解釋我這個Java死忠是如何變成一個Node.js和JavaScript死忠的。

但其實我并沒有完全脫離Java。在過去的三年中,我編寫了大量Java/Spring/Hibernate代碼。但兩年的Spring編碼經歷讓我明白了一個道理:隱藏復雜性并不會帶來簡單性,它只會產生更多的復雜性。

Java已成為一種負擔,Node.js編程卻充滿了樂趣

有些工具是設計師花費數年磨礪和精煉的結果。他們嘗試不同的想法,去掉不必要的屬性,最終得到一個只帶有恰到好處屬性的工具。這些工具的簡潔性甚至達到讓人感到驚艷的程度,但Java顯然不屬于這一類。

Spring是一個非常流行的用于開發Java Web應用程序的框架。Spring(特別是Spring Boot)的核心目的是成為一個易于使用的預配置的Java EE棧。Spring程序員不需要直接接觸Servlet、數據持久化、應用程序服務器就可以獲得一個完整的系統。Spring框架負責處理所有這些細節,你只需要把精力放在業務編碼上。例如,JPA Repository類為“findUserByFirstName”方法合成數據庫查詢——你不需要編寫任何查詢代碼,只需按照特定方式給方法命名,并添加到Repository中即可,Spring將負責處理其余的部分。

這原本是一個偉大的故事,一種很好的體驗,但其實并不然。

當你遇到Hibernate的PersistentObjectException時,你知道是哪里出了問題嗎?你可能花了幾天時間才找到問題所在,導致這個異常的原因是發給REST端點的JSON消息里帶有ID字段。Hibernate想要自己控制ID值,所以拋出了這個令人感到困惑的異常。看,這就是過度簡化所帶來的惡果。除了這個,還有其他成千上萬個同樣令人感到困惑的異常。在Spring棧中,一個子系統套著另一個子系統,它們坐等你犯錯,然后再拋出應用程序崩潰異常來懲罰你。

然后,你會看到滿屏的堆棧跟蹤信息,里面滿是這樣那樣的抽象方法。面對這種級別的抽象,顯然需要更多的邏輯才能找到你想要的內容。如此多的堆棧跟蹤信息不一定是不好的,但它也是在提醒我們:這在內存和性能方面的開銷究竟有多大?

而零代碼的“findUserByFirstName”方法又是如何被執行的?Spring框架必須解析方法名稱,猜測程序員的意圖,構造類似抽象語法樹的東西,生成一些SQL語句……那么完成這個過程需要多少開銷?

在反反復復經歷這樣的過程之后,在花了大量時間學習你本不該學習的東西之后,你可能會得出相同的結論:隱藏復雜性并不會帶來簡單性,它只會產生更多的復雜性。

另一面是Node.js

Spring和Java EE非常復雜,而Node.js卻是一股清流。首先是Ryan Dahl在核心Node.js平臺上所應用的設計美學。他追求別樣的東西,花了數年時間磨練和改進了一系列核心的Node.js設計理想,最終得到一個輕量級的單線程系統。它巧妙地利用了JavaScript匿名函數進行異步回調,成為一個實現了異步機制的運行時庫。

然后是JavaScript語言本身。JavaScript程序員似乎更喜歡無樣板的代碼,這樣他們的意圖才能發揮作用。

我們可以通過實現監聽器的例子來說明Java和JavaScript之間的差別。在Java中,監聽器需要實現抽象接口,還需要指定很多啰七八嗦的細節。程序員的意圖的這些繁瑣的樣板中漸漸淹沒。

而在JavaScript中,可以使用最簡單的匿名函數——閉包。你不需要實現什么抽象接口,只需要編寫所需的代碼,沒有多余的樣板。

大多數編程語言都試圖掩蓋程序員的意圖,這讓理解代碼變得更加困難。

但在Node.js中有一點需要注意:回調地獄。

沒有完美的解決方案

在JavaScript中,我們一直難以解決兩個與異步相關的問題。一個是Node.js中被稱為“回調地獄”的東西。我們很容易就掉入深層嵌套回調函數的陷阱,每個嵌套都會使代碼復雜化,讓錯誤和結果的處理變得更加困難。但JavaScript語言并沒有為程序員提供正確表達異步執行的方式。

于是,出現了一些第三方庫,它們承諾可以簡化異步執行。這是另一個通過隱藏復雜性帶來更多復雜性的例子。

const async = require('async'); const fs = require('fs'); const cat = function(filez, fini) {async.eachSeries(filez, function(filenm, next) {fs.readFile(filenm, 'utf8', function(err, data) {if (err) return next(err);process.stdout.write(data, 'utf8', function(err) {if (err) next(err);else next();});});},function(err) {if (err) fini(err);else fini();}); }; cat(process.argv.slice(2), function(err) {if (err) console.error(err.stack); });

這是個模仿Unix cat命令的例子。async庫非常適合用于簡化異步執行順序,但同時也引入了一堆模板代碼,從而模糊了程序員的意圖。

這里實際上包含了一個循環,只是沒有使用循環語句和自然的循環結構。此外,錯誤和結果的處理邏輯被放在了回調函數內。在Node.js采用ES 2015和ES 2016之前,我們只能做到這些。

Node.js 10.x中,等價的代碼是這樣的:

const fs = require('fs').promises; async function cat(filenmz) {for (var filenm of filenmz) {let data = await fs.readFile(filenm, 'utf8');await new Promise((resolve, reject) => {process.stdout.write(data, 'utf8', (err) => {if (err) reject(err);else resolve();});});} } cat(process.argv.slice(2)).catch(err => { console.error(err.stack); });

這段代碼使用async/await函數重寫了之前的邏輯。雖然異步邏輯是一樣的,但這次使用了普通的循環結構。錯誤和結果的處理也顯得很自然。這樣的代碼更容易閱讀,也更容易編碼,程序員的意圖也更容易被理解。

唯一的瑕疵是process.stdout.write沒有提供Promise接口,因此用在異步函數中時需要丟Promise進行包裝。

回調地獄問題并不是通過隱藏復雜性才得以解決的。相反,是語言和范式的演變解決了這個問題。通過使用async函數,我們的代碼變得更加美觀。

通過明確定義的類型和接口提升清晰度

當我還是Java的死忠時,我堅信嚴格的類型檢查對開發大型的應用程序來說是有百利而無一害的。那個時候,微服務的概念還沒有出現,也沒有Docker,人們開發的都是單體應用。因為Java具有嚴格的類型檢查,所以Java編譯器可以幫你避免很多錯誤——也就是說可以防止你編譯錯誤的代碼。

相比之下,JavaScript的類型是松散。程序員不確定他們收到的對象是什么類型,那么程序員怎么知道該怎么處理這個對象?

但是,Java的嚴格類型檢查同樣導致了大量樣板代碼。程序員經常需要進行類型轉換,或以其他方式確保一切都準確無誤。程序員需要花很時間確保類型是準確的,所以使用更多的樣板代碼,希望通過及早捕獲和修復錯誤來節省時間。

程序員不得不使用復雜的大型IDE,僅僅使用簡單的編輯器是不行的。IDE為Java程序員提供了一些下拉列表,用于顯示類的可用字段、描述方法的參數,幫助他們構建新的類和進行重構。

然后,你還得使用Maven……

在JavaScript中,不需要聲明變量的類型,所以通常不需要進行類型轉換。因此,代碼更易于閱讀,但可能會出現未編譯錯誤。

這一點會讓你更喜歡Java還是痛恨Java,取決于你自己。十年前,我認為Java的類型系統值得我們花費額外的時間,因為這樣可以獲得更多的確定性。但在今天,我認為代價太大了,使用JavaScript會要簡單得多。

使用易于測試的小模塊來掃除bug

Node.js鼓勵程序員將程序劃分為小單元,也就是模塊。模塊雖小,卻能從一定程度上解決剛剛提到的問題。

一個模塊應該具備以下特點:

  • 自包含——將相關代碼打包到一個單元中;
  • 強壯的邊界——模塊內部的代碼可以防止外部代碼入侵;
  • 顯式導出——默認情況下,代碼和模塊中的數據不會導出,只將選定的函數和數據暴露給外部;
  • 顯式導入——聲明它們依賴哪些模塊;
  • 可能是獨立的——可以將模塊公開發布到npm存儲庫或其他私有存儲庫,方便在應用程序之間共享;
  • 易于理解——更少的代碼意味著更容易理解模塊的用途;
  • 易于測試——小模塊可以輕松進行單元測試。

所有這些特點組合在一起,讓Node.js模塊更容易測試,并具有明確定義的范圍。

人們對JavaScript的恐懼源自它缺乏嚴格的類型檢查,所以可能很容易導致錯誤。但在具有清晰邊界的模塊中,受影響代碼被限于模塊內部。所以,大多數問題被安全地隱藏在模塊的邊界內。

松散類型問題的另一個解決方案是進行更多的測試。

你必須將節省下來的一部分時間(因為編寫JavaScript代碼更容易)用在測試上。你的測試用例必須捕獲編譯器可能捕獲的錯誤。

對于那些想要在JavaScript中使用靜態檢查類型的人,可以考慮使用TypeScript。我沒有使用TypeScript,但聽說它很不錯。它與JavaScript兼容,同時提供了有用的類型檢查和其他特性。

但我們的重點是Node.js和JavaScript。

包管理

一想起Maven我就頭大。據說一個人要么愛它,要么鄙視它,沒有第三種選擇。

問題是,Java生態系統中并沒有一個核心的包管理系統。Maven和Gradle其實也很不錯,但它們并不像Node.js的包管理系統那樣有用、可用和強大。

在Node.js世界中,有兩個優秀的包管理系統,首先是npm和npm存儲庫。

有了npm,我們就相當于有了一個很好的模式用來描述包依賴性。依賴關系可以是嚴格的(指定具體的版本),或者使用通配符表示最新版本。Node.js社區已經向npm存儲庫發布了數十萬個包。

不僅僅是Node.js工程師,前端工程師也可以使用npm存儲庫。以前他們使用Bower,現在Bower已被棄用,他們現在可以在npm存儲庫中找到所有可用的前端JavaScript庫。很多前端框架,如Vue.js CLI和Webpack,都是基于Node.js開發的。

Node.js的另一個包管理系統是yarn,它也是從npm存儲庫中拉取包,并使用與npm相同的配置文件。yarn的主要優點運行得更快。

性能

曾幾何時,Java和JavaScript都因為運行速度慢而橫遭指責。

它們都需要通過編譯器將源代碼轉換為由虛擬機執行的字節碼。虛擬機通常會進一步將字節碼編譯為本地代碼,并使用各種優化技術。

Java和JavaScript都有很大的動機讓代碼運行得更快。在Java和Node.js中,動機就是讓服務器端代碼運行得更快。而在瀏覽器端,動機是獲得更好的客戶端應用程序性能。

甲骨文的JDK使用了HotSpot,這是一個具有多種字節代碼編譯策略的超級虛擬機。HotSpot經過高度優化,可以生成非常快的代碼。

至于JavaScript,我們不禁在想:我們怎么能期望在瀏覽器中運行的JavaScript代碼能夠實現復雜的應用程序?基于瀏覽器JavaScript實現辦公文檔處理套件似乎是件不可能實現的事情?是騾子是馬,拉出來溜溜就知道了。這篇文章是我用谷歌文檔寫的,它性能非常好。瀏覽器端JavaScript的性能每年都在飛漲。

Node.js直接受益于這一趨勢,因為它使用的是Chrome的V8引擎。

下面是Peter Marshall的演講視頻鏈接,他是谷歌的一名工程師,主要負責V8引擎的性能增強工作。他在視頻中描述了為什么V8引擎使用Turbofan虛擬機替換了Crankshaft虛擬機。

V8引擎中的高性能JavaScript:https://youtu.be/YqOhBezMx1o

在機器學習領域,數據科學家通常使用R語言或Python,因為他們十分依賴快速數值計算。但由于各種原因,JavaScript在這方面表現很差。不過,有人正在開發一種用于數值計算的標準JavaScript庫。

JavaScript中的數值計算:https://youtu.be/1ORaKEzlnys

另一個視頻演示了如何通過TensorFlow.js在JavaScript中使用TensorFlow。它提供了一個類似于TensorFlow Python的API,可以導入預訓練模型。它運行在瀏覽器中,可用于分析實時視頻,從中識別出經過訓練的對象。

基于JavaScript的機器學習:https://youtu.be/YB-kfeNIPCE

在另一個演講視頻中,IBM的Chris Bailey討論了Node.js的性能和可伸縮性問題,特別是在Docker/Kubernetes部署方面。他從一組基準測試開始,演示了Node.js在I/O吞吐量、應用程序啟動時間和內存占用方面遠遠超過Spring Boot。此外,得益于V8引擎的改進,Node.js每次發布的新版在性能方面都有顯著的提升。

Node.js的性能和高度可伸縮的微服務:https://youtu.be/Fbhhc4jtGW4

在上面的這個視頻中,Bailey說我們不應該在Node.js中運行計算密集型的代碼。因為Node.js采用了單線程模型,長時間運行計算密集型任務會導致事件阻塞。

如果JavaScript的改進還無法滿足你的應用程序的要求,還有其他兩種方法可以將本地代碼直接集成到Node.js中。最直接的方法是使用Node.js本地代碼模塊。Node.js工具鏈中包含了node-gyp,可用于處理與本地代碼模塊的鏈接。下面的視頻演示了如何集成Rust庫和Node.js:

JavaScript與Rust集成,遠比你想象得簡單:https://youtu.be/Pfbw4YPrwf4

WebAssembly可以將其他語言編譯為運行速度非常快的JavaScript子集。WebAssembly是一種可在JavaScript引擎內運行的可執行代碼的可移植格式。下面的視頻做了一個很好的概述,并演示了如何使用WebAssembly在Node.js中運行代碼。

在NodeJS中使用WebAssembly:https://youtu.be/hYrg3GNn1As

富Internet應用程序(RIA)

十年前,軟件行業一直熱議利用快速的JavaScript引擎實現富Internet應用程序,從而取代桌面應用程序。

這個故事實際上在二十多年前就已經開始了。Sun公司和Netscape公司達成了共識,在Netscape Navigator中使用Java小程序(Applet)。JavaScript語言在某種程度上是作為Java小程序的腳本語言而開發出來的。服務器端有Java Servlet,客戶端有Java Applet,這樣就可以在兩端使用同樣的一門編程語言。然而,由于各種原因,這種美好的愿望并沒有實現。

十年前,JavaScript開始變得足夠強大,可以實現復雜的應用程序。因此,RIA被認為是Java客戶端應用程序的終結者。

今天,我們開始看到RIA的想法得以實現。服務器端的Node.js和兩端都有的JavaScript讓這一切成為可能。

當然,Java作為桌面應用程序平臺的消亡并不是因為JavaScript RIA,而是因為Sun公司忽視了客戶端技術。Sun公司把注意力放在要求快速服務器端性能的企業客戶身上。當時我還在Sun公司任職,我親眼看著這件事情發生。真正殺死Applet的是幾年前在Java插件和Java Web Start中發現的一個安全漏洞。這個漏洞導致全球一致呼吁停止使用Java Applet和Java Web Start應用程序。

我們仍然可以開發其他類型的Java桌面應用程序,NetBeans和Eclipse IDE之間的競爭仍然存在。但是,Java在這個領域工作是停滯不前的,除了開發工具之外,很少有基于Java的應用程序。

JavaFX是個例外。

10年前,JavaFX意欲成為Sun公司對iPhone的反擊。它用于開發基于Java的手機GUI應用程序,想把Flash和iOS應用程序打垮。然而,這一切都沒有發生。JavaFX現在仍然可以使用,但沒有了當初的喧囂。

這個領域的所有興奮點都發生在React、Vue.js和類似的框架上,JavaScript和Node.js在很大程度上要得益于此。

結論

現在,開發服務器端應用程序有很多選擇。我們不再局限于“P”開頭的語言(Perl、PHP、Python)和Java,我們還有Node.js、Ruby、Haskell、Go、Rust等等。

至于為什么我會轉向Node.js,很明顯,我更喜歡在使用Node.js編程時的那種自由的感覺。Java成了負擔,而Node.js沒有這樣的負擔。如果我再次拿起Java,那肯定是因為有人付了錢。

每個應用程序都有其真實需求。只是因為個人喜歡而一直使用Node.js也不見得是對的。在選擇一門語言或一個框架時總歸是有技術方面的考量的。例如,我最近完成的一些工作涉及XBRL文檔,由于最好的XBRL庫是用Python實現的,所以就有必要學習Python。
轉載地址:http://www.infoq.com/cn/articles/why-is-a-java-guy-so-excited-about-node-js-and-javascript
英文原文:https://blog.sourcerer.io/why-is-a-java-guy-so-excited-about-node-js-and-javascript-7cfc423efb44

總結

以上是生活随笔為你收集整理的从Sun离职后,我“抛弃”了Java,拥抱JavaScript和Node的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。