电竞比分网-中国电竞赛事及体育赛事平台

分享

別和一種語(yǔ)言廝守終生:為工作正確選擇編程語(yǔ)言

 西北望msm66g9f 2016-12-16

本文由程序猿編譯團(tuán)隊(duì)-薇WEI 編譯

原文鏈接:https:///articles/do-not-marry-a-language-selecting-the-correct-lang

轉(zhuǎn)載請(qǐng)注明來(lái)自:程序猿(微信號(hào):imkuqin)


在為您的下一個(gè)APP選擇編程語(yǔ)言時(shí)可以參考下面一些思路。


開(kāi)發(fā)人員在項(xiàng)目上需要作的關(guān)鍵選擇之一,就是語(yǔ)言或者語(yǔ)言組的選擇,以執(zhí)行系統(tǒng)。這個(gè)選擇不僅關(guān)系到系統(tǒng)的執(zhí)行,也關(guān)系到設(shè)計(jì)。例如,是該選擇面向?qū)ο笳Z(yǔ)言還是面向過(guò)程語(yǔ)言?這個(gè)選擇會(huì)對(duì)整個(gè)項(xiàng)目產(chǎn)生深遠(yuǎn)影響,亦或是影響項(xiàng)目中的一部分程序的壽命。我們常常不多加考慮就輕易作出選擇:我總是用這種語(yǔ)言來(lái)執(zhí)行這種系統(tǒng);我最了解這個(gè)語(yǔ)言;我最喜歡這個(gè)語(yǔ)言;我享受用這個(gè)語(yǔ)言來(lái)編程的過(guò)程等等。


既然編程語(yǔ)言影響深遠(yuǎn),在選擇上就該契合實(shí)際。我們常常意識(shí)不到自己在選擇上的偏見(jiàn);更何況,有時(shí)候我們不喜歡選用一種語(yǔ)言的原因卻正是我們必須選擇這種語(yǔ)言的原因所在。


如果能打開(kāi)心胸,坦誠(chéng)面對(duì)自己的偏見(jiàn),或許就能減少比如硬要往圓孔釘方釘?shù)耐纯?。在選擇一個(gè)比較好或者比較合適的語(yǔ)言時(shí),我們可以考慮以下幾個(gè)原則。


沒(méi)有完美的編程語(yǔ)言


開(kāi)發(fā)人員包括新手都會(huì)承認(rèn)“這個(gè)語(yǔ)言當(dāng)然不是個(gè)完美的語(yǔ)言”,但同時(shí)也會(huì)說(shuō)“但這是最好的編程語(yǔ)言”,對(duì)此我們并不會(huì)感到驚訝。說(shuō)一個(gè)語(yǔ)言是一個(gè)項(xiàng)目的最好語(yǔ)言關(guān)鍵點(diǎn)在于項(xiàng)目環(huán)境,只在某種特定環(huán)境中是最佳語(yǔ)言。因此我們的第一個(gè)選擇原則是:


沒(méi)有完美的語(yǔ)言,每個(gè)語(yǔ)言都有優(yōu)劣。


舉例說(shuō),許多常用運(yùn)行時(shí)語(yǔ)言如Java或Python的開(kāi)發(fā)人員聲稱C語(yǔ)言或C++讓人不勝其煩,總讓他們關(guān)注低級(jí)細(xì)節(jié)如內(nèi)存管理或編譯時(shí)類型檢查的嚴(yán)格粒度。這點(diǎn)無(wú)可否認(rèn),只要我們所開(kāi)發(fā)的項(xiàng)目并非真正的關(guān)注貌似瑣碎的任務(wù)如內(nèi)存管理或單一循環(huán)內(nèi)的copy-assignments操作量。


相反,如果我們所做的項(xiàng)目或項(xiàng)目的一部分對(duì)我們的編碼效率或安全關(guān)鍵有極端偏見(jiàn),而這種偏見(jiàn)又是自然而然的事,那么這種看似繁瑣的細(xì)節(jié)可能就是我們所要找的粒度水平。在這種環(huán)境下,Jave或Python的運(yùn)行時(shí)性質(zhì)似乎顯得無(wú)動(dòng)于衷或者事不關(guān)己的模樣。相反,我們會(huì)希望最大程度地嚴(yán)格控制在分配或解除分配內(nèi)存時(shí),執(zhí)行了多少move-assignments 或copy-assignments,在編譯時(shí)上捕捉到盡可能多的錯(cuò)誤而不是讓錯(cuò)誤滲透到運(yùn)行時(shí)(或在運(yùn)行時(shí)異常時(shí)顯現(xiàn))


