調試一段代碼兩個小時都沒搞定,繼續死磕還是尋找其他方式,你一般會怎麼做?

作為一個合格碼農,踩坑是必備人生經驗。在你調試一段代碼兩個小時都沒出坑的情況下,接下來你會怎麼做?


推薦我私家珍藏的:小黃鴨調試法

以前我遇到問題就拉著隔壁工位的同事給他講代碼思路,實現過程。

我說這叫做小黃鴨調試法,他問我是什麼意思,我說你讓對面工位的小哥解釋一下。

對面小哥耿直的說,就是當你代碼出了問題的時候,找一個傻X給他講一遍...

後來我的小黃鴨都不跟我說話了...

祝大家都能找到自己的小傻X,啊不,小黃鴨…


我教你們這個方法不是讓你們拿我當雲端的小黃鴨啊,摔...

T.T

你們這是逼良為鴨啊...


兩個小時只算是 warm up,鬥志初燃,豪情萬千,「小樣,別走,等老子擼好了袖子來收拾你!」,你對著翻滾著代碼的 IDE 說。

兩天後,「不可能,真的不可能,一樣的代碼,一樣的流程,怎麼可能只有那台機器出問題?你說,是不是沒有道理?」,你對著正在刷杯子的保潔阿姨說。

兩星期後,「這不是 bug,這是系統的一個新特性」,你對著一臉震驚的 PM/老闆/客戶 說。

兩年後,「當初他們的那個 bug 就是我寫的,迄今沒人能 fix」,吃飯的的時候,你對著新公司的同事說。


我來說一個親身經歷的慘痛教訓:

有一次我跟一段出錯的代碼死磕,但無論如何努力調試修改,代碼都沒辦法正常運行,也找不到問題在哪裡,到最後已經幾乎每句代碼都加了斷點和日誌輸出,還是不知道問題出在哪裡。

大概前後花了有半個多月吧,每天精神恍惚,夜裡經常會驚醒,覺得夢到了什麼,然後拿筆記本一試又不通。

半個月以後,微軟給我郵寄了新的一版MSDN,我打開一看,一個勘誤: 「某系統函數的保留參數應該設為-1,
而不是之前寫的0...
不是之前寫的0...
之前寫的0...
寫的0...
0...」

你看,這就是為什麼不要跟代碼死磕的原因之一:你有可能在用別人的錯誤來懲罰自己。

當然這事給我的另一個教訓是:誰也不能信,哪怕是微軟。

以下是雞湯時間:
遇到問題的時候不要一味想著如何解決問題,要想著如何解決提出問題的人(刪掉),要停下來想一想這個問題是不是真的需要現在解決。

有些問題隨著時間流逝就不再是問題。
有些問題在解決了其他問題後也不再是問題。
有些問題根本沒有解決的必要性或急迫性。
有些問題我們壓根沒能力解決,坐下來忍受也是一條出路。

總之,血的教訓是:沒有必要的話,就不要死磕(處女座可以跳過不看)。


就我的人生經驗來看,如果bug發生在晚上六點之後,並且到了晚上七點還沒有成功,特別是那種看上去「好像馬上立刻再搞一下就可以解決了的樣子」,就回家睡覺,第二天再搞。在目前的二三十次嘗試中,只有一次是成功的在堅持到八點後搞出來了,其它的都是第二天早晨解決的。

我們公司的晚上六點約等於互聯網公司的晚上九點。

白天一般不會發生這樣的事情,這就是疲勞積累的bug無法解決定律。不管是學習還是工作,遇到這種難題的最好解決辦法都是睡覺。


本人親測並長期使用的:上廁所調試法。

每當bug解決不了或者沒思路的時候,起身去上廁所,廁所離工位距離遠一些效果更佳。

因為要去上廁所,所以不比坐著的時候那麼專註,同時也會讓人不自覺從更宏觀的角度去考慮問題,走出思維的死胡同,找到新的思路。

屢試不爽。


調試代碼的難度是編寫這些代碼的兩倍。因此,如果需要殫精竭慮才能寫出一段代碼的話,那麼很顯然,你肯定不具備調試這些代碼的能力。——Brian Kernighan

所以,很簡單,兩個方向,三條道路:

方向一:把編程語言、用到的庫、涉及的各種機制完全搞明白。

1、徹底搞明白任何技術難點的來龍去脈,對任何一條語句的side effect了如指掌

2、寧可把代碼寫的「笨」一些,只用最簡單最直白的手法解決問題

