而立之年——回顧我的前端轉行之路

譚光志發表於2020-11-17

為什麼轉行

因為混得不好。

在成為程式設計師之前,我幹過很多工作。由於學歷的問題(高中),我的工作基本上都是體力活。包括但不限於:工廠普工、銷售(沒有幹銷售的才能)、搬運工、擺地攤等,轉行前最後一份工作是修電腦。這麼多年,月薪沒高過 3300...

後來偶然一個機會我發現了知乎這個網站,在上面瞭解到程式設計師的各種優點。於是,我下定決心轉行(2016 年,當時 28 了),辭職在家自學程式設計。並且也得到了媳婦的支援,感謝我的媳婦。

轉行準備

轉行選擇前端也是在知乎上看網友分析的,比後端好入門。

如何選擇教程?

最好在網上多查查資料,找評價高的或者去豆瓣上找評分高的書。

我在網上查了很多資料,最終確定 HTML、CSS 在 w3cschool 學習。JavaScript 則選擇了JavaScript 高階程式設計第三版(俗稱紅寶書,現在已經有第四版了)。

光看不練是學不好程式設計的,我非常幸運的遇到了百度前端技術學院。它從易到難設定了 52 個任務,共分為四個階段。任務難度循序漸進,每一個任務都有清晰的講解和學習參考資料。它還怕你不會做,允許你檢視其他人上傳的任務答案。

我先學習了 HTML、CSS,做完了第一階段任務。再看完紅寶書前十三章,做完了第二階段任務。然後把紅寶石剩下的全看完,做到第三階段的任務四十五。後面的任務對於當時的我來說實在太難了,就沒往下做。在 1 月的時候,又學習了 ajax,瞭解了前後端如何相互通訊。

我從 16 年 11 月開始自學前端,一直到 17 年 2 月。歷時 3 個月,平均每天學習 3-4 個小時。中間有好幾次因為太難想過放棄,不過最後還是堅持下來了。

找工作的過程非常艱難,我在網上各大招聘平臺投了很多簡歷,但由於沒學歷、沒經驗,所以一個回覆都沒有。最後還是我媳婦工作的公司在招前端,給了我一個內推的機會,才有了第一次面試。並且第一次面試也很順利,居然過了,這是我沒想到的。直到多年後我和麵試官又在一個公司的時候,才知道原因。他的意思是:看在我這麼努力自學程式設計的份上,願意給我一個機會。

雖然人生很艱難,但很有可能,遇到一個願意給你機會的人,就能改變你的命運。

正式工作

第一年

在正式的專案中寫程式碼和在學習時寫程式碼是不一樣的。你必須得考慮這樣寫安不安全,會不會引起 BUG,會不會引起效能問題。在工作的第一年,寫業務程式碼對我的提升非常大。

第一年的主要任務,就是提升前端基礎能力。因此我看了很多 JavaScript 的書籍來提升自己的水平:

  1. JavaScript高階程式設計(第三版)
  2. 高效能JavaScript
  3. JavaScript語言精粹
  4. 你不知道的JavaScript(上中下三卷)
  5. ES6標準入門
  6. 深入淺出Node.js

這些書都是非常經典的書籍,有幾本我還看了好幾篇。

除了看書外,我還做了百度前端技術學院 2017 年的任務,它比 2016 年的任務(轉行時做的是 2016 年的任務)更有難度和深度,非常適合進階。

另外還學習了 jquery 和 nodejs。jquery 是工作中要用,nodejs 則是出於興趣學習的,沒有多深入。

第二年

到了第二年,寫業務程式碼對於我來說,已經提升不大了,就像一個熟練工一樣。而且感覺前端方面掌握的知識已經足夠把工作做好了。於是我就想,為了成為一名頂尖的程式設計師,還需要做什麼。我在網上查了很多資料,看了很多前輩的回答,最後決定自學計算機專業。

我制定了一個自學計算機專業的計劃,並且減少花在前端上的時間。因為說到底,基礎是地基。基礎打好了,樓才能建得高。

計算機系統要素

計算機系統要素是我制訂計劃後開始學習的第一本書。它主要講解了計算機原理(1-5章)、編譯原理(6-11章)、作業系統相關知識(12章)。不要看內容這麼多,其實這本書的內容非常通俗易懂,翻譯也很給力。每一章後面都有相關的實驗,需要你手寫程式碼去完成,堪稱理論與實踐結合的經典。

這裡引用一下書裡的簡介,大家可以感受一下:

