非專業學生如何系統的學習計算機編程?

去年剛畢業,專業是新聞傳媒,實習是在一家雜誌社做小助理。。。其實小時候就一直對編程非常熱愛,一直以來自己有買各種推薦書籍來學,但總覺得自己是架空了在學,也許看懂一些簡單程序的代碼,也許可以自己寫一些小東西(計算器之類的),其實根本不懂這一切是為什麼,慢慢就發現,計算機科學的博大精深不是這樣的海市蜃樓能夠涵蓋的,現在也畢業了,如果有機會很想從新來一遍,真正系統的學習這門科學,學習編程,但當前的各種現實情況不允許,所以我想哪怕花個3年5年的,自己自學,感問各位前輩有什麼好方法,什麼推薦,真正學進去,學出來。


三年多前的某天,我還在考慮畢業後該去哪個建築工地報道的時候(非調戲,我是暖通工程專業,畢業去工地是標準出路),突然覺得就這麼參加工作太沒有趣味了。

然後,我11塊買了本盜版的《C++ Primer》,呆在宿舍看了兩個月,然後在網上投了份簡歷,恰好被做暖通專業軟體的某公司約去面試,雖然談不上會啥,但靠著嘴皮子把工作拿下了。

剛開始自然是苦逼中的戰鬥機,畫個對話框都弄不好,總是寫出各種複雜的繼承關係,還經常遲到,被領導冷嘲熱諷基本是家常便飯,不過總算是堅持混了大半年。

後來,我覺得繼續這麼混,人生也太沒趣味了,然後我又開始看書了,繼續翻那本盜版神書,其他一些經典圖書也找到了盜版的,不過這次,是認認真真看了,不久,我可以寫一些複雜的功能了(雖然某個功能給自己挖了個大坑,但總算填了),後來,我會用一些設計模式了,再後來,搞明白堆和棧,知道怎麼調試軟體,怎麼優化性能了。然後,看著手上的工資不順眼,便一怒跳槽了,工資double一下,非常舒心。

跳槽完,姿態立馬就變高了,博取了領導信任,開始做一些底層的東西了,比如反應器,自動化處理,內存模型之類的東西。另外,我可以調得一手好程序了,性能方面直接解決了軟體中最讓人頭疼的部分,最終測試報告下來,大型工程文件的編輯時間從4小時變成十幾秒了,老闆都驚呆了,到了半年又給我把工資怒漲了40%。

後面就越來越順了,特別在計算幾何方面,興趣非常大,學的也很快,寫了布爾運算庫,各種三維計算,前一陣子老闆又怒漲4k,慢慢的發現,自己也不比那些計算機專業的差了,從2k到15k花了三年時間,但是半路出家的人,工作的感覺就像娛樂,棒極了。

另外,千萬別加班來彌補差距,沒啥用,該工作的時候做好,回家好好休息,能夠保證戰鬥力持久。


計算機被發明出來解釋去解決人類的實際需求。

所以,編程一定要去試著解決實際問題。有了實際的需求,才會有更多的動力去深入學習。有了興趣和動力,那麼一切都不是難事。

不要把編程當作學問來學習,編程是解決問題的工具!


昨晚在另一個地方發了個類似的回答:哪種學習編程方式更好,系統學習還是邊做邊學?

昨天才進入知乎社區,不知道社區的轉載主要以什麼方式,所以就用最傳統的方式——複製黏貼,這麼轉過來了。

剛註冊知乎就見到了這條問題,所以就留到晚上來回答了。

雖然才畢業一年,但是因為競賽的原因從小學低年級的時候就開始學習程序設計,直到大學讀了計算機,被各種老師教導過、自學過、教過學生。

什麼是編程?

我剛開始學習那時,面向對象和互聯網,至少在國內,還沒推廣開來,甚至不多人知道。直到現在,也就現在大家見到的這個時代了。

扯這歷史要說的是,「編程」對我而言從一開始的競賽,到現在的「創作」,已經是兩個範疇的概念了;同樣對於時代的需求,從從前的科學計算,到現在的各個行業各個角落的各種應用實現,已經不是一個同樣的行為範疇了。

但是,編程的本質上跟當年課本上寫的沒多大區別,就是編寫(廣義上的)計算機可執行的指令(集合)。

這個領域的知識是什麼樣的?

然後要延伸一下時代問題。