雖然這一個(gè)原則在理論上顯而易見(jiàn),但實(shí)際上開(kāi)發(fā)者又經(jīng)常偏離這一原則:我們說(shuō)我們知道我們最喜歡的語(yǔ)言不是完美語(yǔ)言,但是我們?nèi)耘f在開(kāi)發(fā)的每一個(gè)項(xiàng)目上使用這個(gè)語(yǔ)言,不管是否真正適合。而且,當(dāng)其他開(kāi)發(fā)者質(zhì)疑我們的語(yǔ)言選擇時(shí),我們又很教條式的捍衛(wèi)自己的選擇,而看不到對(duì)方的論點(diǎn)中的優(yōu)點(diǎn)。所以記住:每一種語(yǔ)言都有優(yōu)點(diǎn)和缺點(diǎn)。理解你所知道的(和你所不知道的)語(yǔ)言的優(yōu)缺點(diǎn)并依此作出選擇。


你不喜歡一個(gè)編程語(yǔ)言的原因或許正是你需要使用這種語(yǔ)言的原因所在


可能看似有反直覺(jué),但有時(shí),你不喜歡一個(gè)編程語(yǔ)言的原因或許正是你需要使用這種語(yǔ)言的原因所在。繼續(xù)剛才的例子,我做C++開(kāi)發(fā)人員的時(shí)候,經(jīng)常有很多不同概念要跟蹤(內(nèi)存管理和對(duì)象壽命,執(zhí)行編程三原則Rule of Three等等),所以完成一個(gè)項(xiàng)目的一個(gè)簡(jiǎn)單功能也變得很冗長(zhǎng)繁瑣。這種類型的開(kāi)發(fā)跟蹤數(shù)周之后,你會(huì)發(fā)現(xiàn)用Python,Java或其他“更高級(jí)別”的語(yǔ)言會(huì)感覺(jué)像是受了恩惠;但是事實(shí)真是如此么?


有時(shí),我們不喜歡一個(gè)編程語(yǔ)言原因或許正是我們需要使用這種語(yǔ)言的原因。如果我在開(kāi)發(fā)一個(gè)驅(qū)動(dòng)或者安全關(guān)鍵、實(shí)時(shí)系統(tǒng),我上面所表達(dá)的繁瑣的理由正是這個(gè)語(yǔ)言最大的優(yōu)點(diǎn)。比如,C++提供了一種機(jī)制用來(lái)表達(dá)該對(duì)象被復(fù)制時(shí)所執(zhí)行的邏輯,當(dāng)效率或者精確度井然有序的時(shí)候,C++在這點(diǎn)上的作用無(wú)可估量。


這點(diǎn)看似很好,但有時(shí)又沒(méi)辦法理解為啥我們的憎惡在某種環(huán)境下會(huì)變成一種優(yōu)點(diǎn)。所以,這種時(shí)候我們?cè)撊绾尉駬??這就引出了第二個(gè)原則:


坦誠(chéng)面對(duì)自己:了解你不喜歡一種語(yǔ)言的原因,別對(duì)自己的憎惡教條化處理。


仍舊是上面C++的例子,我不喜歡長(zhǎng)時(shí)間用C++編程,因?yàn)檫@個(gè)語(yǔ)言要求很高的精準(zhǔn)度,很容易導(dǎo)致錯(cuò)誤或,就像困于叢林中(只見(jiàn)樹(shù)木不見(jiàn)森林)。這種精準(zhǔn)度會(huì)阻礙開(kāi)發(fā)人員去質(zhì)疑一些決定,“這個(gè)對(duì)象要建立在堆棧上還是堆上?還是創(chuàng)建在堆棧的某一部分或是另外一個(gè)堆?”。在其他語(yǔ)言上,開(kāi)發(fā)人員只要簡(jiǎn)單的創(chuàng)建一個(gè)對(duì)象,或用面向?qū)ο罄^承來(lái)各自完成任務(wù),并直接轉(zhuǎn)移到下一個(gè)功能,因?yàn)檫@些語(yǔ)言(或者更準(zhǔn)確的說(shuō),編譯器或注釋器)能負(fù)責(zé)這些底層實(shí)現(xiàn)。


但是,如果誠(chéng)實(shí)一點(diǎn),我會(huì)承認(rèn)我不習(xí)慣C++這些特性的原因是它讓我來(lái)承擔(dān)實(shí)現(xiàn)這些細(xì)節(jié)的責(zé)任。在其他語(yǔ)言上,我并不需要負(fù)責(zé)這些細(xì)節(jié),也不懂得如何實(shí)現(xiàn):這些細(xì)節(jié)已經(jīng)從開(kāi)發(fā)者身上抽離出來(lái)。在一些這種細(xì)節(jié)必不可缺的環(huán)境中,我不喜歡C++的原因正是我們需要用這個(gè)語(yǔ)言的原因。


