如何掌握所有的程序語(yǔ)言?

發(fā)布時(shí)間:2017-7-13 09:42    發(fā)布者:技術(shù)小白
關(guān)鍵詞: C語(yǔ)言
如何掌握所有的程序語(yǔ)言?

對的,我這里要講的不是如何掌握一種程序語(yǔ)言,而是所有的……

很多編程初學(xué)者至今還在給我寫(xiě)信請教,問(wèn)我該學(xué)習什么程序語(yǔ)言,怎么學(xué)習。由于我知道如何掌握所有的程序語(yǔ)言,我總感覺(jué)這種“該學(xué)什么語(yǔ)言”的問(wèn)題是如此低級,所以一直沒(méi)來(lái)得及回復 可是逐漸的,我發(fā)現原來(lái)不只是小白們有這個(gè)問(wèn)題,就連美國大公司的很多資深工程師,其實(shí)也沒(méi)搞明白。

今天來(lái)統一回答一下這個(gè)擱置已久的“初級問(wèn)題”。這個(gè)話(huà)題貌似曾經(jīng)寫(xiě)過(guò),然而現在我想把它重新寫(xiě)一遍。因為在跟很多人交流之后,我對自己頭腦中的(未轉化為語(yǔ)言的)想法,有了更精準的表達。

如果你存在以下的種種困惑,那么這篇文章也許會(huì )對你有所幫助:

你是編程初學(xué)者,不知道該選擇什么程序語(yǔ)言來(lái)入門(mén)。
你是資深的程序員或者團隊領(lǐng)導,對新出現的種種語(yǔ)言感到困惑,不知道該“投資”哪種語(yǔ)言。
你的團隊為使用哪種程序語(yǔ)言爭論不休,發(fā)生各種宗教斗爭。
你追逐潮流采用了某種時(shí)髦的語(yǔ)言,結果兩個(gè)月之后發(fā)現深陷泥潭,痛苦不堪……

雖然我已經(jīng)不再過(guò)問(wèn)這些世事,然而無(wú)可置疑的現實(shí)是,程序語(yǔ)言仍然是很重要的話(huà)題,這個(gè)情況短時(shí)間內不會(huì )改變。程序員的崗位往往會(huì )要求熟悉某些語(yǔ)言,甚至某些奇葩的公司要求你“深入理解 OOP 或者 FP 設計模式”。對于在職的程序員,程序語(yǔ)言至今仍然是可以爭得面紅耳赤的宗教話(huà)題。它的宗教性之強,以至于我在批評和調侃某些語(yǔ)言(比如 Go 語(yǔ)言)的時(shí)候,有些人會(huì )本能地以為我是另外一種語(yǔ)言(比如 Java)的粉絲。

顯然我不可能是任何一種語(yǔ)言的粉絲,我甚至不是 Yin 語(yǔ)言的粉絲 ;) 對于任何從沒(méi)見(jiàn)過(guò)的語(yǔ)言,我都是直接拿起來(lái)就用,而不需要經(jīng)過(guò)學(xué)習的過(guò)程?戳诉@篇文章,也許你會(huì )明白我為什么可以達到這個(gè)效果。理解了這里面的東西,每個(gè)程序員都應該可以做到這一點(diǎn)。嗯,但愿吧。

重視語(yǔ)言特性,而不是語(yǔ)言

很多人在乎自己或者別人是否“會(huì )”某種語(yǔ)言,對“發(fā)明”了某種語(yǔ)言的人倍加崇拜,為各種語(yǔ)言的孰優(yōu)孰劣爭得面紅耳赤。這些問(wèn)題對于我來(lái)說(shuō)都是不存在的。雖然我寫(xiě)文章批評過(guò)不少語(yǔ)言的缺陷,在實(shí)際工作中我卻很少跟人爭論這些。如果有其它人在我身邊爭論,我甚至會(huì )戴上耳機,都懶得聽(tīng)他們說(shuō)什么 ;) 為什么呢?我發(fā)現歸根結底的原因,是因為我重視的是“語(yǔ)言特性”,而不是整個(gè)的“語(yǔ)言”。我能用任何語(yǔ)言寫(xiě)出不錯的代碼,就算再糟糕的語(yǔ)言也差不了多少。