方向二:把業務邏輯徹底弄清楚

3、徹底搞明白業務邏輯,理清當前狀態和數據格式/邏輯,把當前數據是否合法、會經過哪些邏輯進入哪種狀態徹底弄清楚;然後觀察軟體處理過程的每一步是否符合期望。

具體做法就複雜多了。不過基本上還是那麼幾板斧:

1、通過業務數據/邏輯的追蹤展示(一般使用日誌),找出異常點

2、利用對程序狀態的追蹤展示(斷點、日誌等),隔離出異常代碼段

3、剝離出骨幹代碼,分析其邏輯;必要時,用不同手段實現,通過正常/異常數據比較執行情況,找出不合預期之處;然後逐漸加入細節,觀察何時出現異常。

4、盡量多的收集異常表現,猜測其原因,然後寫出代碼驗證

歸根結底,關鍵還是一要徹底搞明白業務相關問題,清楚任何一條正常/異常路徑;二要徹底理解自己所用工具,有意識的繞開語言中的坑,沒有經過充分實驗、沒有徹底理解的東西,不要用到正式代碼里。


正常啦,兩個小時怎麼可能搞定問題,不都是要好幾天的嗎?


謝邀,但是這個題真沒什麼好回答的,絕對需要看具體場景、具體 case 了。

不過我有個獨家秘制視頻給你們看,就幾秒鐘,訴說了一個信息量很大的故事,大家體會一下吧。

作為前端開發者,大家都用那種雙屏幕吧,就是筆記本再外聯一個顯示器,然後這是一個關於下拉菜單為什麼不出現的 bug:

來自@justjavac 票圈;
推薦德福大佬的高贊回答,也挺想請教下@王德福 德福哥,這情況我能跟小黃鴨講述一下嗎?


兩周以下的還談不上「死磕」,兩周是一個Sprint的工期。把兩小時叫死磕的,估計還是耐力不夠。

死磕是一門兒科學。

經驗豐富的人可以用直覺,就是負責任地「猜」,猜問題可能在哪裡,然後驗證猜想,這就是基本的科學方法。猜對了搞定,猜錯了再猜,再驗證。

沒有直覺的時候,要學會「隔離」技巧,要動手臨時簡化邏輯,剔除無關部分,簡化執行路徑到一定程度,自然能debug範圍縮小到不必死磕,而能通過單步log調試就能解決的程度。

如果是自己能控制的代碼,我還沒碰到過無法用隔離和單步調試解決不了的問題。很多人過分依賴調試工具,這樣的壞處是過分依賴一個調試工作流,過分信任工具,而工具只會給你一個有限的角度。

另外就是到了死磕的時候,還不認賬,心理還默念「這怎麼可能是我的錯呢,明明電腦錯了」。

明明是你錯了。


半年時間定位修復了一個bug……


2小時剛熱身好不好,進入狀態後根本沒有時間感。只要你一直有思路就繼續調下去,不然思路就斷了。沒思路了就歇息吧。


我是在我做直播的時候發現這個問題的。(見:自由飛:在鬥魚直播寫代碼是一種怎樣的體驗?)

一個bug給堵住了,心裡急啊!可有人看著呢,這下臉丟到姥姥家了,延時又延時(我定的一次直播1個小時),一直搞不定,最後無奈投降,休息一會先(嘴說幹了)。

結果,媽蛋,休息的時候,思路一下就來了……

不太清楚原理,但我從此以後,死磕一次絕不超過1小時。

+++++++++++++++++++++

收藏於:野生程序員,歡迎關注

+++++++++++++++++++++

我真想給自己一耳光,太特么的沒有推廣意識了:

去 一起幫 求助啊!真心的,而且絕對適合這個場景,2個小時都還沒搞定,讓別人給你瞧瞧,遠程看看,說不定就迎刃而解了!—— bug嘛,什麼都有可能的,燈下黑……

暈死!

連我自己都沒有用「一起幫」的意識,要推廣「一起幫」,難度確實不小啊……


找個干白盒的測試兄台聊一聊…
這不是小黃鴨調試法!


如果你是以解決問題為目的,比如在公司:

能自己解決就自己解決,不能自己解決就別硬撐,充分利用身邊的資源。

如果你是以學習為目的,比如在大學:

能自己解決就自己解決,不能自己解決再加把勁。


此處推薦我屢試不爽私家珍藏的:大牛調試法!

