Code review是個(gè)數(shù)學(xué)問題:從二向箔說起
寫代碼有兩件最重要的事情信轿,一是仰望星空晃痴,二是腳踏實(shí)地。在搞code review之前财忽,我們先看一張星空的圖倘核,梵高的星空:
看到了這張星空,不知道讀過《三體》的同學(xué)是不是聯(lián)想到了二向箔即彪。
即使是沒有看過《三體》的同學(xué)紧唱,對(duì)于降維攻擊這個(gè)詞應(yīng)該也不陌生活尊。二向箔是將三維空間變成二維空間的武器。
我們引用一段原文:
“兩個(gè)二維體的結(jié)構(gòu)在星光下清晰地顯現(xiàn)出來(lái):在二維化的太空艇漏益,可以看到二維展開后的三維構(gòu)造蛹锰,可以分辨出座艙和聚變發(fā)動(dòng)機(jī)等部分,還有座艙中那個(gè)卷曲的人體绰疤。在另一個(gè)二維化的人體上铜犬,可以清楚地分辨出骨骼和脈絡(luò),也可以認(rèn)出身體的各個(gè)部位轻庆。在二維化的過程中癣猾,三維物體上的每個(gè)點(diǎn)都按照精確的幾何規(guī)則投射到二維平面上,以至于這個(gè)二維體成為原三維太空艇和三維人體的兩張最完整最精確的圖紙余爆,其所有的內(nèi)部結(jié)構(gòu)都在平面上排列出來(lái)纷宇,沒有任何隱藏,但其映射規(guī)程與工程制圖完全不同蛾方,從視覺上很難憑想象復(fù)原原來(lái)的三維形狀像捶。”
關(guān)鍵的一句來(lái)了:
“與工程圖紙最大的不同是桩砰,二維展開是在各個(gè)尺度層面上進(jìn)行的作岖,曾經(jīng)隱藏在三維構(gòu)型中的所有結(jié)構(gòu)和細(xì)節(jié)都在二維平面排列出來(lái),于是也呈現(xiàn)了從四維空間看三維世界時(shí)的無(wú)限細(xì)節(jié)五芝《焕埽”
這簡(jiǎn)直就是在講code review的方法論嘛。code review的最終愿景枢步,就應(yīng)該是將所有可能出錯(cuò)的代碼都找出來(lái)沉删,或者說能證明代碼是正確的。
這可能跟很多搞code review的同學(xué)的思路是不同的醉途,有的同學(xué)認(rèn)為矾瑰,最強(qiáng)大的code review系統(tǒng),應(yīng)該是能夠精確發(fā)現(xiàn)未來(lái)能夠被發(fā)現(xiàn)有bug的代碼隘擎,沒有發(fā)現(xiàn)的不算殴穴。這樣最節(jié)省力量,也符合很多同學(xué)對(duì)牛人的美好愿望货葬。
這本質(zhì)上是一種歸納法采幌,通過為每個(gè)已經(jīng)發(fā)現(xiàn)的問題寫規(guī)則來(lái)預(yù)防未來(lái)出現(xiàn)的問題。這當(dāng)然要搞震桶。但是休傍,當(dāng)想對(duì)規(guī)則做一些拓展和泛化的時(shí)候就會(huì)發(fā)現(xiàn),實(shí)現(xiàn)這些規(guī)則的難度一點(diǎn)也不低蹲姐,甚至發(fā)現(xiàn)用現(xiàn)有的算力也仍然做不到磨取。
如果一個(gè)問題是有限的人柿,那么通過分治法可以將問題拆解到原子狀態(tài)。但是如果一個(gè)問題是分形的忙厌,那么無(wú)論如何拆分得到的都是同樣的問題凫岖。
那么面對(duì)這樣復(fù)雜的一個(gè)問題,我們?cè)撊绾无k逢净?我的答案是從數(shù)學(xué)中想辦法哥放。
我們不講原理,講兩個(gè)故事吧汹胃。
十維空間的故事
無(wú)限的世界跟我們的直覺經(jīng)常是不一致的婶芭,有很多我們直覺上的無(wú)限其實(shí)實(shí)際上是有限的东臀。
比如在地球上的一條線着饥,直覺上是可以無(wú)限延長(zhǎng),一直到想象中的無(wú)限的中惰赋,但是實(shí)際上最長(zhǎng)不過也就是地球球面上的大圓宰掉。
再比如昨天在路上聽到一個(gè)小學(xué)生給同學(xué)講,他要給某物體放到零下幾十萬(wàn)度的環(huán)境里去赁濒。
我們?cè)趯懘a里經(jīng)常是可以創(chuàng)造多維世界的轨奄。比如版本號(hào),大版本號(hào)1.0拒炎,2.0挪拟,3.0可以形成一條主線。1.0可以獨(dú)立發(fā)展為1.1击你,1.2玉组,1.3等,每個(gè)小版本又可以獨(dú)立發(fā)展成不兼容的線丁侄。其實(shí)使用正實(shí)數(shù)來(lái)描述是不對(duì)的惯雳,明明應(yīng)該是用[1,0,0], [2,1,0], [3,2,0, patch1]這樣的向量來(lái)描述才對(duì)。
我們舉個(gè)例子鸿摇,假如給所有已經(jīng)發(fā)布的版本都打上一個(gè)同樣的patch1石景,那么如果線性增長(zhǎng)就容易亂套了。比如有版本1.0.0, 1.0.1, 1.1.0拙吉,比如1.0.0升到1.0.2, 1.0.1升到1.0.3潮孽,1.1.0升到1.1.1這樣的方案就容易亂。現(xiàn)有的線性方案就不管1.0.0了筷黔,直接給1.0.1升1.0.2這樣恩商。
但是其實(shí)如果是長(zhǎng)期維護(hù)的話,故事往往沒有這么簡(jiǎn)單必逆。比如Linux內(nèi)核3.10.*已經(jīng)沒有官方維護(hù)了怠堪,官方的線性版本沒有了揽乱,于是就不可避免地產(chǎn)生分叉,也就是從一維變成n維了粟矿。
在機(jī)器學(xué)習(xí)中凰棉,成百上千維的數(shù)據(jù)更是家常便飯了。
但是陌粹,維度這么多撒犀,是不是像想象中的零下幾十萬(wàn)度一樣是個(gè)錯(cuò)覺?
在超弦理論中掏秩,世界是十維的或舞,到達(dá)十維之后,就只剩下一個(gè)包羅萬(wàn)象的點(diǎn)蒙幻,所有的可能連線都包含在其中映凳。
對(duì)于我們生活的四維空間,雖然沒有廣義相對(duì)論加持邮破,但是也還算是有足夠經(jīng)驗(yàn)诈豌。
從四維到五維是一個(gè)艱難的突破,不過我們有《星際穿越》做教材抒和,這就是講五維世界的矫渔。
在四維空間里,我們只能經(jīng)過過去走向未來(lái)摧莽。而如果我們從五維上看庙洼,就可以回到過去,預(yù)知未來(lái)镊辕。
回到過去了之后油够,你想起了曾經(jīng)錯(cuò)過的女生,想要改變歷史丑蛤。當(dāng)歷史改變的那一刻叠聋,你已經(jīng)進(jìn)入了六維空間,因?yàn)闀r(shí)間線分叉了受裹。
既然都分叉了碌补,那干脆把所有的可能性都試一下??jī)蓷l線可以確定一個(gè)平面棉饶,而從一點(diǎn)發(fā)出無(wú)數(shù)條直線厦章,這是一個(gè)球。
我們?nèi)∏騼?nèi)的任意兩點(diǎn)做連線照藻,這就是一條七維空間的線袜啃。這樣的兩條線相交就成為一個(gè)新的面,即八維空間幸缕。兩條線不可能只在一個(gè)平面上群发,變成一個(gè)三維的體晰韵,就是九維空間。
九維空間中的所有的點(diǎn)任意相連熟妓,最終就形成十維空間雪猪。不過現(xiàn)有理論認(rèn)為十維空間包容一切可能的點(diǎn),再也不能構(gòu)成十一維的空間了起愈。
請(qǐng)注意只恨,上面我不是講科學(xué)理論,是講個(gè)故事抬虽。就是說官觅,我們不想投機(jī)的辦法,直接用最笨的辦法阐污,面對(duì)的問題可能并不是無(wú)限的休涤,而是可能有邊界的。
程序代碼的邏輯可能要更復(fù)雜一點(diǎn)疤剑,比如有死循環(huán)走不出來(lái)的滑绒。但是闷堡,寫代碼的目的并不是要把code review系統(tǒng)搞死隘膘,而是盡可能借用它的力量來(lái)節(jié)省腦力體力。
戰(zhàn)勝一切市場(chǎng)的人的故事
講完無(wú)限可能是有限的故事杠览,我們?cè)僦v一個(gè)數(shù)學(xué)家的故事弯菊。
常言說,買的沒有賣的精踱阿。在做生意的人中管钳,可能沒有比開賭場(chǎng)的更精明了,因?yàn)橘€博本身就是個(gè)玩數(shù)學(xué)的游戲软舌。
歷史上研究賭博的數(shù)學(xué)家不計(jì)其數(shù)才漆,比如概率論學(xué)科就是這么起源的。但是直到索普出手之前佛点,所有數(shù)學(xué)家的結(jié)論都是玩家不可能擊敗莊家醇滥。
索普這個(gè)人牛就牛在,不但數(shù)學(xué)理論扎實(shí)超营,也懂得使用最先進(jìn)的算力鸳玩。1959年,索普用當(dāng)時(shí)很先進(jìn)的IBM大型計(jì)算機(jī)演闭,推演了最有利于玩家的游戲21點(diǎn)的所有可能情況下的概率分布不跟。經(jīng)過推算發(fā)現(xiàn),在有利于玩家的情況下米碰,可以比莊家的勝率高5%窝革。
但是也不能推著IBM大型機(jī)去賭場(chǎng)啊购城,于是索普研究特征工程,總結(jié)出前面出現(xiàn)的小牌越多虐译,剩下的牌對(duì)于玩家越有利的規(guī)律工猜。索普親自到賭場(chǎng)去實(shí)踐,賭場(chǎng)甚至派上出老千的發(fā)牌手仍然無(wú)計(jì)于事菱蔬。最后只好把索普拉黑篷帅。索普甚至出了一本書來(lái)指導(dǎo)玩家,差點(diǎn)被賭場(chǎng)的大佬干掉拴泌。
索普還是端智能的前輩魏身,為了計(jì)算更復(fù)雜的輪盤賭中的小球的軌跡,他和信息論之父香農(nóng)一起制造了一個(gè)放在鞋里的IoT計(jì)算設(shè)備蚪腐,證明有效箭昵。只不過因?yàn)楫?dāng)時(shí)的硬件設(shè)備穩(wěn)定性還不行所以沒有推廣開來(lái)。
不過再這么玩下去回季,索普被賭場(chǎng)大佬干掉是早晚的事了家制,于是他又轉(zhuǎn)戰(zhàn)股票市場(chǎng)。他沒學(xué)過證券分析更不懂經(jīng)濟(jì)學(xué)泡一,也沒有內(nèi)幕信息颤殴,于是又把投資變成了一個(gè)數(shù)學(xué)問題,他的辦法是對(duì)沖鼻忠。他開創(chuàng)的方法被稱為量化投資涵但,至今仍是證券市場(chǎng)的主流流派之一。
索普這次算法沒開源帖蔓,于是有三位學(xué)者搞了個(gè)開源的實(shí)現(xiàn)矮瘟,最終健在的兩位獲得了諾貝爾經(jīng)濟(jì)學(xué)獎(jiǎng),他們推出的模型就是BSM模型塑娇,可能很多同學(xué)都學(xué)習(xí)過澈侠。
小結(jié)
講了這么多,我想說的是:
- code review本質(zhì)上要做的事情是將代碼運(yùn)行的所有可能都鋪開埋酬。這可以認(rèn)為是code review的第一性原理哨啃。
- 狀態(tài)全展開的復(fù)雜度很可能與歸納法做完善的等價(jià)的,它可能是有邊界的奇瘦。
- 從索普的故事可知棘催,就算第2條做不到,我們只要能打敗目前市場(chǎng)上其它的code review系統(tǒng)就有生意做耳标。