
前言
bug, 又名程式缺陷或者程式漏洞, 是每個程式員每天都回避不了的東西,程式員對bug的感情可謂是五味雜陳:一方面bug非常可惡,尤其是一些偶現的bug,它強大到可以摧毀一個優秀程式員的意志;另一方面很多bug又是程式員自己親手寫下的,無奈之余只能自嘲一句:不寫bug我們就要失業了!
作為一名職業程式員,同時也是一名開源創作者, 夸張點說,我解過的bug可以繞地球一圈, 每天寫bug解bug幾乎是我的日常,
但是,作為一個善于思考和總結的技術up主,我怎么能止步于每天寫bug和解bug呢?更何況,人生在世,總得有點追求,既然我不能夠阻止bug的產生,那么就讓我總結一點bug的修復技巧,讓bug消失地更快點吧!

1.bug修復的生命周期
中醫講究"望聞問切",其實修復一個bug就像給病人看一場病,本質上是相通的,
當我們遇到一個bug(問題)的時候,一般我們需要經歷如下6個步驟:
- 1.
了解bug,我們首先需要到底出了什么bug,現象是什么,怎樣發生的, - 2.
復現bug,在了解了bug的大致情況之后,我們需要能夠找到復現的路徑,這就為后面bug的定位提供可靠的依據, - 3.
定位bug,當有了穩定的復現途徑之后,要做的就是打斷點、打日志進行除錯,來一步一步分析和定位bug,到底是那塊代碼導致的錯誤, - 4.
確認bug,當我們定位到bug出錯的地方之后,我們就需要分析這到底是不是bug,如果是bug,那么這個bug出現的根源是什么,到底能不能解決, - 5.
修復bug,在明確了bug的根本原因之后,下面就需要發揮我們的聰明才智去修復這個bug了, - 6.
驗證bug,并不是每次我們修復完bug之后就可以萬事大吉了,此時我們還需要去重現bug以確保bug被真正修復,除此之外,有條件的我們還需要去驗證相關場景,以保證修復該bug不會引入其他bug,
以上可以總結為12字方針–"了解、復現、定位、確認、修復、驗證"bug,一般在稍微大一點的公司,都會有對應的流程對bug的修復進行流程控制,最終形成倍訓,
可以看到的是,其實修復bug只是解決一個bug的6個步驟中的其中一步,很多剛剛參與作業的程式員經常犯的錯誤就是一遇到bug,就開始漫無目的地看代碼或者是上網各種瞎搜索,又或者各種無腦問,最后搞了一圈可能連自己要解決的bug到底是什么都不知道,這樣解決bug的效率可想而知,
可能讀到這的你此刻非常想問:怎樣才可以更快地修復一個bug呢?那么下面我就根據上面講的六個步驟來分別講解一下對應的技巧,

2.解決bug的藝術
在我看來,修復一個bug是相對容易的,因為修復一個bug的方法可能有很多種,但是如何從根本上解決一個bug,并保證這個bug下次不再復現的話,其實是非常難的,這就需要我們學習一下解決bug的藝術,
2.1 了解bug
俗話說,知己知彼百戰不殆,bug修復的第一步當然是先了解bug了,
了解bug是解決bug最重要的一步,它直接決定了后面五步執行的效率和質量,糟糕的錯誤報告和不負責任的問題描述都是埋葬程式員修復bug意志的罪魁禍首,
在了解bug之前,我們需要收集足夠的資訊,了解它產生的現象、描述、復現步驟、以及解決后的預期是什么等等,那么我們應該怎么做才能更加全面地了解它呢?
下面我給幾點建議供大家參考:
2.1.1 觀察現象
光憑文字說明是無法準確領悟到bug的精髓的,因為每個人思考問題的角度以及文字表達描述都是千差萬別的,
如果說這個時候能提供一段出錯的視頻或者問題截圖,又或者能夠現場演示錯誤的話,這樣觀察現象,然后再結合問題描述之后,一定能夠幫助你快速地了解這個bug,
2.1.2 詢問相關人員
這里你詢問的可以不僅限于發現bug的人(一般是測驗人員),當然你首先應當詢問的還是這個發現bug的人,
這里你需要著重詢問bug報告上你覺得迷惑的點,比如出現bug的應用版本、設備型號、bug出現的頻率、bug產生的步驟和恢復的途徑、bug修復的預期效果等,這里你需要進行刨根問底地詢問,因為可能bug發現人覺得一些無關緊要的細節,對你來說卻是至關重要的點,
問完發現bug的人之后,我們還可以向bug對應模塊的負責人(測驗、開發、產品)詢問該模塊的業務邏輯,說不定能夠獲取到有價值的資訊哦,
2.1.3 提供bug報告模板
一份優秀的bug報告模板,可以讓程式員直接跳過bug修復的前三步,直接進入到確認bug步驟,從而能夠極大地提高bug修復的效率,那么一份優秀的bug報告模板應當具備哪些內容呢?
- bug的標題和問題描述
- 出現bug的應用版本
- 出現bug的設備資訊(型號、版本等)
- bug產生相關的視頻、截圖和錯誤日志
- bug復現的步驟
- bug出現的必要條件(環境)和恢復途徑
- bug修復后的預期效果
- bug對應的模塊或者關聯bug
有了以上的內容之后,相信程式員能夠很快地了解這個bug,定位出bug產生的原因并予以解決,

