程式設計入門自學指南
每天都看到很多對程式設計感興趣的人在問是不是可以自學軟體開發,或者應該怎麼自學 程式設計才能入門。在這篇文章裡,我將嘗試重現一個初學者在學習計算機程式設計時可能會 碰到的問題,並儘量提供相應的解決思路,希望對初學者有所幫助。如果你在看完 這篇文章後還是有些疑惑,歡迎點選這裡諮詢我。
目錄
- 程式設計可以自學嗎?
- 學習程式設計需要什麼基礎?
- 什麼是程式語言?什麼是程式?
- 我應該學習哪種程式語言?
- 程式設計的核心思維是什麼?
- 應該按什麼步驟學習程式語言?
- 學習程式設計有什麼方法嗎?
1、程式設計可以自學嗎?
答案是肯定的,而且自學是學習軟體程式設計極其重要的一個途徑。不過最好的方式是 自學的同時,有一個可以幫助解決問題的同事或者老師,這樣可以避免卡在一個問題上 太長時間。
現在有很多途徑可以自學,例如IT圖書,或者線上視訊教程,我們的網站 也提供一些面對初學者的免費的線上互動課程,可以邊學習邊實踐, 你也可以嘗試一下:
2、學習程式設計需要什麼基礎?
簡單地說,只要具備正常的思維能力,就可以學習程式設計。
讓我們從一個實際的梗來理解這一點:如何把大象裝進冰箱裡?
你也許知道這個搞笑問題的搞笑答案:
這就是程式設計所需要的最基本的思維能力:把一個大的問題分解為若干個小的問題, 解決了小的問題,大的問題就解決了,這種分而治之的思考方法是一種相當工程化 的思維,也是科學技術在過去的兩百年裡的統治性思維。
回憶一下,你在生活中難道不就是這麼做的嗎?程式設計實際上就是把生活中 常見的思維活動用程式語言表達出來的一個過程。
3、什麼是程式語言?什麼是程式?
如果把計算機看成一個人,程式語言就是你和計算機對話的語言,你需要用計算機 能聽懂的語言才能和計算機對話,就像你需要用當地的語言才能和老外溝通一個 道理。
不過由於發明一種新的程式語言的成本相當低,而成就感相當高,因此目前已經 出現了太多的程式語言。即有針對娃娃的圖形化程式語言,也有中文的程式語言, 更有針對不同計算平臺的程式語言,試圖學習所有的程式語言是不明智的,也是 毫無必要的,因為程式設計最重要的是思維,語言只是向計算機表達你的思維的 一個手段而言。
在和計算機溝通時,一次說一句話是比較低效的,因為它會處理的非常快,大量的 時間浪費在等待我們的輸入上。所以通常是寫很多句話一併告訴計算機照著做,這 就是我們常說的計算機程式。例如,對於前面說到的把大象放進冰箱這個任務,可 以編寫如下包含三句話的計算機程式:
openFrigDoor putElephantIntoFrig closeFrigDoor
基本上就是我們的操作步驟的翻譯,對吧?
4、我應該學習哪種程式語言?
雖然程式語言不重要,但是初學者選擇合適的程式語言卻非常重要,因為它會 影響你的學習效果和成就感的達成,而且,你終歸需要選擇一種程式語言才能 開始學習程式設計。
就像大家都喜歡學英語而不是非洲某個國家的法語變種一樣,通常你選擇一個 大家都在用的程式語言是不會有大的問題的,例如看一下權威的TIOBE 程式語言排行榜2019年3月的統計:
Mar 2019 | Mar 2018 | Change | Programming Language | Ratings | Change |
---|---|---|---|---|---|
1 | 1 | Java | 14.880% | -0.06% | |
2 | 2 | C | 13.305% | +0.55% | |
3 | 4 |
![]() |
Python | 8.262% | +2.39% |
4 | 3 |
![]() |
C++ | 8.126% | +1.67% |
5 | 6 |
![]() |
Visual Basic .NET | 6.429% | +2.34% |
6 | 5 |
![]() |
C# | 3.267% | -1.80% |
7 | 8 |
![]() |
JavaScript | 2.426% | -1.49% |
8 | 7 |
![]() |
PHP | 2.420% | -1.59% |
9 | 10 |
![]() |
SQL | 1.926% | -0.76% |
10 | 14 |
![]() |
Objective-C | 1.681% | -0.09% |
11 | 18 |
![]() |
MATLAB | 1.469% | +0.06% |
12 | 16 |
![]() |
Assembly language | 1.413% | -0.29% |
13 | 11 |
![]() |
Perl | 1.302% | -0.93% |
14 | 20 |
![]() |
R | 1.278% | +0.15% |
15 | 9 |
![]() |
Ruby | 1.202% | -1.54% |
16 | 60 |
![]() |
Groovy | 1.178% | +1.04% |
17 | 12 |
![]() |
Swift | 1.158% | -0.99% |
18 | 17 |
![]() |
Go | 1.016% | -0.43% |
19 | 13 |
![]() |
Delphi/Object Pascal | 1.012% | -0.78% |
20 | 15 |
![]() |
Visual Basic | 0.954% | -0.79% |
不過貿然地從眾選擇並不適合所有的情況,每種程式語言都有它特定的優勢領域和優勢生態, 我嘗試根據你學程式設計的目的以及特定領域從業企業的主流選擇給出適合初學者的幾種選擇, 但更細化地分析遠遠超出了本文的範圍:
學習目的 | 推薦程式語言 | 推薦理由 |
---|---|---|
只是玩玩 | JavaScript | 隨處可以找到執行環境,容易獲得成就感 |
開發網頁應用或網站 | JavaScript | 只有JavaScript可以支援單一語言前後端全棧開發 |
開發安卓應用 | kotlin、java | Kotlin是趨勢,Java更通用 |
開發蘋果應用 | Swift、Object-C | Swift是趨勢,初學者不要選Object-C |
開發遊戲 | C#、JavaScript、C/C++ | C#是因為Unity的存在,JavaScript更適合網頁遊戲,C/C++更適合網路端遊 |
開發資料分析或機器學習應用 | Python、Julia、R | Python是這一領域當之無愧的王者,Julia是值得關注的趨勢語言,R在資料分析上有自己的價值 |
開發企業應用 | Java、C# | 去偏傳統的IT公司工作的最佳語言是Java和C#,工作機會非常多 |
開發嵌入應用 | C、Assembly Language | 穿戴裝置或IOT軟體的執行環境受限,需要這種底層的語言 |
開發服務端應用 | JavaScript、Go | JavaScript是因為NodeJS的存在,Go是因為它為網路服務應用開發專門進行了優化 |
如果你目前還沒有明確的學習目的或者傾向性,我推薦兩種語言:JavaScript 和Python 。 這兩種語言都有很好的生態,意思是當你需要幫助或者需要使用第三方程式碼時比較容易獲取。 如果你有意向資料分析/機器學習/人工智慧方向發展,那麼選擇Python,其他情況,選擇JavaScript。
無論如何,還是建議你首先考慮自己學習程式設計的目的是什麼,有哪個方向是自己感興趣 並且願意付出時間和努力的,畢竟,興趣是最好的老師。
5、程式設計的核心思維是什麼?
在機器學習成為顯學之前,傳統的程式設計思維只有一條主線,就是邏輯的表達:把你解決問題 的思維,用特定的程式語言表達出來,整理出程式讓計算機去執行。這需要你把目標 問題分解成一個一個的已經解決的小問題,然後再把這些小問題的解決方案整合成最終 的完整解決方案。
理論上只需要三種整合手段就可以實現任何計算任務:順序、條件判斷和跳轉:
第一種就是我們解決大象問題時用到的,順序整合邏輯,依次執行分解後的解決方案就 可以得到最終的解決方案。順序執行是最基本的整合邏輯,它為程式的編寫奠定了基礎。
第二種關鍵的整合手段是條件判斷,意思是需要根據執行時的實際情況判斷是執行 方案A還是執行方案B,這個看起來極其簡單的判斷邏輯事實上是程式展現出千變萬化 的核心所在。你可以在很多軟體裡觀察到條件判斷的存在,例如高鐵的煙感探測軟體只有 在檢測到有人在車廂內抽菸時才會報警,而遊戲只有在你擊殺大BOSS之後才會通關,或者 12306檢測到你成功識別了它相當有情趣的驗證碼之後才允許你登入…
第三種整合手段是跳轉,這使得程式可以改變執行的先後流程,從而改變程式的 執行效果。實際上條件判斷之後執行的就是一種規範化的跳轉,例如跳過方案A的片段或者 跳過方案B的片段。
迴圈則是另一種常見的規範化跳轉,它可以讓我們將一個方案重複執行若干次,而不是在程式 中將這個方案複製若干次。例如,當需要我們編寫程式實現猴子吃香蕉的任務時,可以看到使用 樸素的順序整合與迴圈整合的區別:
因此,在傳統意義上的程式設計,其核心思維就是目標任務的分解與解決方案的整合 ,將目標任務 分解細化到你已有的解決方案層面,再使用以上三種手段進行整合。
軟體2.0
在機器學習興盛之前,幾乎所有的軟體都是規則邏輯的表達,開發者需要對任務進行分解, 理清每一個細節的解決方案,然後再整合到一起。雖然技術不斷地更迭,也不斷出現新的 開發語言和領域模型,但是這一基本的思路是從來沒有變化過的。
不過機器學習尤其是最近十年深度學習的興起,已經逐漸產生了一種新的軟體開發正規化, 這種新的正規化被Tesla的AI主管Andrej Karpathy稱為軟體2.0 。 如果你學習程式設計的目的是要進入人工智慧領域,希望這部分的內容對你有所幫助。
在傳統的程式設計中,開發者是規則的制定者,這些規則以程式的形式存在,而計算機則僅僅 負責執行,也許由於開發者的某個疏忽可能會導致程式的執行出人意料,但整體上來講 開發者是程式的強力操控者,所有的執行邏輯是開發者的思維的展示。
但是在軟體2.0 中,開發者只是實現一個基準的程式,而大量具體化的處理規則是這個 基準程式通過對大量資料的處理而得出的,也就是說,程式執行的規則一部分由開發者設定 (被稱為模型的超引數),而另一部分規則卻是由程式自己通過與資料的磨合優化出來的。
例如,人臉識別已經從早期的手工設計用於識別的特徵進化到由深度神經網路自動從大量 標註資料中提取特徵:
在軟體2.0 中的基準程式需要更高層級的抽象,而不侷限在一事一議的具體問題解決 的邏輯表述上。在目前這一層主要是利用人工神經網路來實現的,程式自主學習的規則體現 在神經元的連線權重調整上。因此軟體2.0 的開發正規化,其核心思維就是設計適合 問題領域的模型 ,然後用資料 來優化出模型的引數。
軟體2.0還處於極其早期的萌芽階段,但非常值得初學者關注,它的發展也許會最終 改變軟體開發的模式,雖然我確信在相當長的時間內程式設計作為一種工作而言都不會消失。
6、應該按什麼步驟學習程式語言?
程式設計是需要熟練的掌握一些基本技能的,因為需要用這些基本技能來組合出來針對特定 問題的解決方案。當你還是一張白紙的時候,即使瞭解了順序、條件判斷或者跳轉、迴圈 之類的思維也解決不了具體問題,因為分解到最後還是找不到可用的武器。
程式語言是你的第一個武器,要用好這個武器,就需要儘可能多的瞭解一個程式語言 的能力。可以參考下面的問題探索程式語言的能力:
1、這個程式語言怎麼定義變數、函式或者類?
變數是讓同一段程式能夠適應各種執行環境的必備品,在程式中順利地使用變數意味著 你有了初步的抽象能力。幾乎所有的程式語言都支援變數,那麼先了解一個程式語言如何 定義變數、如何給變數賦初值是理所應當的。
例如,你要編寫的程式可能有很多個註冊使用者,而你的程式核心邏輯並不需要根據使用者的不同 而區別對待,那麼將註冊使用者抽象成一個變數來編寫你的程式邏輯就是合理的選擇:
函式(或者過程)是組織可複用程式碼的一種常用手段。如果有一個功能你會在多個地方使用, 那麼把這個功能封裝到一個函式裡是常見的程式碼複用手段,這樣就避免了同樣的實現程式碼 在程式的不同地方重複出現,優化了程式碼,也更容易維護。
如果說函式是對計算機原生的順序過程化思維的一種優化組合方法,那麼類則是面向 物件的軟體設計思維的優化組合方式,不妨簡單地把面向物件視為對現實世界中的 實體物件以及相互關係的模擬,例如可以把所有的使用者視為一個類,因為在我們的程式 中這些使用者有一些共同的特性和方法。
2、這個程式語言怎麼表達順序、條件判斷、跳轉或迴圈邏輯?
就像前面說到的,這些組合手段用來把程式的各部分拼裝在一起,因此是必須掌握的。
3、這個程式語言提供了哪些基準解決方案?
所謂基準解決方案就是可以解決某個單一問題的方案,例如:怎麼輸出一句話、顯示一個圖片 或者訪問伺服器上的資料庫。通常一個程式語言都會提供一些內建的基準解決方案,以 函式或者類的形式提供給開發者,這些函式或者類,就是我們常說的API —— 應用開發介面。
因此在瞭解了程式語言的基礎語法之後,需要學習的就是程式語言提供的API的使用方法。 雖然不需要逐個驗證每個API的功能,但是強烈建議你設定一些問題,然後帶著這些問題 找出可以解決這些問題的API進行練習 —— 這些API是你解決具體問題的基礎。
4、這個程式語言有哪些優秀的第三方開發包?
大多數的程式語言都採用開發包的形式支援第三方提供擴充套件解決方案,以便開發者可以根據 自己的領域需求進行選擇。瞭解你選擇的程式語言有哪些常用的開發包是非常重要的一件事, 這可以避免你重新發明輪子,提高學習效率。
例如,同樣是學習Python,如果你的目標是要開發Web應用,那麼需要了解的就是Flask之類的 Web開發包,而如果你的目標是要開發機器學習/深度學習應用,那麼需要了解的就是numpy、 scikit-learn這些開發包了:
7、學習程式設計有什麼方法嗎?
毋庸置疑,和學習其他知識或技能一樣,學習程式設計也需要掌握正確的方法。
1、多實踐基準API
第一個學習方法就是多實踐,只有思路是遠遠不夠的。過於強調看書看視訊而忽略實踐 的結果就是眼高手低。你看到一個問題,思路上覺得行得通,但是卻怎麼也實現不出來。 這是因為程式設計需要精確地考慮並實現每一個細節,如果只是粗線條的理解,是很難達到 學習目標的。
那麼怎麼才能多實踐?應該多模擬一些實戰專案嗎?
不是這樣的。在早期的學習中,不應該參與複雜的實戰專案,而是應該儘可能多的 瞭解程式語言的能力,比如練習它的基礎API的使用方法、練習它的擴充套件包的API的使用方法。 一個實踐任務一定不要包含太多的程式碼,最好聚焦於一個API,儘可能地理解 它的用法,以及它對應的抽象模型的內在機制。
有的時候一個API用起來很簡單,但是它有對應的抽象模型存在,這個模型並不容易一下理解。 例如當你學習JavaScript操作網頁的時候,就會接觸到文件物件模型、Flex盒模型等諸多 抽象,在這種情況下,建議你先遵循黑盒法則,就是先了解這個模型的作用,掌握API 的使用方法,而暫時忽略其內部執行機制,然後將這個不理解的問題暫且記到小本本上, 留待日後解決。
所以,我們說的多實踐,不是實戰專案的實踐,而是在很細粒度上的實踐,理想 的粒度是在單一API上完成一個實踐 ,因為API本身就體現了程式語言或開發包的設計者 的初衷。
2、多問自己為什麼
第二個學習方法就是在學習的過程中,多問自己一些為什麼,有意識地設計一些問題 挑戰自己,把一時解決不了的問題記錄下來,帶著問題繼續學習。
第一種問題是在學習過程中自發產生的,比如前面提到的,現在學習的某個知識點可能 涉及到了另一個之前不瞭解的知識點,如果那是一個比較難理解的知識點,那麼還是先 記錄下來,不要打斷當前的學習思路。
第二種問題是有意識的發問。例如當你練習一個API的使用時,不妨考慮一下這幾個問題: 這個API可能在什麼場景下能用到?為什麼這個API需要這些引數?這個API和之前學的哪些 API經常一起用?
能夠主動地向自己提出問題是很了不起的進步,這意味著你真正進入了主動思考 的狀態。
3、設定分級目標,繼續實踐
在實踐API的時候,我們的目標就是理解並掌握這個API的使用方法。當初步熟悉了程式設計 語言的API之後,就可以設定下一級的目標,嘗試著用已經掌握的知識去實現這個目標。 不需要完成一個大程式,對於大多數情況而言,這時候試著編寫一個諸如貪吃蛇這樣 的小遊戲是合適的:
當然這種階段性的目標也是與你的最終學習目標相關的,例如,如果你的學習動力是要開發 網頁應用,那麼這個階段試著實現一個簡單的圖片分享或者部落格系統都是可以的;而如果 你的目標是人工智慧,那麼這個階段可以試著用神經網路解決一下文字分類的問題。總之 階段性的分級目標的設定是為了給自己一個前進的動力,過高或者過低都不好。
4、在戰鬥中學習戰鬥
學習程式設計的目標是不是學習,而是開發出有價值的程式。因此完全脫產的學習終究會告一段落, 你可能會投入到繁忙的程式設計工作中去。不過這並不意味著你不再需要學習,事實上, 技術的演變是極其快速甚至劇烈的,因此別忘了:
保持積極學習的心態和敏銳的好奇心,在戰鬥中學習戰鬥!
匯智網原創,轉載請標明出處