阿里巴巴Java工作手冊---學習筆記__Java

來源:互聯網
上載者:User

本文轉自:java團長

最近瀏覽了一下阿里巴巴的Java開發手冊,感覺內容確實非常的贊,發現了不少自己在編程中的誤區,因此決定通過成文牢固掌握,文中將選取個人認為比較重要的部分進行描述與分析。”願站在巨人的肩膀上,碼出高效,碼出品質“。 概述

手冊中內容很多,包括編碼規約、工程結構、MySQL資料庫、異常日誌、安全規約、單元測試等6大部分。其中工程結構部分在整體上對項目進行了把控,編碼規約和MySQL設計規約中有非常多的“最佳實務”,個人認為是最為有價值的部分。次重點安全規約很符合互連網情境的需要,異常日誌和單元測試部分相對來說內容和價值相對小一點。
下圖是個人對手冊的簡單匯總(將圖片拖到瀏覽器新開頁面,之後放大可以清晰很多),其中紅星表示重點,黃色表示次重點。此外,其中的集合處理、並發處理、MySQL規約和工程結構有一定理解難度,會專門放到重痛點增強一節進行詳細分析。當然這隻是個人的淺見,完整部分請見最下方的參考資料,目前阿里公司已推出這套規約的IDE外掛程式,大家可以試試。 重痛點增強 工程結構

Open Interface:提供RPC或Restful風格的介面,並通過架構進行網關安全控制、流量控制等。
終端顯示層:前端模板渲染並執行顯示的層。
Web Layer: 主要是對存取控制進行轉寄, 各類基本參數校正, 或者不複用的業務簡單處理等。
Service Layer:商務邏輯服務層。


Manager Layer:這一層比較有意思,既包含了常見的外部介面的Agent功能,也包含了對DAO介面的簡單封裝用於複用,還可以在改成構建對於DAO的緩衝。
DAO Layer:與底層 MySQL、Hbase等進行資料互動,通常基於各類DAL架構。
ExternalInterface: 包括其它部門 RPC 開放介面, 基礎平台, 其它公司的 HTTP 介面。
Tip: 實際項目中完全可以遵循該模式構建包的層次。 集合處理

集合操作一直是一個關鍵點,常見的小技巧包括通過Set元素唯一的特性,可以快速對一個集合進行去重操作,JD8中通過steam流對集合操作做了不錯的增強。合理利用好集合的有序性 (sort) 和穩定性 (order) ,避免集合的無序性 (unsort) 和
不穩定性 (unorder) 帶來的負面影響,ArrayList是order&unsort;HashMap是unorder&unsort;TreeSet 是order&sort。


TIp: 不同類型Map集合K/V能不能儲存null值的情況如下表所示 並發處理

合理的通過並發控制來高效利用系統資源是工程師永遠的追求,該手冊的不少要求很好的認識到自己在該方面的不足。


線程池的建立
過去一半都通過Executors 去建立線程池,實際上這是不合理的,比如FixedThreadPool的阻塞隊列大小Integer.MAX_VALUE,很容易造成大量請求的堆積,造成OOM。而ScheduledThreadPool允許線程的數量為Integer.MAX_VALUE,更加容易出現OOM。因此必須使用ThreadPoolExecutor建立線程池,明確的制定線程池的參數。


使用鎖的原則
1.高並發時,同步調用應該去考量鎖的效能損耗。能用無鎖資料結構,就不要用鎖 ; 能鎖區塊,就不要鎖整個方法體 ; 能用對象鎖,就不要用類鎖。
2.對多個資源、資料庫表、對象同時加鎖時,需要保持一致的加鎖順序,否則可能會造成死結。
3.並發修改同一記錄時,避免更新丟失,需要加鎖。要麼在應用程式層加鎖,要麼在緩衝加鎖,要麼在資料庫層使用樂觀鎖,使用 version 作為更新依據。如果每次存取違規機率小於 20%,推薦使用樂觀鎖,否則使用悲觀鎖。樂觀鎖的重試次數不得小於 3 次。


