一、背景
場景如下:
應(yīng)用新增了一個功能冕茅,升級了版本伤极,客戶端靜默升級后蛹找,從桌面打開應(yīng)用竟然出現(xiàn)了直接閃退、奔潰的現(xiàn)象哨坪!
測試:不能忍庸疾,無論如何,這是不允許存在的現(xiàn)象当编,怎么可以出現(xiàn)如此嚴重的bug届慈!
服務(wù)端開發(fā):這是由于新增的數(shù)據(jù)字段,沒有被賦予正確格式的原因?qū)е路尥担瑴y試只要在服務(wù)端推送數(shù)據(jù)時修改為正確的格式即可解決金顿。
測試:服務(wù)端并沒有約定說一定要填入那種格式的數(shù)據(jù),我填入“非法數(shù)據(jù)”時鲤桥,并沒有被拒絕揍拆。我不管你們是怎么實現(xiàn)的,總之茶凳,不應(yīng)該在引入新功能的時候發(fā)生如此嚴重的必現(xiàn)bug嫂拴。
服務(wù)端開發(fā):那在客戶端那邊加個try catch,規(guī)避這種crash的嚴重問題贮喧。
客戶端開發(fā):客戶端不像服務(wù)端筒狠,不是所有的問題都是用try catch來解決就可以了,加try catch嚴重影響了效率問題箱沦。就不能在服務(wù)端那邊控制一下辩恼,只傳特定格式的數(shù)據(jù)嗎?
二谓形、分析
服務(wù)端發(fā)送給客戶端的數(shù)據(jù)灶伊,由于不是指定格式的數(shù)據(jù),導(dǎo)致客戶端解析時出現(xiàn)問題套耕,導(dǎo)致應(yīng)用奔潰谁帕。
測試認為服務(wù)端傳入的數(shù)據(jù)應(yīng)該可以是任意的,而客戶端必須要有容錯機制冯袍,一定不能出現(xiàn)這種嚴重的crash問題匈挖。
而服務(wù)端為什么不控制一下,數(shù)據(jù)只能設(shè)置為指定格式數(shù)據(jù)康愤,否則彈出非法數(shù)據(jù)警告提示呢儡循?對服務(wù)端理解尚淺,不理解其中的原理征冷,暫且就認為這是有一定道理的吧择膝。
那么,我們就來探討一下检激,如何從客戶端出發(fā)肴捉,添加數(shù)據(jù)的容錯機制吧腹侣。
前面開發(fā)建議,添加try catch齿穗,若接收到的數(shù)據(jù)為非法數(shù)據(jù)傲隶,則返回默認值。的確窃页,這是解決問題的一種方案跺株,至少,它能確保脖卖,不會因為數(shù)據(jù)格式問題導(dǎo)致crash的不能忍問題乒省。
然而,try catch卻要付出時間的代價畦木。若代碼中大量使用try catch來解決問題袖扛,一是代碼不夠簡潔,二是若數(shù)據(jù)格式確實是非法的馋劈,則增加時間消耗攻锰。
為什么不考慮在做數(shù)據(jù)格式轉(zhuǎn)換之前晾嘶,先做一個數(shù)據(jù)格式檢查妓雾,若為指定格式才對數(shù)據(jù)進行轉(zhuǎn)換呢?這樣一來垒迂,至少在代碼簡潔度上是更加有保障的械姻。
為了對比以上兩種方法的效率問題,我們用數(shù)據(jù)說話机断!
三楷拳、論證
1. 目的:
對比try catch機制與先檢查格式再轉(zhuǎn)換的執(zhí)行效率
2. 準備:
A. 利用junit單元測試來測試代碼塊的執(zhí)行時間,由于代碼的執(zhí)行都是閃速的吏奸,而junit測試也包含了一些初始化的準備時間欢揖,為了更加精確地統(tǒng)計代碼的執(zhí)行時間,采用循環(huán)100次取平均值及納秒級別的時間差來做測試奋蔚。
B. 從所在項目的情況來看她混,最主要問題存在于轉(zhuǎn)化為long型時出錯上,下一步的案例均基于long型數(shù)據(jù)的轉(zhuǎn)化來設(shè)計泊碑,且基本上為項目中常用到的一些情況進行對比坤按。
3. 測試案例編寫:
A. 直接得到的非法字符串轉(zhuǎn)化為long型
B. 從SharedPrefrence中獲取字段非long型強制轉(zhuǎn)化為long型
C. 直接得到的純數(shù)字String轉(zhuǎn)化為long型
4. 結(jié)果對比:
將上步中的案例執(zhí)行多次,進行耗時對比馒过,為避免偶然性臭脓,進行了多次比較,以下隨機截取了5次執(zhí)行結(jié)果:從結(jié)果可以看出腹忽,雖然每次的執(zhí)行耗時都略有不同来累,但相同的是:不管是在正確格式情況下還是非法數(shù)據(jù)強制轉(zhuǎn)化砚作,tryCatch的耗時都比通過正則表達式先判斷數(shù)據(jù)格式再轉(zhuǎn)換,平均多耗時1ms左右(執(zhí)行100次的情況下)嘹锁,即執(zhí)行1次約多耗時0.01ms 偎巢。
四、結(jié)論
從第三部分的論證過程可以看出兼耀,先通過正則表達式判斷后再做數(shù)據(jù)處理稍微比tryCatch方式高效率压昼,雖然0.01ms是一個幾乎可以忽略不計的時間,但編碼是一種習(xí)慣瘤运、優(yōu)秀也是一種習(xí)慣窍霞,不只是簡單地用tryCatch來規(guī)避crash問題,而是找到問題的本質(zhì)拯坟,并擇優(yōu)采取更合適的方式解決問題但金,這樣不是更好嗎?同時郁季,盡可能避免tryCatch的使用冷溃,在一定程度上也能夠提高代碼的簡潔度。
五梦裂、代碼
文中涉及代碼鏈接:GitHub