軟體除錯的一般思路

2021-06-12 13:55:18 字數 1819 閱讀 4417

解決軟體的bug就像警察破案一樣。警察在掌握了案件發生的時間地點和相關人物後進行分析推理,採訪相關人員,排除嫌疑人,最終找到**。同樣的,軟體開發人員在接到bug時,也是分析bug發生的背景,然後在運用各種方法來找出問題的原因。並不是所有的bug都能一眼看出問題發生在哪個地方。雖然bug發生的原因千差萬別,但是我們還是有一些比較通用的方法來逐步縮小bug的根源的範圍。在水缸裡面抓魚要比在河裡面抓魚要容易,同樣的如果能把問題的根源縮小到乙個類,乙個函式,那麼我們就能更容易找出bug是如何發生的了。本文結合最近的一些經驗以及閱讀的一些資料,簡單談談如何有效地找出問題的根源。

簡單來講,導致軟體出現問題的因素有如下幾個方面:

但最終來講都是軟體的問題,是軟體本身沒有處理好這些變化的因素。因此,在剛接到bug的時候,我們可能無法立刻判斷問題是由哪個因素引起的,誰都可能是**,因此我們要逐漸縮小懷疑的範圍。

當問題出現了,我們可以根據看到的現象,結合問題發生的環境以及我們對軟體邏輯的理解來分析推斷出問題的原因。這當然是一種可行的方法,但是隨著軟體變得更加複雜,這並不是最有效的辦法。軟體除錯相對於其他領域來講還是比較容易的。比如,發生一起車禍以後,找出事故的原因只能靠分析,交警不能說事故現場沒有發動機的日誌,要求重現這個事故後再來分析事故的原因。而軟體的優勢就在於能做各種實驗來證明你的想法。比如你懷疑是某個地方的問題,那麼就去做個實驗來看看。這就是利用實證的手段來分析bug。它的一般步驟為:

需要注意的是:

假如有兩個「同樣」配置的機器,一台有問題,另外一台沒有問題,那麼要找出那台有問題機器出問題的原因,可以關注一下兩台機器有什麼差別。雖然配置看起來一樣,但他們肯定有差別。找出這些可能和問題相關的差別,利用上一節介紹的實證性分析的方法來證明你的假設。

另外乙個例子,如果你開發中的軟體,版本001沒有問題,而版本002有問題,那麼就看看這兩個版本之間有什麼差異,比如通過scm來看看都改動了哪些檔案,或者使用的第三方庫是否發生了變化等。

我們都知道二分查詢的效率很高。同樣我們也可以利用二分法的一般原理來縮小問題的範圍。還是以上面的那個例子,假如版本001沒問題,而版本008有問題,那麼怎麼快速找到問題是在哪個版本裡面引入的呢。最直接的辦法,從版本002一直試到008,但是這樣效率就太低了。我們假設問題被引入後就不會自動消失,這樣就可以利用二分法來找到查詢問題被引入的第乙個版本。我們先看版本005有沒有同樣的問題,如果有,那麼問題就在版本002-004之間引入的,然後在繼續用同樣的方法找下去,最多找3次就能找到首次引入這個問題的版本,然後就可以看看那個版本裡面有什麼改動,就可以把問題的根源縮小到這些改動上了。

這也是持續整合的思想了,每次提交**都會觸發一次構建和單元測試。如果構建或者測試失敗了,問題的的根源就是上一次**提交造成的,在問題被引入的第一時間修復這個問題要比過了幾個版本後再修復要容易一些。

如果軟體的問題是由於第三方的庫導致的,在向第三方庫報告問題的時候,最好是能寫出乙個簡單的程式來向其說明問題的發生條件,而不是把直接把你的軟體的問題扔給第三方。

同樣的,如果問題就是軟體內部造成的,如果能寫乙個單元測試來重現問題,那麼也能提高你測試和除錯的速度,因為單元測試啟動和執行的速度肯定比把整個系統啟動起來的速度要快。任何時候,我們都要提高反饋的速度。

在遇到問題的時候要先分析以縮小問題根源的範圍,而不是直接就跳到**裡面去看**出錯了(那些一眼就看出問題出錯的地方除外)。如果問題在某個環境(這裡的環境是各種可能因素的組合,比如os,軟體,第三方庫或者系統)發生了,而在另外的環境沒有發生,利用這兩個環境的差異來找出可能導致問題的因素。利用實證的方法來逐漸縮小問題根源的範圍,利用二分法或者其他策略來快速排除一些干擾因素。在找到問題的根源後,最好能寫出乙個單元測試來重現問題,它能提高測試和除錯的反饋速度,也有助於向第三方描述問題。我相信本文介紹的方法大家都曾經使用過,我只是將大家都知道的內容簡單總結了一下,希望能有些幫助。

程式除錯的一般思路

每個程式設計師的很多時間都在和bug打交道,而debug的過程總不那麼令人高興。本人在除錯過程中總結了幾點除錯程式的一般方法,寫出來和大家分享,能力有限,歡迎各位大神批評指正!1.單步除錯 從問題程式的起點開始,單步執行程式 觀察變數的變化過程,是最基本的程式除錯方法。這種方法適合錯誤定位範圍較小的...

實現爬蟲的一般思路

實現爬蟲的套路 一 準備url 準備start url url位址規律不明顯,總數不確定 xpath 尋找url位址,部分引數在當前的響應中 比如,當前頁碼數和總的頁碼數在當前響應中 準備url list 頁碼總數明確 url位址規律明顯 二 傳送請求,獲取響應 新增隨機的user agent,反反...

動態規劃解題一般思路

摘自mooc的程式設計與演算法 一.遞迴到動規的轉換方法 遞迴函式有n個引數,就定義乙個n維的陣列,陣列的下標就是遞迴函式引數的取值範圍,陣列元素的值就是遞迴的返回值,這樣就可以從邊界值開始逐步填充陣列,相當於計算遞迴函式值的逆過程 二.動態規劃解題一般思路 1.將原問題分解成子問題 把原問題分解成...