讀阿里Java開發(fā)手冊后的一些整理

之前看過阿里內(nèi)部整理的Java開發(fā)手冊文檔旅敷,全篇讀完以后缰趋,整理出一份覺得可能對大家有所幫助的信息~总放。

1.POJO 類中布爾類型的變量哺眯,都不要加 is谷浅,否則部分框架解析會引起序列化錯誤。

反例:定義為基本數(shù)據(jù)類型boolean isSuccess;的屬性,它的方法也是isSuccess()一疯,RPC 框架在反向解析的時候撼玄,“以為”對應的屬性名稱是 success,導致屬性獲取不到违施,進而拋出異常互纯。

2.包名統(tǒng)一使用小寫瑟幕,點分隔符之間有且僅有一個自然語義的英語單詞磕蒲。包名統(tǒng)一使用 單數(shù)形式,但是類名如果有復數(shù)含義只盹,類名可以使用復數(shù)形式辣往。

正例: 應用工具類包名為com.alibaba.open.util、類名為MessageUtils(此規(guī)則參考 spring 的框架結(jié)構(gòu))

3.不要使用一個常量類維護所有常量殖卑,應該按常量功能進行歸類站削,分開維護。如:緩存 相關的常量放在類:CacheConsts 下;系統(tǒng)配置相關的常量放在類:ConfigConsts 下孵稽。

說明:大而全的常量類许起,非得使用查找功能才能定位到修改的常量,不利于理解和維護

4.所有的相同類型的包裝類對象之間值的比較菩鲜,全部使用 equals 方法比較园细。

說明:對于Integer var=?在-128至127之間的賦值,Integer對象是在 IntegerCache.cache 產(chǎn)生接校,會復用已有對象猛频,這個區(qū)間內(nèi)的 Integer 值可以直接使用==進行 判斷,但是這個區(qū)間之外的所有數(shù)據(jù)蛛勉,都會在堆上產(chǎn)生鹿寻,并不會復用已有對象,這是一個大坑诽凌, 推薦使用 equals 方法進行判斷毡熏。

5.所有的POJO類屬性必須使用包裝數(shù)據(jù)類型,RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型,所有的局部變量【推薦】使用基本數(shù)據(jù)類型。

6.關于 hashCode 和 equals 的處理侣诵,遵循如下規(guī)則痢法。

只要重寫equals,就必須重寫hashCode窝趣。

因為Set存儲的是不重復的對象疯暑,依據(jù)hashCode和equals進行判斷,所以Set存儲的 對象必須重寫這兩個方法哑舒。

如果自定義對象做為Map的鍵妇拯,那么必須重寫hashCode和equals

String 重寫了 hashCode 和 equals 方法,所以我們可以非常愉快地使用 String 對象 作為 key 來使用。

7.不要在 foreach 循環(huán)里進行元素的 remove/add 操作越锈。remove 元素請使用 Iterator方式仗嗦,如果并發(fā)操作,需要對 Iterator 對象加鎖甘凭。

8.使用 entrySet 遍歷 Map 類集合 KV稀拐,而不是 keySet 方式進行遍歷。

說明:keySet 其實是遍歷了 2 次丹弱,一次是轉(zhuǎn)為 Iterator 對象德撬,另一次是從 hashMap 中取出 key 所對應的 value。而 entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中躲胳,效 率更高蜓洪。如果是 JDK8,使用 Map.foreach 方法

9.高度注意 Map 類集合 K/V 能不能存儲 null 值的情況坯苹。

反例: 由于 HashMap 的干擾隆檀,很多人認為 ConcurrentHashMap 是可以置入 null 值,注意存儲 null 值時會拋出 NPE 異常

10.獲取單例對象需要保證線程安全粹湃,其中的方法也要保證線程安全恐仑。

資源驅(qū)動類、工具類为鳄、單例工廠類都需要注意裳仆。

11.線程池不允許使用 Executors 去創(chuàng)建,而是通過 ThreadPoolExecutor 的方式济赎,這樣 的處理方式讓寫的同學更加明確線程池的運行規(guī)則鉴逞,規(guī)避資源耗盡的風險。