CountDownLatch
使用 CountDownLatch 進行非同步轉同步操作,每個線程退出前必須調用 countDown方法,線程執行代碼注意 catch 異常,確保 countDown 方法被執行到,避免主線程無法執行至 await 方法,直到逾時才返回結果。需要注意子線程拋出異常堆棧,不能在主線程的try-catch塊中捕獲到。


ThreadLocalRandom
避免 Random 執行個體被多線程使用,雖然共用該執行個體是安全執行緒的,但會因競爭同一seed 導致的效能下降,推薦使用ThreadLocalRandom。


Volatile
volatile 解決多線程記憶體不可見問題。對於一寫多讀,是可以解決變數同步問題,但是如果多寫,同樣無法解決安全執行緒問題。在完成飽漢的單例模式時,可以使用Volatile關鍵字實現延遲初始化。


LongAdder
對於count++操作,可以使用AtomicInteger count = new AtomicInteger();,JDK8中推薦使用LongAdder,通過減少樂觀鎖的重試次數提高效能。


HashMap
HashMap 在容量不夠進行 resize 時由於高並發可能出現死鏈,導致 CPU 飆升,在開發過程中可以使用其它資料結構或加鎖來規避此風險。


ThreadLocal
ThreadLocal 對象建議使用 static修飾。這個變數是針對一個線程內所有操作共用的。 MYSQL規約

資料庫方面的最佳化一直困擾著我,書上的一下幾個原則給予個人在資料庫最佳化方面不少啟示。


索引長度
過去一直沒有注意過索引還有長度這個概念,現在才知道在varchar等類型欄位上建立索引時,可以指定索引長度,達到一定區分度即可,一般對於字串類型資料,長度為 20 的索引,區分度會高達 90%以上,可以使用count(distinct left( 列名, 索引長度 )) / count( * )的區分度來確定。

此外頁面搜尋嚴禁左模糊或者全模糊,如果需要請走搜尋引擎來解決。索引檔案具有B-Tree的最左首碼匹配特性,如果左邊的值未確定,那麼無法使用此索引。


order by
在有order by的情境,請注意利用索引的有序性。例如where a =? and b =? order by c的索引為a _ b _ c


覆蓋索引
利用覆蓋索引可以減少原表查詢,通過索引頁(目錄)即可查到所需資訊。通常來說,能夠建立索引的種類包括主鍵索引、唯一索引、普通索引,而覆蓋索引是查詢的一種效果,可以通過explain查看到extra 列會出現using index 。

分頁查詢
MySQL並不是跳過offset行,而是取 offset + N 行,之後放棄offset行,返回所需N行,當資料量大時,推薦如下方式進行最佳化。先快速定位需要擷取的 id 段,然後再關聯:
SELECT a.* FROM 表 1 a, (select id from 表 1 where 條件 LIMIT 100000,20 ) b where a.id=b.id SQL 效能最佳化的目標
至少要達到 range 層級, 要求是 ref 層級, 如果可以是 consts最好。


consts 單表中最多隻有一個匹配行(主鍵或者唯一索引),在最佳化階段即可讀取到資料。
ref 指的是使用普通的索引 (normal index) 。
range 對索引進行範圍檢索。
tip: type = index,索引物理檔案全掃描,速度非常慢,這個 index 層級比較 range 還低,與全表掃描是小巫見大巫。

在Mysql Workbench中表述稍微有些區別:consts沒變,Non-Unique Key Lookup表示ref, Index Range Scan表示range, full table Scan表示All, full index scan表示index,當然也可以選擇Tabular視圖替代Visual視圖。

複合式索引
區分度最高的在最左邊,對於where a =? and b =?來說,a 列的值越唯一越好。此外,存在非等號和等號混合判斷條件時, 在建索引時, 請把等號條件的列前置。
隱式轉換
防止因欄位類型不同造成的隱式轉換,導致索引失效,當資料查詢逾時,也需要把此作為很重要的考慮部分。

參考資料

阿里巴巴Java開發手冊

阿里規約github

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.