中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

談?wù)劸幾g和運(yùn)行

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用


[作者按] 今天 hacker news 爆炸性的新聞是我們敬愛(ài)的葛老頭:Andy Grove 去了。70后,80后大多聽(tīng)過(guò)這個(gè)響當(dāng)當(dāng)?shù)拿,也?tīng)過(guò)(或者讀過(guò))『只有偏執(zhí)狂才能生存』這本書(shū)。在90年代,葛魯夫和蓋茨一樣,基本上等同于他們所締造的王國(guó),以及他們創(chuàng)立的 Wintel 聯(lián)盟。如今90后創(chuàng)業(yè)者們所津津樂(lè)道的所謂創(chuàng)業(yè)大師們總結(jié)的:專(zhuān)注,獨(dú)特,10倍速因子等等其實(shí)是拾了老爺子牙慧的。老爺子還有一本據(jù)說(shuō)更好的書(shū):High output management ,Ben(a16z 的合伙人)對(duì)其大為推崇。后知后覺(jué)的我沒(méi)有讀過(guò),趕緊去圖書(shū)館 hold 了一本。去年,老爺子參加了 Ben 主持的一個(gè)頒獎(jiǎng)會(huì),看他幾乎站都站不穩(wěn),話都快說(shuō)不清楚的老態(tài)讓我心酸,接著,聽(tīng)到他顫巍巍說(shuō)出這句話,我?guī)缀醵家獪I奔了:


Let's remember that millions of young people who have had the misfortune of being born in the wrong national boundaries are going through all the horrors that Ben described. I made it. Let's try in a little way to help them make it.


老爺子此時(shí)已經(jīng)病入膏肓,無(wú)藥可醫(yī),但依然心系那些和他有著類(lèi)似磨難的年輕人。這便是范文正所謂的「不以物喜,不以己悲,居廟堂之高則憂其民;處江湖之遠(yuǎn)則憂其君」的寫(xiě)照。


葛老師一路走好。


。。。


言歸正傳。本來(lái)今天要講講 API 系統(tǒng)的配置和 CLI 等子系統(tǒng),但是很多同學(xué)對(duì)我上一篇文章 再談 API 的撰寫(xiě) - 架構(gòu) 中所述的「編譯時(shí)」和「運(yùn)行時(shí)」有不少困惑。這篇文章先講講這兩個(gè)概念。


在 上一篇 文章里,我講到:


通過(guò)這樣一個(gè)接口,我們把 API 系統(tǒng)區(qū)隔為「編譯時(shí)」和「運(yùn)行時(shí)」。這個(gè)接口寫(xiě)出來(lái)的 API,更像是一個(gè)等待編譯的源文件。在 API 系統(tǒng)啟動(dòng)的時(shí)候,會(huì)經(jīng)歷一個(gè)「編譯」的過(guò)程,把所有的 route 匯總起來(lái),生成 restify 認(rèn)識(shí)的路由形式,同時(shí),收集里面的各種信息(比如 validator,authentication),供框架的各個(gè) middleware 使用。


「編譯」(compile)是軟件系統(tǒng)的一個(gè)非常非常重要的概念;很可惜,在 python / ruby / javascript 等解釋型語(yǔ)言大行其道的當(dāng)下,很多人已經(jīng)不知道編譯為何物。當(dāng)然,即便你使用 c / go / java 等編譯型語(yǔ)言,有多少人又真正清楚「編譯」究竟是個(gè)什么過(guò)程呢?


在 wikipedia,compile / compiler 的解釋如下:


A compiler is a computer program (or a set of programs) that transforms source code written in a programming language (the source language) into another computer language (the target language), with the latter often having a binary form known as object code.[1] The most common reason for converting source code is to create an executable program.


