如何高效debug

這是一個公司內網上的問題,原意是題主以爲debug很是費時,影響了項目的效率,問如何改進。當時也在內網隨手碼了幾點,回頭又看了一遍以爲頗有共性,能夠再擴展一下單獨寫寫,因而誕生此文。由於專業所限,本文的部分細節也只限於web前端,但思路和其它語言是相通的。html

首先,程序員要調整好心態。前端

事實上,debug是程序員工做的重要組成部分,甚至在產品的某些階段是惟一的組成部分,因此不用把調bug當作是拖累產品進度、下降效率的兇手,這是一件必需要花時間認真去作的事情,它就是你的工做,也是整個項目進度過程當中必不可少的組成部分。因此在debug的時候也能夠更加平心靜氣一些,不用那麼急躁。git

固然,這個心態的改變也會涉及到項目進度安排上的一些調整,好比在排期的時候就要預估debug的時間,而不能僅僅只安排編碼的時間。此外,還須要給本身作好時間管理,儘可能能排比較大段的不被打擾的時間來debug。程序員

把心態放平以後,有的bug可能解決起來真的就沒那麼耗時了。在心態平和、思路清晰、無人打擾的狀況下,通常修起bug來都有如神助,效率高得連本身都不太敢相信。相反,每每越是着急的時候越是難定位到bug的真正緣由。github

而後說提升調試效率的一些辦法:web

練好基礎

這個不論對開發仍是調試效率都有決定性影響,一旦基礎紮實了,在編寫代碼的過程當中就能避免很是多的bug,在調試過程當中也很敏銳地察覺到異常之處。編程

這裏所指的基礎其實包含了兩個部分:一部分是編程語言的基礎知識,只有掌握好才能知道一個問題如何用最低成本、最正統、最能扛住需求變動、最不容易出問題的方式寫出來。另外一個部分則是良好的編碼習慣,基本上各個語言都有各家總結的一些編碼規範和習慣,而且也會解釋爲何建議這麼寫,若是掌握好的編碼習慣,通常而言能夠避免很是多編碼細節致使的bug。json

好比,關於數組去重,若是你去網上隨便找一段代碼,頗有可能找到利用對象的key來去重的代碼:gulp

Array.prototype.delRepeat=function(){
    var newArray=[];
    var provisionalTable = {};
    for (var i = 0, item; (item= this[i]) != null; i++) {
        if (!provisionalTable[item]) {
            newArray.push(item);
            provisionalTable[item] = true;
        }
    }
    return newArray;
};

再好比,若是你習慣花括號另起一行,那麼在函數中返回一個對象就很容易寫成這樣:數組

function A()
{
    return
    {};
}

但事實上因爲JavaScript的分號補全機制,這裏最後返回的是<span class="kwd">undefined</span>,而若是將花括號跟在<span class="kwd">return</span>後面則不會存在問題。這就是典型的編碼習慣能夠避免的bug。

練好基礎的工夫必然是在工做以外的時間,由於基本上工做時間是滿負荷輸出,不太有時間去接觸新東西,若是你每行代碼都須要先Google一下再寫,那想必你的老闆也會不樂意。因此給本身充電的時間就只能是在工做以外,這是件很是考驗人的事情。

用好工具

工具包括三個方面:

質量工具

質量工具對於前端來講是特別必要的,甚至比其它語言更必要,由於HTML、CSS、JS都是沒有語法檢查沒有編譯過程的,基本上編寫完就直接丟上線了。因此爲了保證代碼質量,咱們能夠引入一些檢查工具來輔助控制代碼質量。

至於具體的工具,多是IDE,多是命令行下的各類lint,也多是集成構建過程當中的語法檢查過程,還多是在線的語法檢查器等,方法不一而足,但作的事情都是差很少的。