從面向對象開始,互聯網時代興起,到現在的移動互聯網時代,編程絕大部分的目的是在於創造「軟體」,而創造軟體也由於世界上最聰明的人群高速集中湧入,以及時代的需求壓力,已經形成了一整套工程學,也就是「軟體工程」了。

現在「編程」被集中在「軟體工程」的需求中,產生的一個結果就是「工程化」,而「工程化」就是整個生產體系開始逐步分化以及逐步專業化,從而出現了這個領域中的各種針對性專業,比如「前端工程師」、「測試工程師」、「演算法分析師」、「.NET軟體工程師」。

在整個軟體的開發周期中,我們都需要跟不同的人在不同程度的合作。即使是個人開發者,都會用到開源的代碼、各種下載的人家做好的工具。

這就是工程化後的結果,也就是「編程」被和其他不同的專業,比如數學、醫學、建築、人文等科學結合在一起然後具體地分化成了各個關聯的模塊。這些模塊有一個特點,就是整體上「臨近相連」。

這什麼意思呢?

舉例說明就是,但從(某個)網站開發而言,就有客戶、老闆、美工、前端工程師、服務端工程師、資料庫管理員、網路推廣等等。這些角色兩兩間可能有工作上的直接關聯,單指這個軟體項目的開發工作的話。

無論哪個是因,哪個是果,現在的情況都是沒兩個角色間的知識必定關聯和有交集。在往廣度上看,整個軟體工程領域以及世界都如此,只是軟體工程領域如建築領域一般,有比較大的定量的專業化,一切都是有根據有標準的。

而至此,形成的一個結果就是,沒有人能掌握所有知識;所有知識都是有關聯的,追尋著關聯的路徑學習產生的效果普遍情況下是最大的。

後面那條可以簡單地證明,假設兩樣知識八竿子打不著,那麼你就要等很久它們才能連起來,發揮加成效用。雖然喬幫主說過,總有一天這些dots總會連起來的,但是嘛......靠譜點也不是不好。

所以,學習這個領域的知識是這樣子進行的

那麼,回到學習上,就變得很明確了。開發的需求需要各種技能,各種技能都是相關的,而一個項目所需要的技術在一定期限內是大致有限的。如果你要開發某樣東西,或者做某種用途(比如科學計算),都需要某個知識點進行切入,從哪裡都好,切入某個知識點,然後用關聯的方式擴充。如果在過程中見到新的不懂的名次,要麼馬上去「擴充」,要麼就記下來,留待以後「點亮」這個天賦,總有一天這些dots......

以上是學習編程要要知道的第一點,這個領域的知識是怎麼組織的。以下第二點,關於學習方法。

一個學習的誤區與結果

有句名言,是布魯克斯(Frederick P. Brooks)說的吧,說過,最好的程序員和最差的產出差n倍。

為何?計算機科學基本上是由數學和機械類學科衍生而來,最大的特徵就是兩道門檻:能不能做出來、這個方法(演算法或者設計)效率有多高。

前者不說,後者最明顯的舉例就是,用加法來計算和用乘法來計算效率差別極大。

這個領域的只是最大的特點就是它們的關係如果你想打通,是需要「理解」的,至少知道怎麼用。你不懂得一個公式、一個技術怎麼使用,你知道有,到需要的時候也用不了。所以鑽研是一種必要的學習習慣。

看到以上內容的時候,你可能會覺得,一開始都設定好要做的目標,然後弄清楚這個範圍需要的知識點,然後都從某點開始,全部學透,就能完成了。

這犯了個軟體工程的一個極端化錯誤,在學習上也同樣適用,因為每次開發都是基本上是一次學習過程,你又不是*訊,你所做的東西就算別人做過,你也一定沒做過。如果別人做好了給你,也不用你做了,騰*也不用去抄了是吧?

這個錯誤就是將整個項目理想化,如果把這次學習視為一個項目的話。整個項目都是原本不存在這個世界上的東西,沒人知道開發(學習)過程中會發生什麼,怎有任何可以相信的精細的計劃?

如果這麼學,你會很容易陷入一個,拿了一本專業書(一個切入點),然後看,然後看著看著就看不下去了。然後?然後就沒有然後了......

我們是怎麼解決這個問題的

軟體工程里是怎麼解決這個問題的呢?敏捷開發(Agile Development),每個項目或多或少都能用到。

