作者:餘果 | 騰訊社交使用者體驗設計部高階UI工程師,前端開發組負責人,UI開發通道評委,騰訊雲特邀佈道師,《Web全棧工程師的自我修養》作者。
此文已由作者授權騰訊雲+社群釋出,原文連結:https://cloud.tencent.com/developer/article/1004490?fromSource=waitui
本文是我在“重慶前端交流會(渝 FE )”上的演講,整理分享出來,希望能對更多人有幫助,以及激起更大範圍的討論。本文並不是預先準備的演講稿,而是後續根據 PPT 圖片來複盤,所以內容跟現場表達可能會有些許差別。 感謝主辦方的安排和組織,感謝熱情的現場觀眾,以下是正文:
大家好,感謝渝 FE 組委會的組織,感謝各位付費來到現場,今天我給大家分享自己在面向未來的全棧開發方面的話題。
“面向未來的跨界開發技術”是一個非常龐大的話題,為了能夠稍微具體一點來討論,我想分解為兩部分來講。
首先是“面向未來”。何謂面向未來,如何面相對來?
保羅·格雷厄姆是一個我很崇拜的程式設計師、產品經理、作家和投資人。
他在《黑客與畫家》中說過,“100年後的程式語言……擁有最小最簡潔核心”,我認為與其說這是“預言”,不如說這是他的一個“理想”。
另一個行業大牛松本行弘(Ruby之父)讀到《100年後的程式語言》的時候,有不同的看法。
在《松本行弘的軟體世界》中,他認為100年後的程式語言,存在無限種可能性,技術上是無法預測的(可能語音對話或者腦波輸入?)
預測20年後的程式語言倒是可以試一試。松本行弘認為合理的預測方法是縱觀過去20年程式語言的進化規律,然後將各語言的起伏線條延伸,就應該是20年後的程式語言。
根據這條線的延伸,松本行弘的預判是:程式語言要解決的問題將從“如何做”變成“做什麼”,即完成一個任務需要的指令會更加簡潔。
我更傾向於松本行弘老師的觀點。我從 PYPL 上找到了下圖,圖中顯示了十幾年來一些程式語言的“有名程度”的變化值。
有一些基業長青的程式語言,比如 Java、C++;也有一些近幾年才從無到有異軍突起的程式語言,比如 Python、Ruby、Objective-C、Swift 等。
稍微分析一下,我發現新的語言興起主要來自兩個方面原因:
- 行業趨勢從桌面到移動的轉移,Swift 和 Objective-C 是這一種。
- 技術趨勢從 how 到 what 的轉移,簡單的說就是更容易完成一個需求。這一趨勢就不只由語言本身決定,還由該語言配套的框架決定。
比如 Ruby 的 RoR 框架就大大提升了 Ruby 在 Web 開發者中的競爭力,因為Rails內建了一些最佳實踐,甚至直接可用的專案架構,讓 web 開發更容易。
而 JavaScript 在 Node 端的發展也是由於 Express 的易用。當然到了後期 Node 的開發者更多了,會有更多競爭者加入,原本的框架可能會被更易用的框架來代替。
因此我開始調查一些框架的使用趨勢,來驗證這一判斷。
先介紹一個我個人調研趨勢的方法,就是在 Google Trends 中輸入需要調查的技術關鍵詞 + tutorial。這個方法樣能反映英語世界中的開發者對特定技術的學習熱情,也就能相對客觀地反映出未來趨勢。
以 JavaScript 為例,我們能發現 jQuery 已經不可避免地走下坡趨勢,原因就是從2014年開始,直接操作 DOM 的模式已經被更易用的雙向繫結和模板類庫(Angular、React、Vue)取代。也就是說從“怎麼改變頁面的行為和樣式”變成“改變資料,而讓頁面的行為和樣式自動變化”。
除了框架的使用之外,我還專門調查了前端構建工具的趨勢。
前端構建已經是現代 web 開發必不可少的環節。因為 HTTP2 還沒有完全普及(有伺服器的原因也有瀏覽器的原因),所以我們要把模組化的 JavaScript 和 CSS 模組混淆、打包以及MD5化,以減少 HTTP 請求數量並控制快取。因為使用者的瀏覽器的版本號不統一,所以我們需要把ES2015、ES2016、ES2017 等新功能轉譯成大部分瀏覽器都支援的最小子集。這些工作都需要用前端構建工具來完成。
從前端構建工具的趨勢來看,grunt是先烈,但是日漸式微被 gulp 趕超,原因一是基於檔案IO的流程比基於 stream 的流程慢很多,二是因為 grunt 的基於配置的方式比 gulp 的基於“正常 JavaScript 程式碼”的方式更固化,風格上不討人喜歡。
而 webpack 興起是因為 JavaScript 模組化程式設計這一趨勢。webpack 和 Browserify 差不多是做一樣的事情,就是把一個一個的 JavaScript 模組打包成一個檔案(這一過程稱為 bundle),然後在瀏覽器環境中使用。其實在伺服器端的 JavaScript 模組也可以打包,不過沒有太大必要。本來 JavaScript 原生不支援模組,所以就有了第三方規範(CommonJS之類的),後來 ES6 新增了模組功能(就叫 ES6 Module),所以各種各樣的模組要在一起協作就是要解決的一個問題。Webpack 和 Browserify 就是解決這一問題的。
我想,可以得出一個結論是,無論是程式語言,還是配套的框架,和對應腳手架,都長期處於變化之中。有一些框架和腳手架能夠順應一時潮流和風格,也許能暫時拔得頭籌,但很容易就會被後起之秀(vue、webpack)超越,這樣的迭代變化在未來也不會停止。
所以,唯一能面向未來的知識只有“又快又好地學習”的能力。
說到學習,我收到一個讀者郵件。這個讀者碩士畢業之後找了一份C++的工作,但是產品方面不太喜歡,希望轉行做 Python Web 開發。
我認為這個讀者焦慮的主要原因在於兩點:
- 從 C++ 到 python 轉型學習的時間其實還比較短,遠遠不到10000小時。技能還不是很熟練,這時看到一些招聘要求出現大量不理解的詞,就覺得理想與現實的差異太大。
- 學習過程比較獨立,沒有從做中學。
我說一下我理解的“程式設計”,可以分解為三點:智力、知識和經驗。
具體如下:
具體到“程式設計”這門手藝而言,這三者都不可能單獨去提升。也就是說不可能只提升經驗,而不去學習;也不可能只是學習,而不去動手提升經驗。
好的學習方法是迴圈式地,學習一些新的知識,然後邊做邊學(learn by doing),在這過程中再加入一些思考,提升智力。
對於有一些工作經驗的程式開發者來說,可能已經進入這個迴圈中,遇到了一些瓶頸,這時候可以對照上圖來看,現在卡在了什麼地方。
對於初學者,或者從新開始學習一個技術棧的有經驗者,就需要有一個學習路徑。也就是“地圖”,以及“我在哪裡”。下圖是一個學習React-Native的藍圖示例:
開啟迴圈之後,就採用下面模式來迴圈。
我在2010年讀到Outliers(局外人)的時候,學習到了一個終身受用的概念,就是10000小時定律。
這個定律大家都聽過,好像很簡單嘛,一句話就概括了一本書。
其實不是的,這本書裡有很多發人深省的內容。比如講了比爾蓋茲和賈伯斯都是同一年代出生,周圍的環境和他們自己的興趣給了他們練習10000小時的機會,才會有機會成為微軟和蘋果的創始人。
10000小時也不是重複重複再重複,而是要持續在learning zone去練習。不是在comfort zone枯燥地重複已經會了的事情,更不是在panic zone去恐慌。
我就這樣跟這位讀者說明了我的觀點:
- 放鬆焦慮心情,工作才一年多,要成為python web開發的大師需要10000小時;
- 要找到一個python工作不需要10000小時,基本上1000小時可能就夠了,但是要邊學邊用才有效;
- 開始用,而不是一直學。我看到你fork的awsome-python,裡面的工具很多,不要一昧追逐,可以看一些好的專案,自己去搭建部落格、爬蟲、CMS等;
- 持續提交你的github程式碼,看到專案的功能越來越多,也能減少焦慮;
- 每天2小時也有點少,最好能增加到4小時。
過了一天,這位讀者竟然給我送了一張亞馬遜禮品卡表示感謝。所以我把這個故事分享給大家,也希望大家有所收穫。
再講一個我親身經歷的例子。
我為了保持對演算法和資料結構的“感覺”,偶爾會在 LeetCode 上找一些題目來做,特別是網站現在支援 JavaScript 了,就更加方便。
有一天我看到這樣一個題目。
大家先不要看我的答案,來想一想這個題目怎麼解。
。
。
。
。
。
。
。
。
。
我的第一次解法很直白,每次需要計算 i 到 j 之間的和的時候,就迴圈計算一次。心算了一下,感覺應該沒有問題,就提交了。
然而,系統提示計算超時!
我看了一下超時的測試案例,是一個超長陣列。更重要的是,系統對這個物件進行了多次求sumRange運算,導致超時。
唔……所以怎樣才能不要執行那麼多迴圈呢?各位開動腦筋想一想。。。
重點是題目中的“提示”部分。
。
。
。
。
。
。
。
。
。
於是我想到這個優化後的方案:在初始化物件時就計算出一個 sumToNumber 的陣列,表示“從 0 到 n 的和”,這樣要計算 sumRange(i, j)
的時候,就只需要sumToNumber[j] - sumToNumber[i-1]
就好了,最後再處理一下邊際情況。
因為假設陣列不會變化,所以無需更新陣列內容。
完美通過測試!
通過這個題目,我對時間複雜度和空間複雜度的印象又加深了,這是單純看演算法書不能提升的。
以上,就是我在學習程式設計、打磨手藝方面的經驗。
說完了“面向未來”這一話題,下一篇我將講講“跨界開發”這一話題,敬請期待!
歡迎大家前往騰訊雲+社群或關注雲加社群微信公眾號(QcloudCommunity),第一時間獲取更多海量技術實踐乾貨哦~