? ? ? ? 在入職公司以來羔砾,大部分時間都是在維護手Q小程序模塊相關(guān)的代碼裕便,包含日常的新需求開發(fā)和bug修復(fù)工作鸣哀,這里會不可避免的涉及對別人代碼的評審和被人對自己提交的代碼的評審镣屹,為了提高自身代碼的質(zhì)量答憔,也同時減少別人MR自己代碼時可能會反復(fù)提及的一些代碼缺陷評審建議项栏,結(jié)合自身的實際情況,匯總了入職以來別人對我提交的代碼有效代碼評審建議嫂用,感謝對我提出有效代碼評審的同學(xué)型凳,也希望自己的代碼質(zhì)量可以不斷提升,后續(xù)會持續(xù)更新最新的My CheckList(嚴格來說應(yīng)該是自己代碼缺陷list才對)嘱函。
日志類相關(guān):
1甘畅、打印日志時,考慮是否會觸發(fā)高頻日志問題。
2疏唾、有些必須的日志蓄氧,又容易觸發(fā)高頻日志,可以考慮使用染色日志或者對日志做限頻處理荸实。
3、在一些關(guān)鍵代碼實現(xiàn)邏輯缴淋,例如:某個變量突然為null了准给,返回的int值為-1等情況,要記得添加日志重抖,方便后續(xù)定位問題露氮。
4、??注意去除高頻日志時钟沛,別去除關(guān)鍵性的日志畔规,要了解日志前后邏輯,是否可以去除恨统。
5叁扫、??衛(wèi)語句記得需要添加E級別錯誤日志信息,方便函數(shù)觸發(fā)時畜埋,定位問題莫绣。
6、??try?catch觸發(fā)異常時悠鞍,記得添加E級別錯誤日志信息对室,并把exception錯誤帶到日志中。
7咖祭、??try?catch模塊應(yīng)該盡量范圍小一點掩宜,且必須添加異常日志信息。
空指針類型相關(guān):
1么翰、變量通過引用賦值進函數(shù)后牺汤,再對外部變量做修改時,賦值進去的變量不會改變浩嫌。
2慧瘤、在一些對象的使用時,注意要先做判空判斷固该,例如:if(null?!=?bundle)锅减、if(null?!=?dialog?&&?!dialog.isShow())、if(null?!=?activity?&&?!activity.finish())伐坏,
判斷一下activity的合法性和有效性怔匣,是否finish等。
3、在使用單例類時每瞒,如果單例類里面包含界面控件相關(guān)變量或者Acitivity變量時金闽,要注意使用弱引用,避免內(nèi)存泄露問題剿骨。
4代芜、處理一些空指針異常時,也要考慮異常時浓利,為空的兜底處理邏輯挤庇。
9、??使用靜態(tài)內(nèi)部類+弱引用避免內(nèi)存泄露時贷掖,注意內(nèi)部獲取弱引用對象時嫡秕,做判空處理。
10苹威、調(diào)用接口獲取數(shù)組對象時昆咽,如果不確定是否會返回空值,需要做判空和數(shù)組是否為空操作牙甫。
11掷酗、在各個類型轉(zhuǎn)換的地方,函數(shù)前可以添加衛(wèi)語句窟哺,判斷對象是否為空汇在,以及是否為該轉(zhuǎn)換的類型。
12脏答、對回調(diào)函數(shù)返回的數(shù)組index獲取數(shù)組數(shù)據(jù)時糕殉,需要判斷數(shù)組是否為null與空,也需要判斷index是否在數(shù)組的大小范圍內(nèi)(大于等于0殖告、小于等于size?-1)
內(nèi)存泄露與內(nèi)存溢出相關(guān):
1阿蝶、所有的add、register等事件黄绩,都要記得添加對應(yīng)remove羡洁、unregister事件。
2爽丹、在創(chuàng)建圖片筑煮、大數(shù)據(jù)流等相關(guān)大對象時,需要做try{}catch防護粤蝎,防止觸發(fā)OOM真仲。
生命周期釋放相關(guān):
1、重新啟動小程序時初澎,注意數(shù)據(jù)的清除秸应,websocket斷開等操作。
2、小程序的插件(plugin)都有生命周期软啼,銷毀時桑谍,記得做清除、remove祸挪、反注冊等操作锣披。
多線程安全問題相關(guān):
1、注意在創(chuàng)建單例類時贿条,可以直接實現(xiàn)靜態(tài)內(nèi)部類的方式雹仿,滿足延遲初始化和線程安全的情況,如果單例構(gòu)造函數(shù)有參數(shù)闪唆,則直接用雙重所方式實現(xiàn)盅粪。
2钓葫、??做類似ThreadManager.getUIHandler().post()操作時悄蕾,可能會觸發(fā)線程切換操作時,注意添加空指針保護础浮。
3帆调、??注意異步回調(diào)的二次判空邏輯。
4豆同、??根據(jù)原子性番刊、可見性、有效性影锈,了解concurrentHashMap與
Collections.synchronizedList芹务、CopyOnWriteArrayList的區(qū)別,多線程遍歷集合時鸭廷,其他線程執(zhí)行修改操作枣抱,Collections.synchronized為什么會有concurrentmodificationexception異常。
5辆床、??concurrentHashMap的key和value不能為null佳晶,否則多線程操作時有二義性。
5.1讼载、迭代器不同:Collections.synchronizedMap?中的迭代器是同步的轿秧,即在迭代期間其他線程不能修改?Map?中的內(nèi)容,而?ConcurrentHashMap?中的迭代器是弱一致性的咨堤,即在迭代期間其他線程可以修改?Map?中的內(nèi)容菇篡,但是不保證迭代器能夠訪問到最新的修改。
5.2一喘、空值不同:ConcurrentHashMap?不允許存儲空值逸贾,而?Collections.synchronizedMap?可以存儲空值。
6、如果不確定函數(shù)是否在主線程運行铝侵,又需要保證函數(shù)在主線程運行灼伤,可以通過
???if?(Looper.getMainLooper()?==?Looper.myLooper())?{?
????????}?else?{
????????????ThreadManagerV2.getUIHandlerV2().post?{
?????????????????????}}
7、??各個回調(diào)函數(shù)返回時咪鲜,如果對回調(diào)函數(shù)的處理需要在主線程狐赡,也需要判斷返回的回調(diào)函數(shù)是否執(zhí)行在主線程。
8疟丙、??通過弱引用修復(fù)內(nèi)存泄露時颖侄,所有使用該弱引用的對象,都需要做判空處理享郊,例子:if(null?!=?mActivity?&&?null?!=?mActivity.get())览祖。
9、??Toast也需要在主線程觸發(fā)執(zhí)行炊琉。
性能相關(guān):
1展蒂、注意性能問題,盡量減少函數(shù)邏輯的重復(fù)執(zhí)行次數(shù)苔咪,如果需要外部變量做數(shù)據(jù)存儲锰悼,寧愿多創(chuàng)建存儲對象,也不要重復(fù)執(zhí)行函數(shù)邏輯团赏,案例:拖動小程序時箕般,部分函數(shù)會重復(fù)執(zhí)行,會觸發(fā)一些不必要操作重復(fù)執(zhí)行(空間換時間的概念)
主題適配與國際化適配相關(guān):
1舔清、??對控件和界面的背景或顏色修改丝里,要時刻考慮適配QUI。
2体谒、??使用token時杯聚,設(shè)置背景色時,只能使用background="drawable/qui_..bg"营密,不能使用color="color/qui_....."
3械媒、??字符串都放到xml,否則后續(xù)無法做國際化评汰。
其他綜合相關(guān):
1纷捞、面對實現(xiàn)復(fù)雜的函數(shù),建議把各個功能抽離出來被去。
2主儡、實現(xiàn)功能或修復(fù)bug時,修改的邏輯范圍要盡量在最小的范圍內(nèi)惨缆,不然容易導(dǎo)致修復(fù)一個問題糜值,導(dǎo)致另外新的問題出現(xiàn)丰捷,sdk代碼尤其需要注意一些公共代碼部分,調(diào)用鏈路會很多寂汇。
3病往、去除無用的成員變量。
4骄瓣、常量不應(yīng)該放到抽象類中停巷,應(yīng)該放在抽象類的實現(xiàn)類里。
5榕栏、使用SystemClock.uptimeMillis()替代System.currentTimeMillis()畔勤,避免用戶調(diào)整系統(tǒng)事件導(dǎo)致的異常。
6扒磁、小程序中使用到plugin插件接口時庆揪,對需要外發(fā)的異常信息常量,需要和前端同學(xué)同步異常信息數(shù)據(jù)妨托,并同步到線上文檔中缸榛。
7、??Activity做類型轉(zhuǎn)換時始鱼,有可能部分Activity基類不是BaseActivity仔掸,導(dǎo)致異常脆贵,可衍生到fragment等其他類医清。
8、??Long.valueOf?與?Long.parseLong轉(zhuǎn)換問題比較卖氨,原理:在字符串轉(zhuǎn)換為long類型的數(shù)據(jù)時会烙,如果只需要轉(zhuǎn)換為基礎(chǔ)類型,用Long.parseLong性能較好筒捺,如果需要獲得Long對象柏腻,并且數(shù)值在-128到127之間,Long.valueOf性能比較好系吭。
9五嫂、??調(diào)用時序?qū)е碌臐撛赽ug問題。
10肯尺、小程序插件發(fā)生異常時沃缘,需要執(zhí)行failed相關(guān)函數(shù),觸發(fā)通知前端頁面相關(guān)異常消息则吟,方便前端定位異常原因槐臀。
11、??小程序proxy要延遲初始化氓仲,并做判空處理水慨。
12得糜、??在清除舊代碼前,注意要判斷是否保留try{?}catch晰洒。
13朝抖、??在修改函數(shù)代碼時,注意這種有關(guān)聯(lián)的函數(shù)前后關(guān)系:player.pause()谍珊,player.isPlaying();
14槽棍、??避免頁面穿透問題,觸發(fā)不同層級控件響應(yīng)抬驴,可以直接把當前最頂布局的根布局設(shè)置點擊或觸摸事件炼七。
15、??各個回調(diào)函數(shù)返回的對象或者數(shù)組布持,也要通過衛(wèi)語句豌拙,判斷相關(guān)對象或者數(shù)組是否可用,再執(zhí)行正常操作题暖。
16按傅、判斷兩個數(shù)組數(shù)據(jù)是否相同,需要通過:if?(handlerItem.getFilter().size()?==?handlerFilterSize?&&?handlerItem.getFilter().containsAll(handler.getFilter())?&&?handler.getFilter().containsAll(handlerItem.getFilter()))
歡迎大家留言補充自己的checklist的鏈接胧卤、文檔等唯绍,愿世界再無BUG哈。