編程語言隨想

歡迎光臨個人 [QQ空間](http://user.qzone.qq.com/570926881/blog/1477487825) java

本人其實沒有足夠的資格談論這個問題,其實真正用過的語言也就C/C++,PHP,JS。其餘的不少語言也只停留在知道的階段,固然用過的語言也不精通,只是想就這個一直堆積在本身內心的問題作一個總結,也算是給不枉這幾年跟你們的討論。如下觀點僅僅是我的簡介因爲水平有限確定有不少疏漏,望見諒,歡迎交流,也會不記名提到一些同窗,沒有任何惡意僅僅說明現象。node

### 語言不是程序的所有python

先從一個簡單的事情提及。這一部份內容在計算機專業的同窗看來應該不是問題,你們應該不會這樣想問題,可是其餘人每每不這麼看。程序員

記得三年前,在剛來到大學,認識計算機,認識編程這件事情的時候,就以爲會一門語言是一種能力的體現,由於很明顯,語言的使用場景大都是不一樣的,你多會一門語言就意味着你能在一個新的領域作一些新的事情。由於當時仍是抱着「我會什麼才能作什麼」心態的。(我認爲程序員對於本身程序設計技術最終可以完成的產品的能力有三種心態,一是「我會什麼才能作什麼」,二是「我能學會什麼我就能作什麼」,三是「我認識可能會什麼的人,我就能作什麼」,這種心態的發展也體現了程序員的「浪」和成長)算法

學着學着發現了編程語言的統一性,原來不一樣語言只是語法不一樣啊(後面會反駁這種觀點),因而本身不多再去接觸新的語言了,只是把不一樣的語言當成工具在使用。可是某個假期你們一塊兒出去玩,有個高中同窗問我「如今會多少編程語言」的時候我就有點愣了,想了想他應該不是諷刺我吧,可能不太瞭解狀況吧。編程

編程語言雖然在每一個層面執行着不一樣的任務,可是程序設計思想實際上是大於語言的。緣由我就很少解釋了,你們應該也都清楚。數組

### 不一樣語言不只是語法不一樣babel

有些深刻研究某個領域的老師,或者其餘專業接觸編程語言較少的同窗可能持有這種觀點,相信不少以工具心態使用編程語言並且不多開發大型工程的人應該也有這種體會。若是把條件、循環的結構換一下、API的名稱瞭解事後兩種語言的區別就不剩什麼了。這樣想也沒有什麼問題,由於這種想法寫出的指令式的程序也能正常運行,每每還能下降學習成本,徹底不用在乎理解和實現的細節。閉包

經過語法能夠把語言大概分紅幾類,標籤式(VB,Matlab,...),縮進式(python)和{}式,我的比較喜歡{}這種c-like的語法,靈活清楚。架構

可是我認爲,不一樣的語言仍是有很大不一樣的,其實這篇文章以後可能都要討論這種不一樣,每種語言的做者在發明這種語言的時候的思想就會潛移默化的影響你的程序設計行爲,尤爲是在構建大型工程的時候,每每每種語言爲了實現大工程的「優雅」都有本身的一套寫法,他們的運行機制也每每不一樣,而理解這些應該是深刻認識一門語言的基礎。

如何認識變量,如何處理內存,需不須要虛擬機,採起怎樣的回收機制,這樣實現對象,怎樣實現異步其實都是語言須要考慮的不一樣點。

### 語言的分類

若是把語言分爲兩類,你認爲最重要的不一樣點應該選哪一個?應該不會有太多人按照標籤式、縮進式來分吧?若是回答過程、對象、函數式那麼我以爲也沒啥問題,這也能夠算是語言可以提供的一大區別了。可是本文就不討論函數式相關的事情了,由於真的不懂。

我的認爲語言能夠按照對變量本質的認識上,這樣能夠吧語言分爲兩類,C/C++一類,JAVA,JS,Python,等等其餘語言一類。C/C++認爲變量指的是一塊內存空間,修改變量是修改內存肯定地址中的內容因此在這種語言中 「=」 應該解釋爲複寫內存之意,然而JAVA爲表明的這類語言認爲變量是一個符號,它跟數據(或者說常量)是分離的只是指向引用的關係,而數據是不會動的也是不能改的。

相信使用C語言的人若是不瞭解JS語言的機制,得知JS中字符串是常量應該也以爲很驚訝吧,可能這種時候都不知道應該怎樣處理JS中的字符串了,好想```a[0]='A'```賦值啊怎麼辦😥?

從C轉到第二類語言的人也會在學習的時候也會常常問一個問題,python(或者JS)語言中的函數調用究竟是傳值、傳地址仍是傳引用呢?每每老師會告訴「傳引用」,雖然這麼說不確切可是我還真聽過有這樣說的。其實傳引用也不能說沒有道理,只是與C++表現不一樣罷了,若是你恰巧用這兩種語言,那麼你應該能看懂如下例子中函數對外層變量的做用是不一樣的。

```
// C++
void foo(int &a) {
a = 1;
}

// js
function foo(a) {
a = 1;
}
```

其實傳進來的都是地址,或者說引用吧,(傳引用也是另外一個變量了,可是從JS的角度來看C++這種行爲像是傳名,固然這麼說也不對),並非怎樣傳遞致使的做用不一樣,而是內部賦值語句的運行操做不一樣了(一個複寫,一個引用遷移)。

我的認爲這個不一樣是語言之間的根本區別,肯定了這個不一樣以後,基本以後的是否須要使用虛擬機,是否須要回收內存,等等都可以大概肯定了,以後可能就是在回收內存究竟是jc仍是指針計數之類的問題上了。

另外說一句像C語言這樣第一類語言,你編的程序就是最後運行的程序了,雖然你可能引用了不少庫,但不影響這個特色,換句話說,若是全部的庫都是你寫的,你的程序只要編譯就能夠運行了,什麼都不須要依賴。可是其餘語言就沒有這麼單純了,每每須要一個程序輔助運行來解釋你程序的運行幫助你的程序來解決內存等問題,甚至須要一個虛擬機(你們每每這麼作)。

### 做用域與閉包

C語言之中根本沒有提過閉包這個概念,由於C語言設計機制簡單,做用域判斷也儘可能的簡化,到最後只留下了靜態鏈,把動態鏈去掉了(這是編譯裏的概念)。因而一個函數,一個過程就不能保有本身的變量(注意這裏指的是函數閉包變量,是與函數同生命週期的,而不是與函數的執行同生命週期的參數變量和臨時變量),如今的動態語言每每實現一個比C語言稍稍複雜,可是也不能算是完整的動態鏈的東西,用這個來解決新的閉包問題。

這從根源上來講是由於動態語言想把函數(或者說類)做爲他的第一成員致使的,若是函數是第一成員,他就不像其餘數據成員那樣單純,由於C中只有數據成員,不存在兩個數據成員的相對生命週期問題。在動態語言中這裏還存在一個弱引用的問題,每每給人帶來不少困擾,總的來講設計有利有弊,這纔是不一樣語言的魅力,在瞭解了這種機制以後其實也好處理和轉化,用起來到是方便。

### 語言暗示

語言的暗示比語言更加劇要!我一個很好的朋友跟我說過這麼一個例子(來自《Java程序員 上班那點兒事》 - 3.2.5 也不要過於迷信C語言)以下,解釋爲何java運行比C++快。

```
int getXXX(int x, int y) { // java
return x+y;
}
```
```

int getXXX(int x, int y) { // C++
for(int i = 0; i < 10000000; i++){
string ss = "I am so slow";
}
return x+y;
}
```

在你們看來,這也許就是一個笑話。那麼我再舉一個例子,大三的時候咱們學編譯,因爲能力有限只能選擇更好實現的JS來作大做業(一個閹割版pascal編譯器),不少同窗選擇使用C++(推薦)來實現這個編譯器,我是很佩服用C++寫編譯器這些人的,由於我以爲這東西C++寫太難了。

然而這裏我想說說效率問題,寫過leetcode的同窗應該知道js一樣算法平均是比c慢100倍的。而在這個編譯器任務中我須要構造一個上千狀態的自動機,這個狀態機是自動構造的,其中每一個狀態都須要各類調整和比較,相同的指導思想,我用js寫的這個狀態機是能夠在5s以內構造的。相比之下C++寫的狀態機須要1分鐘左右才能構造完成。

相同的指導思想,然而js快這麼可能是爲何呢,由於這之中存在大量賦值操做,類對象的大量轉移、建立,在js之中使用的相同表達式在每一個狀態中都是共享的,然而在C++中我想你們也不能作成這樣,我大概猜一下,每一個狀態類對象下的每一個表達式定義爲了表達式對象數組,每一個表達式其實都是源表達式的拷貝,這樣C++程序就花了大量時間在新建對象和拷貝對象上,可是第二類語言就很天然的繞開了這些操做,反而獲得了更高的效率。

考慮這件事情的根源其實就是C++默認「=」深拷貝,而js是賦引用了。固然,若是C++全都合理的使用了引用和Hash(toJSON(self))方法進行比較和賦值,必定可以達到比js快100倍的效果的。我不是說全部狀況js都比C++暗示的好,可是起碼在這件事情上,一些C++程序員就被在不知情得狀況下綁架起來寫了10000000句的```string ss = "I am so slow";```吧。

語言對你的影響是潛移默化的,跳出語言想架構,跳入語言作實現可能可以減小大型失誤,可是細節上仍是會有根深蒂固的影響。

### 類與對象

這裏舉一個例子吧,也是我最很差說清楚的例子了。前陣子看到一篇文章《function/bind的救贖(上)》(http://blog.csdn.net/myan/article/details/5928531)提到這個「怎樣實現對象機制」的問題,裏面解釋了我一直以來有的疑惑,如今你們採用的面向類編程的機制可能徹底違背了「對象理論」的設計初衷。從這個角度其實能夠把Smalltalk,OC分爲一類,其餘對象語言分爲一類了,目前來看面向對象設計中Java的影響仍是很是大的,大型工程中可以活用以後動態腳本語言特性的仍是太少了。

### 關於異步

異步執行這件事情其實也是我接觸JS以後纔有這麼大的體會的,固然以前爲了可以更好地利用計算機的運算資源也是作了不少的嘗試的,好比進程、線程、管程這個發展。到JS這裏直接讓程序之中的每個耗時操做都異步執行了,這樣作確實對性能有不少提高,尤爲是併發的狀況,不用系統處理線程,切換線程了,也是對系統的一種釋放。

可是這種修改致使JS的寫法都和正常的語言不一樣了,後來你們就開始研究如何解決這種詭異的Callback寫法了,甚至搬出Promise來解決問題,這兩天node發佈7,也把async,await支持上了,版本迭代的過程當中,以前的庫就不能支持,在本語言內部出現了一套各類feature的編譯器(babel)打得火熱。

總的來講出現問題想解決辦法仍是一件好事,可是我以爲這事情作的愈來愈不優雅了。甚至我以爲徹底能夠從出發點想辦法。可是想一想這種事情每每是這樣的,好比被稱爲良好分層設計的計網,不也因爲歷史的緣由,有各類不正常的依賴、協議層出不窮麼。

### 更多

關於語言這件事,程序員圈子裏面就沒有中止過爭吵。這篇文字的強行堆砌可能不會有太多人看完再後面吵架了吧(仍是但願你們可以多交流的)。想一想本身也沒有什麼資格談論這個問題,算是對本身的思想有個解放,不在去想這個事情了,到這裏總算是把大三以來關於語言的思考都差很少記下來了吧,怎麼說也是用過世界最好語言和發展最快的語言的人啊。

相關文章
相關標籤/搜索