本文總結(jié)一下學(xué)習(xí)和工作以來思考了一些排錯(cuò)的思路和避免錯(cuò)誤的思路積累在這里,希望對(duì)大家有幫助,也歡迎大家補(bǔ)充。
代碼排錯(cuò)和中醫(yī)理論很相似
發(fā)現(xiàn)寫代碼排查錯(cuò)誤可以學(xué)學(xué)傳統(tǒng)中醫(yī)的診斷方法:
傳統(tǒng)中醫(yī)診斷講究:“望聞問切”
望
望:指對(duì)病人的神色形態(tài)等進(jìn)行有目的的觀察,以測(cè)知病變。中醫(yī)大量實(shí)踐認(rèn)識(shí)到,病人的外在變現(xiàn)和內(nèi)部病變有相關(guān)性。
其實(shí)排除也是一樣,既然有Bug,那么表現(xiàn)多半是異常的,我們先觀察這種表現(xiàn)。
聞、問
聞:包括聽聲音和聞氣味。
問:了解過往的病史,了解病因,發(fā)病的經(jīng)過和治療過程。
這有點(diǎn)類似于復(fù)現(xiàn)Bug,了解觸發(fā)Bug的時(shí)機(jī)和過程。了解哪個(gè)步驟,哪個(gè)接口出了問題。
切
切:指摸脈象來推測(cè)疾病。
類似于通過抓請(qǐng)求響應(yīng)(瀏覽器f12或者抓包工具)根據(jù)請(qǐng)求參數(shù)和響應(yīng)碼判斷問題出在前端還是后端。
通過錯(cuò)誤日志等提供的信息綜合分析。
中醫(yī)是靠經(jīng)驗(yàn)的
老中醫(yī)厲害是因?yàn)橐姸嘧R(shí)廣,見到的病例多,趟過的坑多,這點(diǎn)和程序員很相似。
很多醫(yī)生根據(jù)病狀,就大概知道可能得原因。
優(yōu)秀的經(jīng)驗(yàn)豐富的程序員,遇到一些錯(cuò)誤的表現(xiàn),就大概知道問題出現(xiàn)在哪里。
因?yàn)樗麄冇龅竭^類似的情況,思考過類似的情況,看過別人的案例等。
提供幾個(gè)常用的排錯(cuò)方法
F12看請(qǐng)求和響應(yīng)
請(qǐng)求參數(shù)是否正確,響應(yīng)碼是啥,用來鎖定是前端還是后端錯(cuò)誤。
比如404,基本斷定前端請(qǐng)求地址寫錯(cuò)了,比如500,多半是后端代碼錯(cuò)誤。
很多人只看表現(xiàn),看前端報(bào)錯(cuò)了就認(rèn)為是前端的問題,看控制臺(tái)有報(bào)錯(cuò)就認(rèn)為肯定是后端的錯(cuò)誤。
注意要分析!不要猜測(cè)。看F12的NetWork選項(xiàng),分析參數(shù)的內(nèi)容和格式是否符合預(yù)期等。
看錯(cuò)誤或者請(qǐng)求日志
很多Bug可能是后端的邏輯錯(cuò)誤和一些其他細(xì)節(jié)錯(cuò)誤。
如果報(bào)錯(cuò),直接看報(bào)錯(cuò)的信息,一般會(huì)有非常明確的原因。比如空指針、參數(shù)錯(cuò)誤等。
盡量自己先去分析,而不是直接復(fù)制到百度或者谷歌上找方案一個(gè)一個(gè)試,否則就算解決了問題,印象不深刻,不知其所以然。
如果沒有報(bào)錯(cuò),可以查看從控制層到數(shù)據(jù)訪問層的調(diào)用日志的輸出和輸出等判斷哪一次調(diào)用出了問題。
比如服務(wù)層調(diào)用數(shù)據(jù)訪問層時(shí)參數(shù)少傳了一個(gè),比如查詢的數(shù)據(jù)封裝VO時(shí)少了或者賦值錯(cuò)了字段等等。還有的是不是邏輯有問題?
本地或者測(cè)試服遠(yuǎn)程Debug
直接通過測(cè)試服遠(yuǎn)程Debug,可以單步跟蹤,很容易找到錯(cuò)誤的原因。Debug的時(shí)候可以利用條件斷點(diǎn)、Watch機(jī)制類輔助排錯(cuò)。
控制變量法
這個(gè)思想非常好用。如果是新開發(fā)的功能,通過刪除部分懷疑引入錯(cuò)誤的新增的代碼來排錯(cuò)。比如引入了3個(gè)二方Jar有沖突,可以去除某一個(gè)試試,好了就是這個(gè)Jar的問題。
注意好是拉取新的Git分支來操作,避免污染原有分支的代碼,搞出Bug。
換環(huán)境大法
換瀏覽器,代碼寫到自己的Demo項(xiàng)目中試試等。
官方文檔大法:如果是用法問題,配置問題,盡量查官方文檔,看看這一塊怎么用,是不是自己用錯(cuò)了。
Code Review法
重新對(duì)代碼進(jìn)行Code Review,查看邏輯是否正確,是否有線程安全問題,數(shù)據(jù)結(jié)構(gòu)是否合理,是否有忽略的情況等。
搜索引擎大法
不必多說,很多人都懂。
不過盡量用谷歌,Stack Overflow,而且盡可能用英文關(guān)鍵詞來搜。
但是相對(duì)于學(xué)到的知識(shí),解決的問題其實(shí)很值。現(xiàn)在人吃一頓飯都得十幾塊錢,買個(gè)工具不舍得。
交流請(qǐng)教
實(shí)在自己解決不了,毫無思路,可以在群里請(qǐng)教或者和一些樂于分享和交流的人探討。因?yàn)橛行﹩栴}雖然不難,但是自己很難發(fā)現(xiàn)。還有一些問題別人經(jīng)歷過,一句話可能省去你半小時(shí)。請(qǐng)教別人之前,一定要把問題描述清楚。好能說說自己的想法,自己做了哪些嘗試和努力。而不是“借錢的是大爺”的態(tài)度,覺得被人就該幫你。或者描述不清,讓“大神”們猜測(cè)你遇到了什么問題。
另外盡量尋求思路,而不是具體的方案。
大多數(shù)為問題都可以通過F12大法、日志調(diào)試大法、搜索引擎大法解決。另外排錯(cuò)要靠邏輯,而不是靠猜測(cè),不是靠嘗試。否則浪費(fèi)時(shí)間,而且對(duì)知識(shí)掌握不深入,容易引發(fā)新的Bug等。
懷疑是某個(gè)原因,要去印證。比如有一個(gè)條件的數(shù)據(jù)查不到,或者懷疑代碼查詢出的條數(shù)不對(duì),拿前端的條件直接用SQL查試試。注意細(xì)節(jié),是不是標(biāo)記刪除?是不是漏了某個(gè)條件等等。
不要猜測(cè)是某個(gè)原因就動(dòng)手改,而是通過已有的代碼和數(shù)據(jù)推斷可能性,可能性很大再去試。如果有其他好的方法歡迎補(bǔ)充。
如何避免Bug
以上的都是排錯(cuò)的方法,要保證質(zhì)量應(yīng)該在編碼階段。
1、 要考慮充分再編碼,避免返工,避免邏輯錯(cuò)誤。
要充分進(jìn)行參數(shù)校驗(yàn),考慮各種可能出現(xiàn)的情況;
2、 要進(jìn)行充分的單元測(cè)試。
對(duì)于DAO層必須全部覆蓋。對(duì)于上層代碼可以采用Mock測(cè)試來驗(yàn)證邏輯,驗(yàn)證程序的健壯性,這里超級(jí)推薦Mockito。
3、要養(yǎng)成良好的編碼風(fēng)格
參考《阿里巴巴Java開發(fā)規(guī)范》《重構(gòu)》《編寫可維護(hù)代碼的藝術(shù)》。
舉個(gè)例子,一個(gè)函數(shù)好幾百行,報(bào)了錯(cuò)誤,如果很久之前的代碼,而且邏輯不夠清晰,還得看半天。如果一個(gè)函數(shù)代碼行數(shù)比較短,每個(gè)清晰的子步驟都封裝到了子函數(shù)或者工具類中,那么排錯(cuò)起來就非常容易了。
4、開發(fā)過程中或自測(cè)前自我Code Review
在IDEA里,合并新Master之后,和Master分支比對(duì)代碼。
看看有沒有邏輯錯(cuò)誤,有沒有手誤,有沒有可以改進(jìn)的地方。
5、充分自測(cè)
除了上面的單元測(cè)試外,有時(shí)間要充分自測(cè)。功能的測(cè)試也要簡單過一遍,嘗試一些詭異的操作,看看是否有問題。
6、分享兩個(gè)神器
編程過程中,對(duì)某個(gè)類的用法不熟悉,可以看看知名開源項(xiàng)目都怎么寫。
Codota
插件地址:https://plugins.jetbrains.com/plugin/7638-codota-
官網(wǎng):https://www.codota.com/
使用快捷鍵可以搜索知名開源項(xiàng)目中該類或者方法的使用案例,超贊。
https://www.programcreek.com/java-api-examples/index.php?action=search
可以根據(jù)類名和方法等搜索代碼案例
7、開發(fā)過程中遇到不熟悉的類或方法,建議直接進(jìn)源碼、看注釋
建議在IDEA里進(jìn)入源碼,如果有條件可以去GitHub拉源碼,然后看想了解的類或者方法的配套單元測(cè)試。就很容易知道怎么用,甚至可以運(yùn)行起來看看效果,甚至可以打斷點(diǎn)單步跟。
8、平時(shí)要加強(qiáng)學(xué)習(xí),主動(dòng)學(xué)習(xí)
平時(shí)加強(qiáng)學(xué)習(xí),遇到問題知識(shí)儲(chǔ)備充足才容易快速解決問題。
主要看專業(yè)圖書,比較經(jīng)典的技術(shù)圖書,看一些核心技術(shù)棧的源碼。
另外一個(gè)有趣的現(xiàn)象,很多人用了Spring很久,連Spring的官方文檔都沒仔細(xì)看過一遍,MyBatis依然。
只是看過一些入門視頻,能用罷了,自己并沒有系統(tǒng)看過文檔,了解過原理讀過源碼。
還有很多人總是以忙為借口不去主動(dòng)學(xué)習(xí)。
有其他好的方法歡迎補(bǔ)充。