任何一種“語(yǔ)言”,都是各種“語(yǔ)言特性”的組合。打個(gè)比方吧,一個(gè)程序語(yǔ)言就像一臺電腦。它的牌子可能叫“聯(lián)想”,或者“IBM”,或者“Dell”,或者“蘋(píng)果”。那么,你可以說(shuō)蘋(píng)果一定比 IBM 好嗎?你不能。你得看看它里面裝的是什么型號的處理器,有多少個(gè)核,主頻多少,有多少 L1 cache,L2 cache……,有多少內存和硬盤(pán),顯示器分辨率有多大,顯卡是什么 GPU,網(wǎng)卡速度,等等各種“配置”。有時(shí)候你還得看各個(gè)組件之間的兼容性。

這些配置對應到程序語(yǔ)言里面,就是所謂“語(yǔ)言特性”。舉一些語(yǔ)言特性的例子:

變量定義
算術(shù)運算
for 循環(huán)語(yǔ)句,while 循環(huán)語(yǔ)句
函數定義,函數調用
遞歸
靜態(tài)類(lèi)型系統
類(lèi)型推導
lambda 函數
面向對象
垃圾回收
指針算術(shù)
goto 語(yǔ)句

這些語(yǔ)言特性,就像你在選擇一臺電腦的時(shí)候,看它里面是什么配置。選電腦的時(shí)候,沒(méi)有人會(huì )說(shuō) Dell 一定是最好的,他們只會(huì )說(shuō)這個(gè)型號里面裝的是 Intel 的 i7 處理器,這個(gè)比 i5 的好,DDR3 的內存 比 DDR2 的快這么多,SSD 比磁盤(pán)快很多,ATI 的顯卡是垃圾…… 如此等等。

程序語(yǔ)言也是一樣的道理。對于初學(xué)者來(lái)說(shuō),其實(shí)沒(méi)必要糾結到底要先學(xué)哪一種語(yǔ)言,再學(xué)哪一種。曾經(jīng)有人給我發(fā)信問(wèn)這種問(wèn)題,糾結了好幾個(gè)星期,結果一個(gè)語(yǔ)言都還沒(méi)開(kāi)始學(xué)。有這糾結的時(shí)間,其實(shí)都可以把他糾結過(guò)的語(yǔ)言全部掌握了。

初學(xué)者往往不理解,每一種語(yǔ)言里面必然有一套“通用”的特性。比如變量,函數,整數和浮點(diǎn)數運算,等等。這些是每個(gè)通用程序語(yǔ)言里面都必須有的,一個(gè)都不能少。你只要通過(guò)“某種語(yǔ)言”學(xué)會(huì )了這些特性,掌握這些特性的根本概念,就能隨時(shí)把這些知識應用到任何其它語(yǔ)言。你為此投入的時(shí)間基本不會(huì )浪費。所以初學(xué)者糾結要“先學(xué)哪種語(yǔ)言”,這種時(shí)間花的很不值得,還不如隨便挑一個(gè)語(yǔ)言,跳進(jìn)去。

如果你不能用一種語(yǔ)言里面的基本特性寫(xiě)出好的代碼,那你換成另外一種語(yǔ)言也無(wú)濟于事。你會(huì )寫(xiě)出一樣差的代碼。我經(jīng)?吹接行┤ Java 代碼寫(xiě)得相當亂,相當糟糕,卻罵 Java 不好,雄心勃勃要換用 Go 語(yǔ)言。這些人沒(méi)有明白,是否能寫(xiě)出好的代碼在于人,而不在于語(yǔ)言。如果你的心中沒(méi)有清晰簡(jiǎn)單的思維模型,你用任何語(yǔ)言表述出來(lái)都是一堆亂麻。如果你 Java 代碼寫(xiě)得很糟糕,那么你寫(xiě) Go 語(yǔ)言代碼也會(huì )一樣糟糕,甚至更差。

