編程入門指南 -加密數字貨幣交易所平台

編程⼊⻔指南

前⾔

如今編程成為了⼀個越來越᯿要的「技能」:作為設計師,懂⼀些編程可能會幫你更好地理解⾃⼰的⼯作內容;作 為創業者,技術創始⼈的身份則會讓你的很多⼯作顯得更容易。⽽作為剛想⼊⻔的新⼿,⾯對眼前海ᰁ的信息,或 许根本不知道從哪⾥開始;⼊⻔輕鬆度過初級材料的學習後,發現學習越來越困難,陡峭的學習曲線⼜讓你望⽽却 步;你知道如何在⻚⾯上打印輸出⼀些⽂本⾏,但是你不知道何時該進⾏⼀個真正的有⽤的項⽬;你不清楚⾃⼰還 有哪些不知道的東⻄,你甚⾄搞不清下一步該學什麼。

這篇⽂章的內容对此不仅会有⼀些⽅向性的建議,还会包含⼀個基础核心向的编程⼊⻔导引。当然,Step by Step 的路线是不现实的,并且每个⼈都会有⾃⼰的特点,所以给出的这个编程⼊⻔导引更多的是为了引发读者的 思考,最终帮助你形成适⽤于⾃⼰的学习路线。

但要注意:这篇⽂章是写给那些真⼼想学编程的⼈看的——那些憋着⼀股狠劲⼉,⼀定要做出个什么真东⻄,不学 好不罢休的⼈;⽽不是那些「听说编程好玩」的⼈,在我看来,这种⼈永远都⼊不了编程的⻔,更别提做出个像样 的东⻄来了。

虽然整篇⽂章的基调都是所谓的「强观点,弱坚持」(Strong Opinions, Weakly Held),但读者还是应该像怀疑 身边所有东⻄那样,怀疑我们所写内容的准确性。若有任何相关疑问欢迎公开讨论。

⼼态调整

确定⽬标

在你学习编程之前思考⼀下你的⽬标,当你有最终⽬标时道路会更加的清晰。那么,你想要写什么?⽹站?游戏? iOS 或者 Android 应⽤?或是你是想⾃动化完成⼀些乏味的任务让你有更多的时间看窗外的⻛景?也许你只是想 更具有就业竞争⼒找个好⼯作。所有的这些都是有价值的⽬标,这些⽬标都是你编程学习推动⼒的⼀部分,没有推 动⼒的人,是⽆法在略显枯燥的漫⻓学习之旅中⾛远的。

这段视频也许能给你启发:《⼤多数学校都不会教的东⻄》

不要浮躁

Bad programming is easy. Even Dummies can learn it in 21 days. Good programming requires thought, but everyone can do it and everyone can experience the extreme satisfaction that comes with it. 糟糕的编程很容易。即使是傻⽠也能在21天内学会它。好的编程需要思考,但每个⼈都能做到,每个⼈都能 体验到它带来的极度滿⾜感。

不管是在线下还是线上的书店,满⽬都是《21天学通 X》这种速成书⽬,它们都承诺在很短⼀段时间内就让你能够 学会相关技术。Matthias Felleisen 在他的著作 How to Design Programs ⼀书中明确指出了这种「速成」的趋 势并予以了以上的讽刺。

所谓的「捷径」或者说「银弹」是不存在的,智者说过,精通某个东⻄需要10年或10000个⼩时,也就是汉语中的 「⼗年磨⼀剑」,所以不用着急,功不唐捐。

培养兴趣

Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

⼤多数优秀的程序员做编程不是因为他们期望得到报酬或得到公众的崇拜,⽽是因为编程很有趣。

– Linus Torvalds

沉醉于编程,编程更是为了兴趣。兴趣是推动⼒的不竭源泉,保持这种充满兴趣的感觉,以便于你能将其投⼊到你 的10年/10000⼩时的编程时间中。编程很有趣,那是探索的喜悦。那是创造的喜悦。看到⾃⼰亲⼿完成的作品显 示在屏幕上很有趣。有⼈为你的代码⽽惊叹很有趣。有⼈在公共场合称赞你的产品、邻居使⽤你的产品、以及在媒 体上讨论你的产品很有趣。编程应该⼗分有趣,若并⾮如此,就找出导致编程⽆趣的问题,然后解决之。

