我最近將一個(gè)系統(tǒng)從Node重構(gòu)到了Go荧关,花了大概兩周多的時(shí)間溉奕,這個(gè)過(guò)程也是不得已而為之,因?yàn)楣鹃_(kāi)發(fā)的系統(tǒng)最終需要部署到客戶的服務(wù)器忍啤,而又不想暴露源碼加勤。
但是NodeJs開(kāi)發(fā)的系統(tǒng)卻無(wú)法從根本上來(lái)保護(hù)源碼,由于JavaScript是個(gè)解釋型的腳本語(yǔ)言(實(shí)際上現(xiàn)在已不是直接解釋)同波,因此鳄梅,即便有各種加殼加密方案,但是運(yùn)行時(shí)還是要解壓出源碼(即便是在內(nèi)存)未檩。那么只能把目光投向其他語(yǔ)言了戴尸,這個(gè)語(yǔ)言首先不能是腳本語(yǔ)言,那么PHP冤狡,Python孙蒙,Ruby就直接Pass掉了;然后是編譯成中間字節(jié)碼的java和C#,貌似會(huì)更安全一些悲雳,但是還是可以很輕易的被反編譯到源碼挎峦,雖然加殼混淆等技術(shù),但畢竟治標(biāo)不治本合瓢,還是不放心坦胶;接下來(lái)那就只剩下靜態(tài)編譯型語(yǔ)言了(實(shí)際上是指直接編譯到機(jī)器碼的語(yǔ)言),這類語(yǔ)言是直接編譯到二進(jìn)制,執(zhí)行的時(shí)候不需要依賴任何運(yùn)行時(shí)環(huán)境顿苇,可直接執(zhí)行編譯好的二進(jìn)制程序峭咒,那么想把二進(jìn)制代碼最終反編譯到源碼,幾乎是不可能的岖圈,頂多能拿到匯編代碼讹语,然后想要根據(jù)匯編代碼反推邏輯...那我估計(jì)他會(huì)暈死在半路上,蜂科,顽决,因此,終極方案就是采用一種直接編譯到機(jī)器碼的語(yǔ)言進(jìn)行重構(gòu)导匣,可選的較成熟語(yǔ)言有:C/C++,Go,Rust,更進(jìn)一步得講才菠,只有Go和Rust可選,C/C++就是做底層贡定,做系統(tǒng)的赋访,做web還是想都不要想,Go和Rust相比缓待,明顯Go這幾年的生態(tài)更好一些蚓耽,做起Web來(lái)坑會(huì)更少一些。經(jīng)過(guò)各種方案的對(duì)比斟酌旋炒,我們最終決定采用Golang這門語(yǔ)言對(duì)系統(tǒng)進(jìn)行重構(gòu)步悠,這樣,我們最終發(fā)布到客戶服務(wù)器上的就只是一個(gè)可執(zhí)行文件瘫镇,以及一些配置文件和靜態(tài)頁(yè)面文件鼎兽,Go源碼就無(wú)法拿到了。
我使用NodeJs已經(jīng)有兩年了铣除,我不敢說(shuō)精通谚咬,但最起碼是相當(dāng)熟悉了,相當(dāng)親切了尚粘,這個(gè)環(huán)境里的一切都是那么自然择卦,那么舒服±杉蓿可人都有一個(gè)弱點(diǎn)互捌,就是在一個(gè)熟悉的環(huán)境待久了,會(huì)本能地抗拒新的環(huán)境行剂,新的事物秕噪,尤其是成年人。因此厚宰,突然來(lái)到一個(gè)陌生的環(huán)境腌巾,會(huì)有種種不適遂填,會(huì)有一段相當(dāng)艱難的磨合期。感性就是這樣澈蝙,可理性告訴我吓坚,為了達(dá)到最優(yōu)目標(biāo),應(yīng)該拋棄原有的偏見(jiàn)和有色眼鏡(其實(shí)我一直認(rèn)為用Golang做Web開(kāi)發(fā)不是最優(yōu)的方案灯荧,盡管它是一門很便捷的靜態(tài)語(yǔ)言)礁击,去做該做的事情。
其實(shí)每門語(yǔ)言天生就具備了各自不同的基因逗载,都有自己最適用的領(lǐng)域和場(chǎng)景哆窿,沒(méi)有哪門語(yǔ)言可以做到擅長(zhǎng)所有方面(雖然JavaScript號(hào)稱通吃所有領(lǐng)域,PC端厉斟,移動(dòng)端挚躯,桌面端,甚至是嵌入式領(lǐng)域擦秽,但通吃不代表擅長(zhǎng))码荔,曠日持久的語(yǔ)言之爭(zhēng)其實(shí)就是無(wú)所謂的口水戰(zhàn)罷了。對(duì)于實(shí)際的問(wèn)題和場(chǎng)景感挥,相互配合缩搅,各取所長(zhǎng),才是實(shí)用之道触幼!尤其是隨著最近Docker和微服務(wù)的興起誉己,各語(yǔ)言各技術(shù)體系之間可以完美協(xié)作,共同組成一個(gè)完整系統(tǒng)域蜗!和諧社會(huì)大家為什么不能和諧相處呢?
JavaScript和Go的本質(zhì)區(qū)別是:一個(gè)是無(wú)類型的動(dòng)態(tài)語(yǔ)言噪猾,一個(gè)是強(qiáng)類型的靜態(tài)語(yǔ)言霉祸。這個(gè)本質(zhì)區(qū)別也決定了不同的編程體驗(yàn)(雖然Go融入了一些腳本語(yǔ)言的味道),強(qiáng)類型就是強(qiáng)類型袱蜡,即便搞了個(gè)自動(dòng)類型推斷丝蹭,你也處處擺脫不了類型,你需要多花一些額外精力去把所有變量的類型搞清楚坪蚁,這對(duì)于一個(gè)從弱類型語(yǔ)言轉(zhuǎn)過(guò)來(lái)的人是相當(dāng)折磨奔穿,寫起來(lái)會(huì)讓人感覺(jué)拖拖拉拉和麻煩,使人無(wú)法一心專注業(yè)務(wù)邏輯敏晤,會(huì)明顯感覺(jué)到增加了額外的心智負(fù)擔(dān)贱田。就好像你開(kāi)慣了自動(dòng)擋,再回去開(kāi)手動(dòng)擋就會(huì)覺(jué)得很麻煩很累嘴脾。代碼啰嗦重復(fù)我都可以忍男摧,可就是這個(gè)類型問(wèn)題真的折磨到我一度想打退堂鼓蔬墩,看來(lái)真的是被弱類型語(yǔ)言“慣壞了”,說(shuō)句實(shí)話:如果不是出于保護(hù)代碼考慮耗拓,我仍會(huì)毫不猶豫地選擇NodeJs來(lái)開(kāi)發(fā)拇颅,開(kāi)發(fā)效率實(shí)在不是一個(gè)級(jí)別的∏茄可這就是事實(shí)樟插,魚與熊掌總是不能兼得!8偷蟆黄锤!你想要靜態(tài)編譯的特性,你就得犧牲開(kāi)發(fā)的便捷性们妥。其實(shí)從另一個(gè)角度想想猜扮,Go作為一門靜態(tài)語(yǔ)言,能做到這步已經(jīng)算很不錯(cuò)了监婶,想想用C/C++來(lái)寫業(yè)務(wù)...旅赢,Go已經(jīng)算是很便捷了。所以惑惶,放下抱怨煮盼,接受現(xiàn)實(shí)吧!
不過(guò)令我欣慰的是带污,Golang這門語(yǔ)言確實(shí)有它不可掩蓋的優(yōu)勢(shì):1. 系統(tǒng)運(yùn)行速度明顯感覺(jué)會(huì)快點(diǎn)兒僵控;2. 編譯速度挺快,搞個(gè)熱編譯跟Node是一個(gè)體驗(yàn)鱼冀,Ctrl+S瞬間就編譯好了报破;3. 部署方便,干脆利落千绪;4.七牛云開(kāi)發(fā)的Golang嵌入腳本qlang可以極大提高開(kāi)發(fā)便捷性充易。除了這幾個(gè)明顯的優(yōu)勢(shì)外,還有些地方感覺(jué)體驗(yàn)不錯(cuò):代碼提示比較完善準(zhǔn)確(由于是強(qiáng)類型)荸型,因而可以加快一點(diǎn)編碼速度盹靴,也降低了出錯(cuò)的概率;其次就是生態(tài)還行瑞妇,雖然還比不上Node稿静,但基本常用的工具包都有
記得有句話叫:不要去做你喜歡做的,要去喜歡你現(xiàn)在做的辕狰!也確實(shí)應(yīng)該要這樣改备,何必折磨自己,既然別無(wú)選擇蔓倍,那就好好去愛(ài)绍妨!