反思報告:調(diào)試?yán)碚?,防御性編程,invariant,COW,感受痛苦以及擺爛和熬夜
????????隨便聊聊。最近de?COW的?bug實在是讓我太痛苦了,50行不到的代碼足足讓我de了那么三天,加上中間擺爛的天數(shù),那就是五天,五天就那么消失了,現(xiàn)在回過頭來看,我覺得我不應(yīng)該但是可以理解,也許我習(xí)慣好點我不會有那么多痛苦。
????我覺得我的收獲是很大的,但是是否要吃這么多的苦呢?那些直接copy 445 和 824的人,又失去了多少東西呢?他們真的得到了自己認(rèn)為的效率最大化的結(jié)果了嗎?
????看了jyy的調(diào)試?yán)碚撜n,發(fā)現(xiàn)程序出錯大概可以抽象成三個東西。
????一個是 bug,然后是fault,最后是error。
????bug是你代碼實現(xiàn)和需求的不匹配,你的軟件設(shè)計里有一個坑。
????fault是你的狀態(tài)機執(zhí)行到了對應(yīng)的那個地方,掉到坑里了,導(dǎo)致了錯誤狀態(tài)的出現(xiàn)(機器永遠(yuǎn)是對的,對于你寫的代碼而言,這個狀態(tài)是合理的,但是和你的需求有g(shù)ap)
????error是你發(fā)現(xiàn)你的狀態(tài)機出問題了,可能是崩潰,也可能是其他的什么東西,總之結(jié)果不對。
????就我目前比較淺薄的視角來看。我們在為了方便?debug?做的所有的努力,就是為了盡快的讓你定位到對應(yīng)的fault,努力減少?fault 和 error 之間的 gap,然后,就誕生了防御性編程。
? ? 說實話,我覺得這些有啟發(fā),但是如果你真的不去做的話,這些都是空話。高屋建瓴的話,怎么說都是對的,只有落實到實處,讓自己真正切切的感受到痛苦后,我們可能才會意識到這些話的重要性,很多軟件工程的書都是需要有一定的代碼開發(fā)經(jīng)驗之后才能看懂;大概是這個樣子吧。
????我很痛苦,之后我理解了防御性編程的寶貴。
????系統(tǒng)的出錯,實在是太痛苦了,首先debug就很難,gdb要來回在用戶態(tài)和內(nèi)核切,接著就是你一個小地方出錯,可能過了很久才會在另一個地方暴雷,最后我敢保證,暴雷的這個,對應(yīng)的kernel trap 或者 user trap 導(dǎo)致的panic,你大概率是看不懂的。
????我知道我有錯,但是我不知道我哪里有錯,這就是從零開始的debug生活。
????jyy在課上說,所有的程序的功能都是現(xiàn)實世界的需求在軟件世界的投影,這個投影并不是完全一比一照搬的,所以我們的程序在執(zhí)行的時候可能會有一些隱含的假設(shè),我們可能沒有寫出來的假設(shè)。
????比如說銀行卡里面的錢,它不可能是負(fù)數(shù),只可能是正數(shù),這是你的假設(shè),你的程序運行在這個假設(shè)上面。
????防御性編程,我現(xiàn)在的理解就是,他的目的是為了檢驗?zāi)愠绦蜻\行的假設(shè)。
? ? 比如你不能?kfree 之前你 kfree過的塊。不能 kalloc 之前你 kalloc 的內(nèi)存。
????assert做的就是這種檢驗前提的事情。
????說實話一開始防御性的編程的時候,我有一個疑問:如果你知道哪里可能出錯的話,那么,你為什么還會出錯呢?如果在每個可能出錯的地方,你都打上了assert,你的代碼不是會非常的冗余嗎?
????對此我現(xiàn)在的回答是,如果你的理所應(yīng)當(dāng)都是對的,那么就不會有bug,但是既然有,就不存在什么理所應(yīng)當(dāng)。代價是有的,但是是有限的。你可能不能找出所有的錯誤,但是你不能什么都不干啊。
? ?bug是讓人最痛苦的事情(如果有其他還要痛苦的,一定是debug),首先,你不知道哪里會有bug。其次,你不知道這個東西為什么是bug?最后你甚至發(fā)現(xiàn)為了修補這個bug,你需要把你設(shè)計的東西全部推倒,重新設(shè)計一個對應(yīng)的結(jié)構(gòu)。
????日。
????曾經(jīng)我上jyy的課,大受震撼但是不理解,直到COW的后期,我基本對每個函數(shù)都進行了合法性的檢查我才發(fā)現(xiàn),早點麻煩的吃點土,就不會吃自己生產(chǎn)出來的()了。
????這可能就像是代碼復(fù)用和代碼風(fēng)格的干凈一樣,只有在你真正的處理非小型項目的時候,需要用到它的時候,可能才會猛然間的發(fā)現(xiàn)這個東西會有多少有用。
說到前提,我想起以前看過的一篇文章
有趣的CS - 種程序 - 圓角騎士魔理沙的文章 - 知乎 https://zhuanlan.zhihu.com/p/587249189
我覺得我好像抓到點什么?
感覺invariant,遞歸,之類的,唔。
程序是一套規(guī)則,然后遞歸是規(guī)則的自然推導(dǎo)(規(guī)則之間的規(guī)則),然后防御性編程是規(guī)則的前提或者后果的檢查。但是問題來了。
如何設(shè)計一個復(fù)雜的系統(tǒng)呢?曾經(jīng)想過什么數(shù)據(jù)流之類的,把控幾個修改的函數(shù)就可以把控之類的。但是如果系統(tǒng)越來越大,越來越復(fù)雜。
哎,不是很清楚,接著學(xué)吧,希望可以7.15前收掉081(估計不行。)
之后又是碎碎念。
說實話我原來都放棄了COW,不管怎么搞,總有些free頁會莫名其妙的消失,最后我想著,就算了吧,出于程序員的潔癖,我合并了一下我的代碼,把decrease改成了kfree,結(jié)果就panic了,一開始我沒怎么在意,只覺得這個機器怎么又抽風(fēng)了,就直接改了回去,換了一條路走,后來不知道怎么的,kalloc也開始報panic了。
我那個時候,我覺得糟透了。但是。忽然的,電光火石間,我想到了一些什么東西,我沒有考慮并發(fā)。
結(jié)果是我粗暴的上了一把大鎖,解決了并發(fā)問題,拿到了110分。
哎,我已經(jīng)連著5天看到早上的白天,希望能乘著軍訓(xùn)調(diào)整回狀態(tài)。
解鎖技能:防御性編程。