Executors 返回的線程池對象的弊端如下

FixedThreadPool 和 SingleThreadPool:允許的請求隊列長度為 Integer.MAX_VALUE司训,可能會堆積大量的請求构捡,從而導致 OOM。

CachedThreadPool 和 ScheduledThreadPool:允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE壳猜,可能會創(chuàng)建大量的線程勾徽,從而導致 OOM。

12.SimpleDateFormat 是線程不安全的類统扳,一般不要定義為static變量喘帚,如果定義為static,必須加鎖咒钟,或者使用 DateUtils 工具類吹由。

正例:注意線程安全,使用 DateUtils朱嘴。亦推薦如下處理:

如果是 JDK8 的應用倾鲫,可以使用 Instant 代替 Date粗合,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 Simpledateformatter乌昔,官方給出的解釋:simple beautiful strong immutable thread-safe隙疚。

13.高并發(fā)時,同步調(diào)用應該去考量鎖的性能損耗磕道。能用無鎖數(shù)據(jù)結(jié)構(gòu)供屉,就不要用鎖;能 鎖區(qū)塊,就不要鎖整個方法體;能用對象鎖溺蕉,就不要用類鎖伶丐。

14.對多個資源、數(shù)據(jù)庫表焙贷、對象同時加鎖時撵割,需要保持一致的加鎖順序贿堰,否則可能會造 成死鎖辙芍。

線程一需要對表 A、B羹与、C 依次全部加鎖后才可以進行更新操作故硅,那么線程二的加鎖順序 也必須是 A、B纵搁、C吃衅,否則可能出現(xiàn)死鎖。

15.并發(fā)修改同一記錄時腾誉,避免更新丟失徘层,要么在應用層加鎖,要么在緩存加鎖利职,要么在 數(shù)據(jù)庫層使用樂觀鎖趣效,使用 version 作為更新依據(jù)。

如果每次訪問沖突概率小于 20%猪贪,推薦使用樂觀鎖跷敬,否則使用悲觀鎖。樂觀鎖的重試次 數(shù)不得小于 3 次热押。

16.多線程并行處理定時任務時西傀,Timer 運行多個 TimeTask 時,只要其中之一沒有捕獲 拋出的異常桶癣,其它任務便會自動終止運行拥褂,使用 ScheduledExecutorService 則沒有這個問題。

17.使用 CountDownLatch 進行異步轉(zhuǎn)同步操作牙寞,每個線程退出前必須調(diào)用 countDown方法饺鹃,線程執(zhí)行代碼注意 catch 異常,確保 countDown 方法可以執(zhí)行,避免主線程無法執(zhí)行 至 countDown 方法尤慰,直到超時才返回結(jié)果馏锡。

說明:注意,子線程拋出異常堆棧伟端,不能在主線程 try-catch 到杯道。

18.避免 Random 實例被多線程使用,雖然共享該實例是線程安全的责蝠,但會因競爭同一 seed 導致的性能下降党巾。

在 JDK7 之后,可以直接使用 API ThreadLocalRandom霜医,在 JDK7 之前齿拂,可以做到每個 線程一個實例。

19.通過雙重檢查鎖(double-checked locking)(在并發(fā)場景)實現(xiàn)延遲初始化的優(yōu) 化問題隱患(可參考 The "Double-Checked Locking is Broken" Declaration),推薦問題 解決方案中較為簡單一種(適用于 JDK5 及以上版本)肴敛,將目標屬性聲明為 volatile 型署海。

反例:

20.volatile 解決多線程內(nèi)存不可見問題。對于一寫多讀医男,是可以解決變量同步問題砸狞, 但是如果多寫,同樣無法解決線程安全問題镀梭。如果是 count++操作刀森,使用如下類實現(xiàn)。

AtomicInteger count = new AtomicInteger(); count.addAndGet(1); 如果是 JDK8报账,推 薦使用 LongAdder 對象研底,比 AtomicLong 性能更好(減少樂觀鎖的重試次數(shù))。