很多初學(xué)者不了解,一個(gè)高明的程序員如果開(kāi)始用一種新的程序語(yǔ)言,他往往不是去看這個(gè)語(yǔ)言的大部頭手冊或者書(shū)籍,而是先有一個(gè)需要解決的問(wèn)題。手頭有了問(wèn)題,他可以用兩分鐘瀏覽一下這語(yǔ)言的手冊,看看這語(yǔ)言大概長(cháng)什么樣。然后,他直接拿起一段例子代碼來(lái)開(kāi)始修改搗鼓,想法把這代碼改成自己正想解決的問(wèn)題。在這個(gè)簡(jiǎn)短的過(guò)程中,他很快的掌握了這個(gè)語(yǔ)言,并用它表達出心里的想法。

在這個(gè)過(guò)程中,隨著(zhù)需求的出現,他可能會(huì )問(wèn)這樣的問(wèn)題:

這個(gè)語(yǔ)言的“變量定義”是什么語(yǔ)法,需要“聲明類(lèi)型”嗎,還是可以用“類(lèi)型推導”?
它的“類(lèi)型”是什么語(yǔ)法?是否支持“泛型”?泛型的 “variance” 如何表達?
這個(gè)語(yǔ)言的“函數”是什么語(yǔ)法,“函數調用”是什么語(yǔ)法,可否使用“缺省參數”?
……

注意到了嗎?上面每一個(gè)引號里面的內容,都是一種語(yǔ)言特性(或者叫概念)。這些概念可以存在于任何的語(yǔ)言里面,雖然語(yǔ)法可能不一樣,它們的本質(zhì)都是一樣的。比如,有些語(yǔ)言的參數類(lèi)型寫(xiě)在變量前面,有些寫(xiě)在后面,有些中間隔了一個(gè)冒號,有些沒(méi)有。

這些實(shí)際問(wèn)題都是隨著(zhù)寫(xiě)實(shí)際的代碼,解決手頭的問(wèn)題,自然而然帶出來(lái)的,而不是一開(kāi)頭就抱著(zhù)語(yǔ)言手冊看得仔仔細細。因為掌握了語(yǔ)言特性的人都知道,自己需要的特性,在任何語(yǔ)言里面一定有對應的表達方式。如果沒(méi)有直接的方式表達,那么一定有某種“繞過(guò)方式”。如果有直接的表達方式,那么它只是語(yǔ)法稍微有所不同而已。所以,他是帶著(zhù)問(wèn)題找特性,就像查字典一樣,而不是被淹沒(méi)于大部頭的手冊里面,昏昏欲睡一個(gè)月才開(kāi)始寫(xiě)代碼。

掌握了通用的語(yǔ)言特性,剩下的就只剩某些語(yǔ)言“特有”的特性了。研究語(yǔ)言的人都知道,要設計出新的,好的,無(wú)害的特性,是非常困難的。所以一般說(shuō)來(lái),一種好的語(yǔ)言,它所特有的新特性,終究不會(huì )超過(guò)一兩種。如果有個(gè)語(yǔ)言號稱(chēng)自己有超過(guò) 5 種新特性,那你就得小心了,因為它們帶來(lái)的和可能不是優(yōu)勢,而是災難!

同樣的道理,最好的語(yǔ)言研究者,往往不是某種語(yǔ)言的設計者,而是某種關(guān)鍵語(yǔ)言特性的設計者(或者支持者)。舉個(gè)例子,著(zhù)名的計算機科學(xué)家 Dijkstra 就是“遞歸”的強烈支持者,F在的語(yǔ)言里面都有遞歸,然而你可能不知道,早期的程序語(yǔ)言是不支持遞歸的。直到 Dijkstra 強烈要求 Algol 60 委員會(huì )加入對遞歸的支持,這個(gè)局面才改變了。Tony Hoare 也是語(yǔ)言特性設計者。他設計了幾個(gè)重要的語(yǔ)言特性,卻沒(méi)有設計過(guò)任何語(yǔ)言。另外大家不要忘了,有個(gè)語(yǔ)言專(zhuān)家叫王垠,他是早期 union type 的支持者和實(shí)現者,也是 checked exception 特性的支持者。

很多人盲目的崇拜語(yǔ)言設計者,只要聽(tīng)到有人設計(或者美其民曰“發(fā)明”)了一個(gè)語(yǔ)言,就熱血沸騰,佩服的五體投地。他們卻沒(méi)有理解,其實(shí)所有的程序語(yǔ)言,不過(guò)是像 Dell,聯(lián)想一樣的“組裝機”。語(yǔ)言特性的設計者,才是像 Intel,AMD,ARM,Qualcomm 那樣核心技術(shù)的創(chuàng )造者。