所以用這種讓我們惱怒的語(yǔ)言會(huì)讓我們苦不堪言么?未必?;蛟S可以換個(gè)角度:不是將這些功能視為缺點(diǎn),或許可以擁抱他們,將他們視為完成任務(wù)的一種必須。不說(shuō)“苦不堪言”,而說(shuō)“謝天謝地我可以用這個(gè)語(yǔ)言來(lái)完成任務(wù)”。只需記?。涸谝恍┉h(huán)境中,這些功能會(huì)是恩賜;而在其他環(huán)境中,又會(huì)很繁瑣。坦誠(chéng)面對(duì)你不喜歡一種語(yǔ)言特征的原因。


越熟悉其他語(yǔ)言,對(duì)你越有幫助


關(guān)于這一點(diǎn),我們直接開(kāi)始第三個(gè)原則:


如果你所擁有的唯一工具是錘子,那么每個(gè)問(wèn)題看起來(lái)都像是釘子。


這個(gè)原則并不特定適用于軟件工程,但也深刻地體現(xiàn)在許多軟件開(kāi)發(fā)情況中。很多時(shí)候,我們選擇一門(mén)語(yǔ)言,或一門(mén)語(yǔ)言所支持的工具(如Java的JMS,Python的asyncio,Ruby的Rails等),因?yàn)槲覀冎浪鼈兊拇嬖?。如果我們所熟知的語(yǔ)言只有Java,我們就會(huì)用它來(lái)解決在Java環(huán)境中所遇上的任何問(wèn)題。比如,“我需要為通信軟件創(chuàng)建一個(gè)路由框架,可以怎么通過(guò)Java來(lái)實(shí)現(xiàn)?”這便會(huì)限制我們能使用的手段并人為地限制我們?yōu)楣ぷ鬟x擇正確語(yǔ)言的能力。


解決這個(gè)問(wèn)題是為了拓寬你的眼界,學(xué)習(xí)其他語(yǔ)言的功能與復(fù)雜性。正如Andrew Hunt和DavidThomas在《程序員修煉之道》(《The PragmaticProgrammer》)中所建議的那樣,重要的原則就是每年學(xué)習(xí)一種新語(yǔ)言。這并不像聽(tīng)起來(lái)的那么簡(jiǎn)單,因?yàn)閷W(xué)習(xí)一種語(yǔ)言對(duì)不同的人來(lái)說(shuō)意味不同。還有個(gè)事實(shí)問(wèn)題是,我們經(jīng)常用一種單一的語(yǔ)言來(lái)實(shí)現(xiàn)一個(gè)項(xiàng)目,這就使學(xué)習(xí)的其他語(yǔ)言顯得毫無(wú)用處。比如如果我在開(kāi)發(fā)Android應(yīng)用時(shí)每天都是用Java,那么學(xué)習(xí)C#對(duì)我來(lái)說(shuō)就顯得浪費(fèi)時(shí)間。


但正如第三個(gè)原則所揭示的,這只是假象。 學(xué)習(xí)其他語(yǔ)言的好處會(huì)在我們從不同的角度看待問(wèn)題,以及選擇應(yīng)對(duì)問(wèn)題工具的能力時(shí)凸顯出來(lái)。為了凸顯這種能力,我們必須學(xué)習(xí)多種語(yǔ)言帶給我們的警示,學(xué)習(xí)開(kāi)發(fā)人員用它們解決問(wèn)題的方式。比如,如果一個(gè)開(kāi)發(fā)人員要用C++執(zhí)行元編程,TA可能會(huì)使用C++的模板元編程TMP(TemplateMetaprogrammming),但也可能會(huì)用Java的反射(reflection)。知道了用其他語(yǔ)言解決類似問(wèn)題的方法就會(huì)減少把自己局限在特定思維的風(fēng)險(xiǎn)。


再舉個(gè)例子,如果我們需要能夠改變一個(gè)類的運(yùn)行時(shí)特征,那么一個(gè)熟知C++的復(fù)雜程度的C++開(kāi)發(fā)人員,可能創(chuàng)造出能夠拓展編譯時(shí)語(yǔ)言邊界的解決方案。而另一個(gè)稍微熟悉Java的開(kāi)發(fā)人員就能說(shuō),“我喜歡C++,但Java的運(yùn)行時(shí)反射更適合解決這個(gè)問(wèn)題”


供開(kāi)發(fā)人員選擇的編程語(yǔ)言不計(jì)其數(shù),因此優(yōu)先學(xué)習(xí)哪種語(yǔ)言至關(guān)重要。從今天流行的語(yǔ)言開(kāi)始學(xué)起便是不錯(cuò)的選擇(比如可參考《most popularlanguages on Github》,《Language Trends on Github》,《The9 most popular computer languages》,《according to theFacebook for programmers》等)。