2.2 復現bug
如果你在第一步了解bug中獲得了良好的bug報告的話,則此部分可以很容易,你只需要按照bug報告中的bug復現步驟,按順序操作即可穩定復現bug,
當然,很多時候往往并不是一帆風順的,即使你手握bug報告,做了非常詳細的調查作業,然而bug就是無法復現,那么這個時候我們應該怎么做呢?
2.2.1 重新了解bug
此時為了能夠復現bug,你可能需要回到上一步,重現去了解bug,因為你之前對bug的理解可能產生偏差,又或者你第一步并沒有做好才導致了bug未能復現,這個時候帶著疑問去重現了解bug,可能你會發現新的大陸,
2.2.2 將偶現bug轉為必現bug
偶現bug算是bug家族中最調皮的一個了,它們以沒有規律,難以復現等特性,經常能把以一個好好的程式員給逼瘋,
但是既然是要復現bug,那么肯定要找到bug穩定復現的路徑,這樣才能方便下面bug的定位,這里我推薦大家的一個做法就是想辦法把偶現的bug轉化為必現的bug,因為即使是偶現的bug,很多也是特定條件下必現的bug,只不過此時你還沒發現這個特定條件而已,
那么怎樣才能將偶現bug轉為必現bug呢?這里我簡單介紹一下我常用的技巧:
-
1.
對比法:觀察并對比復現和不復現的各方面條件,找到那個必現的特定條件, -
2.
注釋(洗掉)代碼法:對懷疑的代碼進行注釋(洗掉),直到徹底將偶現bug轉變為必現bug,

2.3 定位bug
一旦我們找到了bug穩定復現的步驟之后,下面的作業就是開始定位bug產生的地方了,
這一步可以說是解決bug的關鍵環節,這一步驟的難易程度一般取決于以下幾個因素:
- 1.程式員自身的代碼量(作業經驗)
- 2.對專案代碼(業務)的熟悉程度,
- 3.分析問題和解決問題的能力
那么我們如何才能更快地定位出bug產生的位置呢?下面我提供一些思路供大家參考:
- 1.
斷點除錯法,這是程式員通用,同時也是最有效的定位問題的方式,一個不會斷點除錯的程式員和瞎子沒有本質上的區別, - 2.
日志分析法,其實并不是所有bug都可以進行斷點除錯的,比如在一些回圈呼叫或者業務較為復雜的場景下,打日志分析定位是較為適合的方式, - 3.
排除法,如果一個bug產生的原因可能有多種情況的時候,這個時候采取排除法的方式是最優的,你可以把可能導致bug產生的代碼塊都打上日志或者斷點,然后重現一下bug進行問題的定位, - 4.
代碼回滾法,如果你這個bug在之前的版本是好的,但是在現在版本上又出現了,這個時候就可以使用代碼回滾大法,把你的代碼回滾到你懷疑的版本,運行看bug是否消失,然后對兩個版本之前代碼有何區別,最終定位出bug產生的位置,這里我們可以使用二分法來提高代碼的回滾效率, - 5.
注釋(洗掉)代碼法,這個我在上一個步驟中也提到過,對于一些難以理解和定位的bug,我們可以使用這個方法進行嘗試,不過這個方法使用起來有一定的風險,因為可能你洗掉的那一串代碼雖然能夠解決bug,但是卻不是bug產生的根源,這個時候你可能會將必現bug改成了偶現bug,讓問題變得更加復雜, - 6.
原始碼分析法,有的時候有些bug可能并不是你的代碼導致的問題,可能是第三方庫本身的bug,又或者是系統本身的bug,又或者是你誤用api導致的問題,這個時候就需要你擁有原始碼分析的能力,深入原始碼中,一層層分析直到最終找到bug產生的原因, - 7.
聯想法,通過一些類似的bug修改經驗從而聯想猜測出bug產生的位置,這個方法對使用者本身有較高的要求,需要使用者對專案代碼和業務邏輯非常熟悉,同時對問題分析的能力有較高的要求,這就是我們常說的牛人能夠一眼就能看出問題,他們常用的就是這種方式, - 8.
場外支援法,這是實在定位不出bug才采取的下下策,因為它并不能提高你定位bug的能力,同時請別人幫忙定位bug,你就需要把你之前所做的作業都要全盤地向他表述一遍,這樣不僅會降低bug修復的效率,同時還不一定能保證定位出bug產生的位置,它取決于你表述問題的能力和幫你的人分析和解決問題的能力,