21.HashMap 在容量不夠進行 resize 時由于高并發(fā)可能出現(xiàn)死鏈透罢,導致 CPU 飆升榜晦,在 開發(fā)過程中注意規(guī)避此風險。

22.ThreadLocal 無法解決共享對象的更新問題琐凭,ThreadLocal 對象建議使用 static 修飾芽隆。這個變量是針對一個線程內(nèi)所有操作共有的,所以設置為靜態(tài)變量统屈,所有此類實例共享 此靜態(tài)變量 胚吁,也就是說在類第一次被使用時裝載,只分配一塊存儲空間愁憔,所有此類的對象(只 要是這個線程內(nèi)定義的)都可以操控這個變量腕扶。

23.不能在 finally 塊中使用 return,finally 塊中的 return 返回后方法結(jié)束執(zhí)行吨掌,不 會再執(zhí)行 try 塊中的 return 語句半抱。

24.應用中不可直接使用日志系統(tǒng)(Log4j脓恕、Logback)中的 API,而應依賴使用日志框架SLF4J 中的 API窿侈,使用門面模式的日志框架炼幔,有利于維護和各個類的日志處理方式統(tǒng)一。

25.對 trace/debug/info 級別的日志輸出史简,必須使用條件輸出形式或者使用占位符的方式乃秀。

說明:logger.debug("Processing trade with id: " + id + " symbol: " + symbol); 如果日志級別是 warn,上述日志不會打印圆兵,但是會執(zhí)行字符串拼接操作跺讯,如果 symbol 是對象, 會執(zhí)行 toString()方法殉农,浪費了系統(tǒng)資源刀脏,執(zhí)行了上述操作,最終日志卻沒有打印超凳。

正例:(條件)

正例:(占位符)

26.避免重復打印日志愈污,浪費磁盤空間,務必在 log4j.xml 中設置 additivity=false聪建。

正例:

27.異常信息應該包括兩類信息:案發(fā)現(xiàn)場信息和異常堆棧信息钙畔。如果不處理,那么往上拋金麸。

正例:

28.建表時小數(shù)類型為 decimal,禁止使用 float 和 double簿盅。

float 和 double 在存儲的時候挥下,存在精度損失的問題,很可能在值的比較時桨醋,得到不 正確的結(jié)果棚瘟。如果存儲的數(shù)據(jù)范圍超過 decimal 的范圍,建議將數(shù)據(jù)拆成整數(shù)和小數(shù)分開存儲喜最。

29.varchar 是可變長字符串偎蘸,不預先分配存儲空間,長度不要超過 5000瞬内,如果存儲長 度大于此值迷雪,定義字段類型為 text,獨立出來一張表虫蝶,用主鍵來對應章咧,避免影響其它字段索引效率。

30.如果有 order by 的場景能真,請注意利用索引的有序性赁严。order by 最后的字段是組合 索引的一部分扰柠,并且放在索引組合順序的最后,避免出現(xiàn) file_sort 的情況疼约,影響查詢性能卤档。

正例:where a=? and b=? order by c; 索引:a_b_c

反例:索引中有范圍查找,那么索引有序性無法利用程剥,如:WHERE a>10 ORDER BY b; 索引 a_b 無法排序裆装。

31.利用延遲關聯(lián)或者子查詢優(yōu)化超多分頁場景。

說明:MySQL 并不是跳過 offset 行倡缠,而是取 offset+N 行哨免,然后返回放棄前 offset 行,返回 N 行昙沦,那當 offset 特別大的時候琢唾,效率就非常的低下,要么控制返回的總頁數(shù)盾饮,要么對超過 特定閾值的頁數(shù)進行 SQL 改寫采桃。

正例:先快速定位需要獲取的 id 段,然后再關聯(lián):

32.SQL 性能優(yōu)化的目標:至少要達到 range 級別丘损,要求是 ref 級別普办,如果可以是 consts 最好。

1.consts 單表中最多只有一個匹配行(主鍵或者唯一索引)徘钥,在優(yōu)化階段即可讀取到數(shù)據(jù)衔蹲。

2.ref 指的是使用普通的索引(normal index)。

3.range 對索引進行范圍檢索呈础。