一個(gè)好的做法是不僅學(xué)習(xí)語(yǔ)言的語(yǔ)法,也學(xué)習(xí)語(yǔ)言的特質(zhì)。在Stackoverflow上查閱那個(gè)語(yǔ)言的最普遍問(wèn)題,加入該語(yǔ)言最流行的社區(qū)板塊或論壇。


編程語(yǔ)言只是方法,不是目的


第四個(gè)也是最后一個(gè)原則似乎最充滿哲理,也最重要:


編程語(yǔ)言是一種方法,不是目的。


除非你是個(gè)語(yǔ)言標(biāo)準(zhǔn)作者或編譯器作者,否則編程語(yǔ)言是只是一種通往目標(biāo)的方法,這個(gè)目標(biāo)便是完成項(xiàng)目:就是完成項(xiàng)目,而不是使用一種特定語(yǔ)言。這并不意味著每個(gè)開(kāi)發(fā)人員都無(wú)權(quán)選擇喜歡或不喜歡的語(yǔ)言(實(shí)際上,如果夠誠(chéng)實(shí),這些好惡可以成為我們的優(yōu)點(diǎn),參考上面第二個(gè)原則),但我們不應(yīng)該自欺欺人地做出這樣的決定比如“這是我們用那種語(yǔ)言功能的好機(jī)會(huì)”,除非這個(gè)語(yǔ)言功能確實(shí)適用于這個(gè)項(xiàng)目。


將這一點(diǎn)銘記于心很重要:語(yǔ)言只是一種對(duì)手頭的問(wèn)題表達(dá)解決方案的一種手段。確保你選擇了最能實(shí)現(xiàn)解決問(wèn)題域的一種語(yǔ)言。


其他需要考慮的原則:


這里有一些補(bǔ)充原則供你選擇語(yǔ)言時(shí)作考慮:


1、考慮某些語(yǔ)言是如何與其他語(yǔ)言相互作用的。比如,如果你覺(jué)得Python是你完成大部分項(xiàng)目的最好語(yǔ)言,但項(xiàng)目中又存在極端要求粒度水平或效率水平的定義良好的部分(通常適用C或者C++),這并不意味著你不能在該項(xiàng)目使用Python。相反,應(yīng)該使用Python,用C或C++做這些特定部分的編寫(xiě),并和以Pyhton C API做接口。注意,為了實(shí)現(xiàn)這個(gè)方案,我們必須知道Python有CAPI;因此知道最流行語(yǔ)言的一些功能對(duì)我們很有好處。


2、中間件可能允許使用多種語(yǔ)言。舉例說(shuō),如果有兩個(gè)應(yīng)用程序需要通信,比如移動(dòng)設(shè)備和服務(wù)器應(yīng)用程序,這并不意味著需要二者必須用同一種語(yǔ)言(雖然可以,如果你判斷說(shuō),這是最好的選擇)如果移動(dòng)設(shè)備是一個(gè)安卓手機(jī),服務(wù)器應(yīng)用程序也適合于Python應(yīng)用程序,那就是用消息代理中間件,比如RabbitMQ,可以讓你在通信時(shí)使用兩種語(yǔ)言:安卓應(yīng)用程序可以使用Java Rabbit MQ API,服務(wù)器應(yīng)用程序可以使用Python Rabbit MQ API。


3、擁抱其他語(yǔ)言的怪異。如果你是個(gè)Java開(kāi)發(fā)人員,你會(huì)使用包來(lái)分割源代碼的邏輯單位;如果是個(gè)Python開(kāi)發(fā)人員,會(huì)用Python包架構(gòu)來(lái)做同樣的事;如果是C++開(kāi)發(fā)人員,就會(huì)使用命名空間或前綴類名(如'DZone_MyClassName').了解你所使用的語(yǔ)言的特別之處,擁抱它們:入鄉(xiāng)隨俗。否則就像是用意大利口音說(shuō)德語(yǔ),因?yàn)槟愀矚g用意音發(fā)音。當(dāng)然如果一種語(yǔ)言的某個(gè)特性長(zhǎng)盛不衰,這必有其因,那么你得確保你知道個(gè)中原因。



●本文編號(hào)111,以后想閱讀這篇文章直接輸入111即可。

●輸入m可以獲取到文章目錄

推薦↓↓↓
 

Linux學(xué)習(xí)

推薦15個(gè)技術(shù)類公眾微信

涵蓋:程序人生、算法與數(shù)據(jù)結(jié)構(gòu)、黑客技術(shù)與網(wǎng)絡(luò)安全、大數(shù)據(jù)技術(shù)、前端開(kāi)發(fā)、Java、Python、Web開(kāi)發(fā)、安卓開(kāi)發(fā)、iOS開(kāi)發(fā)、C/C++、.NET、Linux、數(shù)據(jù)庫(kù)、運(yùn)維等。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多