樸靈:打破限制,從前端到全棧(圖靈訪談)
樸靈,真名田永強,文藝型碼農,Node.js 布道者。現就職于阿里巴巴數據平臺,任資深工程師,著有《深入淺出 Node.js》。他活躍于 CNode 社區,是線下會議 NodeParty 的組織者,同時也是 JSConf China(滬 JS、京 JS,以及杭 JS)的組織者之一。樸靈熱愛開源,是多個 Node.js 模塊的作者,個人 GitHub 地址:http://github.com/JacksonTian。叩首問路,碼夢為生。
從前端到全棧
“當時我們團隊的 Leader 不會去限制工程師做什么事情,而是說這件事是你在負責,所以你就要從前做到后。”
問:你從什么時候開始編程的?
我高二的時候才剛剛接觸互聯網,那時候看別人搭一個 BBS 我心里就特別崇拜,我很好奇這個過程是怎么實現的。以前有一個叫“中國博客網”的網站,上面提供了可以自己編輯模板的功能。在那個年代,腳本特效很流行, 我經常把代碼拷到那個模板里面去,測試效果。后來上大學之后我才知道,這個論壇的構建者其實就是利用了一個類似于 Discuz 的系統,搭這個網站并沒有想象中那么復雜。
問:聽說你在大學學的是 Java,在這過程中你的興趣點有沒有轉移?
學校教了很多東西,但是我的重心一直放在前端技術上。雖然學校教了C和 C++ 這樣的語言,但是教了之后也不告訴我們這個東西到底有什么用,所以我當時仍然癡迷于網頁。工作幾年以后才發現學校教的東西很有用,所以現在再回去補。
問:你是怎么變成所謂的全棧工程師的?是你自己的興趣使然還是工作環境給了你這樣一個機會?
我一般不說我是全棧工程師(笑)。我剛進大學的時候,目標其實很明確,就是想看看那些 JS 特效是怎么實現的。2009 年畢業之后我開始工作,就側重去做前端。那時候前端也才剛剛興起,后來我就成了一個真正的前端工程師。
去了淘寶之后,我碰到了 Node.js 這樣一個我很感興趣的東西,我用了兩年時間完成了從前端工程師到全棧工程師的演變。我的個人習慣就是,如果我對什么感興趣,就會在這塊投入精力去研究。所 以通過這一兩年的學習,我已經可以完成所謂的后端的工作了。當時我們那個團隊由空無和玄澄帶領,他們不會去限制工程師做什么事,而是說這件事情是你在負 責,所以你就要從前做到后。
問:在你看來全棧意味著什么?你在 QCon 大會上主持了這個專題之后有沒有帶給你一些新的思考?
以前我認為全棧就是一個開發者能力的提升。如果你在某個領域非常專,有一個點很擅長,這時候別人才稱你是專家;如果你有多個點比較擅長,那別人 才有可能稱你是全棧工程師。另外,責任也很重要。一個人不再只是負責在前端寫 CSS,也不只是在大工程里面做一小塊東西,而是有了一個全局的視野。我以前對于全棧工程師的理解可能就是集中在工程師個人能力以及責任這兩點上,通過主 持 Qcon 的全棧工程師專題,我覺得還有一點,就是環境對全棧的影響。
個人能力是不太好復制的,有的工程師能力強,有的工程師能力沒那么強,這種情況下你對能力稍微弱一點的工程師做這種要求,是很難達到目標的。 Coding 的分享給我帶來了這個想法:基礎設施建設對全棧的影響也是很大的。如果你不能幫助一個工程師成長,那就應該在環境上做出改變,你要去打造適合這樣的人才成 長的環境才行,這樣才是正向循環。
問:淘寶現在使用 Node.js 的范圍有沒有擴大,主站有沒有在用?
主站也有在用。現在幾乎每個 BU 都在用 Node 做嘗試,不管它做的是大系統還是小系統。我看到有很多團隊嘗到了甜頭,但我也看到有很多團隊不愿做改變,不愿去嘗試新技術。
問:方便說一下你現在的工作內容是什么嗎?
我最近半年在社區都不怎么活躍,是因為我做的內容剛剛開始,現在才有了一些進展,將來我們有計劃把我們做的東西對外產品化。我現在的主要工作就是改 Node.js 和 V8。在 Node.js 上改動我會直接接到 Io.js 的倉庫里面,現在已經提了很多。
我可以舉個例子解釋一下我們現在做的事情。在 Node.js 社區上有一些性能調優的工具,比如 Chrome 上有個 CPU 調優工具,它可以幫你找出哪段代碼運行得比較慢。我們在這個基礎上做了更多的工作,我們做的這個性能調優的工具不僅要知道慢,還要知道為什么慢。用我的工 具掃過之后,我就知道怎么去改,其實現在我打的很多補丁都是通過這個工具發現的。造成性能慢的原因可能有很多,我們盡量去發掘這些問題。
另外一件我在做的事情就是幫助公司內的一些 Node 開發者。比如,這些開發者可能做業務開發時沒有什么問題,但是運維或者運行的時候就會出現問題。我們工作幾年來,并沒有因為使用 Node.js 而造成什么故障,高手寫代碼不太容易出現問題。但是對于每個工程師來說要求是不一樣的,我現在的工作重點就是:出問題的時候能夠馬上解決。線上代碼慢的原 因是什么,為什么會有內存泄露,我們做了一些工具來解決這件事。
雖然用一個新技術的時候可能感覺很爽,但是這個技術會帶來什么后果或者副作用,可能對于很多人來說都是沒底的。為了讓阿里的技術環境能夠更健康 地發展,我們的工作就是要讓大家知道,我們不怕這樣的問題出現,能出現我們也能解決。現在我們努力在公司以內創造更好的環境,在未來我們有計劃把這些東西 推出來,希望國內其他用 Node.js 的公司也能從我們的工作中得到一些好處,獨樂樂不如眾樂樂。我們希望自己能夠做更多的事情,有朝一日能成為 Io.js 或者 Node.js 項目里面的核心貢獻者,然后去影響它。
問:淘寶 UED 正在實踐前后端分離,應該也有其他團隊在做類似的事情,你怎么看?
我個人沒有直接參與這樣的事情。我覺得前后端分離是否能完成的核心在于服務化的程度。如果系統都是面向服務去設計的,那么在這個過程中解耦可能 很容易完成。所以當你真正做一個前端應用層的東西時,就不需要 Java 的同學來參與幫你寫模板,而這個應用層可能是跟業務相關的。
這里的一個概念就是產品應該有兩個部分:一個部分是系統層,另一個部分是應用層。應用層的需求可能天天變,但是這種改動基本上不怎么影響底層系 統的穩定性。系統層應該是趨向于穩定的,除非業務模型上有一些大的變化的時候才會去改動。而平常的日常迭代,也就是應用層,會有頻繁的發布和改動。
如果把兩層東西都混在一起的話,整個系統就會很龐大,界限不清晰。后端的人會干預前端的東西,前端有需求的時候可能后端的同學也不能理解。在這 過程中我覺得可以把應用層獨立出來,讓前端的同學能夠在中間有一個緩沖地帶,既能適應應用層的頻繁發布和需求改動,又能讓后端穩定。
問:JavaScript 有很多框架和庫,對于初級學習者來說,怎么能在這些資源中選擇適合自己的來創建個人技術棧?
我覺得 JavaScript 最核心、最源頭的東西就是它的規范。當然,如果你純粹去讀規范的話也沒有什么目的性,但那是一個核心。當你遇到困惑的時候就不妨去規范上找一找,通常你都能找到答案。這對于我來說是核武器一樣的東西,一般不能用的(笑)。
另外,ECMAScript 不算是純粹的 API,它定義的實現就不能更改,對于那些沒定義的實現,你要去看那些 API 是怎么去做的。我基本上主要靠這兩個東西。
他眼中的 Node
“有一個圈子,有一個社區,其實你會收獲很多東西。"
問:能不能簡要介紹一下 Node 生態環境的發展現狀?
這個話題其實我已經很久不再提了,因為現狀已經太好了。前幾年的時候模塊有幾個了、有幾千個了,然后過了一年這個數字就上萬了,再過一年就蹦到十萬以上了。
我是蠻喜歡這樣一個形態的,在跨過一個相對比較低的起點之后,大家可能都有能力來完成一個模塊。但是,每個工程師的能力有強有弱,每個人的意識 都是不同的,所以這個生態環境又是特別真實的。這里面的東西多,水平參差不齊,但你會發現在很多情況下,如果一個模塊是活躍的,它就一直是活躍的;如果它 的質量不好,它就永遠都是質量不好的。說不定幾年以后,你會發現越來越多的模塊都是以不斷迭代更新的狀態生存的,總是有最好的模塊來適應當下最需要的事 情。
問:我之前聽你在采訪里說,你當時推廣 Node 的初衷是因為你看到國內外對 Node 的理解存在很大差距,現在還有沒有這種差距?
現在還是有。我覺得最大的差距就是在國內推一個技術的時候,總會有很多人來黑。這些人可能也沒有什么前提,不管怎么樣,就是嘴巴爽了再說。另 外,國內外環境還有一個差距,就是在國內大家主動刷新自己知識的能力還不是太強。你會發現有一些工程師可能已經能完成當前的工作了,但是他在持續學習上可 能不會投入太多。
問:你認為前端工程師和后端工程師誰更應該學習 Node.js?誰學習 Node 獲益會更多?
其實無論什么工程師學習 Node 都可以有收獲,但是我覺得前端工程師的收獲會更大。
為什么要有前端這個工種?我不知道國外是不是這樣,但是國內很多人會說前端工程師就是寫 HTML 和 CSS 的,這種工作就像流水線一樣,已經被限定在一個劃定的圈里面去發展。當前端工程師發展到某一個階段的時候,他會發現這個圈子對他是一個限制。我覺得前端工 程師需要打破這個圈子,打破之后就會發現更開闊的視野。當我們想要解決一個問題的時候,就不只是再用已有的熟悉的辦法來解決,而是發現視野以外的、能夠更 好地解決問題的方法。反過來說,如果你總是不想去了解服務器端的一些技術,總是用前端的方法來解決問題,那成本可能很高,做出來的方案也可能不理想。
前后端有 Node.js 連接以后,你就會發現自己的工具鏈已經完成了一次革命。很多工程師可能會用 Java 或 Ruby 來寫一些工具,但是前端工程師不熟悉 Java,也不熟悉 Ruby,他要去完成目標的時候就會特別困難。現在 Node.js 出來以后,你就發現很多工具直接用 Node.js 就可以寫了,比如說 CoffeScript,還有一些像 LESS,Sass 之類的工具。前端工程師用自己熟悉的東西就能夠改良自己的工具,這是第一步。改良工具以后視野就會放開,你會發現還有很多其他東西可以放手去做。
問:你怎么看 LinkedIn 放棄 Node 和 Scala?
做任何一件事情都會有最適合的方法。我覺得像 LinkedIn 這么大的系統,其實是一種很復雜、很復合的模式。我們在淘寶推廣 Node.js 的時候,也不可能去用 Node 把那些最底層最核心的東西替換掉,這是不現實的。如果說在某個系統里面,Node.js 不能勝任某些工作,那就不要用它好了。
據說 LinkedIn 也并沒有完全放棄 Node,只是某一部分棄用。我覺得 Node.js 是有它擅長的地方的,只要能夠在適合的地方去用好就行了。
問:Io.js 和 Node.js 分離開來,是因為 Node 更新太慢造成的嗎?
大部分原因可能在于,雖然 Joyent 公司高管對這個項目還算重視,但是他們對開發進度沒有實質的幫助。
從 2014 年 7 月份開始轉崗以后,我的工作重點就是 Node.js 的內核,所以我對 Node.js 和 Io.js 的提交列表和 PR 都是比較熟悉的。我發現當我提交一個補丁上去的時候,在 Node.js 下面的處理速度特別慢。我剛進去的時候看到的 PR 列表大概只有兩百多個,現在 Io.js 分出去以后 PR 列表更長了。那些在這個項目上做貢獻的人,基本上 80% 已經不在這家公司了。所以現在出力的人并不是來自這家公司,而是社區的一些開發者。如果這家公司只想享受商標帶來的好處,貢獻者們就不會同意,所以他們就 獨立出來了。
目前來說我自己是比較喜歡 Io.js 這個項目的。我跟他們提一個問題上去,很快就會有反應。他們的態度也更開放,就是說不管你的貢獻是大是小,只要對這個項目有好處的,他們都會接受。并且他 們對新事物的接受速度也更快,比如現在 Node.js 的 V8 版本處于 3.2,而 Io.js 里面的 V8 已經是 4.2 了。如果更新慢的話,ES6 的一些特性就沒辦法引進來。因為 Io.js 中有這些新的特性,所以開發者就更愿意進入這個項目。
但是 Io.js 也給我造成了一些困擾。以前一個版本發布至少也要一兩個月,但是現在的版本發布速度已經是以周為單位的了,幾乎每周都能出一版。他們更新速度太快逼著我要 去做很多工作,需要不停地打版本。話說回來,實際上企業內部升級版本的速度要求不是太快,升級一個大版本以后,如果不需要接下來小版本的功能,就可以先忍 忍。
問:你覺得 Node 陣營的分裂是一件好事嗎?
我覺得是好事。我記得很久以前就有人特別想給 Node.js 的異步 IO 全部加上 Promise,如果不分裂,這件事情永遠不可能。雖然現在的 Io.js 也不能完成這件事,但是只有分裂才有更多的可能性,才能產生更好的東西。
問:很多大公司比如 Paypal,從 Java 轉換到 Node.js 非常成功,在后端 Node.js 會取代 Java 嗎?
不太可能,Node.js 還是在應用層上更有優勢。無論是我們在系統層所做的嘗試,還是現在已有的案例,都沒有能夠證明 Node.js 能夠取代 Java。我舉個簡單的例子,現在沒有人能拿 Node.js 來完成緩存或者涉及到集群的大計算,但是 Java 已經能夠做到了。
但是 Node.js 在應用層上是有優勢的,它的最初設計目的就是要優化 IO 和 CPU 的關系。以前的 IO 都是要阻塞 CPU 計算的,Node 把所有 IO 相關的東西全部從主線程上剝離以后,主線程就變得比較高效。而我們在 Java 里面去實現異步是比較麻煩的,可能需要啟用多線程。雖然 Java 也有框架去做這件事,但是對已有的開發者來說,由于他們對原有的模式已經很熟悉,所以不會愿意去做改變。應用層就應該能夠快速運行并且面向很多系統。我可 以用 Node.js 快速地開發,調用各個系統。
問:剛才你也提到,有些人認為 Node.js 在設計上最大的失敗就是它的 API 是基于 Callback,而不是基于 Promise 的,你同意嗎?
當時的情況就是那樣,ES6 沒有出來,Generator 也沒有出來,如果讓 Node.js 創始人 Ryan Dahl 去做這件事,他不僅要去改上層的東西,還要去改 JavaScript。但是現在的情況已經有變化了, ES6 已經出來了,它里面有一個東西叫 Generator,運行過程中我們讓程序調用棧停下來,然后在某個時間再重新把它喚起來。新的框架 Koa 就能夠利用好這個特性,寫程序的時候你會發現程序已經順序執行了,但是背后的實質還是異步。我覺得這些變化將來可能會慢慢影響 Node.js 本身的設計,甚至將來 Io.js 的 API 可能也會慢慢去改。
另外,之所以當時會有 Callback 這樣的設計,就是因為當時的 Callback 特別適合異步調用。這樣做的原因也跟當時選 JavaScript 有很大的關系。Ryan Dahl 去調研過 Java、Ruby 之類的語言,他發現這些語言提供的 API 有很重的歷史負擔。這時候如果給開發者提供新的 API,大家也不會去用,因為這會改變他們的思維模式。他在設計這個模型的過程中,發現事件循環里面有阻塞 IO 的話就會導致效率急劇下降。而 JavaScript 特別適合完成這項工作,它不主動提供同步的 API 給你,所以阻塞的方式就不存在。
問:今年你還會不會舉辦京 JS 或者杭 JS?
今年舉辦的會叫深 JS。我們今年沒有主動去辦會,而是由之前我們的一個合作方去承接了這件事。他們是上海的一家外企,對 JS 社區有比較高的熱情,過去三年舉辦的會他們都幫助我們做了很多事情,這次交給他們辦也是順理成章的。
問:以后你還會再舉辦這樣的活動嗎?你在這幾次辦會的過程中遇到過什么困難?
我們以后不排除仍然會舉辦這樣的活動。有一次在北京辦會,我們三個人都身在外地,所有的事情都是通過遠程操作,在外地辦會感到資源上的限制。另外的一個困難在于溝通,比如怎么去邀請國外的講師或者跟我們國外的主辦方溝通,中西方的文化差異會造成一些困擾。
我覺得辦會最重要的還是內容,對內容的挑選和審核,講師怎么邀請,主題要怎么規劃。不能某個主題今年講,明年講,后年講,有的公司可能出于商業目的有這樣的需求,但有些東西是不能去妥協的。
問:縱然有這么多困難,但是你還是一直在堅持做這件事,舉辦這樣的活動對社區來說最大的收獲是什么?
其實在辦活動這件事上,我有一個老師叫周裕波,我在上海工作的時候就遇到過他,他經常會辦一些前端的活動。對于個人開發者而言,他們很少愿意主 動出來組織這些活動,但周裕波做到了,我覺得我應該也能為 Node 做一些事情。當時我看到 Node 沒有這樣的氛圍,國內的很多開發者都不愿意出來,當時的社區也關注不到這個東西,所以我就辦了很多次 NodeParty。
這個過程其實收益還是很多的。首先我對這個社區更加了解了,跟很多高手都很熟悉。另外,我接觸了很多贊助商,各種資源其實都是大家互相需要的。 沒做過這件事的人可能會覺得非常難,但做了以后你會發現沒有想象中那么難。因為你總是會得到一些幫助,來自各個方面的幫助,你在經濟上也沒有什么損失,還 會結交一些的朋友。有一個圈子,有一個社區,其實你會收獲很多東西。