開始學習

令⼈警醒的故事

剛上初中時我便開始了編程學習,很不幸,我讀完了好⼏本當時普遍存在的諸如《21天精通C++》這類的垃圾書, 當時讀完也⽆⼤碍,甚至还能寫點⼩程序。但是軟體出故障了我不知道為什麼,稍顯龐⼤的編程問題⽆從下⼿,碰 到現有的庫做不到的事也只能兩⼿⼀摊。雖然我每天不停地編碼,但我發現⾃⼰的編程能⼒卻是提⾼的如此緩慢, 對於「迭代」與「遞歸」的概念只有極其有限的了解,可以說只是把計算機當成了計算器來使⽤。

進⼊⼤學後,我主修了物理學,最初的⼀段時間⾥我⼀直在記憶背誦那些物理公式,卻不理解她們是如何得出的, 她們之間有什麼聯繫,亦或是她們的意義。我不停地學習如何計算解答⼀些常⻅的物理問題,但對在這些 How 背 後的 Why ⼀⽆所知。

⽽在我嘗試做⼀些基於物理⾏為的電腦遊戲時我再次遇到了之前的的困難:⾯對新問題時⽆從下⼿,⾯對新問題時 的恐懼不斷累積滋⽣,我開始主動逃避,不去真正地理解,⽽是幻想能通過Google搜索複製粘貼程式碼解決問題。 幸運的是,⼤⼆時的⼀堂課完全改變了我的學習⽅法。那是第⼀次我有了「開天眼」的感覺,我痛苦地意識到,我 對⼀些學科只有少的可憐的真正的理解,包括我主修的物理與輔修的計算機科學。

關於那堂課:那時我們剛剛學習完電學和ሀ義相對論的內容,教授在⿊板上寫下了這兩個主題,並畫了一根線將他 們連了起來。「假設我們有⼀個電子沿導線以相對論級別的速度移動…」,⼀開始教授只是寫下了那些我們所熟悉 的電學與ሀ義相對論的常⻅公式,但在數個⿊板的代數推導後,磁場的公式神奇的出現了。雖然幾年前我早已知道 這個公式,但那時我根本不知道這些現象間的有著這樣潛在的聯繫。磁與電之間的差別只是「觀察⻆度」的問題, 我猛然醒悟,此後我不再僅僅追求怎麼做 (How),我開始問為什麼 (why),開始回過頭來,拾起那些最基 礎的部分,學習那些我之前我本該好好學的知識。這個回頭的過程是痛苦的,希望你們能就此警醒,永遠不要做這種傻 事。

警醒後的反思

這幅圖取⾃ Douglas Hofstadter 的著作 Gödel, Escher, Bach。圖中的每⼀個字⺟都由其他更⼩的字⺟組成。在 最⾼層級,我們看的是 “MU”,M 這個字⺟由三個 HOLISM (整全觀)構成,U則是由⼀個 REDUCTIONISM (還原論)構成,前者的每⼀個字⺟都包含後者的後者整個詞,反之亦然。⽽在最低層級,你會發現最⼩的字⺟⼜ 是由᯿復的 “MU” 組成的。

每⼀層次的抽象都蘊含著資訊,如果你只是幼稚地單⼀運⽤整體論在最⾼層級觀察,或運⽤還原論觀察最低層級, 你所得到的只有 “MU” (在⼀些地區的⽅⾔中 mu 意味著什麼都沒有)。問題來了,怎樣才能盡可能多的獲取每 個層級的資訊?或者換句話說,該怎樣學習複雜領域(諸如編程)包含的眾多知識?

教育與學習過程中普遍存在⼀個關鍵問題:初學者們的⽬標經常過於傾向整全觀⽽忽略了基礎,舉個常⻅的例⼦, 學⽣們⾮常想做⼀個機器⼈,卻對背後

理解物理模型 → 理解電子⼯程基礎 → 理解伺服系統與傳感器 → 讓機器⼈動起來

這⼀過程完全提不起興趣。