HTML檢查的話主要是W3C的標準驗證(http://validator.w3.org/),也有各類牛人編寫的HTML Lint之類的工具。

CSS檢查的話主要是CSSLint,此外不規範(無效)的屬性在Chrome開發者工具的console中會顯示警告。

JS檢查的話主要是JSLint/JSHint。

此外還有一些針對特殊文件、語法而作的工具,好比用於檢查json語法的jsonlint之類,種類繁多,不一一列出。

以上這些工具基本都有對應的grunt、gulp插件,也有IDE插件,能夠直接集成到編碼過程或者構建過程當中。

質量工具除了語法檢查類的以外,還有一類是屬於「規範」類的,即用來統一項目的編碼規範,好比editorconfig,建議每一個項目都能引入,它能夠更好地控制項目的縮進、換行符、編碼之類的規範。

調試工具

其實調試工具不只僅是一個工具,要用好的話還得掌握調試方法。這一節的核心思想就只有一句話「代碼調試真的要靠調試,而不能靠猜」。見過很是多的前端同窗,在某個邏輯與預期不一致的時候基本都是對着源代碼猜,是否是這個地方單詞寫錯了?是否是這裏循環少了一次?是否是後臺返回的數據是空的?而後用各類奇葩的方法一遍遍地改代碼,直到終於讓結果符合預期了,纔算「調試」完畢了。

怎麼樣纔算是「調試」呢?那就是你能夠看到你寫的每一句代碼最終跑起來是什麼樣的。具體而言,HTML主要檢查生成的DOM樹結構,CSS主要看樣式的層疊關係及最後應用的樣式來自哪裏,JS主要看代碼每一行的結果和預期是否相符。

以Chrome dev tool爲例,看HTML的問題主要在Elements面板,看CSS的問題主要也在Elements面板(有時候也須要在Resource面板),看JS的問題則主要在Source面板。

好比兩句簡單的代碼:

var words = location.hash;
$('#test').append(words);

若是頁面上沒有出現你想要的文字,該怎麼樣?不少人這個時候就開始猜了,是否是<span class="pln">location</span><span class="pun">.</span><span class="pln">hash</span>兼容有問題?是否是jQuery沒引入?是否是<span class="pln">$</span>被覆蓋了?是否是不支持取ID?是否是<span class="pln">append</span>用法不對?

頗有可能你拿調試工具斷一下點,看看每一個表達式的結果,你就會發現,其實緣由是<span class="pln">$</span><span class="pun">(</span><span class="str">'#test'</span><span class="pun">)</span>取不到。而後恍然大悟,原來沒有把DOM操做放在DOM Ready中!

由於不是調試工具教程,因此細節很少說,放個截圖,我說的就是這一堆。

調試工具截圖.png

另外強烈建議將畫圈的按鈕點一下讓它高亮,這樣能夠在代碼報錯以前當即自動斷點下來,避免由於報錯而致使頁面刷新、表單提交之類的動做,使得調試變得困難。

若是看不懂上面一堆在說什麼,那麼這一段的目標讀者就是你了,你須要好好學習一下前端調試方法和工具的使用了。

與上面說的相似,移動端的調試也有不少方案,好比weinre、MIH Tools之類,iOS和Android也有各自的USB調試方案。

多多掌握這些調試方法和工具可以真正在你想找問題的時候事半功倍。

生成工具

有時候咱們的代碼中還會有一些假數據或者寫死的數據,或者是一些根據數據生成的代碼(好比拼接HTML),或者是一些模板化的代碼,此時若是藉助工具來生成數據或者代碼,會比手工編寫靠譜得多,也能夠避免不少錯誤產生。

好比http://www.json-generator.com/http://shancarter.github.io/mr-data-converter/http://www.colorzilla.com/gradient-editor/http://matthewlein.com/ceaser/都是很是好的生成工具。

用好搜索

若是在調試以後定位到某個很詭異的地方,實在沒法解釋或者找不到緣由的話,不妨搜索一下看看,通常這種詭異的問題都已經有前人碰到了,在stackoverflow或者是開源代碼的官方討論區基本上都能找到答案,絕大部分也能夠找到規避方法或者替代方案。

這裏值得注意的是,你仍然須要先調試再搜索,由於在你調試以前,你對問題的描述只能是「現象」,可是調試以後通常能夠定位到某個具體的代碼或者對象或者API,去搜索對象或者API的行爲比搜索「現象」獲得的答案每每會更接近真相。

多總結

每調完一個重大bug就會有比較大的成就感,通常這也是進行總結的最佳時機。

每一個程序員都應該有總結bug和緣由的習慣,好比爲何會形成這個bug,若是是編碼習慣的問題可否規避,可否利用工具在編碼階段就解決掉?若是是邏輯上的問題,可否推給產品、交互去從新梳理,避免相似問題?

總結以後最好還要有提煉和分享,好比bug是因爲鮮爲人知的特性或者API致使的,可否對與之相關的任務進行封裝,或者可否將這個坑埋掉,而後共享給組員讓你們避開這個坑,甚至回饋給組件做者讓更多人避免這些坑?若是能將你的成果分享給你們,就避免其它人再掉入同一個坑,而若是將這個坑埋掉,就可讓地球上的程序員永遠再也不掉進這個坑,想一想都是一件很幸福的事情。

轉載自如何高效debug

相關文章
相關標籤/搜索