寫給自學者的入門指南
在IT工程師和培訓機構多如牛毛的時代,拜師學藝並不難。但自學程式設計對於毫無基礎的同學來說卻可能是個問題,相信有過類似經歷的朋友都有一把辛酸淚和一肚不吐不快的體會。讓我們從一個故事說起…
故事
某君在一個普通大學讀著自己不喜歡的專業,以打遊戲、刷段子和睡覺度日,突然有一天想學點什麼。學程式設計好像挺酷,而且聽說IT行業充滿了機會,沒準一不小心就和大佬一起“改變世界”了。
那麼第一個問題來了,他該選擇什麼語言?
是世界上最好的語言PHP?還是語言之母的C?幸好還知道個程式語言排行榜,找到一看、幾十種不帶重樣,這要逼死天秤座的小朋友。選PHP吧?上非誠勿擾都要被滅燈,而且就只能做個網頁。萬般糾結之後我們選C吧,聽起來既高階又底層,說不準還能考個計算機二級。
接下來得幹正事兒了。在這個便捷的網路時代,自學可選擇的方式非常豐富。除了在網路上收集資料、閱讀乾貨外,某君還向一些前輩諮詢了自學的方法。
網路上流傳的程式設計學習方式有:
- 看書(這是最容易想到的方法)
- 觀看視訊教程
- 閱讀官網文件
- 讀原始碼
- 到大學蹭課或者報名培訓(不知道還算不算自學,沒交學費都算吧?)
某君又得糾結一番了,大學蹭課和培訓並不一定有合適條件,且不符合自學的氣質;觀看視訊教程,前輩們覺得比較low;閱讀官網文件和原始碼,這不適合初學者。總得來說看書算是比較中肯的方法,至於看什麼書呢,前輩推薦了《C Primer Plus》,據說是學習C語言的經典之作。
好吧,不再糾結,直接啃這本大部頭,雖然有人說看原版好一些,但是實在能力有限,還是看中文版吧。一口氣花了一週時間讀完這本書,果然是經典,變數、語句、條件判斷甚至指標都知道怎麼回事了。
某君決定按照書中的說法實踐一下了,於是打開了記事本,折騰很久裝了GCC,把書上的第一個例子抄了下來,在控制檯的小黑窗輸出了“Hello World”,成就感滿滿。決定上手寫點高階的的東西一試身手,合上書。咦,為什麼會報錯?哦,原來少個分號。不禁陷入思考:為什麼學了兩個月還是隻能在這個黑視窗算算秋水仙數?網友還說要看官網文件、要讀原始碼、要看英文原版,我一樣都不能做到,我一定是能力不夠,程式設計果然是天才做的事情……
正經話
上面的故事是我編的,但其中的糾結卻是自學者或多或少都經歷過的。實際上,IT從業者並不像傳說中那樣需要天才般的智商,要點在於能否找到合適的入門途徑,再加上一點點堅持和思考。比較可惜的情況是一些人沒能找到適合自己的學習方法,並在糾結和碰壁後失去信心,然後沮喪的認定自己並不適合幹這行。學程式設計很多時候就是一個趟坑的過程,但不是每一個坑都有必要趟,寫這篇文章的目的是希望能夠幫助初學者儘量少趟一些坑。
IT世界的地圖
初學者遇到的一個典型問題是對IT世界沒有一個大的圖景。比如大多數的Java書籍,教完你基礎語法知識和秋水仙數的求法後就結束了,並沒告訴你接下來能幹什麼。我曾經為此感到非常困惑,學完Java SE後做了一個非常簡陋的GUI demo,就失去了後續的Java學習方向,帶著對Java的偏見,這成為了我一段令人沮喪的學習經歷。關於這個話題一本書可能都不夠,簡單來說,我嘗試從電腦科學知識和技術實踐兩方面來聊聊成為一名IT工程師需要具備哪些東西。
電腦科學基礎
首先初學者要具備一些非常基礎的知識,這些知識在你踏上工作崗位後能被實際的用到,比如計算機執行原理、網路的傳輸、常用資料結構和演算法等。這部分屬於電腦科學,也是應該被計算機專業本科課程涵蓋的,不要傷心錯過了大學本科的相關課程,我會分享一些有用的資源。
這裡我羅列了一些計算機專業的學生一般需要學習的課程,當然每個學校專業設計都不一樣,甚至採用的教材名字也不一樣,僅供參考。大學電腦科學課程往往包括:《高等數學》、《離散數學》、《電子電路》、《資料結構》、《程式設計》、《計算機組成原理》、《編譯原理》、《計算機網路》、《軟體工程》、《資料庫原理》等。有些學校會有一些額外的課程,例如《通訊原理》、《組合語言》、《線性代數》、《C語言》、《Java 語言》等。
儘管IT行業知識更迭非常快,但是基礎知識並不容易過時,因此有大量的資料可以選擇。可以選擇從計算機經典叢書系列開始,比如佛羅贊和莫沙拉夫的《電腦科學導論》,甚至可以閱讀一些計算機科普類讀物例如《穿越計算機的迷霧》。另一種直觀的方式是觀看大學精品課和去跟慕課課程,比較推薦的有幾個:
- 中國大學精品開放課程,高等教育出版社的精品課程專案,有全國大量的名校授課視訊和課件
- 中國大學MOOC ,這個是中國大學MOOC和網易合作的,提供了上文附圖中計算機課程體系中所有課程
- 果殼網的MOOC學院,主打翻譯全球名校的優秀課程,比如斯坦福的《編譯原理》和MIT的《Python》
從知識到實踐
除此之外,還需要了解實際應用於設計軟體或者開發網站中的實踐類知識,包括某個特定語言以及周邊的庫、框架和工具等。 我們可以把特定需求中用到的語言、庫和框架以及其他的工具稱為技術棧,在技術選型上通常也是被這樣考慮的,HR常常會根據技術棧來尋找需要的工程師。比如需要學習SSH三大框架和Java的Java技術棧;為伺服器web開發而生的PHP技術棧;在移動開發領域流行的iOS、安卓技術棧等。當然這裡面有一些重合和共用的技術也需要學習,比如版本管理器Git、SVN就是每個合格的工程師需要去學習的。
換句話說,大學課程主要定位在上面說到的電腦科學基礎知識,而市面上的培訓機構主要是告訴你在怎麼在實際工作中運用,所以大學和培訓機構都有他們的價值。
想要更加詳細的瞭解這部分內容,這裡有一些開源的技能圖譜可以參考:
圖片來自: http://skill-map.stuq.org/
如何挑選你的兵器?
在介紹完計算機領域的大致圖景後,就需要選擇一門合適的程式語言,一個較為形象的例子是把程式語言比喻成兵器,因為我們深知程式語言對於工程師而言是實實在在的工具,我們不是為了學它而學,學程式設計不僅僅是學語言特性,一般來說我們也不用知道賦值語句像“茴香豆蔻”的“茴”字有四種寫法。
當然語言之爭從來沒有停止過,如果把程式語言比喻江湖武器的話十分有趣。
C語言是M1式加蘭德步槍,很老但可靠。
C++是雙截棍,揮舞起來很強悍,很吸引人,但需要多年的磨練來掌握,很多人希望改用別的武器。
Perl語言是燃燒彈,曾經在戰場上很有用,但現在很少人使用它。
Java是M240通用彈夾式自動機槍,有時它的彈夾是圓的,但有時候不是,如果不是,當你開火時,會遇到NullPointerException問題,槍會爆炸,你就會被炸死。
JavaScript是一把寶劍,但沒有劍柄。
— 來自網路
老實來講IT行業的最終目的是交付可用的軟體,程式語言也是適應市場的。這對於初學者或許有些殘酷,在工作中我們發現最好的語言是用來處理工作任務或者構建合適的應用,並不是出於愛好或者某種Geek精神。
對於初學者而言,在選擇合適的入門語言時至少需要考慮兩點:
- 是否能適用於構建你想要的應用。如果你的目標是建立一個執行在iPhone上的App,那麼最好選擇 Objective-C 或者 Swift,學習web開發可以選擇PHP或者JAVA。實際上我們仍然可以用匯編做出網頁,但是這樣做成本高昂。
- 是否容易學習,在滿足第一點的條件下請儘量選擇容易學習的語言。容易不僅僅指語法簡單,包括環境搭建、部署等都需要考慮在內,以及能不能容易找到好的學習資料,因此儘可能的選擇主流語言。
別忘了非常重要的一點,學習程式語言還包括平臺提供的API,比如Win 32 之於C++/C#/VB,以及周邊的庫和框架(這些庫、框架和工具能在上面說的技術圖譜中找到)。IT歷史上甚至出現框架和庫引領程式語言走向的情況:jQuery和Angular改變了前端開發的思想;Rails搶走了Ruby的名氣;而SSH三大框架一度代表了Java世界。
最後我為初學者整理了一個流行程式語言和用途的表:
另外還需要注意的是開發工具,可以選用IDE和有程式碼提示的編輯器,但儘量不要在這上喋喋不休,這就像用來盛放你鋒利兵器的架子,用著順手就行,也不推薦使用純文字編輯器,這看起來像赤手空拳。 推薦一些編輯器和IDE
挑選合適的資料和有效的閱讀
對初學者而言,我仍然推薦好的視訊教程,雖然我已經聽到不下5個人聲稱是靠閱讀官方文件或者看原始碼學會程式設計的,而且認為觀看視訊教程見效太慢。但這個思想對初學者很危險,不得不承認閱讀文件和原始碼能更準確找到自己想要的資訊,這對深入技術原理非常有用,但視訊能比文字傳達出更豐富的內容,有更直觀的演示和細緻的講解,我想沒有比這個更適合初學者了。
除了上面提到的精品課程和慕課教程,國內有像網易雲課堂,國外有lynda.com這種線上學習視訊網站,甚至在優酷和土豆都能找到足夠的教程資源。
如果選擇了閱讀技術類書籍,我們來聊聊怎麼有效的閱讀一本技術書籍。
讀IT類書籍和讀考試類書籍的方式不同,初學者需要選擇更接地氣、並且能告訴你最終能做出什麼案例的書籍。你不需要通讀整本書,而是需要搭建好和書中版本一致的環境,然後把書中的每行程式碼敲入電腦,觀察這些程式碼怎樣被執行,在遇到問題時去請教朋友或者到搜尋引擎中尋找解決辦法,直到示例程式能被正確執行。
可能一個月才能讀完一本書,但慢點並沒什麼壞處,敲過一遍的程式碼才能算是你的,否則永遠存在於紙上的程式碼清單中。對於關鍵的概念和知識點,可以在閱讀的同時做一些筆記,去嘗試使用思維導圖來做你的筆記吧,這讓你的筆記跟上你的思考,並形成一個知識網路。
自我激勵
自學無疑是寂寞的。程式設計學習耗時較長,如何保證在這個階段能堅持下去?
我們知道很多人都能對遊戲產生強烈的興趣、願意為之投入時間,這其中的祕密就是遊戲的獎勵規則。殺死一個怪物就能得到一些金幣,通過完成任務獲得滿足感,通過關卡的設計產生持續吸引力,進而形成正向的反饋。
其實學習程式設計也一樣,實現一小段程式並執行,足以讓人感到成就感和滿足,借鑑這個簡單的心理學技巧,定期給自己設定一些有實際意義但是不太難的目標和任務。太難會讓人失去耐心,太簡單又很無聊,最好設定一個跳起來剛好摸得著的任務。每完成一個目標就給予自己獎勵,可以是完成任務的成就感,也可以是其他的物質獎勵。
這個時候一個代辦記事的清單就可以幫上忙了,可以是一個to do list的軟體,或者自己手寫一張卡片貼到牆上,關鍵在於不要忘了在任務達成後給予自己適當的獎勵。
圖片來源:https://appadvice.com
那如果真的遇到一些麻煩的任務呢,如何順利解決而不至於喪失信心?笛卡爾在《方法論》一書中告訴了我們研究複雜問題的方法和步驟:
- 儘量將其分解為多個比較簡單的小問題,一個一個地分開解決
- 將小問題從簡單到複雜排列,先從容易解決的問題著手
- 子問題被解決後,進行聯調測試,看是否能協同執行
在敏捷開發這種工程思想中我們正是這樣做的,我們需要把業務需求進行拆分然後評估工作量,不僅可以直觀的看到任務進展,手上的工作也不會看起來龐大得難以完成。
最後多說幾句
非科班出身的工程師入門是有一定痛苦的,不像武俠世界裡面的名門正派弟子,也沒有機緣遇到骨骼精奇的世外高人,如何選擇合適自己的學習方式並自我管理是很重要的一方面。沒有任何Low的學習方式,只要直接而又高效,而且要能達到我們的目的就好。以我為例,從大專學校畢業並沒有機會參加本科課程,曾經也在網上攫取各種視訊教程,去別的學校蹭課,甚至帶上禮物去一個老師那裡登門拜訪補課。
另一方面是如何上桌,吃上程式設計這碗飯。學習的成果如果無處施展便成為屠龍之技,參加一些開源專案和一些公益活動,誰不喜歡一個熱心的人呢。也可以嘗試去實現自己的一些idea,當做一個小專案來開發,有了一些專案實踐後去找一個公司實習會容易的多。
我不知道算是有幸還是不幸經歷了這一個過程,矯情一點來說是有一些曲折,但是我知道“聰明”從來不是這個行業的門檻。引用流行於知乎的一句老話“以大多人的努力程度,還輪不到拼天賦的程度”,在Thoughtworks有大量優秀的工程師,從他們身上我能看到聰明不是學習程式設計成功的關鍵,堅持和勤于思考才是。