在這⾥對於初學者有兩個⼤坑:

  1. 如果初學者們只與預先構建好的「發動機和組件」接觸(沒有理解和思考它們構造的原理),這會嚴᯿限制他 們在將來構建這些東⻄的能⼒,並且在診斷解決問題時⽆從下⼿。
  2. 第⼀個坑沒有第⼆個那麼明顯:幼稚的「整體論」⽅法有些時候會顯得很有效,這有⼀定的隱蔽性與誤導性, 但是⼀兩年過後(也許沒那麼⻑),當你在學習路上⾛遠時,再想回過頭來「補⾜基礎」會有巨⼤的⼼理障 礙,你得抛棄之前⾃⼰ሀ隘的觀念,耐⼼地緩步前進,這⽐你初學時學習基礎知識困難得多。

但也不能矯枉過正,陷⼊還原論的⼤坑,初學時便⼀⼼試圖做宏⼤的理論,這樣不僅有⼀切流於理論的危險,枯燥 和乏味還會讓你失去推動⼒。這種情況經常發⽣在計算機科班⽣身上。

為了更好理解,可以將學習編程類⽐為學習廚藝:你為了燒得⼀⼿好菜買了⼀些關於菜譜的書,如果你只是想為家 ⼈做菜,這會是⼀個不錯的主意,你᯿復菜譜上的步驟也能做出不賴的菜餚,但是如果你有更⼤的ᰀ⼼,真的想在 朋友⾯前露⼀⼿,做⼀些ᇿ⼀⽆⼆的美味佳肴,甚⾄成為「⼤廚」,你必須理解這些菜譜背後⼤師的想法,理解其 中的理論,⽽不僅僅是⼀味地實踐。但是如果你每天唯⼀的⼯作就是閱讀那些厚᯿的理論書籍,因為缺乏實踐,你 只會成為⼀個糟糕的廚⼦,甚⾄永遠成不了廚⼦,因為看了⼏天書後你就因為枯燥放棄了廚藝的學習。 總之,編程是連接理論與實踐的紐帶,是計算機科學與計算機應⽤技術相交融的領域。正確的編程學習⽅法應該 是:通過⾃頂⾯下的探索與項⽬實踐,獲得編程直覺與推動⼒;從⾃底向上的打基礎過程中,獲得最᯿要的通⽤⽅ 法並鞏固編程思想的理解。

作為初學者,應以後者為主,前者為輔。

程序設計基礎

「學編程應該學哪⻔語⾔?」這經常是初學者問的第⼀個問題,但這是一個錯誤的問題,你最先考慮的問題應該是 「哪些東⻄構成了編程學習的基礎」?

編程知識的⾦字塔底部有三個關鍵的部分:

  1. 算法思想:例如怎樣找出⼀組數中最大那個數?⾸先你得有⼀個 maxSoFar 變⼦,之後對於每個數…
  2. 語法:我怎樣⽤某種編程語⾔表達這些算法,讓計算機能夠理解。
  3. 系統基礎:為什麼 while(1) 時線程永遠⽆法結束?為什麼 int *foo() { int x = 0; return &x; } 是不可⾏的?

啟蒙階段的初學者若選擇C語⾔作為第一⻔語⾔會很困難並且枯燥,這是因為他們被迫要同時學習這三個部分,在 能做出東⻄前要花費很多時間。

因此,為了盡ᰁ最⼩化「語法」與「系統基礎」這兩部分,建議使⽤ Python 作為學習的第一⻔語⾔,雖然 Python 對初學者很友好,但這並不意味著它只是⼀個「玩具」,在⼤型項⽬中你也能⻅到它強⼤⽽靈活的身影。 熟悉 Python 後,學習 C 語⾔是不錯的選擇:學習 C 會幫助你以靠近底層的視⻆思考問題,並且在後期幫助你理解操作系統層級的⼀些原理。

下面給出了一個可供參考的啟蒙階段導引,完成後你會在頭腦中構建起⼀個整體框架,幫助你進⾏⾃頂⾯下的探索。下面的材料沒有先後順序,請任意選擇,如果卡殼的話可以考慮換另一份材料。

MIT 6.00.1x (麻省理⼯:計算機科學和 Python 編程導論)。雖然該課程的教學語⾔為 Python,但作為⼀⻔優秀的導論課,它強調學習計算機科學領域⾥的᯿要概念和範式,⽽不僅僅是教你特定的語⾔。如果你不是科 班⽣,這能讓你在⾃學時開闊眼界;課程內容:計算概念,Python 編程語⾔,⼀些簡單的數據結構與算法, 測試與調試。

