程式語言用什麼方法學習_程式語言有哪些學習方法
很多程式設計初學者至今都不懂怎麼學習,該學習什麼程式語言,怎麼學習。下面由小編為大家整理的程式語言學習方法,希望大家喜歡!
程式語言學習方法
1、重視語言特性,而不是語言
很多人在乎自己或者別人是否“會”某種語言,對“發明”了某種語言的人倍加崇拜,為各種語言的孰優孰劣爭得面紅耳赤。這些問題對於我來說都是不存在的。雖然我寫文章批評過不少語言的缺陷,在實際工作中我卻很少跟人爭論這些。如果有其它人在我身邊爭論,我甚至會戴上耳機,都懶得聽他們說什麼 ; 為什麼呢?我發現歸根結底的原因,是因為我重視的是“語言特性”,而不是整個的“語言”。我能用任何語言寫出不錯的程式碼,就算再糟糕的語言也差不了多少。
任何一種“語言”,都是各種“語言特性”的組合。打個比方吧,一個程式語言就像一臺電腦。它的牌子可能叫“聯想”,或者“IBM”,或者“Dell”,或者“蘋果”。那麼,你可以說蘋果一定比 IBM 好嗎?你不能。你得看看它裡面裝的是什麼型號的處理器,有多少個核,主頻多少,有多少 L1 cache,L2 cache……,有多少記憶體和硬碟,顯示器解析度有多大,顯示卡是什麼 GPU,網絡卡速度,等等各種“配置”。有時候你還得看各個元件之間的相容性。
這些配置對應到程式語言裡面,就是所謂“語言特性”。舉一些語言特性的例子:
變數定義
算術運算
for 迴圈語句,while 迴圈語句
函式定義,函式呼叫
遞迴
靜態型別系統
型別推導
lambda 函式
面向物件
垃圾回收
指標算術
goto 語句
這些語言特性,就像你在選擇一臺電腦的時候,看它裡面是什麼配置。選電腦的時候,沒有人會說 Dell 一定是最好的,他們只會說這個型號裡面裝的是 Intel 的 i7 處理器,這個比 i5 的好,DDR3 的記憶體 比 DDR2 的快這麼多,SSD 比磁碟快很多,ATI 的顯示卡是垃圾…… 如此等等。
程式語言也是一樣的道理。對於初學者來說,其實沒必要糾結到底要先學哪一種語言,再學哪一種。曾經有人給我發信問這種問題,糾結了好幾個星期,結果一個語言都還沒開始學。有這糾結的時間,其實都可以把他糾結過的語言全部掌握了。
初學者往往不理解,每一種語言裡面必然有一套“通用”的特性。比如變數,函式,整數和浮點數運算,等等。這些是每個通用程式語言裡面都必須有的,一個都不能少。你只要通過“某種語言”學會了這些特性,掌握這些特性的根本概念,就能隨時把這些知識應用到任何其它語言。你為此投入的時間基本不會浪費。所以初學者糾結要“先學哪種語言”,這種時間花的很不值得,還不如隨便挑一個語言,跳進去。
如果你不能用一種語言裡面的基本特性寫出好的程式碼,那你換成另外一種語言也無濟於事。你會寫出一樣差的程式碼。我經常看到有些人 Java 程式碼寫得相當亂,相當糟糕,卻罵 Java 不好,雄心勃勃要換用 Go 語言。這些人沒有明白,是否能寫出好的程式碼在於人,而不在於語言。如果你的心中沒有清晰簡單的思維模型,你用任何語言表述出來都是一堆亂麻。如果你 Java 程式碼寫得很糟糕,那麼你寫 Go 語言程式碼也會一樣糟糕,甚至更差。
很多初學者不瞭解,一個高明的程式設計師如果開始用一種新的程式語言,他往往不是去看這個語言的大部頭手冊或者書籍,而是先有一個需要解決的問題。手頭有了問題,他可以用兩分鐘瀏覽一下這語言的手冊,看看這語言大概長什麼樣。然後,他直接拿起一段例子程式碼來開始修改搗鼓,想法把這程式碼改成自己正想解決的問題。在這個簡短的過程中,他很快的掌握了這個語言,並用它表達出心裡的想法。
在這個過程中,隨著需求的出現,他可能會問這樣的問題:
這個語言的“變數定義”是什麼語法,需要“宣告型別”嗎,還是可以用“型別推導”?
它的“型別”是什麼語法?是否支援“泛型”?泛型的 “variance” 如何表達?
這個語言的“函式”是什麼語法,“函式呼叫”是什麼語法,可否使用“預設引數”?
……
注意到了嗎?上面每一個引號裡面的內容,都是一種語言特性或者叫概念。這些概念可以存在於任何的語言裡面,雖然語法可能不一樣,它們的本質都是一樣的。比如,有些語言的引數型別寫在變數前面,有些寫在後面,有些中間隔了一個冒號,有些沒有。
這些實際問題都是隨著寫實際的程式碼,解決手頭的問題,自然而然帶出來的,而不是一開頭就抱著語言手冊看得仔仔細細。因為掌握了語言特性的人都知道,自己需要的特性,在任何語言裡面一定有對應的表達方式。如果沒有直接的方式表達,那麼一定有某種“繞過方式”。如果有直接的表達方式,那麼它只是語法稍微有所不同而已。所以,他是帶著問題找特性,就像查字典一樣,而不是被淹沒於大部頭的手冊裡面,昏昏欲睡一個月才開始寫程式碼。
掌握了通用的語言特性,剩下的就只剩某些語言“特有”的特性了。研究語言的人都知道,要設計出新的,好的,無害的特性,是非常困難的。所以一般說來,一種好的語言,它所特有的新特性,終究不會超過一兩種。如果有個語言號稱自己有超過 5 種新特性,那你就得小心了,因為它們帶來的和可能不是優勢,而是災難!
同樣的道理,最好的語言研究者,往往不是某種語言的設計者,而是某種關鍵語言特性的設計者或者支持者。舉個例子,著名的電腦科學家 Dijkstra 就是“遞迴”的強烈支持者。現在的語言裡面都有遞迴,然而你可能不知道,早期的程式語言是不支援遞迴的。直到 Dijkstra 強烈要求 Algol 60 委員會加入對遞迴的支援,這個局面才改變了。Tony Hoare 也是語言特性設計者。他設計了幾個重要的語言特性,卻沒有設計過任何語言。另外大家不要忘了,有個語言專家叫王垠,他是早期 union type 的支持者和實現者,也是 checked exception 特性的支持者,他在自己的博文裡指出了 checked exception 和 union type 之間的關係 :P
很多人盲目的崇拜語言設計者,只要聽到有人設計或者美其民曰“發明”了一個語言,就熱血沸騰,佩服的五體投地。他們卻沒有理解,其實所有的程式語言,不過是像 Dell,聯想一樣的“組裝機”。語言特性的設計者,才是像 Intel,AMD,ARM,Qualcomm 那樣核心技術的創造者。
2、合理的入門語言
所以初學者要想事半功倍,就應該從一種“合理”的,沒有明顯嚴重問題的語言出發,掌握最關鍵的語言特性,然後由此把這些概念應用到其它語言。哪些是合理的入門語言呢?我個人覺得這些語言都可以用來入門:
Scheme
C
Java
Python
JavaScript
那麼相比之下,我不推薦用哪些語言入門呢?
Shell
PowerShell
AWK
Perl
PHP
Basic
Go
總的說來,你不應該使用所謂“指令碼語言”作為入門語言,特別是那些源於早期 Unix 系統的指令碼語言工具。PowerShell 雖然比 Unix 的 Shell 有所進步,然而它仍然沒有擺脫指令碼語言的根本問題——他們的設計者不知道他們自己在幹什麼 :P
採用指令碼語言學程式設計,一個很嚴重的問題就是使得學習者抓不住關鍵。指令碼語言往往把一些系統工具性質的東西比如正則表示式,Web 概念加入到語法裡面,導致初學者為它們浪費太多時間,卻沒有理解程式設計最關鍵的概念:變數,函式,遞迴,型別……
不推薦 Go 語言的原因類似,雖然 Go 語言不算指令碼語言,然而他的設計者顯然不明白自己在幹什麼。所以使用 Go 語言來學程式設計,你不能專注於最關鍵,最好的語言特性。
3、掌握關鍵語言特性,忽略次要特性
為了達到我之前提到的融會貫通,一通百通的效果,初學者應該專注於語言裡面最關鍵的特性,而不是被次要的特性分心。
舉個誇張點的例子。我發現很多程式設計培訓班和野雞大學的程式設計入門課,往往一來就教學生如何使用 printf 列印“Hello World!”,進而要他們記憶 printf 的各種“格式字元”的意義,要他們實現各種複雜格式的列印輸出,甚至要求列印到文字檔案裡,然後再讀出來……
可是殊不知,這種輸出輸入操作其實根本不算是語言的一部分,而且對於掌握程式設計的核心概念來說,都是次要的。有些人的 Java 課程進行了好幾個星期,居然還在佈置各種 printf 的作業。學生寫出幾百行的 printf,卻不理解變數和函式是什麼,甚至連算術語句和迴圈語句都不知道怎麼用!這就是為什麼很多初學者感覺程式設計很難,我連 %d,%f,%.2f 的含義都記不住,還怎麼學程式設計!
然而這些野雞大學的“教授”頭銜是如此的洗腦,以至於被他們教過的學生比如我女朋友到我這裡請教,居然罵我淨教一些沒用的東西,學了連 printf 的作業都沒法完成 :P 你別跟我講 for 迴圈,函式什麼的了…… 可不可以等幾個月,等我背熟了 printf 的用法再學那些啊?
所以你就發現一旦被差勁的老師教過,這個程式設計師基本就毀了。就算遇到好的老師,他們也很難糾正過來。
當然這是一個誇張的例子,因為 printf 根本不算是語言特性,但這個例子從同樣的角度說明了次要膚淺的語言特性帶來的問題。
這裡舉一些次要語言特性的例子:
C 語言的語句塊,如果裡面只有一條語句,可以不打花括號。
Go 語言的函式引數型別如果一樣可以合併在一起寫,比如 func foos string, x, y, z int, c bool { ... }
Perl 把正則表示式作為語言的一種特殊語法
JavaScript 語句可以在某些時候省略句尾的分號
Haskell 和 ML 等語言的 currying
4、自己動手實現語言特性
在基本學會了各種語言特性,能用它們來寫程式碼之後,下一步的進階就是去實現它們。只有實現了各種語言特性,你才能完全地擁有它們,成為它們的主人。否則你就只是它們的使用者,你會被語言的設計者牽著鼻子走。
有個大師說得好,完全理解一種語言最好的方法就是自己動手實現它,也就是自己寫一個直譯器來實現它的語義。但我覺得這句話應該稍微修改一下:完全理解一種“語言特性”最好的方法就是自己親自實現它。
注意我在這裡把“語言”改為了“語言特性”。你並不需要實現整個語言來達到這個目的,因為我們最終使用的是語言特性。只要你自己實現了一種語言特性,你就能理解這個特性在任何語言裡的實現方式和用法。
舉個例子,學習 SICP 的時候,大家都會親自用 Scheme 實現一個面向物件系統。用 Scheme 實現的面向物件系統,跟 Java,C++,Python 之類的語言語法相去甚遠,然而它卻能幫助你理解任何這些 OOP 語言裡面的“面向物件”這一概念,它甚至能幫助你理解各種面向物件實現的差異。
這種效果是你直接學習 OOP 語言得不到的,因為在學習 Java,C++,Python 之類語言的時候,你只是一個使用者,而用 Scheme 自己動手實現了 OO 系統之後,你成為了一個創造者。
類似的特性還包括型別推導,型別檢查,惰性求值,如此等等。我實現過幾乎所有的語言特性,所以任何語言在我的面前,都是可以被任意拆卸組裝的玩具,而不再是凌駕於我之上的神聖。
程式語言分類
☞ APL
APL 以《程式語言A Programming Language》一書命名Iverson,Kenneth E.,1962,它是一種陣列程式語言。它可以在多個數據陣列上同時工作。 它是一種解釋型、可互動和函式式的程式語言。
☞ AutoIt
它是自由軟體,是一種用於 Microsoft Windows 的自動化語言。 主要目的是建立可用於在 Windows 上執行某些重複任務的自動化指令碼。
☞ BASIC
於1964年由約翰·喬治·凱米尼John George Kemeny和托特·尤金·庫爾茨Thomas Eugene Kurtz在達特茅斯Dartmouth開發,它是初學者多用符號指令程式碼Beginner’s All-purpose Symbolic Instruction Code的縮寫。它的目的是為非科學人士提供一個使用電腦的途徑。
☞ Eiffel
它是一種被 ISO 標準化了的面向物件程式語言,用於開發可擴充套件和可重複使用的軟體。它是一個可面向許多行業的開發平臺,如金融,航空航天和視訊遊戲。
☞ Forth
它是一種結構化的指令式程式設計語言,其實現基於堆疊。它支援互動式的命令執行以及對命令序列的編譯。
☞ Frink
由 Alan Eliasen 開發,以 John Frink 教授命名——他是一位頗受歡迎的虛構人物。它基於 Java 虛擬機器,專注於科學和工程領域。其突出特點是能通過所有的能讓數量包含其測量單位的計算,來對測量單位進行跟蹤。
☞ Game Maker 語言
它是一種解釋型的計算機程式語言,旨在與 Game Maker 配合使用—— Game Maker 是一種遊戲製作應用程式。荷蘭電腦科學家馬克·奧馬斯Mark Overmars設計了這種語言。
☞ ICI
ICI 是由 Tim Long 於1992年設計的,它是一種通用的解釋型計算機程式語言。它支援動態輸入,靈活的資料型別以及其它的一些類似於 C 的語言結構。
☞ J
Ken Iverson 和 Roger Hui 開發了這個只需要使用基礎 ASCII 字符集的程式語言。它是一種陣列程式語言,適用於數學和統計操作。
2017年的程式語言有哪些
1、Java
就受歡迎的程度而言,Java是C的主要對手,二者共享前2名的位置。Java獲得“2015年年度最佳語言”獎,而據Oracle公司稱,使用它的開發者超過900萬。
Java在世界範圍內被幾百萬的開發者應用於幾十億裝置中。它是一種基於類的面向物件的語言,它的跨平臺特性使得所有的平臺、作業系統和裝置都對其相容。它被用於開發安卓app,桌面app和電子遊戲,是許多企業後臺的開發語言。Java的跨平臺特性將保持很長一段時間,而這正是Java受歡迎的理由。
據說2017年Java9將釋出,它的新功能將很受程式設計師歡迎。Java9擁有對HTTP2.0支援以及新的API。
2、C語言
2015年3月,C語言被評為全世界最受歡迎的語言。C語言的應用幾乎是無止境的,它也一直是最受歡迎的語言前2名。
C++由C發展而來,而C更加簡單,功能也較少。C語言是由Dennis Ritchie,於1972年開發的面向過程的語言,在UNIX作業系統中使用。雖然C是一種相對較老的語言,但它仍然被廣泛應用於系統程式設計,編寫其它語言及嵌入式系統之中。Linux作業系統的核心就是用C語言編寫的。
經過這麼長時間,其他語言的排行版一直髮生變化,而C語言依然很流行。C語言很好的控制硬體,還提供非常好用的程式設計工具。不僅如此,一個系統往另外一個系統的移植方面,C語言更容易。
3、Python
Python是一種應用廣泛的高階通用程式語言,簡單,易讀。它是一種萬能的嵌入式指令碼語言,是許多網站架構的堅實基礎,同時也是自動化任務包括在3D應用中,桌面程式設計工具,資料科學等的不二選擇。Python還被用於教育,因此它還包含了數學,物理等內容。許多技術巨頭如Google和Yahoo,以及NASA,PBS和Reddit等都使用Python編寫他們的網站。
4、GO
Go或者GOLANG由Google在2007年開發,是一種免費的開源程式語言。它有著優秀的標準庫,且編譯速度很快。同時,它也很善於處理併發任務和程式。Google給了Go大量的支援,比如使用Go語言的網站有Netflix,YouTube和Adobe。
5、Java Script
JavaScript是現今傳播最廣的程式語言之一。它是一種流行的,強大的,動態指令碼語言,尤其善於開發優秀的網頁,和網頁遊戲。JavaScript的許多語法都是從C語言而來。它與所有瀏覽器相容,並被用於超過90%的網頁中。近幾年,JavaScript還被作為Node.js的基礎,後者是一種服務端技術,功能之一是實現實時通訊。
JavaScript最早在Netscape Navigator網景導航器中出現,併成為了現代動態網頁的基礎。
6、PHP
PHP超級文字預處理語言是一種伺服器端的語言。如今,它被用於超過80%的網站,包括Facebook,Wikipedia,Tumblr和WordPress。PHP不僅因為易於上手,而受到新晉開發者們的歡迎,也為很多成熟的開發者提供了大量的優秀特性。因此,世界各地都對PHP網路開發者需求巨大。
2004年,PHP被TIOBE授予“年度最佳語言”獎。此外,PHP還是截止2010年3月,第3受歡迎的語言。
2016年12月的時候,PHP7.1釋出了。PHP7.1有所改變,那就是帶來了增強。和去年7.0相比較,PHP7.1的效能有所改進,把PHP轉變成構建WEB應用程式的快速平臺。
7、Ruby
Ruby是一種動態,反射式,面向物件的通用程式語言。它支援多正規化程式設計,包括函式式,面向物件等。
在2016年3月時,Ruby語言在TOP10中也排得很前,如今,它仍然是創業公司,開發者,甚至是成熟企業偏好的工具。然而,雖然Ruby很大程度上改進了其框架Ruby on Rails,變得更加靈活且使得開發新的應用可區塊化,但是Node.js的崛起,很大程度上使得Ruby無法擁有極具競爭力的新一代開發者。
8、Visual Basic.NET
Visual Basic .NET由微軟開發,是一種多正規化,面向物件的程式語言。最初設計的目的是希望能夠方便地將Visual Basic應用匯入到VS.NET中,而這種充分利用新的執行時runtime的例子是非常少見的。這種做法使得很大一部分老派的開發者們能夠切換到新的開發環境中,與倉促地學習一種新語言相比,學習曲線要平滑得多。
9、Swift
作為Objective-C的接班人,Swift是歷史上發展最快的程式語言之一。它由Apple開發,所以非常適合用於編寫iOS,macOS,watchOS和tvOS上的應用。Swift相對乾淨、快速且正確率高,同時也可以縮短程式碼的長度,節省時間和精力。由於Swift是開源的,所以開發者也可以在Windows或者Linux上進行開發,設計自己的編譯器,但需確保自己寫的App和Apple裝置相容。
10、Scala
Scala是由Martin Odersky設計的一種通用程式程式語言。2004年1月20日,Scala開始支援函數語言程式設計,並推出強靜態型別系統。為了達到簡潔的目的,Scala的所有設計都來自於大家對於java的批評總結。Scala的原始碼會被編譯成Java位元組程式碼,因此生成的可執行程式碼將在Java虛擬機器上執行。