一、
這篇文章是應(yīng)之前在微博上爆過(guò)的下個(gè)周末某出版社的線(xiàn)下活動(dòng)而寫(xiě)的。回顧我和C++在這個(gè)世紀(jì)的第二個(gè)春天開(kāi)始發(fā)生過(guò)的種種事情,我發(fā)現(xiàn)我并不是用一個(gè)正常的方法來(lái)學(xué)會(huì)如何正常使用C++的。我的C++學(xué)習(xí)伴隨著很多其他流行或者不流行的語(yǔ)言。現(xiàn)在手中掌握的很多淫蕩的技巧正是因?yàn)閷W(xué)習(xí)了很多編程語(yǔ)言的緣故,不過(guò)這并不妨礙我正常地使用C++來(lái)在合理的時(shí)間內(nèi)完成我的目標(biāo)。
學(xué)習(xí)C++是一個(gè)艱難的過(guò)程。如果從我第一次看C++的書(shū)算起,現(xiàn)在已經(jīng)過(guò)了11年了。一開(kāi)始的動(dòng)機(jī)也是很不靠譜的。剛開(kāi)始我很喜歡用VB6來(lái)開(kāi)發(fā)游戲,但是我能找到的資料都是用C++來(lái)做例子的,文字部分又不豐富,于是我遇到了很多困難。因此我去三聯(lián)書(shū)店買(mǎi)了本C++的書(shū),想著我如果學(xué)會(huì)了C++,就可以把這些例子翻譯成VB6的代碼,然后繼續(xù)用VB6來(lái)寫(xiě)游戲。陰差陽(yáng)錯(cuò),我買(mǎi)到的是一本語(yǔ)法手冊(cè)。不過(guò)那個(gè)時(shí)候我還小,不知道什么是MSDN,也不知道MSDN是可以打印出來(lái)賣(mài)的:

不過(guò)因?yàn)镃++在當(dāng)時(shí)并不是我學(xué)習(xí)的重點(diǎn),于是我就沒(méi)事的時(shí)候翻一翻。我們都知道語(yǔ)言參考手冊(cè)(MSDN里面叫Language Reference)的順序都是按照類(lèi)別而不是教學(xué)順序來(lái)排列的。于是當(dāng)我花了很長(zhǎng)時(shí)間看完了第一遍的時(shí)候,就覺(jué)得這本書(shū)寫(xiě)的云里霧里。剛開(kāi)始講什么是表達(dá)式的時(shí)候,例子就出現(xiàn)了大量的函數(shù)和類(lèi)這種更加復(fù)雜的東西。于是我選擇重新看一遍,基本的概念就都知道了。當(dāng)然這個(gè)時(shí)候完全不能算“學(xué)會(huì)C++”,編程這種事情就跟下象棋一樣,規(guī)則都很容易,但是你想要下得好,一定要通過(guò)長(zhǎng)期的練習(xí)才能做到。
當(dāng)然,在這段時(shí)間里面,我依然是一邊看C++一邊用VB6來(lái)學(xué)習(xí)編程。初二的時(shí)候?qū)W校發(fā)了QBasic的課本,當(dāng)時(shí)看了一個(gè)星期就完全學(xué)會(huì)了,我覺(jué)得寫(xiě)代碼很好玩,于是從此就養(yǎng)成了我沒(méi)事逛書(shū)店的習(xí)慣(就連長(zhǎng)大了之后泡MM也有時(shí)候會(huì)去書(shū)店,哈哈哈哈哈)。值得一提的是,我第二次去書(shū)店的時(shí)候,遇到了下面的這本書(shū)《Visual Basic高級(jí)圖形程序設(shè)計(jì)教程》:

在這之前我買(mǎi)到的兩本VB6的書(shū)都是在教你怎么用簡(jiǎn)單的語(yǔ)法,拖拖界面。然后就做出一個(gè)程序來(lái)。那個(gè)時(shí)候我心目中編程的概念就是寫(xiě)寫(xiě)記事本啊、寫(xiě)字板啊、計(jì)算器等等這些東西,直到我發(fā)現(xiàn)了這本書(shū)。我還記得當(dāng)時(shí)的心情。我在書(shū)架上隨手翻了翻,發(fā)現(xiàn)VB竟然也可以寫(xiě)出那么漂亮的圖形程序。
這本書(shū)包含的知識(shí)非常豐富,從如何調(diào)用VB內(nèi)置的繪圖命令、如何調(diào)用Windows API函數(shù)來(lái)快速訪(fǎng)問(wèn)圖片,講到了如何做各種圖像的特效濾鏡、如何做幾何圖形的變換,一直到如何對(duì)各種3D物體做真實(shí)感渲染,甚至是操作4維圖形,都講得清清楚楚。這本書(shū)比其他大多數(shù)編程讀物好的地方在于,讀者可以?xún)H靠里面的文字,基本不用看他的代碼,就可以學(xué)會(huì)作者想讓你學(xué)會(huì)的所有東西。因此當(dāng)我發(fā)現(xiàn)我怎么著也找不到這本書(shū)的光盤(pán)(事實(shí)上書(shū)店就沒(méi)有給我)的時(shí)候,我并沒(méi)有感到我失去了什么。這本書(shū)的文字部分不僅寫(xiě)得很詳細(xì),而且作者還很負(fù)責(zé)任。作者知道像圖形這種對(duì)數(shù)學(xué)基礎(chǔ)有一定要求的東西,程序員不一定懂——尤其是我那個(gè)時(shí)候才上初中,就更不可能懂了——所以在書(shū)里面看到一些復(fù)雜的數(shù)學(xué)公式的時(shí)候,作者都會(huì)很耐心的告訴你這些公式的來(lái)源,它們的“物理意義”,有些時(shí)候甚至還會(huì)推導(dǎo)給你看。因此可以想象,這本書(shū)包含的內(nèi)容也特別的豐富。這導(dǎo)致我在讀的時(shí)候不斷地找資料補(bǔ)充自己的數(shù)學(xué)知識(shí),從而可以親自把那些程序?qū)懀ǘ皇浅┏鰜?lái)。這個(gè)過(guò)程一直持續(xù)到了我終于不用VB轉(zhuǎn)Delphi,到最后上大學(xué)改用C++的那個(gè)時(shí)候,我終于理解了整本書(shū)里面講的所有內(nèi)容,給我后面的很多事情打下了堅(jiān)實(shí)的基礎(chǔ)。
因?yàn)閿?shù)學(xué)知識(shí)缺乏的關(guān)系,學(xué)習(xí)這些基礎(chǔ)知識(shí)又不可能那么快,所以我把一部分時(shí)間投入在了游戲開(kāi)發(fā)里面,嘗試自己弄點(diǎn)什么出來(lái)。畢竟當(dāng)時(shí)對(duì)編程有興趣,就是因?yàn)?#8220;說(shuō)不定游戲也可以用代碼寫(xiě)出來(lái)”的想法,于是我得到了下面的這本書(shū):

