一轉(zhuǎn)眼刽沾,半年過去了,半年前排拷,還是一個(gè)連http請(qǐng)求侧漓,handler怎么用都不太會(huì)的標(biāo)準(zhǔn)菜鳥(當(dāng)然,現(xiàn)在也是菜鳥)监氢。
才來公司的時(shí)候布蔗,老大交給我一個(gè)老項(xiàng)目讓我改bug。那一改就是3個(gè)月浪腐,三個(gè)月的時(shí)間纵揍,邊開發(fā)新功能,變修復(fù)原有bug议街。說實(shí)話泽谨,一來就是一個(gè)class有上千行代碼,一個(gè)包幾十個(gè)類的項(xiàng)目特漩,看著都頭疼吧雹。連出現(xiàn)bug的位置都要找半天。具體哪些bug涂身,已經(jīng)不太記得了雄卷,只是把一些經(jīng)驗(yàn)性的東西,總結(jié)出來分享蛤售。
改bug的幾個(gè)階段(場(chǎng)景)丁鹉,我來聊聊吧(也是自己改bug的階段陕凹,每個(gè)階段改的方式,方向可能都有 不同):
第一個(gè)階段:最基礎(chǔ)的階段鳄炉,看日志。這種搜骡,就是那種錯(cuò)誤明顯的拂盯,直接點(diǎn)日志,跳到對(duì)應(yīng)位置那種记靡。比如空指針谈竿,改的方法就是看哪個(gè)值為空了,再看看這個(gè)類摸吠,什么時(shí)候賦值了呀什么的空凸。修改難度,應(yīng)該算最小的寸痢。
第二個(gè)階段(場(chǎng)景):也有日志呀洲,但是,你點(diǎn)擊日志跳到對(duì)應(yīng)位置啼止,發(fā)現(xiàn)(臥槽道逗,這代碼不是我寫的,是Android自己寫的)献烦,然后滓窍,就糾結(jié),這tm什么問題呀巩那,都不是我寫的吏夯,怎么搞呀。經(jīng)過一番思來想去之后即横,決定噪生,百度一下吧,把這段錯(cuò)誤信息放到網(wǎng)上一查东囚,誒杠园,有結(jié)果了。然后按照網(wǎng)上說的那樣舔庶,改改改抛蚁,行了。
第三個(gè)階段(場(chǎng)景):還是有日志惕橙,但是瞧甩,沒有可以點(diǎn)擊的日志,全是一啪啦英文弥鹦,靠肚逸,這什么鬼爷辙,完全沒思路呀。然后朦促,又是糾結(jié)膝晾,沉思,最后實(shí)在沒辦法了务冕,讀日志吧血当,一句句讀,最后終于讀懂什么意思了禀忆,然后臊旭,又把錯(cuò)誤內(nèi)容加上自己的理解百度一下,再不行就在it群里面問箩退,最后离熏,也解決了。
第四個(gè)階段(場(chǎng)景):我×戴涝,沒有報(bào)錯(cuò)滋戳,沒有蹦,沒有日志啥刻,這tm怎么就跟我想的不一樣呀胧瓜。這個(gè)時(shí)候,只能去讀代碼了郑什,看自己這個(gè)模塊的代碼是哪些府喳,哪一步是應(yīng)該顯示我那個(gè)正確結(jié)果的,然后蘑拯,一步一步往上推钝满,看數(shù)據(jù)從哪里來,走了哪些步奏申窘,看view哪里創(chuàng)建弯蚜,又在哪里顯示。然后打斷點(diǎn)剃法,單步調(diào)試碎捺,最后發(fā)現(xiàn),原來是這一步?jīng)]有傳值(或者取值錯(cuò)了什么的)贷洲。
第五個(gè)階段(場(chǎng)景):這類場(chǎng)景比較復(fù)雜了收厨,這類場(chǎng)景就是,我一個(gè)類很大(幾千行代碼那種)优构,然后诵叁,引用了10幾個(gè)類(可能更多)。在這個(gè)類里面某句話出了問題钦椭,或是怎么樣拧额。這種情況千萬不要碑诉,一上去,就改侥锦,因?yàn)榻裕苡锌赡埽ǚ凑沂前俜种伲?huì)這個(gè)bug改了恭垦,又出現(xiàn)新的bug了快毛。這種情況最正確的做法是,先把這部分內(nèi)容讀懂署照,弄明白是干什么的,最好是能重構(gòu)一下吗浩。讓整體結(jié)構(gòu)和思路變清晰建芙,然后,再去找問題的根源懂扼。
第六個(gè)階段(我現(xiàn)在的階段):基本問題禁荸,秒改,復(fù)雜問題阀湿,先重構(gòu)再改赶熟。
ok,最后總結(jié)一些經(jīng)驗(yàn)性的話吧陷嘴,遇到問題的幾個(gè)處理步奏:1找現(xiàn)場(chǎng)映砖,還原現(xiàn)場(chǎng)。2向上溯源灾挨,向下延伸邑退。3累積
第一點(diǎn):找現(xiàn)場(chǎng),還原現(xiàn)場(chǎng)劳澄。說的是地技。先找到這個(gè)問題,這個(gè)場(chǎng)景秒拔,出現(xiàn)的地方(包莫矗,類,代碼塊)砂缩,其實(shí)就和警察辦案一樣作谚,先到案發(fā)現(xiàn)場(chǎng)找線索,因?yàn)榘赴l(fā)之后一定會(huì)留下蛛絲馬跡庵芭。然后食磕,就是還原現(xiàn)場(chǎng),就是把這個(gè)問題復(fù)現(xiàn)喳挑,就想警察會(huì)還原案發(fā)現(xiàn)場(chǎng)一樣彬伦,幫助推理滔悉,和理清線索。
第二點(diǎn):向上溯源单绑,向下延伸:找到現(xiàn)場(chǎng)之后回官,分析這個(gè)問題,數(shù)據(jù)源是哪里搂橙,傳來的數(shù)據(jù)是什么歉提,向下延伸,是指区转,考慮這個(gè)對(duì)象苔巨,對(duì)他后續(xù)的對(duì)象(比如誰引用了他)有什么影響。簡(jiǎn)單來說废离,就是侄泽。向上溯源,是為了解決當(dāng)前這個(gè)問題蜻韭,向下延伸悼尾,是規(guī)避制造新的bug。也可以換一種說法肖方,叫依賴闺魏。相信搞java的同學(xué)對(duì)這個(gè)詞理解應(yīng)該會(huì)很深。
第三點(diǎn):累積俯画,其實(shí)就是累積經(jīng)驗(yàn)析桥,我現(xiàn)在之所以能秒改一些問題,就是因?yàn)榧璐梗?jīng)一天要改10幾個(gè)bug烹骨,改了3個(gè)月。見都見了很多bug了材泄,看著就不陌生了沮焕,就好辦了。所以拉宗,遇到bug峦树,不要著急,改一個(gè)旦事,就進(jìn)步一點(diǎn)魁巩。
還有千萬不要以為改bug,不如寫項(xiàng)目姐浮。這么說吧谷遂,我改的bug,比我寫的項(xiàng)目還多(真是多虧了之前的哥們卖鲤,給我留了那么多bug肾扰,別讓我遇到畴嘶,遇到打死)。改著改著集晚,就發(fā)現(xiàn)窗悯,這樣寫容易產(chǎn)生bug,該怎樣怎樣寫偷拔,才能避免bug蒋院。比如一個(gè)eventbus,容易忘記反注冊(cè)莲绰。后來欺旧,就寫了一個(gè)生命周期框架,讓activity自己去管理蛤签,我不管了辞友。比如一些規(guī)則驗(yàn)證不寫容易出現(xiàn)奇葩bug,然后就寫了一個(gè)規(guī)則驗(yàn)證的api顷啼,用著很爽踏枣。也是多虧了之前累積的bug昌屉,這次我寫的項(xiàng)目钙蒙,大家都加班了,就我?guī)缀鯖]加班间驮,然后寫出來之后躬厌,基本上沒什么bug,測(cè)試也通過主流程竞帽,只是改一些小細(xì)節(jié)了扛施。所以才有這時(shí)間寫這篇文章。
最后分享一點(diǎn)屹篓,作為一個(gè)程序員(雖然我現(xiàn)在疙渣,已經(jīng)在漸漸負(fù)責(zé)框架,架構(gòu)方面的設(shè)計(jì))堆巧,編碼才是硬本事妄荔,寫出來的代碼bug越少,代碼越少谍肤,性能越高啦租,擴(kuò)展性越好才是能證明你的水平。別一來就是xx模式荒揣,xx架構(gòu)篷角,xx框架的。