合理的入門(mén)語(yǔ)言

所以初學(xué)者要想事半功倍,就應該從一種“合理”的,沒(méi)有明顯嚴重問(wèn)題的語(yǔ)言出發(fā),掌握最關(guān)鍵的語(yǔ)言特性,然后由此把這些概念應用到其它語(yǔ)言。哪些是合理的入門(mén)語(yǔ)言呢?我個(gè)人覺(jué)得這些語(yǔ)言都可以用來(lái)入門(mén):

Scheme
C
Java
Python
JavaScript

那么相比之下,我不推薦用哪些語(yǔ)言入門(mén)呢?

Shell
PowerShell
AWK
Perl
PHP
Basic
Go

總的說(shuō)來(lái),你不應該使用所謂“腳本語(yǔ)言”作為入門(mén)語(yǔ)言,特別是那些源于早期 Unix 系統的腳本語(yǔ)言工具。PowerShell 雖然比 Unix 的 Shell 有所進(jìn)步,然而它仍然沒(méi)有擺脫腳本語(yǔ)言的根本問(wèn)題——他們的設計者不知道他們自己在干什么

采用腳本語(yǔ)言學(xué)編程,一個(gè)很?chē)乐氐膯?wèn)題就是使得學(xué)習者抓不住關(guān)鍵。腳本語(yǔ)言往往把一些系統工具性質(zhì)的東西(比如正則表達式,Web 概念)加入到語(yǔ)法里面,導致初學(xué)者為它們浪費太多時(shí)間,卻沒(méi)有理解編程最關(guān)鍵的概念:變量,函數,遞歸,類(lèi)型……

不推薦 Go 語(yǔ)言的原因類(lèi)似,雖然 Go 語(yǔ)言不算腳本語(yǔ)言,然而他的設計者顯然不明白自己在干什么。所以使用 Go 語(yǔ)言來(lái)學(xué)編程,你不能專(zhuān)注于最關(guān)鍵,最好的語(yǔ)言特性。

掌握關(guān)鍵語(yǔ)言特性,忽略次要特性

為了達到我之前提到的融會(huì )貫通,一通百通的效果,初學(xué)者應該專(zhuān)注于語(yǔ)言里面最關(guān)鍵的特性,而不是被次要的特性分心。

舉個(gè)夸張點(diǎn)的例子。我發(fā)現很多編程培訓班和野雞大學(xué)的編程入門(mén)課,往往一來(lái)就教學(xué)生如何使用 printf 打印“Hello World!”,進(jìn)而要他們記憶 printf 的各種“格式字符”的意義,要他們實(shí)現各種復雜格式的打印輸出,甚至要求打印到文本文件里,然后再讀出來(lái)……

可是殊不知,這種輸出輸入操作其實(shí)根本不算是語(yǔ)言的一部分,而且對于掌握編程的核心概念來(lái)說(shuō),都是次要的。有些人的 Java 課程進(jìn)行了好幾個(gè)星期,居然還在布置各種 printf 的作業(yè)。學(xué)生寫(xiě)出幾百行的 printf,卻不理解變量和函數是什么,甚至連算術(shù)語(yǔ)句和循環(huán)語(yǔ)句都不知道怎么用!這就是為什么很多初學(xué)者感覺(jué)編程很難,我連 %d,%f,%.2f 的含義都記不住,還怎么學(xué)編程!

然而這些野雞大學(xué)的“教授”頭銜是如此的洗腦,以至于被他們教過(guò)的學(xué)生(比如我女朋友)到我這里請教,居然罵我凈教一些沒(méi)用的東西,學(xué)了連 printf 的作業(yè)都沒(méi)法完成 你別跟我講 for 循環(huán),函數什么的了…… 可不可以等幾個(gè)月,等我背熟了 printf 的用法再學(xué)那些?

所以你就發(fā)現一旦被差勁的老師教過(guò),這個(gè)程序員基本就毀了。就算遇到好的老師,他們也很難糾正過(guò)來(lái)。

當然這是一個(gè)夸張的例子,因為 printf 根本不算是語(yǔ)言特性,但這個(gè)例子從同樣的角度說(shuō)明了次要膚淺的語(yǔ)言特性帶來(lái)的問(wèn)題。