本書通過展現簡單但功能強大的計算機系統之構建過程,為讀者呈現了一幅完整、嚴格的計算機應用科學大圖景。本書作者認為,理解計算機工作原理的最好方法就是親自動手,從零開始構建計算機系統。

通過12個章節和專案來引領讀者從頭開始,本書逐步地構建一個基本的硬體平臺和現代軟體階層體系。在這個過程中,讀者能夠獲得關於硬體體系結構、作業系統、程式語言、編譯器、資料結構、演算法以及軟體工程的詳實知識。通過這種逐步構造的方法,本書揭示了電腦科學知識中的重要成分,並展示其它課程中所介紹的理論和應用技術如何融入這幅全域性大圖景當中去。

全書基於“先抽象再實現”的闡述模式,每一章都介紹一個關鍵的硬體或軟體抽象,一種實現方式以及一個實際的專案。完成這些專案所必要的電腦科學知識在本書中都有涵蓋,只要求讀者具備程式設計經驗。本書配套的支援網站提供了書中描述的用於構建所有硬體和軟體系統所必需的工具和資料,以及用於12個專案的200個測試程式。

全書內容廣泛、涉獵全面,適合計算機及相關專業本科生、研究生、技術開發人員、教師以及技術愛好者參考和學習。

做完這些實驗,讓我有了一個質的提升。以前感覺計算機就是一個黑盒,但現在不一樣了。我開始瞭解計算機內部是如何運作的。明白了自己寫的程式碼是怎麼經過編譯變成指令,最後在 CPU 中執行的。也明白了指令、資料怎麼在 CPU 和記憶體之間流轉的。

這本書所有實驗的答案我都放在了 github 上,有興趣不妨瞭解一下。

Vue

這一年還學會了 Vue。除了熟讀文件外,還為了研究原始碼而模仿 Vue1.0 版本寫了一個 mini-vue。不過學習原始碼對於我寫業務程式碼並沒有什麼幫助。如果不是出於興趣去研究原始碼,最好不要去學,熟讀文件就能完全應付工作了。如果是為了面試,那也不需要閱讀原始碼。只需要在網上找一些質量高的原始碼分析文章看一看,作一下筆記就 OK 了。

為什麼我不建議閱讀原始碼?因為閱讀原始碼效率太低,而且相對於你的付出,收益並不大。到後面 Vue 出了 3.0 版本時,我也是有選擇地閱讀部分原始碼。

第三年

第三年有大半年的時間浪費在王者榮耀上,那會天天只想著衝榮耀,根本沒心思學習。後來終於醒悟過來了,王者榮耀是我成為頂級程式設計師的阻礙。於是痛定思痛,給戒掉了。

由於打王者的原因,第三年沒學習多少新知識。基本上只做了三件事:

  1. 寫了幾個 Vue 相關的外掛和專案。
  2. 將過去所學的前端知識,整理了一下放在 github 上,有空就複習一下。
  3. 學習資料結構與演算法。

資料結構與演算法

資料結構和演算法有什麼用?學了演算法後,我覺得至少會懂得去分析程式的效能問題。

一個程式的效能有問題,需要你去優化。如果學過資料結構和演算法,你會從時間複雜度和空間複雜度去分析程式碼,然後解決問題。如果沒學過,你只能靠猜、碰運氣來解決問題。

理論知識上,我主要看的是演算法這本書,課後習題沒做,改成用刷 leetcode 代替。目前已經刷了 300+ 道題,還在繼續刷。不過由於數學差,稍微複雜一點的演算法知識都看不懂,效果不是很好。

第四年

第四年,也就是今年(2020),是我重新奮鬥的一年。今年比以往的任何一年都要努力,每天保證 3 小時以上的學習時間。如果實在太忙了,達不到要求,那就改天把時間補上。附上我今年的學習時長圖(記錄軟體為 Now Then):

今年我做了非常多的事情:

  1. 研究前端工程化。
  2. 學習作業系統。
  3. 學習計算機網路。
  4. 學習軟體工程。
  5. 學習 C++。
  6. 學英語。

前端工程化

研究前端工程化的目的,就是為了提高團隊的開發效率。為此我看了很多書和資料:

...

研究了一年的時間,寫了一篇質量較高的入門教程——手把手帶你入門前端工程化——超詳細教程。除此之外,還有其他工程化相關的一系列文章:

作業系統

作業系統是管理計算機硬體與軟體資源的計算機程式。通常情況下,程式是執行在作業系統上的,而不是直接和硬體互動。一個程式如果想和硬體互動就得通過作業系統。

如果你掌握了作業系統的知識,你就知道程式是怎麼和硬體互動的。