Harvard CS50x (哈佛⼤學:計算機科學)。同樣是導論課,但這⻔課與MIT的導論課互補。教學語⾔涉及 C, PHP, JavaScript + SQL, HTML + CSS,內容的⼴度與深度⼗分合理,還能夠了解到最新的⼀些科技成果,可以很好激發學習計算機的興趣。⽀線任務:閱讀《編碼》

結束啟蒙階段後,初學者積累了⼀定的程式碼⼦,對編程也有了⼀定的了解。這時你可能想去學⼀⻔具體的技術,例如 Web 開發, Android 開發,iOS 開發什麼的,你可以去嘗試做⼀些盡可能簡單的東⻄,給⾃⼰⼀些正反馈,補充⾃⼰的推動⼒。但記住別深入,這些技術有⽆數的細節,將來會有時間去學習;同樣的,這時候也別過於深⼊特定的框架和語⾔,現在是學習計算機科學通⽤基礎知識的時候,不要試圖去抄近路直接學你現在想學的東⻄,這是注定會失敗的。

那麼⼊⻔階段具體該做些什麼呢?這時你需要做的是反思⾃⼰曾經寫過的程式,去思考程式為什麼 (Why) 要這樣設計?,思考怎樣 (How) 寫出更好的程式?試圖去探尋理解編程的本質:利用計算機解決問題。

設想 :

X = ⽤於思考解決⽅案的時間,即「解決問題」部分

Y = ⽤於實現程式碼的時間,即「利用計算機」部分

⽂編程能⼒ = F(X, Y) (X>Y)

要想提⾼⽂編程能⼒,就得優化 X,Y 與函數 F(X, Y),很少有書的內容能同時著᯿集中在這三點上,但有⼀本書做 到了——Structure and Interpretation of Computer Programs (SICP)《計算機程序的構造和解釋》,它為你指 明了這三個變⼦的⽅向。在閱讀 SICP 之前,你也許能通過調⽤幾個函數解決⼀個簡單問題。但閱讀完 SICP 之後,你會學會如何將問題抽象並且分解,從⽽處理更複雜更龐⼤的問題,這是編程能⼒巨⼤的⻜躍,這會在本質上 改變你思考問題以及⽤程式碼解決問題的⽅式。此外,SICP 的教學語⾔為 Scheme,可以讓你初步了解函數式編 程。更᯿要的是,它的語法⼗分簡單,你可以很快學會它,從⽽把更多的時間⽤於學習書中的編程思想以及複雜問題的解決之道上。

Peter Norvig 曾經寫過⼀篇⾮常精彩的 SICP 書評,其中有這樣⼀段:

To use an analogy, if SICP were about automobiles, it would be for the person who wants to know how cars work, how they are built, and how one might design fuel-efficient, safe, reliable vehicles for the 21st century. The people who hate SICP are the ones who just want to know how to drive their car on the highway, just like everyone else.

如果你是⽂中的前者,閱讀SICP將成為你銜接啟蒙與⼊⻔階段的關鍵點

雖然SICP是⼀本「⼊⻔書」,但對於初學者還是有⼀定的難度,以下是⼀些⼗分有⽤的輔助資源:

  1. Udacity CS212 Design of Computer Program:由上⽂提到的Google 研究主管 Peter Norvig 主講,教學語⾔為 Python,內容有⼀定難度。
  2. How to Design Programs, Second Edition:HtDP 的起點⽐SICP低,書中的內容循循善誘,對初學者很友好,如果覺得完成SICP過於困難,可以考慮先讀⼀讀 HtDP。
  3. UC Berkeley SICP 授課影片以及 SICP 的兩位作者給 Hewlett-Packard 公司員⼯培訓時的錄像(中文版項⽬)
  4. Composing Programs:⼀個繼承了SICP思想但使⽤Python作為教學語⾔的編程導論(其中包含了⼀些⼩項⽬)
  5. SICP 解題集:對於書後的習題,作為初學者應盡⼒並盡⼒完成。