這里舉一些次要語(yǔ)言特性的例子:

C 語(yǔ)言的語(yǔ)句塊,如果里面只有一條語(yǔ)句,可以不打花括號。
Go 語(yǔ)言的函數參數類(lèi)型如果一樣可以合并在一起寫(xiě),比如 func foo(s string, x, y, z int, c bool) { ... }
Perl 把正則表達式作為語(yǔ)言的一種特殊語(yǔ)法
JavaScript 語(yǔ)句可以在某些時(shí)候省略句尾的分號
Haskell 和 ML 等語(yǔ)言的 currying

自己動(dòng)手實(shí)現語(yǔ)言特性

在基本學(xué)會(huì )了各種語(yǔ)言特性,能用它們來(lái)寫(xiě)代碼之后,下一步的進(jìn)階就是去實(shí)現它們。只有實(shí)現了各種語(yǔ)言特性,你才能完全地擁有它們,成為它們的主人。否則你就只是它們的使用者,你會(huì )被語(yǔ)言的設計者牽著(zhù)鼻子走。

有個(gè)大師說(shuō)得好,完全理解一種語(yǔ)言最好的方法就是自己動(dòng)手實(shí)現它,也就是自己寫(xiě)一個(gè)解釋器來(lái)實(shí)現它的語(yǔ)義。但我覺(jué)得這句話(huà)應該稍微修改一下:完全理解一種“語(yǔ)言特性”最好的方法就是自己親自實(shí)現它。

注意我在這里把“語(yǔ)言”改為了“語(yǔ)言特性”。你并不需要實(shí)現整個(gè)語(yǔ)言來(lái)達到這個(gè)目的,因為我們最終使用的是語(yǔ)言特性。只要你自己實(shí)現了一種語(yǔ)言特性,你就能理解這個(gè)特性在任何語(yǔ)言里的實(shí)現方式和用法。

舉個(gè)例子,學(xué)習 SICP 的時(shí)候,大家都會(huì )親自用 Scheme 實(shí)現一個(gè)面向對象系統。用 Scheme 實(shí)現的面向對象系統,跟 Java,C++,Python 之類(lèi)的語(yǔ)言語(yǔ)法相去甚遠,然而它卻能幫助你理解任何這些 OOP 語(yǔ)言里面的“面向對象”這一概念,它甚至能幫助你理解各種面向對象實(shí)現的差異。

這種效果是你直接學(xué)習 OOP 語(yǔ)言得不到的,因為在學(xué)習 Java,C++,Python 之類(lèi)語(yǔ)言的時(shí)候,你只是一個(gè)用戶(hù),而用 Scheme 自己動(dòng)手實(shí)現了 OO 系統之后,你成為了一個(gè)創(chuàng )造者。

類(lèi)似的特性還包括類(lèi)型推導,類(lèi)型檢查,惰性求值,如此等等。我實(shí)現過(guò)幾乎所有的語(yǔ)言特性,所以任何語(yǔ)言在我的面前,都是可以被任意拆卸組裝的玩具,而不再是凌駕于我之上的神圣。

總結

寫(xiě)了這么多,重要的話(huà)重復三遍:語(yǔ)言特性,語(yǔ)言特性,語(yǔ)言特性!不管是初學(xué)者還是資深程序員,應該專(zhuān)注于語(yǔ)言特性,而不是糾結于整個(gè)的“語(yǔ)言品牌”。只有這樣才能達到融會(huì )貫通,拿起任何語(yǔ)言幾乎立即就會(huì )用,并且寫(xiě)出高質(zhì)量的代碼。


想學(xué)習的你和我聯(lián)系預約就可以免費聽(tīng)課了。
以下課程可免費試聽(tīng)C語(yǔ)言、電子、PCB、STM32、Linux、FPGA、JAVA、安卓等。
宋工企鵝號:3524-6590-88   Tel/WX:173--1795--1908


本文地址:http://selenalain.com/thread-453334-1-1.html     【打印本頁(yè)】

本站部分文章為轉載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀(guān)點(diǎn)和對其真實(shí)性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問(wèn)題,我們將根據著(zhù)作權人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页