所以 compile 實(shí)際上是一種 transformation(我們又見(jiàn)到這個(gè)詞了):它把某個(gè)數(shù)據(jù)(如果你認(rèn)為源代碼也是一種數(shù)據(jù)的話)從一種格式轉(zhuǎn)換成另外一種格式。在編譯型語(yǔ)言里,這種轉(zhuǎn)換是為了生成機(jī)器碼(如 c / go),或者 byte code(java / c#),方便機(jī)器執(zhí)行(byte code 會(huì)進(jìn)一步以 JIT 的方式 compile 成機(jī)器碼)。


(題外話:其實(shí)解釋型語(yǔ)言也是有一個(gè) JIT 「編譯」的過(guò)程;現(xiàn)在純粹的,完全在運(yùn)行時(shí)一句句解釋執(zhí)行的語(yǔ)言,只能生存在象牙塔里)


有了這樣一層(indirection)編譯的過(guò)程,源數(shù)據(jù)和目標(biāo)數(shù)據(jù)就被分離開(kāi),可以做很多事情,比如 wikipeidia 上說(shuō)的 compiler 的一大功效:


Compilers enabled the development of programs that are machine-independent.


這里面,這個(gè) machine-independent 可以根據(jù)你的需要被換成 framework-independent,甚至 language-independent。


那么,一份源代碼除了可以生成目標(biāo)代碼(主產(chǎn)品)外,還能有什么副產(chǎn)品?我們以 java 為例:


  • 如果你的注釋遵循 javadoc,那么從代碼里可以生產(chǎn)出來(lái)漂亮的文檔(SDK)。

  • facebook/infer 可以對(duì)你的代碼做詳細(xì)的 static analysis。

  • jacoco 可以根據(jù)源碼和 test case 生成 coverage report。

  • ...


這些副產(chǎn)品帶啦的好處是顯而易見(jiàn)的:我們不用為了一些特定的目的而做一些額外的事情。


回到我們這幾天說(shuō)的 API 系統(tǒng)。我提到了這樣的一個(gè)接口:



你可以將其看做是一段聲明 API 的代碼,但我更愿意將其看做是一段描述 API 的數(shù)據(jù)。這個(gè)數(shù)據(jù)有:


  • method:API 使用何種 http 方法調(diào)用。

  • path:API 使用什么樣的 endpoint。

  • description:API 的文檔。

  • validators:如果要驗(yàn)證 API 的輸入數(shù)據(jù),如何驗(yàn)證。

  • action:API 具體做些什么事情。

  • flags:API 有哪些屬性(需不需要驗(yàn)證,支不支持某些特定的操作等)。


如果你以數(shù)據(jù)的眼光看待這段代碼,那么,每一個(gè) route() 的聲明都可以被聚合起來(lái),放到一個(gè)數(shù)組里。事實(shí)上,route 的實(shí)現(xiàn)就是如此:



每當(dāng)用戶撰寫(xiě)一個(gè) route 的時(shí)候,我們實(shí)際上在往一個(gè) list 里 push 這個(gè) route 的數(shù)據(jù)。這個(gè) list 究竟怎么用,是生成 restify 的 route,還是生成 hapi 的 route,我們?cè)诰幾g時(shí)再具體決定。這便是 framework-independent。


那么,什么是編譯時(shí),什么又是運(yùn)行時(shí)呢?



就這么簡(jiǎn)單。app.compile() 把放在 route list 里面的數(shù)據(jù)轉(zhuǎn)換成 restify 的 route,而 app.run() 開(kāi)始進(jìn)行網(wǎng)絡(luò)監(jiān)聽(tīng)。很多同學(xué)看到這里會(huì)想,有沒(méi)有搞錯(cuò),我還以為是什么高深的東西呢,這代碼我也會(huì)寫(xiě)啊。的確,這里沒(méi)有任何高深的東西。然而,關(guān)鍵的是你會(huì)不會(huì)想到把一段代碼的運(yùn)行分解成:compile() 和run() 兩個(gè)階段。只有你這么去想了,你才會(huì)反過(guò)來(lái)考慮你的 API 的代碼能不能退一步,用一個(gè)數(shù)據(jù)結(jié)構(gòu)封裝,你才會(huì)想這個(gè)數(shù)據(jù)結(jié)構(gòu)該如何設(shè)置,你才會(huì)把 route() 的實(shí)現(xiàn)寫(xiě)成類(lèi)似的方式。


在「編譯時(shí)」你可以做很多繁雜的事情,就像高手過(guò)招前先養(yǎng)氣御劍一樣;這樣,在「運(yùn)行時(shí)」,你才能打出行云流水的招式。


再舉一個(gè)例子。就寫(xiě) blog 而言,你可以用 wordpress,也可用 jekyll 這樣的 static site generator。前者把編譯和運(yùn)行混在一起,在請(qǐng)求頁(yè)面的時(shí)候生成博文;而后者則將二者完全分離,你得使用 jekyll 的工具把 markdown 撰寫(xiě)的博文編譯成 html,才能被正常訪問(wèn)。這樣分離之后,天地開(kāi)闊了很多,你可以在「編譯時(shí)」為所有文章生成全文搜索所用的索引,可以根據(jù)文章的類(lèi)別 / tag 生成目錄,相關(guān)文章,菜單等等,在為運(yùn)行時(shí)提供了閃電般的速度外,還能提供 wordpress 才能提供的動(dòng)態(tài)性和靈活性。


注意,這里所說(shuō)的分離完全是邏輯上的分離,就像上一篇文章中的 pipeline,每個(gè) component 是邏輯上單獨(dú)存在,未必需要物理上完全分離。


把「編譯時(shí)」和「運(yùn)行時(shí)」分離,是一項(xiàng)很重要的抽象能力。






標(biāo)簽: 代碼 搜索 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:Jetty 8長(zhǎng)連接上的又一個(gè)坑

下一篇:Scala學(xué)習(xí)資源整理