完成了這部分學習後,你會逐步建立起⼀個⾃⼰的程式設計模型,你的腦⼦⾥不再是⼀團亂麻,你會意識到記住庫 和語法並不會教你如何解決編程問題,接下來要學些什麼,在你⼼⾥也會明朗了很多。這時候才是真正開始進⾏項 ⽬實踐,補充推動⼒的好時機。關於項⽬實踐:對於⼊⻔階段的初學者,參與開源項⽬還為時過早,這時候應該開始⼀些簡單的項⽬,諸如搭建⼀個⽹站並維護它,或是編寫⼀個⼩遊戲再不斷進⾏擴展,如果你⾃⼰的想法不明 確,推薦你關注 炼⽠研究所 ,或者從 Mega Project List 中選取⾃⼰喜歡的項⽬。

如果你覺得 SICP 就是搞不定,也不要強迫⾃⼰,先跳過,繼續⾛常規路線:開始讀 The Elements of Computing Systems 吧,它會教會你從最基本的 Nand ⻔開始構建計算機,直到俄羅斯⽚在你的計算機上順利 運⾏。 具體內容不多說了,這本書會貫穿你的整個編程⼊⻔階段,你⼊⻔階段的⽬標就是堅持完成這本書的所有 項⽬(包括⼀個最簡的編譯器與操作系統)。

為了完全搞定這本書,為了繼續打好根基。為了將來的厚積薄發,在下⾯這⼏個⽅⾯你還要做⾜功課(注意:下⾯ 的內容沒有絕對意義上的先後順序):

計算機系統基礎

有了之前程式設計的基礎後,想更加深入地把握計算機科學的脈絡,不妨看看這本書:Computer Systems: A Programmer’s Perspective, 3/E《深入理解計算機系統》。這⾥點名批評這本書的中譯名,其實根本談不上什麼深入啦,這本書只是 CMU 的「計算機系統導論」的教材⽽已。CMU的計算機科學專業相對較偏軟體,該書就是從⼀個程式⼈的視⾓觀察計算機系統,以「程式在計算機中如何執⾏」為主線,全面闡述計算機系統內部實現的諸多細節。

如果你看書覺得有些枯燥的話,可以跟⼀⽂ Coursera 上的 MOOC: The Hardware/Software Interface,這⾔課的內容是 CSAPP 的⼀個⼦集,但最經典的實驗部分都移植過來了。同時,可以看看 The C Programming Language,回顧⼀下C語⾔的知識。

完成這本書後,你會具備堅實的系統基礎,也具有了學習操作系統,編譯器,計算機網絡等內容的先決條件。當學習更⾼級的系統內容時,翻閱⼀下此書的相應章節,同時編程實現其中的例⼦,一定會對書本上的理論具有更⼤的感性認識,真正做到經⼿的程式碼,從上層設計到底層實現都了然於胸,並能在腦中回放數據在⽹絡->內存->緩存->CPU 的流向。

資料結構與算法基礎

如今,很多⼈認為編程(特別是做 web 開發)的主要部分就是使⽤別⼈的程式碼,能夠⽤清晰簡明的⽅式表達⾃⼰ 的想法⽐掌握硬核的數學與算法技巧᯿要的多,資料結構排序函數⼆分搜索這不都內建了嗎?⼯作中永遠⽤不到, 學算法有啥⽤啊?這種扛著實⽤主義⼤旗的「碼農」思想當然不可取。沒有扎實的理論背景,遭遇瓶頸是遲早的 事。

資料結構和算法是配套的,⼊⻔階段你應該掌握的主要內容應該是:這個問題⽤什麼算法和資料結構能更快解決。 這就要求你對常⻅的資料結構和算法了熟於⼼,你不⼀定要敲程式碼,⽤紙⼿寫流程是更快的⽅式。對你不懂的資料 結構和算法,你要去搜它主要拿來幹嘛的,使⽤場景是什麼。

