1. 程式人生 > >《阿裏巴巴Java開發手冊1.4.0》閱讀總結與心得(一)

《阿裏巴巴Java開發手冊1.4.0》閱讀總結與心得(一)

更新 java開發手冊 new 開發者 由於 阿裏巴巴 itl 一個bug 項目庫

前言

  下面是阿裏對《阿裏巴巴 Java 開發手冊》(下稱《手冊》)的介紹:

  凝聚了阿裏集團很多同學的知識智慧和經驗,這些經驗甚至是用血淋淋的故障換來的,希望前車之鑒,後車之師,能夠幫助更多的開發者少踩坑,杜絕踩重復的坑。

  技術分享圖片

  在知乎上,也有關於這本開發手冊的討論十分熱烈的帖子:https://www.zhihu.com/question/55642203。

  

  其中一位網友的話讓樓主覺得十分有趣,現貼出來博大家一笑:

  技術分享圖片

  

  在樓主看來,阿裏巴巴的這本Java開發手冊,可謂包羅萬象,幾乎日常Java開發中方方面面都有所涉及。 

  由於裏面涉及的內容比較多,下面重點羅列下一些樓主讀過之後十分贊同與持保留意見的條目:

編碼規範

(一)命名規約

  8. 【強制】POJO 類中布爾類型的變量,都不要加 is 前綴,否則部分框架解析會引起序列化錯誤。
  反例: 定義為基本數據類型 Boolean isDeleted 的屬性,它的方法也是 isDeleted()RPC
框架在反向解析的時候, “誤以為” 對應的屬性名稱是 deleted,導致屬性獲取不到,進而拋出異常。

  看法:此條級別為強制,不過是有特殊的應用場景的,boolean類型變量加上is前綴無可厚非。舉例來說,對於處理狀態標誌,我覺得isProcessed/processed/processFlag/processStatus,這四種寫法都是很OK的。不過我個人可能更偏好用processed,比較簡潔。當然此條目被列舉在開發手冊中,也是前人踩坑的教訓,吸收一下挺好。

  10. 【強制】杜絕完全不規範的縮寫,避免望文不知義。
  反例: AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成 condi,此類 隨意縮寫嚴重降低了代碼的可閱讀性。

  看法:非常贊同,時常在公司項目代碼中看到不能一眼看出含義的拼音或者英文縮寫比如cashFlow縮寫為CF,代碼可讀性降低很多。Java代碼不要害怕變量名或者方法名過長,除非你能找到一個比原先短,並且含義完全相同的更好的命名。

  14. 【參考】枚舉類名建議帶上 Enum 後綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。 說明:枚舉其實就是特殊的常量類,且構造方法被默認強制是私有。 正例:枚舉名字:DealStatusEnum,成員名稱:SUCCESS / UNKOWN_REASON。

  看法:級別被列為參考,代表此條目推薦程度不是太高。我的看法也是如此,其實枚舉類命名後綴什麽type啦,status都可以啊。

(二)常量定義

  3.【推薦】不要使用一個常量類維護所有常量,應該按常量功能進行歸類,分開維護。如:緩存 相關的常量放在類:CacheConsts 下;系統配置相關的常量放在類:ConfigConsts 下。 說明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利於理解和維護。

  看法:挺好的規範,對於大型項目,按照業務功能/模塊常量類分開維護還是很有必要的。

(三)格式規約

  10. 【推薦】方法體內的執行語句組、變量的定義語句組、不同的業務邏輯之間或者不同的語義之間插入一個空行。相同業務邏輯和語義之間不需要插入空行。

  看法:在方法內部,邏輯上互相較為獨立的代碼塊之間加入一個空行,會看起來更為清楚。但是也不要太極端,每行代碼之間都插入空行,顯得反而看起來空洞。

(四)OOP規約

  9. 【強制】定義 DO/DTO/VO 等 POJO 類時,不要設定任何屬性默認值。 反例:POJO類的gmtCreate默認值為new Date();但是這個屬性在數據提取時並沒有置入具 體值,在更新其它字段時又附帶更新了此字段,導致創建時間被修改成當前時間。

  看法:非常贊同。曾經遇到一個bug,按條件篩選數據集怎麽也查不出來,後來發現是實體類中一些字段被加入了默認值,導致查詢的時候帶上了這些莫名增加的篩選字段。

(五)集合處理

  9. 【推薦】集合初始化時,盡量指定集合初始值大小。

  說明:ArrayList盡量使用ArrayList(int initialCapacity) 初始化。

  看法:非常贊同,在確定集合中元素個數的情況下,最好new的時候就指定好大小,這樣不僅可以減少空間開銷,也可以避免內存碎片的產生。

(六)並發處理

  12.【推薦】通過雙重檢查鎖(double-checked locking)(在並發場景)實現延遲初始化的優化問題隱患(可參考 The "Double-Checked Locking is Broken" Declaration),推薦問題 解決方案中較為簡單一種(適用於 JDK5 及以上版本),將目標屬性聲明為 volatile 型。

  看法:雙重檢查鎖可能因為指令重排引發的線程安全問題在《Java並發編程實戰》一書中有提及,然而這種延遲初始化的單例有特定的背景,過去機器內存資源比較珍貴。現在的服務器動輒幾十個G的內存,很多時候不要把問題搞得太復雜,餓漢式單例模式直接搞起就行。

異常日誌

(一)異常處理

1.【強制】捕獲異常是為了處理它,不要捕獲了卻什麽都不處理而拋棄之,如果不想處理它,請 將該異常拋給它的調用者。最外層的業務使用者,必須處理異常,將其轉化為用戶可以理解的 內容。

看法:private方法可以處理或者重拋異常,public方法處理異常,如果能這樣做,可以大大降低異常處理邏輯紊亂/疏漏。

MySQL規約

(一)建表規約

  9. 【強制】表必備三字段:id, gmt_create, gmt_modified。 說明:其中id必為主鍵,類型為unsigned bigint、單表時自增、步長為1。gmt_create, gmt_modified 的類型均為 date_time 類型。

  看法:整數類型的自增主鍵以及創建和修改時間確實是非常有必要的,但名字不一定得要是gmt_create,gmt_modified,類型不一定要datetime。整數類型的自增主鍵的必要性在於每次插入都在B+樹的末尾,相比無序插入,split操作會少很多。

(二)索引規約

  7.【推薦】建組合索引的時候,區分度最高的在最左邊。

  正例:如果 where a=? and b=? ,a 列的幾乎接近於唯一值,那麽只需要單建 idx_a 索引即 可。 說明:存在非等號和等號混合判斷條件時,在建索引時,請把等號條件的列前置。如:where a>? and b=? 那麽即使 a 的區分度更高,也必須把 b 放在索引的最前列。

  看法:建索引真是一門學問,比較簡單的入門就是按照選擇性來定索引。曾經看到公司項目庫中有多重索引把刪除標誌位都給包括進去了,刪除標誌位雖然是sql查詢語句的一部分,但選擇性很低,建索引完全沒必要。

《阿裏巴巴Java開發手冊1.4.0》閱讀總結與心得(一)