《阿里巴巴 Java 開發(fā)手冊》是阿里巴巴集團技術團隊的集體智慧結(jié)晶和經(jīng)驗總結(jié)赐稽,經(jīng)歷了多次大規(guī)模一線實戰(zhàn)的檢驗及不斷完善,系統(tǒng)化地整理成冊馍佑,回饋給廣大開發(fā)者毛肋。
本手冊的旨在碼出高效,碼出質(zhì)量》Ψ現(xiàn)代軟件架構(gòu)的復雜性需要協(xié)同開發(fā)完成孟抗,如何高效地協(xié)同呢?無規(guī)矩不成方圓迁杨,無規(guī)范難以協(xié)同代碼的字里行間流淌的是軟件系統(tǒng)的血液,質(zhì)量的提升是盡可能少踩坑夸浅,杜絕踩重復的坑仑最,切實提升系統(tǒng)穩(wěn)定性,碼出質(zhì)量帆喇。
阿里巴巴編碼規(guī)范基礎認證的考試要點90%來源于這本開發(fā)手冊中的內(nèi)容警医,目前此手冊的最新版本為1.4.0的PDF(詳盡版),此版本已為非常詳盡的版本坯钦,在上一個版本的基礎上新增了設計規(guī)約大章節(jié)预皇,并增加了若干條目。根據(jù)手冊規(guī)約中的內(nèi)容阿里在2017杭州云棲大會上發(fā)布了Java開發(fā)規(guī)約插件婉刀,插件同時支持Intelli IDEA和Eclipse吟温,文后我會簡單介紹下這個插件的安裝及使用。
我在2018-08-21的晚上通過阿里云大學在線考試通過了這個認證突颊,考試包含50道選擇題鲁豪,分為多選和單選,每次考試題目內(nèi)容是隨機生成的律秃,主要是多選題居多爬橡,每次考試單選題目數(shù)量也是隨機的,但不會超過10道單選棒动,考試時間90分鐘糙申,說來慚愧,我第一次考試的時候沒有通過船惨,做的比較快柜裸,45分鐘我就做完了,也沒檢查直接交卷了粱锐,結(jié)果考了78分疙挺,差2分。怜浅。衔统。
如果你關注阿里云在招的Java工程師職位,你會發(fā)現(xiàn)崗位說明中有這樣的字樣“通過阿里巴巴編碼規(guī)范認證的同學優(yōu)先錄取”海雪,足以看出這份認證考試還是有些許價值的。
那么接下來我將聊聊《阿里巴巴Java開發(fā)手冊》(文后簡稱“手冊”)讀后感以及認證考試的主要考試要點舱殿,最后再簡單寫下插件的安裝和使用奥裸。
手冊讀后感
正如阿里官方說明的一樣,這是一本由阿里近萬名Java開發(fā)精英工程師通過大規(guī)模一線實戰(zhàn)的經(jīng)驗總結(jié)而來的沪袭,讀后確實覺得寫的很實用湾宙,有些地方可以說是閉坑指南樟氢,從書的首屏圖樣來說這本書是要做領頭雁的意思。
本手冊以 Java 開發(fā)者為中心視角侠鳄,劃分為編程規(guī)約埠啃、異常日志、單元測試伟恶、安全規(guī)約碴开、MySQL數(shù)據(jù)庫、工程結(jié)構(gòu)博秫、設計規(guī)約七個維度潦牛,再根據(jù)內(nèi)容特征,細分成若干二級子目錄挡育。根據(jù)約束力強弱及故障 敏感性巴碗,規(guī)約依次分為強制、推薦即寒、參考三大類橡淆。對于規(guī)約條目的延伸信息中,“說明”對規(guī)約做了適當擴展和解釋;“正例”提倡什么樣的編碼和實現(xiàn)方式;“反例” 說明需要提防的雷區(qū)母赵,以及真實的錯誤案例逸爵。
這是一本關于Java開發(fā)規(guī)范方面的中文原版說明書,當然有些內(nèi)容它也遵循了Oracle Sun規(guī)范市咽,如編程規(guī)約中類名使用UpperCamelCase風格痊银。方法名、參數(shù)名施绎、成員變量溯革、局部變量都統(tǒng)一使用lowerCamelCase風格,必須遵從駝峰形式谷醉。
講編碼規(guī)范的說明書并不是要求我們程序員去死記硬背這些條條框框致稀,我們應該去發(fā)掘在這些條條框框之后隱藏的真理是什么?如“為什么我們要去遵循這些規(guī)范俱尼,為什么要制定這樣的規(guī)則抖单,使用這樣的規(guī)則有什么好處,它會限制我們代碼內(nèi)容的創(chuàng)造性嗎?”遇八。我覺得帶著這些問題去閱讀本書矛绘,理解這些規(guī)范和標準才是正確的打開方式。為了不讓本章節(jié)拖的太長刃永,我將挑選手冊中重要的幾個規(guī)范點來說下我個人的見解和補充货矮。
(1)編程規(guī)約中POJO概念
POJO(Plain Ordinary Java Object): 在本手冊中,POJO 專指只有 setter / getter / toString的簡單類斯够,包括DO/DTO/BO/VO等囚玫。
- DO(Data Object):此對象與數(shù)據(jù)庫表結(jié)構(gòu)一一對應喧锦,通過 DAO 層向上傳輸數(shù)據(jù)源對象。
- DTO(Data Transfer Object):數(shù)據(jù)傳輸對象抓督,Service 或 Manager 向外傳輸?shù)膶ο蟆?/li>
- BO(Business Object):業(yè)務對象燃少,由 Service 層輸出的封裝業(yè)務邏輯的對象。
- AO(ApplicationObject):應用對象铃在,在Web層與Service層之間抽象的復用對象模型阵具, 極為貼近展示層,復用度不高涌穆。
- VO(View Object):顯示層對象怔昨,通常是 Web 向模板渲染引擎層傳輸?shù)膶ο蟆?/li>
我們在實際簡單的項目中,可能不會將實體像上面分的那么細宿稀,多數(shù)命名會直接末尾加POJO或Entity或Model趁舀,這對于軟件架構(gòu)不是很復雜,對性能要求也不高的小型后臺管理類系統(tǒng)來說祝沸,確實已經(jīng)夠了矮烹。但對于復雜的,且對性能要求高的項目罩锐,就有必要分這么細了奉狈,舉個例子,一般復雜的項目涩惑,開發(fā)團隊都是10人以上仁期,團隊按組劃分,各組負責軟件架構(gòu)中不同的應用層級竭恬,各層級之間肯定要定義接口跛蛋,那么數(shù)據(jù)傳輸?shù)膶嶓w就不能一概而就了,必須分層規(guī)范定義痊硕;再舉個例子赊级,很多時候一個DO實體對應在數(shù)據(jù)庫中表的字段有10多個,但是在頁面中需要顯示的只需要3-5個岔绸,多余的數(shù)據(jù)會導致傳輸速度下降理逊,所以需要新建VO對象去進行頁面顯示,只取需要展示的數(shù)據(jù)盒揉;還有諸如一個用戶實體晋被,密碼不應該在查詢的時候返回給用戶,用戶編號也不是用戶想看到的刚盈,用戶想看到的只是用戶昵稱墨微,這時我們必然需要通過BO或者DTO層進行過濾和轉(zhuǎn)義,最終新建Vo對象用于界面展示扁掸。
【強制】POJO類中布爾類型的變量翘县,都不要加 is 前綴,否則部分框架解析會引起序列化錯誤
這一條我也是感觸挺深的谴分,這個是真細節(jié)锈麸,在我還是個菜鳥的時候,我也遇到過 boolean isSuccess的錯誤牺蹄,debug調(diào)試的時候明明這個值是有值的且為true忘伞,怎么傳遞到前臺來了之后就變成了無值默認false呢,千萬千萬不要這樣命名沙兰。
(2)格式規(guī)范
這里我主要講一點氓奈,代碼縮進的時候到底是敲空格鍵還是tab鍵,我習慣敲tab鼎天,所以我在IDE中設置了一個tab使用4個空格來代替舀奶,因為敲空格容易敲錯。
(3)集合處理
- foreach中不要進行remove和add操作斋射,remove元素請使用 Iterator方式育勺,如果并發(fā)操作,需要對 Iterator 對象加鎖罗岖。
-
下面這張表格是重點(考試必考涧至,敲黑板,可以記一下)
(4)并發(fā)處理
【強制】線程池不允許使用 Executors 去創(chuàng)建桑包,而是通過ThreadPoolExecutor的方式南蓬,這樣的處理方式讓寫的同學更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風險哑了。
說明:Executors 返回的線程池對象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允許的請求隊列長度為 Integer.MAX_VALUE赘方,可能會堆積大量的請求,從而導致 OOM垒手。
2)CachedThreadPool 和 ScheduledThreadPool:
允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE蒜焊,可能會創(chuàng)建大量的線程,從而導致 OOM科贬。
對于FixedThreadPool這個線程池泳梆,我也是掉過坑里,由于系統(tǒng)在一個特殊時期內(nèi)業(yè)務請求量翻了好幾番榜掌,當前線程池設定的最大線程數(shù)不足优妙,工作線程處理任務的速度大大低于請求任務的新增速度,這會導致請求隊列深度無限擴大憎账,內(nèi)存使用量直線攀升套硼,最終造成頻繁FullGC,這樣又導致工作線程處理任務的速度進一步變慢胞皱,形成死鏈邪意,最后OOM服務端進程崩潰了九妈。。雾鬼。
(5)索引規(guī)約
【強制】業(yè)務上具有唯一特性的字段萌朱,即使是多個字段的組合,也必須建成唯一索引策菜。
說明:不要以為唯一索引影響了 insert 速度晶疼,這個速度損耗可以忽略,但提高查找速度是明 顯的;另外又憨,即使在應用層做了非常完善的校驗控制翠霍,只要沒有唯一索引,根據(jù)墨菲定律蠢莺,必然有臟數(shù)據(jù)產(chǎn)生寒匙。
這一點我也是非常贊同,在生產(chǎn)項目實際運行過程中見到太多這樣的臟數(shù)據(jù)導致被業(yè)務或者客戶投訴吐槽(怎么我只操作了一次浪秘,你們系統(tǒng)記錄了2遍蒋情,系這也太坑了吧。耸携。棵癣。)所以這條規(guī)范排在了NO.1。
還有很多痛點和閉坑指南夺衍,這里就不一一舉例了狈谊,我相信每個有經(jīng)驗的Java開發(fā)人員看完這本手冊都會在其中找到自己曾經(jīng)的痛點影子,這是一本可以給自己查漏補缺的好書沟沙。
認證考試要點
絕大部分的考題涉及到的知識點都能在《阿里巴巴JAVA開發(fā)手冊》上找到河劝,這些都是比較基礎的考點,這里就不說明了矛紫,我主要講一些只在書上稍微提及卻又在考試中擴展延伸的考點赎瞎。
JAVA:
1.考點:集合處理這個章節(jié),特別是數(shù)組與集合相互轉(zhuǎn)換颊咬,涉及考題較多务甥。
subList 返回的是 ArrayList 的內(nèi)部類 SubList,并不是 ArrayList 喳篇,而是 ArrayList 的一個視圖敞临,對于SubList子列表的所有操作最終會反映到原列表上(在sublist中添加/刪除元素,不只影響sublist本身麸澜,同時會影響原ArrayList)挺尿。
在subList場景中,高度注意對原集合元素個數(shù)的修改,會導致子列表的遍歷编矾、增加熟史、刪除均會產(chǎn)生ConcurrentModificationException 異常(切記,這個場景是不被允許的窄俏,不要和上一點記混淆)
sublist沒有實現(xiàn)序列化以故,查看源碼就可以發(fā)現(xiàn)其沒有實現(xiàn)Serializable接口,這點必須注意裆操,在大多數(shù)寫入緩存容器、RPC調(diào)用等場景需要做一些調(diào)整炉媒。
特別是最后一條踪区,手冊中并未提及,但是我遇到的多選題吊骤,其中有一個選項就是:subList不能作為RPC接口方法的返回結(jié)果缎岗,因為其沒有實現(xiàn)序列化,第一次考試的時候我沒有選這個選項白粉,要是選了就一次過了(苦笑)
2.考點:所有的相同類型的包裝類對象之間值的比較传泊,全部使用equals方法比較。
對于Integer var = ? 在-128至127范圍內(nèi)的賦值鸭巴,Integer對象是在IntegerCache.cache產(chǎn)生眷细,會復用已有對象,這個區(qū)間內(nèi)的Integer值可以直接使用==進行判斷鹃祖,但是這個區(qū)間之外的所有數(shù)據(jù)溪椎,都會在堆上產(chǎn)生,并不會復用已有對象恬口,這是一個大坑校读,推薦使用equals方法進行判斷
這點在很多書上都有提及,特別重要祖能,這里說下我遇到的題目
代碼:
Integer var1 = 20;
Integer var2 = 20;
Integer var3 = 259;
Integer var4 = 259;
題目選項是讓你選擇 var1 == var2 的值為true還是false歉秫,var3 == var4的值為true還是false。
數(shù)據(jù)庫考點:
數(shù)據(jù)庫題目考試的比重還是比較大的养铸,最主要的是sql索引規(guī)范雁芙,然后就是SQL語句,ORM規(guī)范揭厚。
1.考點:NULL與任何值比較的結(jié)果都為NULL却特。~記住這點很重要。
2.考點:Mysql涉及的索引從數(shù)據(jù)結(jié)構(gòu)角度來看涉及到 B-Tree筛圆、Hash裂明、R-Tree、Full-text,從物理存儲角度闽晦,聚集索引(clustered)扳碍、非聚集索引(non-clustered)。
在MySQL中仙蛉,InnoDB引擎表是(聚集)索引組織表(clustered index organize table)笋敞,而MyISAM引擎表則是堆組織表(heap organize table)。
InnoDB的數(shù)據(jù)文件本身就是索引文件荠瘪,B+Tree的葉子節(jié)點上的data就是數(shù)據(jù)本身夯巷,key為主鍵,這是聚簇索引哀墓。非聚簇索引趁餐,葉子節(jié)點上的data是主鍵(所以聚簇索引的key,不能過長)篮绰。為什么存放的主鍵后雷,而不是記錄所在地址呢,理由相當簡單吠各,因為記錄所在地址并不能保證一定不會變臀突,但主鍵可以保證。
3.考點:索引規(guī)約中相關的點贾漏,考到的題比較多候学,比如索引中有范圍查找,那么索引有序性無法利用磕瓷,如:WHERE a>10 ORDER BY b; 索引a_b無法排序盒齿。又比如頁面搜索嚴禁左模糊或者全模糊,如果需要請走搜索引擎來解決索引文件具有 B-Tree 的最左前綴匹配特性困食,如果左邊的值未確定边翁,那么無法使用此索引。
4.考點:iBATIS自帶的queryForList(String statementName,int start,int size)不推薦使用硕盹,存在性能風險符匾。
說明:其實現(xiàn)方式是在數(shù)據(jù)庫取到 statementName 對應的 SQL 語句的所有記錄,再通過 subList 取 start,size 的子集合
5.考點:利用延遲關聯(lián)或者子查詢優(yōu)化超多分頁場景
說明:MySQL 并不是跳過 offset 行瘩例,而是取 offset+N 行啊胶,然后返回放棄前 offset 行,返回 N 行垛贤,那當 offset 特別大的時候焰坪,效率就非常的低下,要么控制返回的總頁數(shù)聘惦,要么對超過 特定閾值的頁數(shù)進行 SQL 改寫某饰。
6.考點:在代碼中寫分頁查詢邏輯時,若 count 為 0 應直接返回,避免執(zhí)行后面的分頁語句
日志:
1.考點:應用中不可直接使用日志系統(tǒng)(Log4j黔漂、Logback)中的API诫尽,而應依賴使用日志框架SLF4J中的API,使用門面模式的日志框架炬守,有利于維護和各個類的日志處理方式統(tǒng)一牧嫉。
平時常用的日志適配框架是SLF4J,這里重點提一下JCL(Jakarta Commons Logging),題目中出現(xiàn)的减途,后來查詢了資源它也是一種日志適配框架酣藻,考試的時候猜測應該是類似于SLF4J的東西,也選了這個鳍置,蒙對了臊恋。。墓捻。用這些日志框架的好處是降低與具體日志框架的耦合,可以靈活改變使用的具體日志框架坊夫。
單元測試:
1.考點:編寫單元測試代碼遵守 BCDE 原則砖第,以保證被測試模塊的交付質(zhì)量。
B:Border环凿,邊界值測試梧兼,包括循環(huán)邊界、特殊取值智听、特殊時間點羽杰、數(shù)據(jù)順序等。
C:Correct到推,正確的輸入考赛,并得到預期的結(jié)果。
D:Design莉测,與設計文檔相結(jié)合颜骤,來編寫單元測試。
E:Error捣卤,強制錯誤信息輸入(如:非法數(shù)據(jù)忍抽、異常流程、非業(yè)務允許輸入等)董朝,并得 到預期的結(jié)果鸠项。
這里考試的時候我遇到的是BCDE解釋故意混淆,如E:Equal,保證單元測試的運行生產(chǎn)環(huán)境和測試環(huán)境完全一樣(這怎么可能呢子姜,完全一樣了還有測試環(huán)境這個稱呼嗎祟绊,呵呵。。久免。)
2.考點:白盒測試中的代碼覆蓋率相關概念浅辙,語句覆蓋、分支覆蓋(判定覆蓋)阎姥、條件覆蓋记舆、路徑覆蓋。
語句覆蓋是最弱的一種度量方式呼巴,即使是路徑覆蓋也不能保證程序完全沒問題泽腮。這些相關概念還是看下專業(yè)的書籍或者博客等資料,在這里就不多描述了衣赶。
網(wǎng)絡:
1.考點:高并發(fā)服務器建議調(diào)小TCP協(xié)議的time_wait超時時間诊赊。
重點需要理解tcp協(xié)議,三次握手府瞄、四次揮手相關概念及狀態(tài)轉(zhuǎn)換碧磅。
阿里巴巴Java開發(fā)規(guī)約插件安裝及使用
因為我目前使用IDEA開發(fā),這里只簡單介紹下在IntelliJ IDEA下的安裝及使用遵馆,Eclipse的同學可以通過GitHub鏈接傳送門了解:
ailibaba/p3c/Eclipse-plugin
IDEA插件安裝
從插件資源庫中安裝
1.Settings >> Plugins >> Browse repositories...
-
通過關鍵字'alibaba'搜索插件鲸郊,然后安裝'Alibaba Java Coding Guidelines' plugin
- 重啟IDEA即可生效
當然也可以下載插件的zip file 通過本地導入的方式安裝,這里就不說了。
使用
1.語言切換货邓,支持中文和英文兩種語言可選
2.自定義檢查設定秆撮,可以根據(jù)自己公司,自身項目團隊的實際情況自定義勾選插件需要檢查的規(guī)約內(nèi)容
3.項目代碼分析 Code Analyze
我的一個項目使用標準的檢查定義分析之后:
這個插件做的非常簡單换况,也很輕量职辨,設計者秉承的是開箱即用的設計理念。
寫在最后
最后我給大家總結(jié)一下以上你將會用到的資源吧戈二,方便大家今后進入舒裤。
點擊下載《阿里巴巴Java開發(fā)手冊》v1.4.0(最新詳盡版):
https://yq.aliyun.com/attachment/download/?id=5585
編碼規(guī)范考試認證:
https://edu.aliyun.com/certification/cldt02
IDE插件下載:
https://github.com/alibaba/p3c
完