反例:explain 表的結(jié)果舆驶,type=index,索引物理文件全掃描而钞,速度非常慢沙廉,這個 index 級 別比較 range 還低,與全表掃描是小巫見大巫

33.建組合索引的時候臼节,區(qū)分度最高的在最左邊撬陵。

如果 where a=? and b=? ,a 列的幾乎接近于唯一值网缝,那么只需要單建 idx_a 索引即 可巨税。

存在非等號和等號混合判斷條件時,在建索引時途凫,請把等號條件的列前置垢夹。如:where a>? and b=? 那么即使 a 的區(qū)分度更高,也必須把 b 放在索引的最前列维费。

34.不要使用 count(列名)或 count(常量)來替代 count(*)果元,count(*)就是 SQL92 定義 的標準統(tǒng)計行數(shù)的語法促王,跟數(shù)據(jù)庫無關,跟 NULL 和非 NULL 無關而晒。

count(*)會統(tǒng)計值為 NULL 的行蝇狼,而 count(列名)不會統(tǒng)計此列為 NULL 值的行。

35.count(distinct col) 計算該列除 NULL 之外的不重復數(shù)量倡怎。注意 count(distinct col1, col2) 如果其中一列全為NULL迅耘,那么即使另一列有不同的值,也返回為0监署。

36.當某一列的值全是 NULL 時颤专,count(col)的返回結(jié)果為 0,但 sum(col)的返回結(jié)果為 NULL钠乏,因此使用 sum()時需注意 NPE 問題栖秕。

正例:可以使用如下方式來避免sum的NPE問題:SELECT IF(ISNULL(SUM(g)),0,SUM(g)) FROM table;

37.使用 ISNULL()來判斷是否為 NULL 值。注意:NULL 與任何值的直接比較都為 NULL晓避。

38.不得使用外鍵與級聯(lián)簇捍,一切外鍵概念必須在應用層解決。

學生表中的 student_id 是主鍵俏拱,那么成績表中的 student_id 則為外鍵暑塑。 如果更新學生表中的 student_id,同時觸發(fā)成績表中的 student_id 更新锅必,則為級聯(lián)更新事格。 外鍵與級聯(lián)更新適用于單機低并發(fā),不適合分布式况毅、高并發(fā)集群;級聯(lián)更新是強阻塞分蓖,存在數(shù)據(jù)庫更新風暴的風險;外鍵影響數(shù)據(jù)庫的插入速度。


學習Java的同學注意了6怼!终娃!
學習過程中遇到什么問題或者想獲取學習資源的話味廊,歡迎加入Java學習交流群346942462,我們一起學Java棠耕!

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末余佛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子窍荧,更是在濱河造成了極大的恐慌辉巡,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕊退,死亡現(xiàn)場離奇詭異郊楣,居然都是意外死亡憔恳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門净蚤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钥组,“玉大人,你說我怎么就攤上這事今瀑〕堂危” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵橘荠,是天一觀的道長屿附。 經(jīng)常有香客問我,道長哥童,這世上最難降的妖魔是什么挺份? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮如蚜,結(jié)果婚禮上压恒,老公的妹妹穿的比我還像新娘。我一直安慰自己错邦,他們只是感情好探赫,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撬呢,像睡著了一般伦吠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魂拦,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天毛仪,我揣著相機與錄音,去河邊找鬼芯勘。 笑死箱靴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的荷愕。 我是一名探鬼主播衡怀,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼安疗!你這毒婦竟也來了抛杨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤荐类,失蹤者是張志新(化名)和其女友劉穎怖现,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玉罐,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡屈嗤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年潘拨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恢共。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡战秋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讨韭,到底是詐尸還是另有隱情脂信,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布透硝,位于F島的核電站狰闪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏濒生。R本人自食惡果不足惜埋泵,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罪治。 院中可真熱鬧丽声,春花似錦、人聲如沸觉义。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晒骇。三九已至霉撵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洪囤,已是汗流浹背徒坡。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瘤缩,地道東北人喇完。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像剥啤,于是被迫代替她去往敵國和親何暮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容