我只会 Java 一门语言可以吗?
- 面向?qū)ο笥脕斫M織程序是好,但我用C
- 我用C++,函數(shù)式編程的好,跟我有什么關(guān)系
- 動(dòng)態(tài)語言那些特性很好,可惜我用Java
- ……
如果你這么想,說明你被自己的看家本事給局限住了,這種思維方式會(huì)讓你即便學(xué)到了更多好東西,也無可奈何。
程序設(shè)計(jì)語言之間沒有那么涇渭分明界限,多學(xué)幾門,才能打破語言局限,讓設(shè)計(jì)更好落地。可根據(jù)項(xiàng)目特點(diǎn)選擇合適語言,也可以將其它語言一些優(yōu)秀的地方借鑒過來。Andrew Hunt和David Thomas在《程序員修煉之道》(The Pragmatic Programmer)中給程序員們提了一項(xiàng)重要的建議:每年至少學(xué)習(xí)一門新語言。
語言那么多,我要一個(gè)一個(gè)都學(xué)過去嗎?學(xué)語言到底在學(xué)什么呢?
程序設(shè)計(jì)語言本身也是一個(gè)軟件,它也包含模型、接口和實(shí)現(xiàn)。
學(xué)習(xí)程序設(shè)計(jì)語言主要是為了學(xué)習(xí)程序設(shè)計(jì)語言提供的編程模型,比如:不同的程序組織方式,不同的控制結(jié)構(gòu)等等。因?yàn)椴煌木幊棠P蜁?huì)帶給你不同的思考方式。
1 程序設(shè)計(jì)語言發(fā)展簡(jiǎn)史
程序設(shè)計(jì)語言都是圖靈完備:語言指定的數(shù)據(jù)操作規(guī)則能夠?qū)崿F(xiàn)圖靈機(jī)的全部功能(圖靈機(jī)的概念是由阿蘭·圖靈提出的,圖靈機(jī)為計(jì)算機(jī)能夠解決的問題劃定了一個(gè)邊界)。
所以,圖靈機(jī)是所有程序設(shè)計(jì)語言最底層的模型,程序設(shè)計(jì)語言都是在這個(gè)基礎(chǔ)上生長(zhǎng)出來的,包括計(jì)算機(jī)用0和1編碼。
計(jì)算機(jī)能夠識(shí)別的都是0和1,但用0和1直接寫代碼實(shí)在太麻煩。所以,早在計(jì)算機(jī)誕生之初,就產(chǎn)生匯編語言,將那些0101的操作符變成更容易記住的ADD、MOV之類指令。
但人們很快就發(fā)現(xiàn),用匯編寫程序也痛苦,因?yàn)橹挥袑?duì)計(jì)算機(jī)了如指掌,才能寫好匯編。更可怕的是,即便你熟練掌握了一種計(jì)算機(jī)的匯編語言,換成另外一種計(jì)算機(jī),你也必須從頭學(xué)。
高級(jí)程序設(shè)計(jì)語言登場(chǎng)。
第一門高級(jí)程序設(shè)計(jì)語言Fortran,為程序設(shè)計(jì)語言的發(fā)展奠定基礎(chǔ)。數(shù)據(jù)開始擁有了類型(類型就是一種對(duì)內(nèi)存數(shù)據(jù)的解釋方式)。人們逐漸認(rèn)識(shí)到高級(jí)程序設(shè)計(jì)語言對(duì)于開發(fā)效率的提高。
早期程序設(shè)計(jì)語言探索的集大成者就是C語言,它提供了對(duì)于計(jì)算機(jī)而言最為恰當(dāng)?shù)某橄?#xff0c;屏蔽了計(jì)算機(jī)硬件的諸多細(xì)節(jié)。
隨著高級(jí)程序設(shè)計(jì)語言的發(fā)展,門檻逐步降低,可開發(fā)的程序規(guī)模也逐漸膨脹。搭著C語言的便車將面向?qū)ο蟮某绦蛟O(shè)計(jì)風(fēng)格帶入了主流視野,這就是C++。
各種高級(jí)程序設(shè)計(jì)語言已經(jīng)屏蔽了很多細(xì)節(jié),但有一個(gè)問題始終沒有得到很好的解決,也由此引發(fā)了更多的問題,這就是內(nèi)存管理。其實(shí),人們?cè)缇驮趪L試各種屏蔽內(nèi)存管理的方式,但因?yàn)樵缙谟?jì)算機(jī)硬件性能有限,所以沒有任何一種方式能夠成為行業(yè)主流。
后來,計(jì)算機(jī)硬件的能力得到了大幅度提升,這讓那些在故紙堆里的技術(shù)又煥發(fā)了新的活力。這個(gè)階段的勝利者是Java,一方面,它支持面向?qū)ο缶幊?#xff1b;另一方面,它還有垃圾回收機(jī)制——一種內(nèi)存管理的方式。
Java的路其實(shí)也很坎坷,因?yàn)樗缙谠趥€(gè)人電腦上的嘗試并不算成功。后來選擇了企業(yè)級(jí)開發(fā)的賽道,才有機(jī)會(huì)展現(xiàn)自己的優(yōu)勢(shì)。因?yàn)槠髽I(yè)級(jí)服務(wù)器本身性能優(yōu)于個(gè)人電腦,對(duì)Java有更高的容忍度,它才得到了機(jī)會(huì),不斷進(jìn)行自身的優(yōu)化。
當(dāng)硬件不再是程序設(shè)計(jì)語言的發(fā)展障礙之后,程序設(shè)計(jì)語言又該如何發(fā)展呢?
從前面的歷程不難看出,程序設(shè)計(jì)語言的發(fā)展就是一個(gè)“逐步遠(yuǎn)離計(jì)算機(jī)硬件,向著待解決的問題靠近”的過程。所以,程序設(shè)計(jì)語言接下來的發(fā)展方向就是探索怎么更好地解決問題了。
前面說的這些只是程序設(shè)計(jì)語言發(fā)展的主流路徑。
還有一條不那么主流的路徑也一直在發(fā)展,就是函數(shù)式編程的程序設(shè)計(jì)語言,這方面的代表就是LISP。
在這條路上,剛開始,很多人都是偏學(xué)術(shù)風(fēng)格的,關(guān)心解決方案是否優(yōu)雅,也就是說,如何解決問題,如何一層層構(gòu)建抽象。也探索更多可能,垃圾回收機(jī)制就是從這里來的。但同樣受限于當(dāng)時(shí)硬件的性能,這條路上的探索在很長(zhǎng)一段時(shí)間之內(nèi)都只是一個(gè)小眾游戲。
當(dāng)硬件的性能不再成為阻礙,如何解決問題開始變得越來越重要時(shí),函數(shù)式編程終于和程序設(shè)計(jì)語言發(fā)展的主流匯合了。促進(jìn)函數(shù)式編程引起廣泛重視也還有一個(gè)硬件因素:多核。
多核的出現(xiàn),本身是IT行業(yè)應(yīng)對(duì)CPU發(fā)展進(jìn)入瓶頸期的一個(gè)解決方案,但它卻打破了很多程序員只習(xí)慣于利用一個(gè)CPU寫程序的傳統(tǒng)方式。
為了利用多核的優(yōu)勢(shì),人們探索了各種方案,今天看到的各種并發(fā)模型、異步模型等解決方案都從那時(shí)開始得到了蓬勃的發(fā)展。函數(shù)式編程在這個(gè)方面的探索就是利用自己聲明式的表達(dá)方式屏蔽了硬件差異。讓人們注意到函數(shù)式編程的價(jià)值的就是著名的MapReduce。
函數(shù)式編程興起,讓那些在函數(shù)式編程社區(qū)的探索隨之興起,比如,聲明式編程、DSL、元編程等等。一些后出現(xiàn)的程序設(shè)計(jì)語言開始將面向?qū)ο蠛秃瘮?shù)式編程二者融合起來,比如Scala。而像Java和C++這些“老戰(zhàn)士”則逐漸地將函數(shù)式編程的支持加入到語言之中。
相比于這些“正規(guī)軍”,還有一股力量也逐漸從邊緣走上了舞臺(tái),這就是動(dòng)態(tài)語言,代表語言有 Perl、Python、Ruby、PHP等等。
以前,人們更喜歡用“腳本語言”稱呼這類程序設(shè)計(jì)語言,這個(gè)名字表明,它就是為了簡(jiǎn)單地解決一些特定的問題而出現(xiàn)的。所以,在人們心目中,它們顯得并不那么正式。但它們簡(jiǎn)單、輕巧的特性有效地降低了入門的門檻,也贏得了一大批擁躉。
語言的發(fā)展就是一個(gè)互相學(xué)習(xí)和借鑒的過程。以前,動(dòng)態(tài)語言的弱項(xiàng)在于不適用于規(guī)模比較大的工程,而近些年來,隨著動(dòng)態(tài)語言用戶的增多,配套的工具也逐漸多了起來,動(dòng)態(tài)語言項(xiàng)目的規(guī)模也逐漸增大。而在主航道的程序設(shè)計(jì)語言,也紛紛向動(dòng)態(tài)語言學(xué)習(xí),努力地簡(jiǎn)化代碼編寫的難度,比如,Java和C++都開始支持類型推演(Type Inference),目的就是讓程序員少敲幾個(gè)字符。
把程序設(shè)計(jì)語言當(dāng)作一個(gè)軟件,它的發(fā)展歷程就是一個(gè)逐漸添加新模型的過程,而其發(fā)展的結(jié)果就是如今的開發(fā)門檻越來越低,能夠開發(fā)的程序規(guī)模越來越大。
2 語法都是語法糖
C語言提供了對(duì)匯編指令直接的封裝。
C++先是提供了面向?qū)ο?#xff0c;后來又提供了泛型編程。
Java把內(nèi)存管理從開發(fā)者面前去掉了,后來引入的Annotation可以進(jìn)行聲明式編程。
Ruby提供了動(dòng)態(tài)類型,以及由Ruby on Rails引導(dǎo)出的DSL風(fēng)格。
Scala和Clojure提供了函數(shù)式編程。
Rust提供了新的內(nèi)存管理方式,而Libra提供的Move語言則把它進(jìn)一步抽象成了資源的概念。
既然學(xué)習(xí)新的程序設(shè)計(jì)語言是為了學(xué)習(xí)新的編程模型,反過來也可以說,不提供新編程模型的語言是不值得刻意學(xué)習(xí)的。
如果你已經(jīng)學(xué)會(huì)了一兩門程序設(shè)計(jì)語言,學(xué)習(xí)一門新的語言其實(shí)并不困難,因?yàn)槊糠N語言提供的新模型是有限的,基本的元素類似,無非用不同關(guān)鍵字。
所以,學(xué)習(xí)新語言,只是在做增量的學(xué)習(xí),思維負(fù)擔(dān)并沒那么沉重。一旦對(duì)于程序設(shè)計(jì)語言的模型有了新的認(rèn)識(shí),你就能理解一件事:一切語法都是語法糖。
語法糖(Syntactic sugar)是英國(guó)計(jì)算機(jī)科學(xué)家彼得·蘭丁發(fā)明的一個(gè)術(shù)語,指的是那些為了方便程序員使用的語法,它對(duì)語言的功能沒有影響。
懂得了語法糖的道理,要想更好地理解程序設(shè)計(jì)語言,一種好的做法就是打開語法糖,了解一下語法是怎么實(shí)現(xiàn)的:
類型是一種對(duì)內(nèi)存的解釋方式。
class/struct是把有相關(guān)性的數(shù)據(jù)存放到一起的一種數(shù)據(jù)組織方式。
Groovy、Scala、Kotlin、Clojure等JVM上的新語言,提供了一種不同于Java的封裝JVM的方式。
……
3 總結(jié)
語言的發(fā)展并非一蹴而就,而是一個(gè)漸進(jìn)式的發(fā)展歷程。一些新的嘗試總會(huì)在一些不起眼的地方冒出來,而且語言之間也在相互借鑒。
如果你能每年學(xué)習(xí)一門新語言,起初,你可以了解不同的編程模型。當(dāng)你的積累足夠多了,學(xué)習(xí)語言就是在跟蹤程序設(shè)計(jì)語言的最新發(fā)展了。
當(dāng)你手里有了足夠多的“武器”時(shí),你就可以打開思路,運(yùn)用不同的方式解決問題了,甚至把其它語言的好東西,借鑒到自己使用的語言中。
學(xué)習(xí)不同的程序設(shè)計(jì)語言可以幫助我們更好地落地設(shè)計(jì),也可以讓我們向不同的語言借鑒優(yōu)秀的方面。
我們簡(jiǎn)要地了解了程序設(shè)計(jì)語言的發(fā)展歷史,從最開始的對(duì)機(jī)器模型的封裝,到今天不斷降低的開發(fā)門檻,程序設(shè)計(jì)語言的演化從未停止。我們也看到各種不同的編程風(fēng)格在經(jīng)歷了最初各自獨(dú)立的發(fā)展之后,開始慢慢融合。
對(duì)程序設(shè)計(jì)語言發(fā)展的了解,可以幫助我們理解一件事:一切語法都是語法糖。新的語法通常是在既有的結(jié)構(gòu)上不斷添加出來的,為的是簡(jiǎn)化代碼的編寫。
《程序員修煉之道》鼓勵(lì)程序員們每年至少學(xué)習(xí)一門新語言,主要是為了讓我們?nèi)W(xué)習(xí)新的編程模型,而不提供新編程模型的語言不值得刻意去學(xué)習(xí)。
不過,這就需要你對(duì)程序設(shè)計(jì)語言有著更深的理解。
總結(jié)
以上是生活随笔為你收集整理的我只会 Java 一门语言可以吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 儿童手口眼异常识别
- 下一篇: Java 生成订单号(唯一id)方案