例如你知道申請記憶體,釋放記憶體的內部過程是怎樣的;當你按下 k 鍵,你也知道 k 是怎麼出現在螢幕上的;知道檔案是怎麼讀出、寫入的。

對於作業系統,我主要學習了以下書籍:

  1. x86組合語言:從真實模式到保護模式
  2. xv6-chinese
  3. 作業系統導論

然後做 MIT6.828 的實驗,實現了一個簡單的作業系統核心。

計算機網路

計算機網路的作用主要是解決計算機之間如何通訊的問題。

例如 A 地區和 B 地區的的計算機怎麼通訊?同一區域網的兩臺電腦又如何通訊?學習計算機網路知識就是了解它們是怎麼通訊的以及怎麼將它們聯通起來。

對於計算機網路,我主要學習了以下書籍:

  1. 計算機網路--自頂向下
  2. 計算機網路
  3. HTTP權威指南
  4. HTTP/2基礎教程

並且做了計算機網路--自頂向下的實驗。

軟體工程

軟體工程是一門研究用工程化方法構建和維護有效的、實用的和高質量的軟體的學科。它涉及程式設計語言、資料庫、軟體開發工具、系統平臺、標準、設計模式等方面。

學習以下書籍:

  1. 程式碼大全(第2版)
  2. 重構(第2版)
  3. 軟體工程

軟體工程是一門非常龐大的學科,我只學習了一點皮毛。主要學習的是關於程式碼怎麼寫得更好、結構組織更合理的知識,這需要一邊學習一邊在工作中運用。

C++

學習 C++ 其實是為了研究 nodejs 原始碼用的,看的這本書C++ Primer 中文版(第 5 版)

英語

我從轉行開始就一直在學習英語,不過今年花的時間比較多。

英語對於程式設計師的好處非常非常多,就我知道的有:

  1. 可以用 google 和 stackoverflow 來解決問題。
  2. 知道怎麼給變數、函式起一個好的命名。
  3. 很多流行的軟體都是國外程式設計師寫的,有問題你可以直接看文件以及和別人交流。

在我轉行前英語詞彙量只有幾百,三年多過去了,現在詞彙量有 6000(都是用百詞斬測的)。

寫作

寫作的好處是非常多的,越早寫越好。我還記得第一篇文章是 2017 年 2 月發表的,是我工作後的第 13 天,發表在 CSDN 上。

個人認為寫作的好處有三點:

  1. 鍛鍊你的寫作能力。一般情況下,寫得越多,寫作能力越好。這個好,不是說你的文章遣詞造句有多好,而是指文章條理清晰,通俗易懂,容易讓人理解。
  2. 寫作其實是費曼學習法的運用,幫助自己加深理解所學的知識。有沒有試過,學完一個知識點後,覺得自己懂了。但讓你向別人講述這個知識點時,反而吞吞吐吐不知道怎麼講。其實這是沒理解透才會這樣的,要讓別人明白你在表達什麼,首先你得非常熟悉這個知識點。一知半解是不可能把它講明白的,所以寫作也是在幫你梳理知識。
  3. 增加自己的曝光度。在我三年多的程式設計師生涯中,一共寫了 50 多篇文章,因此在一些平臺上也收穫了不少贊和粉絲。因為我寫的某些文章質量還行,不少大廠的程式設計師找過我,給我內推。不過由於個人學歷問題,基本上都沒下文...

總之一句話,寫作對你只有好處,沒有壞處。

學習

有選擇的學習

我覺得學習一定要有非常清晰的目標,知道你要學什麼,怎麼學。對於前端來說,我認為很多框架和庫都是不用學的。例如前端三大框架,沒有必要三個都學,把你工作中要用的那個掌握好就行。

比如你公司用的是 Vue,就深入學習 Vue,如果要看原始碼就只看重點部分的原始碼。例如模板編譯、Diff 演算法、Vue 原生元件實現、指令實現等等。

剩下的兩個框架 React、Angular 做個 DEMO 熟悉一下就行,畢竟原理都是相通的。等你公司要上這兩個再深入學習,不過也不建議閱讀原始碼了,太累。看別人寫的現成的原始碼分析文章就好。

其他的,像 easyui、Backbone.js、各種小程式... 用不到的堅決不學,浪費時間。用的時候看文件就行了,當然,如果有興趣瞭解如何實現也是可以的。

學習方法

我覺得好的學習方法非常重要,對我比較有用的兩個是:

  1. 費曼學習法。
  2. 學習一個知識點,最好把它吃透。