供你參考的學習資源:

  1. 《算法導論》:有人說別把這本書當⼊⻔書,這本書本來就不是⼊⻔書嘛,雖說書名是 Introduction to Algorithms,這只不過是因為作者不想把這本書與其他書搞᯿名罷了。当然,也不是沒辦法拿此書⼊⻔,讀第 ⼀遍的時候跳過習題和證明就⾏了嘛,如果還覺得⼼虛先看看這本《資料結構與算法分析》
  2. Algorithms: Design and Analysis [Part 1] & [Part 2]:Stanford 開的算法課,不限定語⾔,兩個部分跟下來 算法基礎基本就有了;如果英⽂不過關:麻省理⼯學院:算法導論
  3. ⼊⻔階段還要注意培養使⽤常規算法解決⼩規模問題的能⼒,結合前⽂的SICP部分可以讀讀這幾本書:《程式珠璣》,《程式設計實踐》

其他基礎

編程⼊⻔階段⽐較容易忽視的幾點:

  1. 學會提問:學習中肯定會遇到問題,應該學會正確的使⽤搜尋引擎。當單靠檢索⽆法解決問題時,去 Stack Overflow 或知乎提問,提問前讀讀這篇⽂章:能有效解決問題的提問⽅法。
  2. 不要做⼀匹ᇿ狼:嘗試在 CoCode 與他⼈交流想法。嘗試搭建⼀個像這樣簡單的⽂⽹站。試著在部落格上記錄⾃⼰的想法。訂閱⾃⼰喜歡的編程類部落格,推薦⼏個供你參考:Joel on Software, Peter Norvig, Coding Horror
  3. 學好英語:英語是你獲取⾼質⼁學習資源的主要⼯具,但在⼊⻔階段,所看的那些翻譯書資訊損耗也沒那麼嚴᯿,依你⾃⼰情況權衡吧。

⼩結

以上的內容你不應該感到畏懼,編程的⼊⻔不是⼏個星期就能完成的⼩項⽬。期間你還會遇到⽆數的困難,當你碰 壁時試著嘗試「費曼」技巧:將難點分⽽化之,切成⼩知識塊,再逐個對付,之後通過向別⼈清楚地解說來檢驗⾃ ⼰是否真的理解。当然,依舊會有你解決不了的問題,這時候不要強迫⾃⼰——很多時候當你之後回過頭來再看這 個問題時,⼀切豁然開朗。

此外不要局限於上⽂提到的那些材料,還有⼀些值得在⼊⻔階段以及將來的提升階段反覆閱讀的書籍。這⾥不得不 提到在 Stack Overflow 上票選得出的程序員必讀書單中,排在前兩位的兩本書:

Code Complete:不管是對於經驗豐富的程序員還是對於那些沒有受過太多的正規訓練的新⼿程序員,此書都能 ⽤來填補⾃⼰的知識缺陷。對於⼊⻔階段的新⼿們,可以᯿點看看涉及變⼀名,測試,個⼈性格的章節。

The Pragmatic Programmer :有人稱這本書為程式碼⼩全:從 DRY 到 KISS,從做⼈到做程序員皆有涉及。

這本書的作者 Dave ,在書中留了這樣⼀段話:

You’re a Pragmatic Programmer. You aren’t wedded to any particular technology, but you have a broad enough background in the science, and your experience with practical projects allows you to choose good solutions in particular situations. Theory and practice combine to make you strong. You adjust your approach to suit the current circumstances and environment. And you do this continuously as the work progresses. Pragmatic Programmers get the job done, and do it well.

這段話以及他創⽴的 The Pragmatic Bookshelf ⼀直以來都積極地影響著我,因此這篇指南我也盡⼀切努力貫徹了這個思想,引導並希望你們成為⼀名真正的 Pragmatic Programmer 。

後⽂

如果你能設法完成以上的所有任務,恭喜你,你已經真正實現了編程⼊⻔。這意味着你在之後更深入的學習中,不會畏懼那些學習新語⾔的任務,不會畏懼那些「複雜」的 API,更不會畏懼學習具體的技術,甚至覺得很容易。當然,為了掌握這些東⻄你依舊需要⼤量的練習,腰還是會疼,⾛路還是會費⼒,一⼝⽓也上不了5樓。但我能保證你會在思想上有巨⼤的轉變,獲得極⼤的⾃信,看⽼師同學和 CSD

查看原文
此頁面可能包含第三方內容,僅供參考(非陳述或保證),不應被視為 Gate 認可其觀點表述,也不得被視為財務或專業建議。詳見聲明
  • 讚賞
  • 留言
  • 轉發
  • 分享
留言
0/400
暫無留言