調(diào)試從哪里來驴娃?
調(diào)試被稱之為“黑客之瞳”,程序的對錯通常都不是證明出來的循集,而是需要我們?nèi)ビ^測驗證的唇敞。調(diào)試是程序員的工具,幫助我們發(fā)現(xiàn)咒彤、解決程序問題疆柔。在什么情況下,我們會需要調(diào)試呢镶柱?這里可以把調(diào)試分為兩個點:
- 發(fā)現(xiàn)問題
- 解決問題
怎么有效率地進行調(diào)試
1.出問題了旷档,消息是否可靠?
通常歇拆,我們是在知道程序有問題以后才去調(diào)試鞋屈。從這里開始,我們得到了關(guān)于程序出錯的信息查吊。這個信息可能是測試人員告訴你的谐区,也可能是用戶告訴你的,因此第一步是確認這個信息逻卖。也許會急著自己重現(xiàn)這個問題宋列,其實我們不用這么急躁,我們需要先判定這個信息來源是否可靠评也。如果認為是真炼杖,那么就跟著這個假設(shè)往下走灭返,不浪費時間親自重現(xiàn)錯誤。
2.定位問題坤邪,是否需要驗證問題熙含?
如果代碼你非常熟悉,而且有把握預(yù)測寫下的代碼會有什么行為艇纺,那么直接修改問題就完了怎静。對于熟悉的代碼,應(yīng)該最起碼能夠預(yù)期代碼行為黔衡,并且經(jīng)過profile等等測試蚓聘,才能成為合格。
3.如果定位困難盟劫,但是很熟悉代碼
可以動手調(diào)試夜牡,數(shù)據(jù)斷點铡俐、查看內(nèi)存勤庐、代碼斷點、日志备图、轉(zhuǎn)儲文件影所、查看匯編代碼蹦肴、抓網(wǎng)絡(luò)包這些方法都是你的好朋友。
- 代碼斷點大家肯定很熟悉型檀,這里講一個數(shù)據(jù)斷點的例子冗尤。有一次我發(fā)現(xiàn)別人的代碼中出現(xiàn)了內(nèi)存泄漏,雖然我對他的代碼不是非常熟悉胀溺,但我作為框架設(shè)計者裂七,很快就了解具體代碼。然后我跟蹤單個泄漏對象的生命周期仓坞,就是通過對他的引用計數(shù)進行數(shù)據(jù)斷點背零,每次增加引用與釋放引用都看得一清二楚,最終發(fā)現(xiàn)其實是一個很隱晦的无埃,在Lua中重寫了父類釋放引用計數(shù)導(dǎo)致的徙瓶。
- 查看內(nèi)存有時候作用也很大,比如說在使用google protobuf中遇到bug嫉称,直接人肉decode來得更快侦镇。
4.如果代碼不熟悉,那么用二分法
最簡單粗暴织阅,直接注釋某些功能壳繁,直到篩選出問題代碼。看上去很慢闹炉,其實很快就能發(fā)現(xiàn)問題蒿赢。
5.如果連業(yè)務(wù)都不熟悉
或許應(yīng)該讓別人去解決,如果一定要解決渣触,那么請從設(shè)計開始了解羡棵,不要馬上就鉆入代碼里面,否則很危險嗅钻,而且浪費時間皂冰。也許重寫也是一個好方法。
- 比如我發(fā)現(xiàn)cocos2d-x v3.x字體模塊很糟糕养篓,于是去看看怎么解決問題灼擂,但是字體邏輯卻不是很了解,但團隊又需要你去做觉至,那么我就只要從字體的排版設(shè)計上去學(xué)習(xí),花了半天看完freetype的設(shè)計思路睡腿。不久之后重寫整個模塊语御,不僅把原來字體特效的問題解決,而且整個字體模塊只需要2m內(nèi)存就滿足整個游戲的字體需求席怪。
問題之外再問問自己
- 問題是什么应闯?用戶的期望與實際的差異有哪些?
- 為什么會有這次問題挂捻?是數(shù)據(jù)結(jié)構(gòu)設(shè)計得不好嗎碉纺?是數(shù)據(jù)與顯示沒有分離嗎?
- 這是誰的問題刻撒?誰認為是問題骨田?