致:想轉(zhuǎn)行程序員的新手們的第一封信

你有一個(gè)很棒的idea,想要?jiǎng)?chuàng)業(yè),你看了所有關(guān)于精實(shí)創(chuàng)業(yè)的方法論,擁有創(chuàng)業(yè)家精神和準(zhǔn)備冒險(xiǎn)犯難的生活態(tài)度,現(xiàn)在只缺一件事情—你不會(huì)寫code,你沒有把產(chǎn)品做出來的能力,這個(gè)新手正是兩年前的我。
在學(xué)習(xí)寫程序之初,我多么希望能夠有一個(gè)人告訴我該學(xué)什么,需要學(xué)到什么程度,該怎么面對(duì)學(xué)不會(huì)時(shí)的挫折,與怎么培養(yǎng)獨(dú)立解決問題的能力,這些心情我都經(jīng)歷過,現(xiàn)在我想寫這封信給你,告訴你未來會(huì)遇到什么事,該怎么克服,以及你可以成為什么樣的開發(fā)者。
建立正確的心態(tài)
在開始學(xué)習(xí)寫程序之前,我想分享幾個(gè)心態(tài)上的建議,它能幫助你走過未來無數(shù)困難的時(shí)刻,因?yàn)檫@將是條困難且漫長的路,我希望你能用最少的時(shí)間,學(xué)會(huì)你所需要學(xué)會(huì)的知識(shí)和技能。
沒有人規(guī)定你要花多久才能學(xué)會(huì)什么,學(xué)會(huì)了最重要。
學(xué)習(xí)分為知道,會(huì)做和熟悉三個(gè)階段,每學(xué)到一個(gè)新的觀念和技術(shù),都要想辦法和已知的知識(shí)做連接,才能變成自己能獨(dú)立運(yùn)作的技能。
專注在學(xué)會(huì)新的概念是最重要的,網(wǎng)絡(luò)上有非常多的資源,但不同資源適合不同學(xué)習(xí)階段的人,如果一篇教材用你還沒有學(xué)會(huì)的概念為例去解釋你正在學(xué)的概念,請(qǐng)忽略它,我們沒辦法用我們不知道的知識(shí)去記憶新的知識(shí),能用你理解的話教會(huì)你的教材,才是適合你的教材。
大腦里負(fù)責(zé)選擇和學(xué)習(xí)的位置是在不同的區(qū)域,當(dāng)你在選擇要學(xué)什么的時(shí)候,你并沒有在學(xué)習(xí)。
希望我能以過來人的身份幫助你選擇,而你只要專注在學(xué)會(huì)這件事,我將會(huì)告訴你需要學(xué)習(xí)什么和為什么需要學(xué)它,但不會(huì)告訴你它運(yùn)作的方式,因?yàn)楠?dú)立學(xué)習(xí)一個(gè)新的觀念也是你需要培養(yǎng)的能力。
看到這里相信你已經(jīng)準(zhǔn)備好了,那我們開始吧!
學(xué)習(xí)基本語法(Syntax)和運(yùn)算思維(Computational Thinking)
1.選擇第一個(gè)接觸的語言是很重要的,語言的設(shè)計(jì)影響到你對(duì)程序的理解和寫作的習(xí)慣,更重要的,會(huì)影響你學(xué)習(xí)的樂趣與成就感,完全沒有經(jīng)驗(yàn)的你,我會(huì)建議你學(xué)習(xí)Java,更精確一點(diǎn),從Head First Java這本書開始入門,這個(gè)階段你的學(xué)習(xí)目標(biāo)有三個(gè):
第一個(gè)是要是要熟悉語言基礎(chǔ)語法if、for、while、swtich要怎么使用。
第二個(gè)是要學(xué)習(xí)Java的Data Type與理解Primitive Type和Reference Type的差別。
第三個(gè)是要理解面向?qū)ο蟮母拍?,能夠熟悉class的使用,并清楚地解釋Encapsulation、Inheritance、Polymorphism是什么,其中Inheritance最為重要,請(qǐng)務(wù)必理解它。
Java是一個(gè)嚴(yán)格規(guī)范的語言,沒有正確宣告數(shù)據(jù)類別和正確的使用class程序都會(huì)執(zhí)行失敗,現(xiàn)在這個(gè)階段對(duì)你來說也許很不方便,卻也保證你可以建立更正確的觀念,而剛開始學(xué)習(xí)程序,建立正確的觀念是最重要的
做到以上三件事,你在這個(gè)階段的任務(wù)就完成了,但是這個(gè)時(shí)候的你,還不能說會(huì)寫程序,一個(gè)軟件工程師必須要有運(yùn)算思維的思考習(xí)慣,用更簡單的語言說,就是熟悉數(shù)據(jù)結(jié)構(gòu)與算法的運(yùn)用。
2.從熟悉語法到能夠用算法解題是你會(huì)遇到的第一個(gè)門坎,因?yàn)槟氵€沒有建立一步一步拆解問題的能力,沒關(guān)系,讓我?guī)湍阏砟銜?huì)需要用到的方法:
Big O notation:首先你會(huì)需要理解用來分析算法的方法,這個(gè)概念和微積分中多項(xiàng)式極限的概念很像,是用來分析時(shí)間和空間復(fù)雜度的方法,也是我們之后討論不同算法之間權(quán)衡(trade off)的重要依據(jù)。
數(shù)據(jù)結(jié)構(gòu):Array、Stack、Queue、Hash、Linked List、Tree、Graph、Heap。
Java內(nèi)部已經(jīng)幫你實(shí)現(xiàn)Array、Stack、Queue、Hash和Heap,但Linked List、Tree和Graph需要自己建class或是用前面的數(shù)據(jù)結(jié)構(gòu)組合而成,請(qǐng)務(wù)必熟悉各種數(shù)據(jù)結(jié)構(gòu)Java內(nèi)置的操作方式,因?yàn)槲覀兾磥頌樾枰盟鼘?shí)現(xiàn)我們的想法。
算法:Binary Search、Recursion、BFS、DFS、Backtracking、Dynamic Programming。
學(xué)習(xí)算法有一個(gè)重點(diǎn),不同算法的復(fù)雜度不同,請(qǐng)依照上面的順序去學(xué)習(xí)它,如果前一個(gè)概念沒有搞懂就去學(xué)后面,你會(huì)感受到前所未有的痛苦,并非常容易想放棄,例如DFS會(huì)用到Recursion、BFS會(huì)用到Queue和Array、Backtracking會(huì)用到DFS、Dynamic Programming會(huì)用到Recursion、DFS和Hash,觀念是累積下去的,按部就班一步一步學(xué)下去,你會(huì)更容易理解它們的概念。
具備基礎(chǔ)能力前的三個(gè)階段
目前為止,你已經(jīng)知道數(shù)據(jù)結(jié)構(gòu)和算法的基本原理了,但是你還不會(huì)使用它,為了幫助你練習(xí)各種算法運(yùn)用在實(shí)際的問題上面,我會(huì)建議你到leetcode照分類題型練習(xí),解題的平臺(tái)我建議復(fù)制leetcode的題目到coderpad上練習(xí),自己想test case,通過之后,再將解法放到leetcode用別人寫好的test case測試。為了有效熟悉并活用各種算法和數(shù)據(jù)結(jié)構(gòu),你會(huì)經(jīng)歷三個(gè)階段:
一、第一次做題目,你會(huì)完全想不出來,就算是最簡單的題目你可能都沒有想法,這是很正常的,因?yàn)槟氵€沒有建立起運(yùn)算思維,請(qǐng)堅(jiān)持自己想十分鐘,忍住去看解答的沖動(dòng)。我明白這個(gè)過程是很痛苦的,但這十分鐘是連接你學(xué)到的算法和解決實(shí)際問題的重要過程,也是必經(jīng)之路。十分鐘了,你還是想不出來,沒關(guān)系,你可以上網(wǎng)找解答看看其他人是怎么做的了,然后試著在了解他的想法之后,用你的方法再寫一遍,你不需要有任何沮喪的感覺,參考別人的答案也是學(xué)習(xí)的一部分,每種算法和數(shù)據(jù)結(jié)構(gòu)你需要做至少五到十題去熟悉它。
二、所有分類的題型都做過之后,你會(huì)發(fā)現(xiàn)自己重復(fù)做第二次居然還是做不出來,這是非常正常的,因?yàn)檫\(yùn)用算法解決實(shí)際問題這個(gè)過程,你只是知道,還不會(huì)做,所以你需要熟練你的技術(shù)。這個(gè)階段訓(xùn)練的方法就不一樣了,你需要重復(fù)做同一題好幾次,第一次accept之后,請(qǐng)全部清除掉重寫一次,你會(huì)發(fā)現(xiàn)還是有卡住的地方,試著做完,也許你還是需要看解答,沒關(guān)系,每一次做完之后就清除掉重寫,直到你可以獨(dú)立在不看解答的情況下,一次bug free,現(xiàn)在,你才真的搞懂了這一題。
這樣重復(fù)寫的過程,你會(huì)自己歸納出來其中的pattern,這將會(huì)是屬于你自己最珍貴的東西,因?yàn)檫@代表你能獨(dú)立使用算法去解決實(shí)際問題的連接,而這個(gè)pattern在網(wǎng)路上別人的解答里沒有,任何博客也找不到,因?yàn)槊總€(gè)人腦中的pattern都不一樣,這才是能夠跟著你一輩子的東西。
三、這個(gè)時(shí)候你對(duì)做過的題目已經(jīng)非常熟悉了,然而世界上的問題何其多,這個(gè)階段你需要的是大量瀏覽不同類型的題目,現(xiàn)在你不會(huì)知道哪一題要用哪一種算法,所以會(huì)試著嘗試組合不同的算法去解決它,并討論時(shí)間和空間復(fù)雜度,思考在不同情況下你會(huì)用哪一種方法,熟悉這個(gè)過程后你就會(huì)理解,為什么人家說每一題沒有標(biāo)準(zhǔn)答案,因?yàn)閷?shí)際工程問題其實(shí)都有其條件與限制,工程師在做的是討論各種解法的權(quán)衡(trade off),熟悉這個(gè)過程將可以培養(yǎng)你和其他工程師溝通的能力。
到這里,恭喜你具備了初級(jí)軟件工程師的基礎(chǔ)能力,大部分的人在走到這里之前就放棄了,但你沒有,你堅(jiān)持下來了,恭喜!接下來,為了成為初階的web開發(fā)工程師,下一封信我們要來談?wù)剬W(xué)習(xí)新的語言JavaScript和網(wǎng)站開發(fā)所需要的知識(shí)點(diǎn)。