費曼學習法在《寫作》一節中已經說過了,這裡著重說說第二個。

你有沒有過這種感覺:覺得自己會的東西很多,但其實掌握的知識很多都停留在表面上,別人要是往深一問,就懵逼了。

我以前就有過這種感覺,主要問題出在對知識的學習僅停留在淺嘗即止的狀態。就是學習新知識,能寫個 DEMO,就覺得自己學得差不多了。這種學習方法是很有害的,首先知識存留度不高,其次是浪費時間,因為很快就會忘掉。

後來我嘗試改正這種狀態,在學習新的知識點時,時常問自己三個問題:

  1. 這是什麼?
  2. 為什麼要這樣?可以不這樣嗎?
  3. 有沒有更好的方式?

當然,不是所有問題都能適用靈魂三問,但它適用大多數情況。

舉個例子:看過效能優化相關文章的同學應該知道有這麼一條規則,要減少頁面上的 HTTP 請求。

這是什麼?

先了解一下 HTTP 請求是啥,查資料發現原來是向伺服器請求資源用的。

為什麼要減少 HTTP 請求?

查資料發現:HTTP 請求需要經歷 DNS 查詢,TCP 握手,SSL 握手(如果有的話)等一系列過程,才能真正發出這個請求。並且現代瀏覽器對於 TCP 併發數也是有限制的,超過 TCP 併發數的 HTTP 請求只能等前面的請求完成了才能繼續傳送。

我們可以開啟 chrome 開發者工具看一下一個 HTTP 請求所花費的具體時間。

這是一個 HTTP 請求,請求的檔案大小為 28.4KB。

名詞解釋:

  1. Queueing: 在請求佇列中的時間。
  2. Stalled: 從TCP 連線建立完成,到真正可以傳輸資料之間的時間差,此時間包括代理協商時間。
  3. Proxy negotiation: 與代理伺服器連線進行協商所花費的時間。
  4. DNS Lookup: 執行DNS查詢所花費的時間,頁面上的每個不同的域都需要進行DNS查詢。
  5. Initial Connection / Connecting: 建立連線所花費的時間,包括TCP握手/重試和協商SSL。
  6. SSL: 完成SSL握手所花費的時間。
  7. Request sent: 發出網路請求所花費的時間,通常為一毫秒的時間。
  8. Waiting(TFFB): TFFB 是發出頁面請求到接收到應答資料第一個位元組的時間總和,它包含了 DNS 解析時間、 TCP 連線時間、傳送 HTTP 請求時間和獲得響應訊息第一個位元組的時間。
  9. Content Download: 接收響應資料所花費的時間。

從這個例子可以看出,真正下載資料的時間佔比為 13.05 / 204.16 = 6.39%。檔案越小,這個比例越小,檔案越大,比例就越高。這就是為什麼要建議將多個小檔案合併為一個大檔案,從而減少 HTTP 請求次數的原因。

有沒有更好的方式?

使用 HTTP2,所有的請求都可以放在一個 TCP 連線上傳送。HTTP2 還有好多東西要學,這裡不深入講解了。

經過靈魂三問後,是不是這條優化規則的來龍去脈全都理清了,並且在你查資料動手的過程中,知識會理解得更加深刻。

掌握了這種學習方法,並且時刻運用在學習中、工作中,突破瓶頸只是時間的問題

總結

下面提前回答一下可能會有的問題。

百度前端技術學院

百度前端技術學院 2017 年及往後的任務,如果沒有報名,那就只能做部分任務。2016 年的任務則由於百度伺服器的問題,很多題的示例圖都裂了。這個其實是有解決方案的,那就是看別人的答案。把別人的原始碼下載下來,用瀏覽器開啟 html 檔案當示例圖看。這兩年的任務我都做了大部分,附上答案:

  1. 百度前端技術學院2016任務
  2. 百度前端技術學院2017任務

學歷提升

我從 18 年開始,已經報考了成人高考大專,19 年報了自考本科。大專明年 1 月就能畢業,自考本科比較難,可能 2021 年或 2022 年才能考下來。

寫在最後

從轉行到現在,已經過去 3 年多了。不得不說轉行當程式設計師給了我人生第二次機會,我也很喜歡這個職業。不過這幾年一直都是在小公司,導致自己的技術和視野得不到很大的提升。所以現在的目標除了學習計算機專業外,就是進大廠,希望有一天能實現。

雖然今年已經 32 了,但我對未來仍然充滿希望。努力地學習,努力地提升自己,為了成為一名頂尖的程式設計師而努力。

相關文章