這本書(shū)是我覺(jué)得21天驚天陰謀系列里面唯一一本良心的書(shū)。它并沒(méi)有只是簡(jiǎn)單的羅列知識(shí),而是教你利用VB6內(nèi)置的功能搭建從簡(jiǎn)單到復(fù)雜的游戲程序。我第一次看到關(guān)于鏈表的知識(shí)就是在這里。可惜在我還沒(méi)學(xué)會(huì)如何使用VB6的類(lèi)模塊功能之前,我就已經(jīng)投向了Delphi,因此并沒(méi)有機(jī)會(huì)實(shí)踐這個(gè)知識(shí)。不過(guò)在此之后,我用VB6寫(xiě)的小游戲,已經(jīng)嘗試把游戲本身的模塊(這是VB6的一個(gè)功能,就跟namespace差不多)分離,積累一些基礎(chǔ)代碼。
在這段時(shí)間里面,我學(xué)習(xí)語(yǔ)法都學(xué)得很慢。循環(huán)甚至是在我用人肉展開(kāi)循環(huán)的方法一行一行復(fù)制黏貼出了一個(gè)井字棋的AI之后才學(xué)會(huì)的。后來(lái)很晚才學(xué)會(huì)了寫(xiě)函數(shù),全局變量則更晚了。于是在那個(gè)時(shí)候我寫(xiě)了很多看起來(lái)很愚蠢的代碼。曾經(jīng)我以為一個(gè)函數(shù)的全局變量在退出函數(shù)之后是會(huì)保留的,然后對(duì)著自己寫(xiě)出來(lái)的不能運(yùn)行的代碼感到十分的莫名其妙。還有一次做一個(gè)記事本,因?yàn)椴恢?#8220;當(dāng)前文件路徑”要存在什么地方,于是在界面上放了一個(gè)Label來(lái)放文件名。后來(lái)有了雄心壯志,想用VB搞定一個(gè)長(zhǎng)得像Basic的超簡(jiǎn)陋的腳本。這當(dāng)然最后是失敗了,但是我依稀記得,我當(dāng)時(shí)取得的成就就是把腳本語(yǔ)言的字符串分割成了一個(gè)一個(gè)的token之后,保存在了一個(gè)表格控件里面,以便之后(后來(lái)這個(gè)“之后”沒(méi)寫(xiě)出來(lái))讀的時(shí)候方便一點(diǎn)。之后還嘗試寫(xiě)一個(gè)讀四則運(yùn)算字符串計(jì)算結(jié)果的程序,都是先找最里層的括號(hào),把那條不帶括號(hào)的簡(jiǎn)單式子計(jì)算完之后,把結(jié)果也處理成字符串replace回去。直到整個(gè)字符串收斂成一個(gè)值為止。一直等到我后來(lái)買(mǎi)到了一本系統(tǒng)介紹VB6語(yǔ)法和用法的書(shū)之后,我的代碼才稍微變得不像猴子打出來(lái)的。
在剛開(kāi)始學(xué)編程的時(shí)候,基本上都沒(méi)有什么固定的方向,都是在書(shū)店里面碰到什么酒寫(xiě)什么。于是有一次我在書(shū)店里看到了《Visual Basic 網(wǎng)絡(luò)高級(jí)編程》

這本書(shū)是我在學(xué)習(xí)VB的過(guò)程中最后一本我覺(jué)得不錯(cuò)的書(shū)了。雖然VB本身也提供了很多訪(fǎng)問(wèn)網(wǎng)絡(luò)資源的控件,但是這本書(shū)并沒(méi)有讓你僅僅會(huì)用被人的輪子來(lái)寫(xiě)代碼,而是一步一步的告訴你這些網(wǎng)絡(luò)協(xié)議的內(nèi)容,然后讓你用Socket來(lái)跟這些服務(wù)器直接交互。我記得我最后成功的做出了一個(gè)郵件收發(fā)程序,跟聯(lián)想1+1系列自帶程序的功能已經(jīng)可以媲美了。
二、
當(dāng)我發(fā)現(xiàn)C++實(shí)在是太難,根本沒(méi)辦法真的把網(wǎng)上那些C++的程序改成VB之后,我上了高一,接觸了NOI。NOI讓我得到的一個(gè)收獲就是,讓我在上了大學(xué)之后很堅(jiān)定的不把時(shí)間浪費(fèi)在ACM上,從而有了很多時(shí)間可以搞圖形、編譯器和女同學(xué)。參加高中的NOI培訓(xùn)讓我知道了什么是數(shù)據(jù)結(jié)構(gòu),還有什么是指針。老師在講Pascal的時(shí)候說(shuō),要靈活使用指針才可以寫(xiě)出高性能的程序。這讓我大開(kāi)眼界,不僅因?yàn)閂B沒(méi)有指針,而且當(dāng)時(shí)用VB寫(xiě)圖形的程序感覺(jué)怎么樣也快不上去(當(dāng)然這有大半原因是因?yàn)槲掖a寫(xiě)得爛,不能全怪VB)的同時(shí),還讓我認(rèn)識(shí)了Delphi。Delphi跟VB一樣可以拖控件,而且控件長(zhǎng)得還很像。于是我就抱著試一試的心理,開(kāi)始學(xué)習(xí)如何用Delphi來(lái)寫(xiě)代碼。
因?yàn)橛小禫isual Basic 高級(jí)圖形程序設(shè)計(jì)教程》的知識(shí)作為背景,我很快就掌握了如何用Delphi來(lái)開(kāi)發(fā)跟圖形相關(guān)的程序。那個(gè)時(shí)候我覺(jué)得該做的準(zhǔn)備已經(jīng)準(zhǔn)備好了,于是用Delphi寫(xiě)了一遍我在VB的時(shí)候總是寫(xiě)不快的一個(gè)RPG游戲。這個(gè)游戲雖然不大,但是結(jié)構(gòu)很完整。在開(kāi)發(fā)這個(gè)游戲的過(guò)程中,我第一次體驗(yàn)到了模塊化開(kāi)發(fā)的好處,以及積累基礎(chǔ)代碼對(duì)開(kāi)發(fā)的便利性。同時(shí)也讓我嘗到了一個(gè)難以維護(hù)的程序時(shí)多么的可怕。這個(gè)游戲前后開(kāi)發(fā)了八個(gè)月,有一半的事件都是在寫(xiě)代碼。對(duì)于當(dāng)時(shí)的我來(lái)說(shuō),程序的結(jié)構(gòu)已經(jīng)過(guò)于復(fù)雜,代碼也多到差不多失控的地步了。后來(lái)我統(tǒng)計(jì)了一下,一共有一萬(wàn)兩千行代碼。由于那個(gè)時(shí)候我的調(diào)試能力有限,而且也不知道如何把程序?qū)懗梢子谡{(diào)試的形式。結(jié)果我等到了我的核心部分都寫(xiě)完了之后,才能按下F9做第一次的運(yùn)行(!!!)。當(dāng)然運(yùn)行結(jié)果是一塌糊涂。我花了很大的努力才把搞到能跑。
由于程序本身過(guò)長(zhǎng),我在開(kāi)發(fā)的過(guò)程中覺(jué)得已經(jīng)很難控制了。再加上我發(fā)現(xiàn)我的同一個(gè)模塊里的函數(shù)基本上都是下面的形式:
PrefixFunction(var data:DataStructure, other parameters ...)
總覺(jué)得跟調(diào)用Delphi的類(lèi)庫(kù)的時(shí)候很像。所以我就想,既然代碼都變成了這樣,那是不是學(xué)習(xí)面向?qū)ο箝_(kāi)發(fā)會(huì)好一點(diǎn)?在這個(gè)過(guò)程中我有幸遇到了這本《Delphi6 徹底研究》:

雖然說(shuō)這本書(shū)并沒(méi)有包含那些深刻的面向?qū)ο蟮闹R(shí),但是他詳細(xì)的介紹了Delphi的語(yǔ)法、基礎(chǔ)的類(lèi)庫(kù)的用法還有Delphi那套強(qiáng)大的控件庫(kù)和數(shù)據(jù)開(kāi)發(fā)的能力。這本書(shū)第一次讓我知道,Delphi是可以?xún)?nèi)嵌匯編代碼的。這給我對(duì)計(jì)算機(jī)的深入理解打開(kāi)了一扇門(mén)。
學(xué)習(xí)匯編是一個(gè)漫長(zhǎng)的過(guò)程。這倒不是因?yàn)閰R編的概念很復(fù)雜,而是因?yàn)槔锩娴募?xì)節(jié)實(shí)在是太多了。這些知識(shí)靠網(wǎng)絡(luò)上零星的文章實(shí)在是無(wú)法掌握,于是在常年逛書(shū)店的習(xí)慣之下,我又遇到了《Windows 匯編語(yǔ)言程序設(shè)計(jì)教程》。

這本書(shū)內(nèi)容其實(shí)并不是很多,但是他給了我一個(gè)很好的入門(mén)的方法,也講了一些簡(jiǎn)單的匯編的技巧,譬如說(shuō)怎么寫(xiě)循環(huán)啊,怎么用REPZ這樣的前綴等等,讓我可以用匯編寫(xiě)出有意義的程序。匯編和Delphi的結(jié)合也促使我開(kāi)始去思考他們之間的關(guān)系,譬如說(shuō)一段Delphi的代碼就經(jīng)是如何映射到匯編上面的。下面發(fā)生的一個(gè)小故事讓我印象深刻。
那還是一個(gè),我還很喜歡各種不知所謂的奇技淫巧的日子。有一天我在論壇里看到有人說(shuō),交換兩個(gè)integer變量可以用一種奇葩的寫(xiě)法:
a:=a xor b;
b:=b xor a;
a:=a xor b;
于是我就理所當(dāng)然得想,如果我把它改成匯編,那是不是可以更快,并且超過(guò)那種需要中間變量的寫(xiě)法?后來(lái)我試了一次,發(fā)現(xiàn)慢了許多。這個(gè)事件打破了我對(duì)會(huì)變的迷信,當(dāng)然什么C語(yǔ)言是最快的語(yǔ)言之類(lèi)的,我從此也就以辯證的眼光去看帶了。在接下來(lái)的高中生涯里,我只用了匯編一次,那還是在一個(gè)對(duì)圖像做alpha blending的程序里面。我要同時(shí)計(jì)算RGB,但是寄存器每一個(gè)都那么大,我覺(jué)得很浪費(fèi),于是嘗試用R<<16+G放到一個(gè)寄存器里面,跟另一個(gè)R<<16+G相加。中間隔了一個(gè)字節(jié)用來(lái)做進(jìn)位的緩沖,從而達(dá)到了同時(shí)計(jì)算兩個(gè)byte加法的效果。后來(lái)測(cè)試了一下,的確比直接用Delphi的代碼來(lái)寫(xiě)要快一些。
純粹的教程類(lèi)書(shū)籍看多了之后,除了類(lèi)庫(kù)用得熟、代碼寫(xiě)得多以外,好處并不大。所以當(dāng)我有一天在書(shū)店里發(fā)現(xiàn)《凌波微步》的時(shí)候,剛翻開(kāi)好幾頁(yè),我就被它的內(nèi)容吸引住了,斷然入手。

這本書(shū)讓我第一次覺(jué)得,一個(gè)程序?qū)懙煤煤蛯?xiě)得爛竟然有如此之大的差別。作者下筆幽默,行文詼諧,把十幾個(gè)例子用故事一般的形式講出來(lái)。這本書(shū)不告訴你什么是好的,而告訴你什么是不好的。每一個(gè)案例的開(kāi)頭都給出了寫(xiě)得不好的代碼的例子,然后會(huì)跟你解釋的很清楚,說(shuō)這么做有什么不好,改要怎么改的同時(shí),為什么好的方法是長(zhǎng)那個(gè)樣子的。這本書(shū)也開(kāi)始讓我相信方法論的意義。在這個(gè)時(shí)候之前,我在編程這個(gè)東西上的理論基礎(chǔ)基本上就只有鏈表和排序的知識(shí),其它的東西基本都不懂,但是想做出自己想要做的事情卻又不覺(jué)得有什么太大的麻煩。甚至我到高三的時(shí)候?qū)懥艘粋€(gè)帶指令集和虛擬機(jī)的Pascal腳本語(yǔ)言(不含指針)的時(shí)候,我連《編譯原理》這本書(shū)都沒(méi)有聽(tīng)過(guò)。因此以前覺(jué)得,反正要寫(xiě)程序,只要往死里寫(xiě),總是可以寫(xiě)出來(lái)的。但是實(shí)際上,有理論基礎(chǔ)和沒(méi)有理論基礎(chǔ)的程序員之間的區(qū)別,不在于一個(gè)程序能不能寫(xiě)出來(lái),而在于寫(xiě)出來(lái)之后性能是不是好,代碼是不是容易看懂的同時(shí)還很好改,而且還容易測(cè)試。這本書(shū)對(duì)于我的意義就是給我?guī)?lái)了這么一個(gè)觀點(diǎn),從而讓我開(kāi)始想去涉獵類(lèi)似的內(nèi)容。
當(dāng)然,那段時(shí)間只是這么想,但是卻不知道要看什么。所以在一次偶然之下,我發(fā)現(xiàn)了《OpenGL 超級(jí)寶典》。當(dāng)然第一次看的時(shí)候還是第二版,后來(lái)我又買(mǎi)了第三版。

