1. 添加必要的注釋
其實,寫代碼的時候,沒有必要寫太多的注釋,因為好的方法名、變量名,就是最好的注釋。以下就是筆者總結的一些注釋規范:
所有的類都必須添加創建者和創建日期,以及簡單的注釋描述
方法內部的復雜業務邏輯或者算法,需要添加清楚的注釋
一般情況下,注釋描述類、方法、變量的作用
任何需要提醒的警告或TODO,也要注釋清楚
如果是注釋一行代碼的,就用//;如果注釋代碼塊或者接口方法的,有多行/* **/
一塊代碼邏輯如果你站在一個陌生人的角度去看,第一遍看不懂的話,就需要添加注釋了
以下就是一些添加注釋的demo:
/** *@author田螺 *@date2023/04/225:20PM *@desc田螺的實現類,撿田螺、賣田螺 */ publicclassTianLuoClass{ /** *這是賣田螺的兩法,它將兩個田螺的價格整數相加并返回結果。 * *@paramx第一個整數 *@paramy第二個整數 *@return兩個整數的和 */ publicintsellTianLuo(intx,inty){ returnx+y; } }
2.日志打印規范
日志是快速定位問題的好幫手,是撕逼和甩鍋的利器!打印好日志非常重要。如果代碼評審的時候,這些日志規范沒遵守,就需要修改:
日志級別選擇不對。常見的日志級別有error、warn、info、debug四種,不要反手就是info哈
日志沒打印出調用方法的入參和響應結果,尤其是跨系統調用的時候。
業務日志沒包含關鍵參數,如userId,bizSeq等等,不方便問題排查
一些不符合預期的情況,如一些未知異常(數據庫的數據異常等),又或者不符合業務預期的特殊場景,都需要打印相關的日志
3. 命名規范
Java代碼的命名應該清晰、簡潔和易于理解。我們代碼評審的時候,要注意是否有命名不規范,不清晰的代碼。下面是一些命名規范的建議:
類和接口應該使用首字母大寫的駝峰命名法
方法和變量應該使用小寫的駝峰命名法
常量應該使用全大寫字母和下劃線
開發者是不是選擇易于理解的名稱給變量、類和方法進行命名
4.參數校驗
我們代碼評審的時候,要注意參數是否都做了校驗,如userId非空檢查、金額范圍檢查、userName長度校驗等等。一般我們在處理業務邏輯的時候,要遵循先檢查、后處理的原則。
如果你的數據庫字段userName設置為varchar(16),對方傳了一個32位的字符串過來,你不校驗參數,插入數據庫直接異常了。
很多bug都是因為沒做參數校驗造成的,這一軍規,是代碼評審重點關注的哈:
5. 判空處理
獲取對象的屬性時,都要判空處理。要不然很多時候會出現空指針異常。
if(object!=null){ Stringname=object.getName(); }
如果你要遍歷列表,也需要判空
if(CollectionUtils.isNotEmpty(tianLuolist)){ for(TianLuotemp:tianLuolist){ //dosomething } }
6. 異常處理規范
良好的異常處理可以確保代碼的可靠性和可維護性。因此,異常處理也是代碼評審的一項重要規范。以下是一些異常處理的建議:
不要捕獲通用的Exception異常,而應該盡可能捕獲特定的異常
在捕獲異常時,應該記錄異常信息以便于調試
內部異常要確認最終的處理方式,避免未知異常當作失敗處理。
在finally塊中釋放資源,或者使用try-with-resource
不要使用e.printStackTrace(),而是使用log打印。
catch了異常,要打印出具體的exception,否則無法更好定位問題
捕獲異常與拋出異常必須是完全匹配,或者捕獲異常是拋異常的父類
捕獲到的異常,不能忽略它,要打印相對應的日志
注意異常對你的代碼層次結構的侵染(早發現早處理)
自定義封裝異常,不要丟棄原始異常的信息Throwable cause
注意異常匹配的順序,優先捕獲具體的異常
對外提供APi時,要提供對應的錯誤碼
系統內部應該拋出有業務含義的自定義異常,而不是直接拋出RuntimeException,或者直接拋出ExceptionThrowable。
7. 模塊化,可擴展性
代碼評審的時候,關注一下,代碼編寫設計是否滿足模塊話,接口是否具有可擴展性
比如你的需求是醬紫:是用戶添加或者修改員工時,需要刷臉。那你是反手提供一個員工管理的提交刷臉信息接口?還是先思考:提交刷臉是不是通用流程呢?比如轉賬或者一鍵貼現需要接入刷臉的話,你是否需要重新實現一個接口呢?還是當前按業務類型劃分模塊,復用這個接口就好,保留接口的可擴展性。
如果按模塊劃分的話,未來如果其他場景比如一鍵貼現接入刷臉的話,不用再搞一套新的接口,只需要新增枚舉,然后復用刷臉通過流程接口,實現一鍵貼現刷臉的差異化即可。
img
8. 并發控制規范
在使用并發集合時,應該注意它們的線程安全性和并發性能,如ConcurrentHashMap是線性安全的,HashMap就是非線性安全的
樂觀鎖,悲觀鎖防止數據庫并發.樂觀鎖一般用版本號version控制,悲觀鎖一般用select …for update
如果是單實例的多線程并發處理,一般通過Java鎖機制,比如sychronized ,reentrantlock
如果是同一集群的多線程并發處理,可以用Redis分布式鎖或者走zookeeper
如果是跨集群的多線程并發處理,則考慮數據庫實現的分布式鎖。
在使用分布式鎖的時候,要注意有哪些坑,比如redis一些經典的坑.
9. 單元測試規范
測試類的命名,一般以測試的類+Test,如:CalculatorTest.
測試方法的命名,一般以test開頭+ 測試的方法,如testAdd.
單測行覆蓋率一般要求大于75%.
單測一般要求包含主流程用例、參數邊界值等校驗用例
單測一般也要求包含中間件訪問超時、返回空、等異常的用例,比如訪問數據庫或者Redis異常.
單測用例要求包含并發、防重、冪等等用例.
10. 代碼格式規范
良好的代碼格式,可以使代碼更容易閱讀和理解。下面是一些常見的代碼格式化建議:
縮進使用四個空格
代碼塊使用花括號分隔
每行不超過80個字符
每個方法應該按照特定的順序排列,例如:類變量、實例變量、構造函數、公共方法、私有方法等。
11. 接口兼容性
代碼評審的時候,要重點關注是否考慮到了接口的兼容性.因為很多bug都是因為修改了對外舊接口,但是卻不做兼容導致的。關鍵這個問題多數是比較嚴重的,可能直接導致系統發版失敗的。新手程序員很容易犯這個錯誤哦~
所以,如果你的需求是在原來接口上修改,尤其這個接口是對外提供服務的話,一定要考慮接口兼容。舉個例子吧,比如dubbo接口,原本是只接收A,B參數,現在你加了一個參數C,就可以考慮這樣處理:
//老接口 voidoldService(A,B){ //兼容新接口,傳個null代替C newService(A,B,null); } //新接口,暫時不能刪掉老接口,需要做兼容。 voidnewService(A,B,C){ ... }
12. 程序邏輯是否清晰,主次是否夠分明
代碼評審的時候,要關注程序邏輯是否清晰。比如,你的一個注冊接口,有參數校驗、判斷用戶是否已經注冊、插入用戶記錄、發送注冊成功通知等功能。如果你把所有所有功能代碼塞到一個方法里面,程序邏輯就不清晰,主次不夠分明,反例如下:
publicResponseregisterUser(StringuserName,Stringpassword,Stringemail){ if(userName==null||StringUtils.isEmpty(userName)){ log.info("用戶名不能為空!"); thrownewBizException(); } if(password==null||password.length()6)?{ ????????????log.info("密碼長度不能少于6位!"); ????????????throw?new?BizException(); ????????} ????????if?(email?==?null?||?StringUtils.isEmpty(email)?||?!email.contains("@"))?{ ????????????log.info("郵箱格式不正確!"); ????????????throw?new?BizException(); ????????} ????????Response?response?=?new?Response(); ????????UserInfo?userInfo?=?userService.queryUserInfoByUsername(); ????????if?(Objects.nonNull(userInfo))?{ ????????????response.setCode(0); ????????????response.setMsg("注冊成功"); ????????????return?response; ????????} ????????UserInfo?addUserInfo?=?new?UserInfo(); ????????addUserInfo.setUserName(userName); ????????addUserInfo.setPassword(password); ????????addUserInfo.setEmail(email); ????????userService.addUserInfo(addUserInfo); ????????MessageDo?messageDo?=?new?MessageDo(); ????????messageDo.setUserName(userName); ????????messageDo.setEmail(email); ????????messageDo.setContent("注冊成功"); ????????messageService.sendMsg(messageDo); ????????response.setCode(0); ????????response.setMsg("注冊成功"); ????????return?response; ????}
其實,以上這塊代碼,主次不夠分明的點:參數校驗就占registerUser方法很大一部分。正例可以劃分主次,抽一下小函數,如下:
publicResponseregisterUser(StringuserName,Stringpassword,Stringemail){ //檢查參數 checkRegisterParam(userName,password,email); //檢查用戶是否已經存在 if(checkUserInfoExist(userName)){ Responseresponse=newResponse(); response.setCode(0); response.setMsg("注冊成功"); returnresponse; } //插入用戶 addUser(userName,password,email); sendMsgOfRegister(userName,email); //構造注冊成功報文 Responseresponse=newResponse(); response.setCode(0); response.setMsg("注冊成功"); returnresponse; } privatevoidsendMsgOfRegister(StringuserName,Stringemail){ MessageDomessageDo=newMessageDo(); messageDo.setUserName(userName); messageDo.setEmail(email); messageDo.setContent("注冊成功"); messageService.sendMsg(messageDo); } privatevoidaddUser(StringuserName,Stringpassword,Stringemail){ UserInfoaddUserInfo=newUserInfo(); addUserInfo.setUserName(userName); addUserInfo.setPassword(password); addUserInfo.setEmail(email); userService.addUserInfo(addUserInfo); } privatebooleancheckUserInfoExist(StringuserName){ UserInfouserInfo=userService.queryUserInfoByUsername(); if(Objects.nonNull(userInfo)){ returntrue; } returnfalse; } privatevoidcheckRegisterParam(StringuserName,Stringpassword,Stringemail){ if(userName==null||StringUtils.isEmpty(userName)){ log.info("用戶名不能為空!"); thrownewBizException(); } if(password==null||password.length()6)?{ ????????????log.info("密碼長度不能少于6位!"); ????????????throw?new?BizException(); ????????} ????????if?(email?==?null?||?StringUtils.isEmpty(email)?||?!email.contains("@"))?{ ????????????log.info("郵箱格式不正確!"); ????????????throw?new?BizException(); ????????}? ????}
13. 安全規范
代碼評審,也非常有必要評審代碼是否存在安全性問題。比如:
輸入校驗:應該始終對任何來自外部的輸入數據進行校驗,以確保它們符合預期并且不會對系統造成傷害。校驗應該包括檢查數據的類型、大小和格式。
防范SQL注入攻擊:在使用SQL查詢時,應該始終使用參數化查詢或預處理語句,以防止SQL注入攻擊。
防范跨站腳本攻擊(XSS): 在Web應用程序中,應該始終對輸入的HTML、JavaScript和CSS進行校驗,并轉義特殊字符,以防止XSS攻擊。
避免敏感信息泄露: 敏感信息(如密碼、密鑰、會話ID等)應該在傳輸和存儲時進行加密,以防止被未經授權的人訪問。同時,應該避免在日志、調試信息或錯誤消息中泄露敏感信息。
防范跨站請求偽造(CSRF): 應該為所有敏感操作(如更改密碼、刪除數據等)添加CSRF令牌,以防止未經授權的人員執行這些操作。
防范安全漏洞: 應該使用安全性高的算法和協議(如HTTPS、TLS)來保護敏感數據的傳輸和存儲,并定期對系統進行漏洞掃描和安全性審計。
14. 事務控制規范
一般推薦使用編程式事務,而不是一個注解 @Transactional的聲明式事務。因為 @Transactional有很多場景,可能導致事務不生效。
事務范圍要明確,數據庫操作必須在事務作用范圍內,如果是非數據庫操作,盡量不要包含在事務內。
不要在事務內進行遠程調用(可能導致數據不一致,比如本地成功了,但是遠程方法失敗了,這時候需要用分布式事務解決方案)
事務中避免處理太多數據,一些查詢相關的操作,盡量放到事務之外(避免大事務問題)
15. 冪等處理規范
什么是冪等?
計算機科學中,冪等表示一次和多次請求某一個資源應該具有同樣的副作用,或者說,多次請求所產生的影響與一次請求執行的影響效果相同。
代碼評審的時候,要關注接口是否考慮冪等。比如開戶接口,多次請求過來的時候,需要先查一下該客戶是否已經開過戶,如果已經開戶成功,直接返回開戶成功的報文。如果還沒開戶,就先開戶,再返回開戶成功的報文。這就是冪等處理。
一般情況有這幾種冪等處理方案:
select+insert+主鍵/唯一索引沖突
直接insert + 主鍵/唯一索引沖突
狀態機冪等
抽取防重表
token令牌
悲觀鎖
樂觀鎖
分布式鎖
冪等要求有個唯一標記,比如數據庫防重表的一個業務唯一鍵。同時強調多次請求和一次請求所產生影響是一樣的。
16. 中間件注意事項 (數據庫,redis)
代碼評審的時候,如果用數據庫、Redis、RocketMq等的中間件時,我們需要關注這些中間件的一些注意事項哈。
比如數據庫:
關注數據庫連接池參數設置、超時參數設置是否合理
避免循環調用數據庫操作
如果不分頁,查詢SQL時,如果條數不明確,是否加了limit限制限制
數據庫的返回是否判空處理
數據庫慢SQL是否有監控
表結構更新是否做兼容,存量表數據是否涉及兼容問題考慮
索引添加是否合理
是否連表過多等等
比如Redis:
Redis的key使用是否規范
Redis 異常捕獲以及處理邏輯是否合理
Redis連接池、超時參數設置是否合理
Redis 是否使用了有坑的那些命令,如hgetall、smember
是否可能會存在緩存穿透、緩存雪奔、緩存擊穿等問題。
17. 注意代碼壞味道問題
理解幾個常見的代碼壞味道,大家代碼評審的時候,需要關注一些哈:
大量重復代碼(抽公用方法,設計模式)
方法參數過多(可封裝成一個DTO對象)
方法過長(抽小函數)
判斷條件太多(優化if...else)
不處理沒用的代碼(沒用的import)
避免過度設計
18. 遠程調用
遠程調用是代碼評審重點關注的一欄,比如:
不要把超時當作失敗處理: 遠程調用可能會失敗,比如網絡中斷、超時等等。開發者需要注意遠程調用返回的錯誤碼,除非是明確的失敗,如果僅僅是超時等問題,不能當作失敗處理!而是應該發起查詢,確認是否成功,再做處理。
異常處理:遠程調用可能會拋出異常,例如由于服務端錯誤或請求格式不正確等。因此,開發人員需要確保能夠捕獲和處理這些異常,以避免系統崩潰或數據丟失。
網絡安全:由于遠程調用涉及網絡通信,因此開發人員需要考慮網絡安全的問題,例如數據加密、認證、訪問控制等。盡可能使用安全的協議,例如HTTPS 或 SSL/TLS。
服務質量:遠程調用可能會影響系統的性能和可用性。因此,開發人員需要確保服務的質量,例如避免過度使用遠程調用、優化數據傳輸、實現負載均衡等。
版本兼容:由于遠程調用涉及不同的進程或計算機之間的通信,因此開發人員需要注意服務端和客戶端之間的版本兼容性。盡可能使用相同的接口和數據格式,避免出現不兼容的情況。
盡量避免for循環遠程調用: 盡量避免for循環遠程調用,而應該考慮實現了批量功能的接口。
審核編輯:劉清
-
SQL
+關注
關注
1文章
760瀏覽量
44076 -
JAVA語言
+關注
關注
0文章
138瀏覽量
20076 -
CSS
+關注
關注
0文章
109瀏覽量
14354 -
XSS
+關注
關注
0文章
24瀏覽量
2367 -
csrf
+關注
關注
0文章
7瀏覽量
2233
原文標題:亂寫的代碼,bug 到處飛....
文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論