每次有費解的問題的時候,我都從旁邊隨便拉一位大大來陪我調,然後他在解決問題的同時告訴我『代碼更好的寫法』or『某個庫隱藏的bug』。

P. S. 天貓誠邀各位前端大大的加入,歡迎聯繫jiajian.wjj@alibaba-inc.com

Job Description


我能說我曾經調試一個問題花了一周么……因為是業餘項目,恰巧遇到手頭時間緊的時期,再加上那東西跑一次太費時間,跑太多還有不良影響(為大幅節約時間並沒有測試環境)。

看到有人調試了半天結果發現不是自己的鍋的。我其實也遇到過不少,不過因為我使用的都是開源項目,結果就是向這些開源項目貢獻了不少補丁或者 bug 報告,也因此名字被記載在了包含 linux 內核在內的許多開源軟體的日誌中。(調試時發現某系統調用行為似乎與文檔不符,於是去翻了一下內核源碼,果然……)


我選擇狗帶。

寫了十幾年的代碼,經常遇到各種解決不了的問題,於是就放一放。

放一放,放著放著就沒消息了~

反而是上項目上的事情很簡單,遇到問題是各種想辦法,總有笨辦法可以解決掉,只是不夠優雅。

別的不談,就單指Eclipse,經常莫名其妙的編譯錯誤,明明代碼一點都沒改,偏偏就是瞬間全部報紅。

滿屏的紅叉,我一直懷疑微信小紅點的起源就是Eclipse的紅叉叉。

這個時間第一關閉項目再打開,第二重新Build,第三關閉其他不相關的項目重新Clean Install 第四 打開Problem 把所有的錯誤都刪掉 第五 隨便敲個空格再重新保存一下 第六項目全刪掉重新導 第七砸電腦用別人的電腦寫代碼~

全部有效,不過基本上全是Hack。

時間長了,會了很多這種Hack技能。

只有少數一部分,是知道的清清楚楚問題出在哪裡,原因是什麼,怎麼驗證。

所以一般情況下就是先分類,先解決問題,再想辦法查找原因。

跟別人講一講什麼的,基本上沒什麼用,很多時間自己做的孽只有自己才清楚,其他人和你根本不在一個命名空間~


我現在從不調試,只用單元測試和看log,如果感覺單元測試和log都看不出問題,說明code本身太複雜了太晦澀了,就算改好了將來後來人也看不懂,我又不想後來人跑來問我這段code是啥啥意思,所以我就刪掉這些複雜的code重寫。

——更新分割線——

另外,「小黃鴨傾訴法」也是不錯的方法,很多時候,想不通的問題,找個人說一遍,自己就明白了,不過也不一定真要用小黃鴨,可以用任何一個你覺得可以傾訴的對象,甚至也不一定要「一個」傾訴的對象。

我現在遇到困惑的問題傾訴對象就是工位上的這兩位。

我:甄子丹你說這句話什麼意思?可能我沒有講清楚,或者你不懂,姜文你說呢?我再來說一遍看看……哦,我知道了,不管你倆懂不懂,我是懂了。

上次出差的時候趕上迪斯尼店做活動,6塊錢買一送一,沒想到後來還可以拿來當這個用處,呵呵。

了解更多程序員八卦請關注 @程墨Morgan


如果實在日常工作中,搞一個bug兩三個小時還沒頭緒,最好能在team里講一下,不一定是要大家立馬來幫你,主要是讓大家知道你遇到困難停住了,如果有人在等你的結果,他能有個準備。

如果是你自己玩,或者的確沒人願意和你pair一起看,你可以多打log,嘗試各種case反覆測試,有些地方換種寫法,總歸能搞定的。

我覺得最難的問題是在於一些高並發或者多線程的問題,你沒法重現,或者重現很困難,其實也沒有什麼更好的辦法,只能靠你經驗,多和人商量,還有一點運氣了。


做程序員精確點,一段是多少長?


推薦閱讀:

那些 22 歲畢業做程序員的「普通」人,他們 50 歲左右時的人生軌跡是怎樣的?
發布郵件地址時用「#」「at」等替代「@」有助於反垃圾郵件嗎?
從事數據分析(數據挖掘)的工作已經一段時間的你(1年,2~3年,5年,8年),現在是一種怎樣的狀態?
QQ 是否可以取代 Skype,怎樣才能?
阿里金融侵蝕了銀行壟斷體的利益嗎?為什麼後者沒有反應?

TAG:互聯網 | 前端開發 | 程序員 | 軟體調試 |