鑒于以前因?yàn)椤禫isual Basic 高級(jí)圖形程序設(shè)計(jì)教程》的緣故,我在看這本書(shū)之前已經(jīng)用Delphi寫(xiě)過(guò)一個(gè)簡(jiǎn)單的支持簡(jiǎn)單光照和貼圖的軟件渲染程序,于是看起來(lái)特別的快。其實(shí)OpenGL相比起DirectX,入門(mén)級(jí)的那部分API(指glBegin(GL_TRIANGLE_STRIP)這些)是做得比DirectX漂亮的,可惜性能太低,沒(méi)人會(huì)真的在大型游戲里使用。剩下的那部分比DirectX就要爛多了。所以當(dāng)我開(kāi)始接觸高級(jí)的API的時(shí)候,OpenGL的低速部分讓我戀戀不舍。OpenGL的程序我一路寫(xiě)到了差不多要高考的時(shí)候。在那之前學(xué)習(xí)了一些簡(jiǎn)單的技巧。上了大學(xué)之后,學(xué)習(xí)了一些骨骼動(dòng)畫(huà)啊、LOD模型啊、場(chǎng)景管理這些在OpenGL和DirectX上都通用的知識(shí),但是卻并沒(méi)有在最后把一個(gè)游戲給做出來(lái)。
我最后一次用OpenGL,是為了做一個(gè)自繪的C++GUI庫(kù)。這個(gè)庫(kù)的結(jié)構(gòu)比起現(xiàn)在的GacUI當(dāng)然是沒(méi)法。當(dāng)時(shí)用OpenGL來(lái)做GUI的時(shí)候,讓我感覺(jué)到要操作和渲染字符串在OpenGL上是困難重重,已經(jīng)難到了幾乎沒(méi)辦法處理一些高級(jí)文字效果(譬如RichText的渲染)的地步了。最后只能每次都用GDI畫(huà)完之后把圖片作為一個(gè)貼圖保存起來(lái)。OpenGL貼圖數(shù)量有限,為了做這個(gè)事情還得搞一個(gè)貼圖管理器,把不同的文字都貼到同一張圖上。做得筋疲力盡之余,效果還不好。當(dāng)我后來(lái)開(kāi)發(fā)GacUI的時(shí)候,我用GDI和DirectX作為兩個(gè)渲染器后端,都成功的把RichText渲染實(shí)現(xiàn)出來(lái)了,我就覺(jué)得我以后應(yīng)該再也不會(huì)使用OpenGL了。GDI和DirectX才是那種完整的繪圖API,OpenGL只能用來(lái)畫(huà)圖,寫(xiě)不了字。
有些人可能會(huì)覺(jué)得,為什么我會(huì)一直在同時(shí)做圖形圖像、編譯器和GUI的事情。大家還記得上文我曾經(jīng)說(shuō)過(guò)我曾經(jīng)用了好久做了一個(gè)伊蘇那種模式的RPG出來(lái)。其實(shí)我一直都很想走游戲開(kāi)發(fā)的路線(xiàn),可惜由于各種現(xiàn)實(shí)原因,最后我沒(méi)有把這件事情當(dāng)成工作。做出那個(gè)RPG的時(shí)候我也很開(kāi)心,絲毫不亞于我畢業(yè)后用C#寫(xiě)出了一個(gè)帶智能提示的代碼編輯器的那一次。當(dāng)然在上大學(xué)之后我已經(jīng)覺(jué)得沒(méi)有一個(gè)美工是做不出什么好游戲的,但是想花時(shí)間跟你一起干的美工同學(xué)又很難找,因此干脆就來(lái)研究游戲里面的各種技術(shù),于是就變成了今天這個(gè)樣子。當(dāng)然,現(xiàn)在開(kāi)發(fā)游戲的心思還在,我想等過(guò)些時(shí)日能夠空閑了下來(lái),我就來(lái)忽悠個(gè)美工妹紙慢慢搞這個(gè)事情。
雖然說(shuō)《Visual Basic高級(jí)圖形程序設(shè)計(jì)教程》是一本好書(shū),但這只是一本好的入門(mén)書(shū),想要深入了解這方面的內(nèi)容還是免不了花時(shí)間看其他材料的。后來(lái)我跟何詠一起做圖形的時(shí)候,知識(shí)大部分來(lái)源于論文。不過(guò)圖像方面,還是下面這本岡薩雷斯寫(xiě)的《數(shù)字圖像處理》給了我相當(dāng)多的知識(shí)。