詳細解釋可能太多,畢竟我知道的也不多。不過其中最通俗的幾點:將大計劃切分為短周期,並且每個周期結束後調整計劃,使得最近的一個計劃可執行並且有效;計劃中,將每次的產出進行具體化量化,每個周期都發布(生產出)有效的可用的產品,這個產品是在上一個產品的基礎上的改進或者增加;在原有的產出已經難以再升級時,將原來的產品重構(重新設計、重新生產)。

細節的道理就不多說了,都出了多少本書了。

實際上現在你能買到的好的編程教學的書籍都是遵循這個教學模式,也是暫時被認為最有效的書本教學模式。這些書一般會教你從「Hello World!」(到時你就知道是什麼了)開始,讓你手把手做一次,然後逐步深入;有時候做了一次後,在後面介紹了新的技術,又會讓你用新技術跟著做一次;看完整本書,你至少就達到了某個水平了。

要注意的是,你必須有心理準備就是,書上講的,跟你做的根本有不同的產出,或者你根本做不到。比如書上說計算a+b會輸出2,而你的輸出3;書上說要點擊某個按鈕,但是你就是在自己機子上找不到那個按鈕......這些都是不可避免的,而且一般都會浪費很長時間。莫名其妙的問題本身就是以上說的,不知道會遇到的問題的一部分,也是現代程序員加班的其中一主要原因。畢竟,你的機子跟作者的機子肯定不一樣。

所以學習該是這樣的

總的來說,說到了知識是關聯的,學習是以不同的學習成本連接不同知識的過程。還有呢,值得鼓勵的是,隨著知識的增加,智力和經驗會隨之提高,學習成本也會降低,越來越容易學習。

雖然具體到某個知識點只有懂和不懂,但是具體到一個面,還有懂多少的問題。這就回到了剛才的引述,生產效率為什麼會差n倍。因為這是一個廣度和深度的綜合比拼,而隨著時間增長,會形成兩個人知識的「馬太效應」,差距會成倍增長。

不過放心吧,這個增長是有天花板的,無論是知識總量的有限還是需求有限導致的,至少從程序員的工資就可以看出來(哭)。

具體的學習建議

到這裡,至上而下地給出學習建議:

  1. 先有一個想法,像學鋼琴也有一開始想彈奏的曲子,提出一個想用生產出來的產品,或者買一本評價好的入門書,做出書中提出的「產品」為目標

  2. 將這個目標細化,可以找專業人士幫忙,梳理出知識的「切入點」以及周圍的「關聯點」,然後開始計劃第一次迭代(做出第一樣東西),可以是一段很短的程序或者一個作品,但必須有具體的產出

  3. 每次產出後都重新調整計劃,重要的是自己或者專業人士要能具體地評估這次產出的價值。如果是跟著書就自然容易了,就是跟書上對一下就是了

如果要具體給到一個切入點,那麼我的建議是兩個選擇:

  1. 從C語言開始,然後學習演算法,走科班路線

  2. 從網頁製作開始,然後學習網站工程,走產品路線,這是產品中最好入門的了

不必太擔心學錯,因為到達工程級別,你學過的八成知識都不會被作為工具使用,而它們的只是實現了它們的歷史使命——成為你現有某個實用知識的中間點/橋樑、為你現在的學習效率做了一次鋪墊。

實際一點地說,對於一個「畢業了」的程序員,學習一門新的編程語言,可能只需一周,而熟悉需要三周,熟練地用於開發是三個月,精通只需一年。這也是大概而已,嚴謹地說,不同的語言所關聯的知識點的數量是不一樣的。這也不影響舉例,因為在這之前,一個大學生在學習他們的第一門語言,通常是C/C++,用了一個學期,還可能掛科呢(那是態度問題或者是Dota的問題)。

首先吧,別想速成。這要能速成,那麼我們專業人士不就該喝西北風去了?

所以要真解決了學習範圍的問題後,你下一個問題應該是「要實現**應該具備那些知識」一類的了。等你在某個點紮根後,想的就是利用這個學習能力,去另一個自己更喜歡的領域,還是就此為據點擴充範圍,亦或者深入這個領域(也是擴充的一種吧,方向不同)。

最後重申的一點,就是軟體開發本身就是一個學習的過程,只是產出的代碼具備不同的價值而已。軟體的特殊性已經導致了難以重複地寫出兩段相同的代碼,一般只會改寫重寫,或者重用原來的代碼(就是複製黏貼或者引用調用)。