2.4 確認bug
在我們定位出bug產生的位置后,下面的作業就是分析bug產生的根源了,
這一步可以說是bug修復6個步驟中最為關鍵的一步,這一步直接決定了這個bug能否被徹底地解決,同時也是最能體現bug修復藝術的步驟,
但是很遺憾的是,這一步往往被很多人給忽視了,我為什么會這樣說呢?因為很多時候我們修復bug的時候,都會受到各方面的限制:
- 1.
自身經驗水平的限制:一些初入專案的程式員經常因為修復一個bug而導致了另一個bug,又或者只是看到了bug的表象卻不能感知到bug產生更深層次的原因,所以10種產生bug的情況他可能只改了一種,將必現問題改成了偶現問題,讓bug變得更加復雜, - 2.
時間限制:這是我們程式員經常碰到的限制,這在互聯網企業非常普遍,通常解決一個bug是有時間限制的,例如:這個專案明天就要上線了,并強制要求你今晚就得想辦法解決,這個時候你可能就被逼無奈,采取硬編碼的方式去臨時把這個bug給按住,其實這樣雖然bug是被臨時解決了,但是卻會讓這個bug變得愈加復雜,很多公司出現的那些祖傳代碼就是在這種情況下產生的,動一下就可能產生無數未知的bug,令人絕望, - 3.
業務限制:很多時候導致代碼邏輯非常復雜難懂的罪魁禍首就是這種業務限制,我們在修復一個bug的時候,很多時候就是因為這種業務的限制,導致bug的修復一種不能從根源上予以解決,只要業務一調整就可能導致這個bug反復地出現,
說了這么多限制,那么我們如何才能找到問題的根源呢?
- 1.
多積累經驗,提升自身的水平:這是打破自身經驗水平的限制, - 2.
及時處理bug:在收到bug報告的第一時間就去處理,盡可能打破時間的限制, - 3.
多熟悉業務:有時間就多去了解和梳理業務,深入研究專案代碼,這樣我們在解決bug的時候也不會因為對業務不熟悉而無法分析出bug產生的根源, - 4.
準確定位bug:bug定位的準確性直接決定了你能否分析出bug產生的根源,因此你需要仔細分析和定位bug,使用我上面介紹的8種方式去定位bug,

2.5 修復bug
其實前面的四步都是為這一步所做的鋪墊,有了前面四步的作業,相信到這兒也是相對微不足道的了,剩下的就是如何優美地解決這個bug了,
到了這個階段,bug通常不需要大的修改來修復,因此這一步往往會非常快,當然也就沒有什么好的技巧啦,
2.6 驗證bug
作為bug修復的最后一步,它是確保bug被真正修復的最后保障,
在這里需要我們著重注意以下幾點:
- 1.重復之前復現bug的步驟來驗證bug是否被徹底解決,
- 2.驗證bug修復可能改動到的相關模塊是否正常,保證bug修復不引入新的bug,
如果上述有任何一點沒有達到的話,請回傳步驟四和步驟五,重新修復bug!

3.如何提高bug修復的效率
上文我們著重講解了解決bug的藝術,為的是能夠更好地解決bug,但是如何才能保證既有效,又快速地修復bug,提高bug修復的效率呢?
通過上面對于解決bug的藝術的講解,我們可以總結出以下影響bug修復效率的幾個關鍵點:
- 1.bug資訊收集的效率以及有效性,
- 2.時間限制的壓力,
- 3.人員對專案代碼(業務)的熟悉程度,
- 4.人員自身經驗和分析問題的能力,
以上4點可以說直接決定了bug修復的效率,那么如何才能提高bug修復的效率呢?下面我將一一給出我的看法,