這本書(shū)的特點(diǎn)是,里面沒(méi)有代碼,我很喜歡,不會(huì)覺(jué)得浪費(fèi)錢(qián)。不過(guò)可惜的是在看完這本書(shū)之后,我已經(jīng)沒(méi)有真的去寫(xiě)什么圖像處理的東西了。后面做軟件渲染的時(shí)候,我也沒(méi)有把它當(dāng)成我的主業(yè)來(lái)做,權(quán)當(dāng)是消磨時(shí)間。每當(dāng)我找不到程序可以寫(xiě)覺(jué)得很傷心的時(shí)候,就來(lái)看看論文,改改我那個(gè)軟件渲染器,增加點(diǎn)功能之后,我就會(huì)發(fā)現(xiàn)一個(gè)新的課題,然后把時(shí)間都花在那上面。
三、
整個(gè)高三的成績(jī)都不錯(cuò),所以把時(shí)間花在編程上的時(shí)候沒(méi)人理我,直到我二模一落千丈,因此在高考前一個(gè)月只好“封筆”,好好學(xué)習(xí)。最后因?yàn)槭д`看錯(cuò)了題目,在高考的時(shí)候丟了十幾分的原始分,估計(jì)換算成標(biāo)準(zhǔn)分應(yīng)該有幾十分之多吧,于是去了華南理工大學(xué)。所幸這本來(lái)就是我的第一志愿,所以當(dāng)時(shí)我也不覺(jué)得有什么不開(kāi)心的。去了華南理工大學(xué)之后,一個(gè)令我感到十分振奮的事情就是,學(xué)校里面有圖書(shū)館,圖書(shū)館的書(shū)還都不錯(cuò)。雖然大部分都很爛,但是因?yàn)榛鶖?shù)大,所以總能夠很輕松的找到一些值得看的東西。
我還記得我們那一年比較特殊,一進(jìn)去就要軍訓(xùn)。軍訓(xùn)的時(shí)候電腦還沒(méi)來(lái)得及帶去學(xué)校,學(xué)校也不給開(kāi)網(wǎng)絡(luò),所以那一個(gè)月的晚上都很無(wú)聊,跟同學(xué)也還不熟悉,不知道要干什么。所以那段時(shí)間每到軍訓(xùn)吃晚飯,我就會(huì)跑到學(xué)校的圖書(shū)館里面泡到閉館為止。于是有一天讓我發(fā)現(xiàn)了李維寫(xiě)的這本《Inside VCL》。

雖然到了這個(gè)時(shí)候我用Delphi已經(jīng)用得很熟悉了,同時(shí)也能寫(xiě)一些比較復(fù)雜的程序了,但是對(duì)于Delphi本身的運(yùn)作過(guò)程我是一點(diǎn)都不知道。所以當(dāng)我發(fā)現(xiàn)這本書(shū)的時(shí)候,如魚(yú)得水。這本書(shū)不僅內(nèi)容深刻,更重要的是寫(xiě)的一點(diǎn)都不晦澀難懂,所以我看的速度非常快。基本上每個(gè)晚上都可以看100頁(yè),連續(xù)七八天下來(lái)這本書(shū)就被我翻完了。這帶來(lái)了一個(gè)副作用就是,圖書(shū)館的姐姐也認(rèn)識(shí)我了——當(dāng)然這并沒(méi)有什么用。
過(guò)后我又在書(shū)店得到了一本《Delphi 源代碼分析》。

這本書(shū)跟《Inside VCL》的區(qū)別是,《Inside VCL》講的是VCL的設(shè)計(jì)是如何精妙,《Delphi 源代碼分析》講的則是Delphi本身的基礎(chǔ)設(shè)施的內(nèi)部實(shí)現(xiàn)的細(xì)節(jié)。以前我從來(lái)不了解也沒(méi)主動(dòng)想過(guò),Delphi的AnsiString和UnicodeString是指向一個(gè)帶長(zhǎng)度記錄的字符串指針,學(xué)習(xí)了指針我也沒(méi)把這兩者聯(lián)系起來(lái)(當(dāng)然這跟我當(dāng)時(shí)還沒(méi)開(kāi)始試圖寫(xiě)C++程序有關(guān))。于是看了這本書(shū),我就有一種醍醐灌頂?shù)母杏X(jué)。雖然這一切看起來(lái)都是那么的自然,讓我覺(jué)得“就是應(yīng)該這么實(shí)現(xiàn)的才對(duì)”,但是在接觸之前,就是沒(méi)有去想過(guò)這個(gè)事情。
令人遺憾的是,在我得到這本書(shū)的同時(shí),Borland也把Delphi獨(dú)立出來(lái)做了一個(gè)叫做Codegear的公司,后來(lái)轉(zhuǎn)手賣(mài)掉了。我在用Delphi的時(shí)候還想著,以后干脆去Borland算了,東西做得那么好,在那里工作肯定很開(kāi)心。我在高中的時(shí)候還曾經(jīng)把Borland那個(gè)漂亮的總部的圖片給我媽看過(guò),不過(guò)她一直以為是微軟的。于是我在傷心了兩個(gè)晚上之后,看了一眼為了做參考我?guī)У綄W(xué)校來(lái)的《Visual C++ 5.0語(yǔ)言參考手冊(cè)》,找了一個(gè)盜版的Visual C++ 2005,開(kāi)始決定把時(shí)間投入在C++上面了。于是Delphi之旅到此結(jié)束,從此之后,就是C++的時(shí)光了。
四、
學(xué)習(xí)圖形學(xué)的內(nèi)容讓我學(xué)會(huì)了如何寫(xiě)一個(gè)高性能的計(jì)算密集型程序,也讓我不會(huì)跟很多程序員一樣排斥數(shù)學(xué)的內(nèi)容。學(xué)習(xí)Delphi讓我開(kāi)闊了眼界的同時(shí),還有機(jī)會(huì)讓我了解Delphi內(nèi)部工作原理和細(xì)節(jié)。這一切都為我之后做那些靠譜的編譯器打下了基礎(chǔ)。
因?yàn)樵诟呷臅r(shí)候我在不懂得《編譯原理》和大部分?jǐn)?shù)據(jù)結(jié)構(gòu)的知識(shí)的情況下,用Delphi寫(xiě)出了一個(gè)Pascal腳本引擎,所以當(dāng)我聽(tīng)說(shuō)我大學(xué)的班主任是教編譯原理的時(shí)候,我就很開(kāi)心,去跟她交流這方面的內(nèi)容,把我當(dāng)時(shí)的設(shè)想也拿給她看。當(dāng)然我的設(shè)想,沒(méi)有理論基礎(chǔ)的知識(shí),都是很糟糕的,于是班主任就給了我一本《編譯原理》。當(dāng)然,這并不是《龍書(shū)》,而是一本質(zhì)量普通的書(shū)。不過(guò)當(dāng)我了解了這方面的內(nèi)容之后,《龍書(shū)》的大名也就進(jìn)入我的耳朵里了:

由于之前用很愚蠢的方法寫(xiě)了個(gè)Pascal腳本的緣故,看《龍書(shū)》之后很容易就理解了里面各種精妙的算法在工程上的好處。我之前的作法是先用掃描的方法切下一個(gè)一個(gè)的token,然后做一個(gè)遞歸來(lái)遞歸去復(fù)雜到自己都沒(méi)法看的一遍掃描生成簡(jiǎn)單指令的方法來(lái)做。程序?qū)懗鰜?lái)之后我當(dāng)場(chǎng)就已經(jīng)看不懂了。自從看了《龍書(shū)》之后,我才知道這些過(guò)程可以用token和語(yǔ)法樹(shù)來(lái)對(duì)算法之間進(jìn)行解耦。不過(guò)《龍書(shū)》的性質(zhì)也是跟《Visual Basic 高級(jí)圖形程序設(shè)計(jì)教程》一樣,是入門(mén)類(lèi)的書(shū)籍。用來(lái)理解一下編譯器的運(yùn)作過(guò)程是沒(méi)問(wèn)題的,但是一旦需要用到高級(jí)的知識(shí)。
這個(gè)時(shí)候我已經(jīng)初步理解了編譯器前端的一些知識(shí),但是后端——譬如代碼生成和垃圾收集——卻還是一知半解。不過(guò)這并不妨礙我用好的前端知識(shí)和爛的后端知識(shí)來(lái)做出一個(gè)東西來(lái)。當(dāng)時(shí)我簡(jiǎn)單看了一下Java語(yǔ)言的語(yǔ)法,把我不喜歡的那些東西砍掉,然后給他加上了泛型。Java那個(gè)時(shí)候的泛型實(shí)現(xiàn)好像也是剛剛出現(xiàn)的,但是我不知道,我也從來(lái)沒(méi)想過(guò)泛型要怎么實(shí)現(xiàn)。所以當(dāng)時(shí)我想來(lái)想去做了一個(gè)決定,泛型只讓編譯器去檢查就好了,編譯的時(shí)候那些T都當(dāng)成object來(lái)處理,然后就把東西做出來(lái)了。我本來(lái)以為我這種偷工減料拆東墻補(bǔ)西墻忽悠傻逼用戶(hù)的方法是業(yè)界所不容的,不過(guò)后來(lái)發(fā)現(xiàn)Java竟然也是那么做的,讓我覺(jué)得我一定要黑他一輩子。后來(lái)我用我做的這個(gè)破語(yǔ)言寫(xiě)了一個(gè)俄羅斯方塊的游戲,拿給了我的班主任看,向她證明她拿給我的書(shū)我沒(méi)有白看。
不過(guò)由于受到了Delphi的影響,我并沒(méi)有在我的C++代碼里面使用泛型。當(dāng)時(shí)由于不了解STL,也懶得去看,于是自己就嘗試折騰這么幾個(gè)容器類(lèi)自己用。現(xiàn)在代碼還留著,可以給大家貼一段:

這段代碼已經(jīng)可以作為反面教材使用了。除了基類(lèi)有一個(gè)virtual的析構(gòu)函數(shù)和代碼對(duì)齊的比較漂亮以外,基本所有的地方都是設(shè)計(jì)錯(cuò)誤的典型表現(xiàn)。為了這段代碼的貼圖我特地在硬盤(pán)里面翻出來(lái)了我那個(gè)山寨Java腳本的代碼,一打開(kāi)就有一股傻逼的氣息撲面而來(lái),截圖放進(jìn)word之后,屏幕猶如溢屎,內(nèi)容不堪入目。
之所以把代碼寫(xiě)成這樣,跟Delphi的class不是值類(lèi)型的這個(gè)功能是分不開(kāi)的。寫(xiě)了幾年的Delphi之后,再加上第一次開(kāi)始寫(xiě)有點(diǎn)小規(guī)模的C++程序,我從來(lái)沒(méi)考慮過(guò)一個(gè)用來(lái)new的class是可以創(chuàng)建成值類(lèi)型的。所以那個(gè)時(shí)候我一直處于用C++的語(yǔ)法來(lái)寫(xiě)Delphi的狀態(tài)上。當(dāng)然這樣是不對(duì)的,但是因?yàn)槟且欢螘r(shí)間運(yùn)氣比較背,好的C++書(shū)都沒(méi)給我碰上,直到我看到了《C++語(yǔ)言的設(shè)計(jì)和演化》

C++他爹寫(xiě)的這本《C++語(yǔ)言的設(shè)計(jì)和演化》是一本好書(shū),我認(rèn)為每一個(gè)學(xué)習(xí)C++的人都應(yīng)該看。本來(lái)《C++Primer》也是一本不錯(cuò)的書(shū),不過(guò)因?yàn)槲谊幉铌?yáng)錯(cuò)用了《Visual C++ 5.0 語(yǔ)言參考手冊(cè)》入門(mén),所以這本書(shū)就被我跳過(guò)了。一開(kāi)始C++用得很爛,覺(jué)得渾身不舒服,但是有知道為什么。看了這本書(shū)之后很多疑問(wèn)就解決了。
《C++語(yǔ)言的設(shè)計(jì)和演化》講的是當(dāng)年C++他爹發(fā)明C++的時(shí)候如何對(duì)語(yǔ)言的各種功能做取舍的故事。在這個(gè)長(zhǎng)篇小說(shuō)里面,C++他爹不厭其煩地說(shuō),雖然C++看起來(lái)很鳥(niǎo),但是如果不這樣做,那就會(huì)更鳥(niǎo)。看完了這本書(shū)之后,基本上就剩下不會(huì)模板元編程了,剩下的語(yǔ)言的功能都知道在什么時(shí)候應(yīng)該用,什么時(shí)候不該用。C++他爹還描述了一些重要的類(lèi)——譬如說(shuō)智能指針和STL的迭代器——在語(yǔ)義上的意思。其實(shí)這就跟我們?cè)诳创鼵++11的shared_ptr、unique_ptr和weak_ptr的時(shí)候,不要去想這是一個(gè)delete對(duì)象的策略,而是要想這是一個(gè)描述對(duì)象所有權(quán)關(guān)系的這么個(gè)“關(guān)鍵字”一樣。有些時(shí)候細(xì)節(jié)看得太明白,而忽略了更高層次上的抽象,此乃見(jiàn)樹(shù)木不見(jiàn)森林。
C++知道每一個(gè)特性如何正常使用還不夠,如果不知道他們是如何實(shí)現(xiàn)的,那有可能在非常極端的情況下,寫(xiě)出來(lái)的程序會(huì)發(fā)揮的不好。正如同如果你知道C++編譯器、操作系統(tǒng)和CPU內(nèi)部是如何處理這些東西的細(xì)節(jié),如果你順著他們?nèi)?xiě)你的程序的話(huà),那性能的提高會(huì)特別明顯。譬如說(shuō)在做渲染器的時(shí)候,為什么光線(xiàn)追蹤要按照希爾伯特順序來(lái)發(fā)射光線(xiàn),為什么KD樹(shù)可以把每一個(gè)節(jié)點(diǎn)壓縮成8個(gè)字節(jié)的同時(shí)還會(huì)建議你按層來(lái)排列他們,都是因?yàn)檫@些背后的細(xì)節(jié)所致。這些細(xì)節(jié)做得好,渲染器的效率提高一倍是完全沒(méi)問(wèn)題的。這些知識(shí)固然很多,但是C++的那部分,卻包含在了一本《深度探索C++對(duì)象模型》里面:

讀《深度探索C++對(duì)象模型》,不僅僅是為了知道C++在涉及虛擬多重繼承基類(lèi)的成員函數(shù)指針結(jié)構(gòu)是怎樣的,而且你還可以從中學(xué)到很多技巧——當(dāng)然是指數(shù)據(jù)結(jié)構(gòu)的技巧。這本書(shū)的內(nèi)容大概分為兩個(gè)部分。第一個(gè)部分就跟需求一樣,會(huì)跟你介紹C++的對(duì)象模型的語(yǔ)義,主要就是告訴你,如果你這樣寫(xiě),那你就可以獲得XXX,失去YYY。第二部分就跟實(shí)現(xiàn)一樣。按照需求來(lái)得到一個(gè)好的實(shí)現(xiàn)總是一個(gè)程序員想做的事情,那么這就是個(gè)很好的例子。正常使用C++需要的無(wú)限智慧,大部分就包含在上面這兩本書(shū)里面。一旦把這兩本書(shū)的內(nèi)容都理解好,以后寫(xiě)起C++的代碼都會(huì)得心應(yīng)手,不會(huì)被各種坑所困擾,正確審視自己的代碼。
文章之前的部分有提到過(guò),讓我正視理論和方法論的意義的是《凌波微步》,所以當(dāng)工具都掌握的差不多的時(shí)候,總需要花時(shí)間補(bǔ)一補(bǔ)這方面的內(nèi)容。首當(dāng)其沖當(dāng)然就是大家喜聞樂(lè)見(jiàn)的《算法導(dǎo)論》了。我記得當(dāng)時(shí)是唐良同學(xué)推薦給我的這本書(shū),還重點(diǎn)強(qiáng)調(diào)了一定要看原文,因?yàn)橹形牡姆g不行。所以我就在一個(gè)春光明媚的早上,來(lái)到了廣州天河書(shū)城,把這本書(shū)搞到手。

這本書(shū)的封面顏色暗示著你,想讀這本書(shū), 應(yīng)該去一個(gè)山清水秀綠蔭環(huán)繞的地方。事實(shí)證明這是對(duì)的。在差不多考英語(yǔ)四級(jí)的前后,我有一段時(shí)間每天都去華南理工大學(xué)那個(gè)著名的分手亭看這本書(shū)。亭子后面是一個(gè)湖,前面有很多樹(shù)和雜草,旁邊還有一個(gè)藝術(shù)學(xué)院,充滿(mǎn)了人文的氣息。在這種地方看《算法導(dǎo)論》,不僅吸收得快,而且過(guò)了一年,我真的分手了。
說(shuō)實(shí)話(huà)這本書(shū)我沒(méi)有看完,而且那些證明的部分我都跳過(guò)了,實(shí)在是對(duì)這些東西沒(méi)有興趣。不過(guò)關(guān)于數(shù)據(jù)結(jié)構(gòu)和大部分算法我看得很仔細(xì)。于是我在這方面的能力就大幅度提高——當(dāng)然跟那些搞ACM的人相比反應(yīng)還是不夠快,不過(guò)我的志向并不在這里。除此之外,我通過(guò)《算法導(dǎo)論》也學(xué)到了如何準(zhǔn)確的計(jì)算一個(gè)函數(shù)的時(shí)間復(fù)雜度和空間復(fù)雜度。事實(shí)證明這個(gè)技能十分重要,不僅可以用來(lái)找bug,還可以用來(lái)面試。
五、
對(duì)于一個(gè)讀計(jì)算機(jī)的大學(xué)生來(lái)說(shuō),算法懂了,工具會(huì)了,接下來(lái)就是開(kāi)眼界了。不過(guò)這些東西我覺(jué)得是沒(méi)法強(qiáng)求的,就像下面這本《程序設(shè)計(jì)語(yǔ)言——實(shí)踐之路》一樣,都是靠運(yùn)氣才到手的——這是一個(gè)小師妹送我的生日禮物:

原本學(xué)習(xí)的匯編也好,VB、Delphi和C++也好,都是同一類(lèi)的編程語(yǔ)言。這導(dǎo)致我在相當(dāng)長(zhǎng)的時(shí)間里面都無(wú)疑為編程就差不多是這個(gè)樣子。直到我看到了《程序設(shè)計(jì)語(yǔ)言——實(shí)踐之路》。這本書(shū)告訴我,這個(gè)世界上除了命令是語(yǔ)言,還有各種不同的編程的范式和方法。于是借著這本書(shū)的機(jī)會(huì),我了解到世界上還有Prolog、Erlang和Haskell這么美妙的語(yǔ)言。
這對(duì)我的觸動(dòng)很大。一直以來(lái)我都是用一種編程方法來(lái)解決所有我遇到的問(wèn)題的。然后突然有一天,我發(fā)現(xiàn)有很多問(wèn)題用別的方法來(lái)解決更好,于是我就開(kāi)始去研究這方面的內(nèi)容。一開(kāi)始我的認(rèn)識(shí)還是比較淺,應(yīng)用這些方法的時(shí)候還處于只能了解表面的狀態(tài),譬如說(shuō)曾經(jīng)流行過(guò)幾天的Fluent Interface,還有聲明式編程啊,AOP等等。直到我遇到了這本全面改變我對(duì)C++模板看法的書(shū)——《Real World Haskell》:

是的,你沒(méi)看錯(cuò),是《Real World Haskell》!Haskell顛覆了我的世界觀,讓我第一次知道,原來(lái)代碼也是可以推導(dǎo)的。說(shuō)實(shí)話(huà)我用Haskell用的并不熟,而且我也沒(méi)寫(xiě)過(guò)多少個(gè)Haskell的大程序,但是Haskell的很多方面我都去花了很長(zhǎng)時(shí)間去了解,譬如那個(gè)著名的Monad。多虧了當(dāng)時(shí)搞明白了Monad,我借助這方面的知識(shí),理解了《Monadic Parser Combinator》這篇論文,還看懂a(chǎn)joo那篇著名的面向組合子編程系列。
當(dāng)我終于明白了Haskell的類(lèi)型推導(dǎo)之后,我終于體會(huì)到了Haskell和C++之間的巨大差異——Haskell的程序的邏輯,都是完全表達(dá)在函數(shù)簽名上的類(lèi)型里面,而不是代碼里的。當(dāng)你寫(xiě)一個(gè)Haskell函數(shù)的時(shí)候,你首先要知道你的函數(shù)是什么類(lèi)型的,接下來(lái)你就把代碼當(dāng)成是方程的解一樣,找到一個(gè)滿(mǎn)足類(lèi)型要求的實(shí)現(xiàn)。Haskell的表達(dá)式一環(huán)扣一環(huán),幾乎每?jī)蓚€(gè)部分的類(lèi)型都互相制約,要求特別嚴(yán)格。導(dǎo)致Haskell的程序只要編譯通過(guò),基本上不用運(yùn)行都有95%的概率是靠譜的,這一點(diǎn)其他語(yǔ)言遠(yuǎn)遠(yuǎn)達(dá)不到。而且Haskell的類(lèi)庫(kù)(Hackage)之多覆蓋GUI、GPU程序、分布式、并發(fā)支持、圖像處理,甚至是網(wǎng)頁(yè)(Haskell Server Page)都有,用來(lái)寫(xiě)實(shí)用的程序完全沒(méi)問(wèn)題。之所以Haskell不流行,我覺(jué)得僅有的原因就是對(duì)初學(xué)者來(lái)說(shuō)太難了,但是人們一旦熟悉了C的那一套,看Haskell的難度就更大了,比什么都不會(huì)的時(shí)候更大。
于是回過(guò)頭來(lái),模板元編程也就變成一個(gè)很自然的東西了。你把模板元編程看成是一門(mén)語(yǔ)言,把“類(lèi)型”本身看成是一個(gè)巨大的帶參數(shù)enum的一部分(scala叫case type),于是類(lèi)型的名字就變成了值,那么模板元編程的技巧,其實(shí)就是對(duì)類(lèi)型進(jìn)行變換、操作和計(jì)算的過(guò)程。接下來(lái)只要會(huì)用模板的形式來(lái)表達(dá)if、while、函數(shù)調(diào)用和類(lèi)型匹配,那掌握模板元編程是順利成章的事情。撇去type traits這些只是模板元編程的具體應(yīng)用不說(shuō),只要熟悉了Haskell,熟悉C++的模板語(yǔ)法,學(xué)會(huì)模板元編程,只需要一個(gè)下午——就是學(xué)會(huì)用蹩腳的方法來(lái)寫(xiě)那些你早就熟悉了的控制流語(yǔ)句罷了。
當(dāng)模板元編程變成了跟寫(xiě)i++一樣自然的東西之后,我看語(yǔ)言的感覺(jué)也變了。現(xiàn)在看到一個(gè)程序語(yǔ)言,再也不是學(xué)習(xí)與發(fā)這么簡(jiǎn)單了,而是可以看到作者設(shè)計(jì)這門(mén)語(yǔ)言的時(shí)候想灌輸給你的價(jià)值觀。譬如說(shuō),為什么C語(yǔ)言的typedef長(zhǎng)那個(gè)樣子的?因?yàn)樗敫嬖V你,你int a;定義的是一個(gè)變量,那么typedef int a;就把這個(gè)變量的名字改成了類(lèi)型的名字。為什么C語(yǔ)言定義函數(shù)的時(shí)候,參數(shù)是用逗號(hào)隔開(kāi)?因?yàn)槟阏{(diào)用函數(shù)的時(shí)候,也是用逗號(hào)來(lái)隔開(kāi)參數(shù)的。這就是語(yǔ)法里面的一致性問(wèn)題。一個(gè)一致性好的語(yǔ)言,一個(gè)有編程經(jīng)驗(yàn)初學(xué)者只要學(xué)習(xí)到了其中的一部分,就可以推測(cè)他所想要的未知特性究竟是如何用于發(fā)表達(dá)出來(lái)的。一個(gè)一致性差的語(yǔ)言,你每一次學(xué)到一個(gè)新的功能或者語(yǔ)法,都是一個(gè)全新的形式,到處雜亂無(wú)章,讓人無(wú)可適從(所以我很討厭go,還不把go的library移植成C++直接用C++寫(xiě)算了)。
從此之后,我就從一個(gè)解決問(wèn)題的程序員,變成一個(gè)研究編程本身的程序員了。當(dāng)然我并不去搞什么學(xué)術(shù)研究,我也不打算走在理論的前沿——這并不適合我,我還是覺(jué)得做一個(gè)程序員是更快樂(lè)一點(diǎn)的。這些知識(shí)在我后續(xù)學(xué)習(xí)開(kāi)發(fā)編譯器和設(shè)計(jì)語(yǔ)言的時(shí)候,起了決定性的作用。而且當(dāng)你知道如何設(shè)計(jì)一個(gè)優(yōu)美的語(yǔ)法,那么你用現(xiàn)有的語(yǔ)法來(lái)設(shè)計(jì)一個(gè)優(yōu)美的library,也就不會(huì)那么難了。當(dāng)然,設(shè)計(jì)優(yōu)美的library是需要深入的了解正在使用的語(yǔ)言本身的,這樣的話(huà)有可能維護(hù)這個(gè)library的門(mén)檻就會(huì)提高。不過(guò)這沒(méi)有關(guān)系,這個(gè)世界上本來(lái)就有很多東西是2000塊錢(qián)的程序員所無(wú)法完成的,譬如維護(hù)STL,維護(hù)linux內(nèi)核,甚至是維護(hù)Microsoft Office。
六、
上面所列出來(lái)的書(shū),每一本都是對(duì)我有深刻的影響的。當(dāng)然光有深刻的影響是不夠的,具體的領(lǐng)域的知識(shí),還是需要更多的資料來(lái)深入研究,譬如說(shuō)下面的一個(gè)單子,就是我在學(xué)習(xí)開(kāi)發(fā)編譯器和虛擬機(jī)的時(shí)候所看過(guò)的。內(nèi)容都很深刻,很適合消磨時(shí)間。在這里我要感謝g9yuayon同學(xué),他在我需要開(kāi)闊眼界的時(shí)候,給我提供了大量的資料,讓我得以快速成長(zhǎng),功不可沒(méi)。

虛擬機(jī)——系統(tǒng)與進(jìn)程的通用平臺(tái)

Garbage Collection——Algorithms for Automatic Dynamic Memory Management

高級(jí)編譯器設(shè)計(jì)與實(shí)現(xiàn)(鯨書(shū))

程序設(shè)計(jì)語(yǔ)言理論基礎(chǔ)

類(lèi)型與程序設(shè)計(jì)語(yǔ)言

Parsing Techniques——A Practical Guide

The Implementation of Functional Programming Languages
posted on 2013-03-23 22:35
陳梓瀚(vczh) 閱讀(164373)
評(píng)論(35) 編輯 收藏 引用 所屬分類(lèi):
啟示