我覺得嘛,不是程序員的人要學編程,多半也沒什麼複雜的問題要解決,就跟學數學一樣,理解她的美,就能學的進去了。


其實做什麼事都一樣,先弄清為什麼要做這件事,確定要做這件事到什麼程度,再為這件事設計如何達到需要程度的方法。如果只是憑藉興趣,可能需要摸清,你的興趣點在什麼地方。我以前做學術論文,每次做完,我都感覺成就感襲來,我居然搞了這麼複雜的數據,架構了這麼複雜的模型,我就誤認為我對做學術是極為感興趣的。但其實,成就感,來源於很多個方面,我並沒有在做學術上感覺到原始的快樂。如果你搞清楚了你的興趣點,後面的一切都順其自然。

如果你只是不知道如何學習編程,我建議,把英文學好,把邏輯理順。再根據每類語言的教程進行學習。其實在實用的範疇,也沒有要求門清兒,也是一個不斷拓展,不斷加深理解的過程。

Anyway,祝你達到你想要的狀態!!


一般計算機專業的本科教學順序是,先學一門基礎語言,C或者C++,接著學習數據結構、操作系統、組成原理、網路、彙編、編譯等內容,自學的話,我覺得應該先把一門語言從頭到尾學一遍,就像你說的,有的時候也能寫個程序但是搞不清楚為什麼這麼實現,若能系統學門語言,雖說不能從底層了解它是如何運作但是可以知道為什麼要這麼做。學了C,再學C++就沒有什麼困難,會了C++,java什麼的就很容易了。。。


計算機科學與技術專業。圖片是大學所修課程,個人覺得並沒有神馬卵用,僅供參考。紅線所劃為個人自由選擇課程。

渣圖還請湊合看!


其實這門科學很不一般,按照常規的直線學習,效率必然很低;光橫向學習的話,必然像你說的一樣是海市蜃樓,所以,從一門基礎語言(C,++)開始,然後弄出東西後回頭了解其根本,中途有分支內容一併看了,然後再繼續往前走,如此循環。


英國孩子從5歲開始就接觸相關課程,美國則更早。這些國家如何對孩子進行編程教育的? 國外更多是採用國際通用的Python語言進行教學,因為Python可做的任務很多,國外幾乎所有發達國家的學校都以此作為入門的計算機語言啟蒙,而且它的延展性特彆強,可以作出很多不同的用途。由於Python語言方便、通用、簡單明了,受全球很多程序員專家歡迎,但在國內卻很少有人教Python語言,更多是教Scratch簡易編程工具,不得不說這是一個遺憾。但又因為Python用途很廣,在國際上通用,所以國內很多人後來不得不選擇自學。同時,它又是一個兼容性很強的編程語言,一般配置的電腦即可使用。你可以試試參加莎士比亞英語小鎮的外教編程課程,據說教的不錯!


我從事計算機編程已經12年了,以前我從事黑客,破解,外掛,音視頻研究,遊戲伺服器主程,從C++ java delphi Python等等都有使用,下到系統底層,上到應用系統層,我都有涉足,從我個人的經驗來告訴你,其實是不是計算機專業並不重要,基本的計算機語句就那麼幾句,if else while for 等,只要你搞定了這幾個基本的語法,那麼學計算機就沒有問題了,因為目前軟體開發說實在的已經高度封裝了,你會不會底層程序的編寫和設計其實並不重要,重要的是你是否有邏輯思維,我想只要你不是個傻子,一般人都是有思維邏輯的,所以我的觀點只要學習個把月 ,熟悉一兩個項目,出去隨便找個 7 8 千的工作不成問題,話又說回來,能否堅持的人不多,很多人一時衝動,堅持下來的人並不多,主要就是一個興趣問題了,有興趣就沒有學不會的東西


推薦閱讀:

神舟電腦這家公司為什麼能活下來?
為什麼中國有最頂級的超級計算機,卻沒有一個能用的消費級CPU?
海盜船的內存條和金士頓的駭客神條誰更好?
Windows 8 關機為何這樣麻煩,微軟如此設計的原因是什麼?
Windows 為什麼容易死機?

TAG:程序員 | 編程 | 計算機 | 計算機技術 | 計算機科學 | 計算機專業 |