3.1 建立健全的資訊收集機制
bug資訊的收集可以說是修復bug程序中最為耗時的環節,提升bug資訊收集的效率以及有效性可以大幅度地提升我們修復bug的效率,
那么我們應該如何建立健全的資訊收集機制呢?這里我給出我的幾點建議:
3.1.1 提供優秀的bug報告模板
上文我們在了解bug一步中提到過:一份優秀的bug報告模板,可以讓程式員直接跳過bug修復的前三步,直接進入到確認bug步驟,從而能夠極大地提高bug修復的效率,
這里我再次重復一步,一份優秀的bug報告模板應當具備哪些內容:
- bug的標題和問題描述
- 出現bug的應用版本
- 出現bug的設備資訊(型號、版本等)
- bug產生相關的視頻、截圖和錯誤日志
- bug復現的步驟
- bug出現的必要條件(環境)和恢復途徑
- bug修復后的預期效果
- bug對應的模塊或者關聯bug
3.1.2 建立完備的日志體系
一套完備的日志體系,可以讓我們更加清晰地知道用戶到底做了什么才導致bug的出現,
在專案的初期,我們可能為了趕工期而常常忽視了日志列印的重要性,這很可能就會導致該專案日后的維護將非常得艱難,
那么我們為什么要建立一套完備的日志體系呢?
- 1.并不是所有的用戶(測驗)都能夠給你描述清楚bug產生的資訊,
- 2.即使用戶(測驗)給你描述了bug產生相關的資訊,但是他們并不理解你的代碼邏輯,他們只能根據bug出現的現象告訴你問題,可能他們的表述和你的理解不在一個頻道,
如果你有這么一套完備的日志體系,那么你就可以在用戶(測驗)不用開口的情況下,直接get到用戶的操作行為以及對于的代碼邏輯,同時,可能一句關鍵點的報錯日志就可以幫你直接定位到bug產生的位置,從而直接進入第四步確認bug,
說了這么多,我們應該如何列印高效的日志呢?
- 1.在例外分支回傳前列印日志,
- 2.在復雜業務流程的關鍵點列印日志,
- 3.在對外互動或者模塊互動點列印日志,
- 4.在用戶互動或者生命周期的關鍵點列印日志,
- 5.對重要的資訊點列印日志,記錄用戶畫像,
- 6.按重要性分等級列印日志,
- 7.禁止在回圈中列印日志,禁止列印無效的日志,
- 8.禁止列印用戶隱私相關的資訊,
3.2 建立自動化測驗機制
建立自動化測驗機制,可以讓突破
時間限制成為可能,
3.2.1 更早地發現bug
很多時候來自時間限制的壓力,往往是測驗不充分導致的,很多bug直到產品臨近上線或者交付的時候才被發現,這個時候唯一解決問題的方式就是在時間上做出限制,無情壓迫我們這些活在公司權力最底層的程式員們,
如果這個時候能有一套自動化測驗機制,每天下班后都進行自動測驗的話,那樣很多bug就能被提前發現,從而為我們修復bug預留了不少寶貴的時間,
3.2.2 節約bug驗證的時間
對于一些復雜難解、偶現的bug,我們往往會在確認bug到驗證bug之間花費大量的時間,這個時候如果有一套自動化測驗機制或者工具幫助我們驗證bug的話,就可以極大地縮減我們修復bug的時間,

3.3 提高專案代碼(業務)的熟悉程度
提高人員對專案代碼(業務)的熟悉程度,這樣就可以極大地提高人員
定位bug的效率,
3.3.1 建立豐富的知識庫體系
建立一套豐富的知識庫體系,可以幫助我們加深對自己責任內專案代碼(業務)的理解,同時還能幫助我們快速了解我們所不了解的業務模塊,
那么如何才能建立起豐富的知識庫體系呢?下面我給出我的幾點建議:
- 1.對知識進行分類,
- 2.定期添加和更新知識庫的內容,
- 3.提高知識庫的檢索效率,
- 4.定期組織知識的分享,
- 5.激勵貢獻知識庫的人員,
3.3.2 建立責任田劃分機制
劃分責任田的目的就是:讓專業的人做專業的事情,
劃分責任田的好處:
- 1.專業的人做專業的事情,劃分完責任田后,田主需要對自己負責的模塊負責,這就必然要求其對模塊內的代碼(業務)更加熟悉,
- 2.責任到人利于追責和bug跟蹤,
當然責任田也不是想象中的那么完美,它也存在一定的缺陷:
- 1.職責明確之后可能導致缺少全域視野,一些復雜的bug可能是幾個模塊共同作用下才產生的,對于這類bug的定位勢必會大大增加難度,
- 2.劃分責任田之后,可能導致踢皮球的情況,
責任田劃分機制,它是一把雙刃劍,所以是否需要建立責任田劃分機制,還是需要結合企業自身的情況而定的,
3.4 提高人員的綜合素質
提高人員的綜合素質,可以幫助我們提高
定位bug、確認bug以及修復bug三個步驟下的效率,
- 1.
建立公平的員工晉升制度,這樣可以充分調動人員的主動性的積極性,提升人員的個人素質和業務能力, - 2.
建立崗位輪換制度,讓人員定期負責不同的模塊,可以極大地提升人員的綜合素質和全域視野, - 3.
定期組織培訓學習,
4.最后
以上內容,是我參與作業五年,開源六年以來所總結下來的全部經驗,喜歡的可以點擊收藏或者三連支持一下!最后,還是祝福大家從此代碼無bug,哈哈哈!!!
5.微信公眾號
更多資訊內容,歡迎搜索我的微信公眾號:【我的Android開源之旅】
CSDN認證博客專家
Java
Android
架構設計
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241976.html
標籤:其他
上一篇:我與CSDN的2020
