java編碼規(guī)范
常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長。
正例:MAX_STOCK_COUNT
反例:MAX_COUNT抽象類命名使用Abstract或Base開頭;異常類命名使用Exception結(jié)尾;測試類命名以它要測試的類的名稱開始,以Test結(jié)尾
POJO類中布爾類型的變量,都不要加is前綴,否則部分框架解析會引起序列化錯誤。 反例:定義為基本數(shù)據(jù)類型Boolean isDeleted的屬性,它的方法也是isDeleted(),RPC框架在反向解析的時候,“誤以為”對應(yīng)的屬性名稱是deleted,導(dǎo)致屬性獲取不到,進(jìn)而拋出異常
接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔性,并加上有效的Javadoc注釋。盡量不要在接口里定義變量,如果一定要定義變量,肯定是與接口方法相關(guān),并且是整個應(yīng)用的基礎(chǔ)常量
對于Service和DAO類,基于SOA的理念,暴露出來的服務(wù)一定是接口,內(nèi)部的實現(xiàn)類用Impl的后綴與接口區(qū)別。
正例:CacheServiceImpl實現(xiàn)CacheService接口
如果是形容能力的接口名稱,取對應(yīng)的形容詞為接口名(通常是–able的形式)。
正例:AbstractTranslator實現(xiàn) Translatable接口在long或者Long賦值時,數(shù)值后使用大寫的L,不能是小寫的l,小寫容易跟數(shù)字1混淆,造成誤解
關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:
1) 【強制】所有的POJO類屬性必須使用包裝數(shù)據(jù)類型。
2) 【強制】RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。
3) 【推薦】所有的局部變量使用基本數(shù)據(jù)類型。
說明:
POJO類屬性沒有初值是提醒使用者在需要使用時,必須自己顯式地進(jìn)行賦值,任何NPE問題,或者入庫檢查,都由使用者來保證。
正例:數(shù)據(jù)庫的查詢結(jié)果可能是null,因為自動拆箱,用基本數(shù)據(jù)類型接收有NPE風(fēng)險。
反例:比如顯示成交總額漲跌情況,即正負(fù)x%,x為基本數(shù)據(jù)類型,調(diào)用的RPC服務(wù),調(diào)用不成功時,返回的是默認(rèn)值,頁面顯示為0%,這是不合理的,應(yīng)該顯示成中劃線。所以包裝數(shù)據(jù)類型的null值,能夠表示額外的信息,如:遠(yuǎn)程調(diào)用失敗,異常退出類內(nèi)方法定義的順序依次是:公有方法或保護(hù)方法 > 私有方法 > getter/setter方法
final可以聲明類、成員變量、方法、以及本地變量,下列情況使用final關(guān)鍵字:
1) 不允許被繼承的類,如:String類。
2) 不允許修改引用的域?qū)ο蟆?br> 3) 不允許被重寫的方法,如:POJO類的setter方法。
4) 不允許運行過程中重新賦值的局部變量。
5) 避免上下文重復(fù)使用一個變量,使用final描述可以強制重新定義一個變量,方便更好地進(jìn)行重構(gòu)volatile解決多線程內(nèi)存不可見問題。對于一寫多讀,是可以解決變量同步問題,但是如果多寫,同樣無法解決線程安全問題(同時寫有問題)
ThreadLocal無法解決共享對象的更新問題,ThreadLocal對象建議使用static修飾
下列情形,需要進(jìn)行參數(shù)校驗:
1) 調(diào)用頻次低的方法。
2) 執(zhí)行時間開銷很大的方法。
3) 需要極高穩(wěn)定性和可用性的方法。
4) 對外提供的開放接口,不管是RPC/API/HTTP接口。
5) 敏感權(quán)限入口。下列情形,不需要進(jìn)行參數(shù)校驗:
1) 極有可能被循環(huán)調(diào)用的方法。但在方法說明里必須注明外部參數(shù)檢查要求。
2) 底層調(diào)用頻度比較高的方法。畢竟是像純凈水過濾的最后一道,參數(shù)錯誤不太可能到底層才會暴露問題。一般DAO層與Service層都在同一個應(yīng)用中,部署在同一臺服務(wù)器中,所以DAO的參數(shù)校驗,可以省略。
3) 被聲明成private只會被自己代碼所調(diào)用的方法,如果能夠確定調(diào)用方法的代碼傳入?yún)?shù)已經(jīng)做過檢查或者肯定不會有問題,此時可以不校驗參數(shù)。防止NPE,是程序員的基本修養(yǎng),注意NPE產(chǎn)生的場景:
1)返回類型為基本數(shù)據(jù)類型,return包裝數(shù)據(jù)類型的對象時,自動拆箱有可能產(chǎn)生NPE。
2) 數(shù)據(jù)庫的查詢結(jié)果可能為null。
3) 集合里的元素即使isNotEmpty,取出的數(shù)據(jù)元素也可能為null。
4) 遠(yuǎn)程調(diào)用返回對象時,一律要求進(jìn)行空指針判斷,防止NPE。
5) 對于Session中獲取的數(shù)據(jù),建議NPE檢查,避免空指針。
6) 級聯(lián)調(diào)用obj.getA().getB().getC();一連串調(diào)用,易產(chǎn)生NPE。給JVM環(huán)境參數(shù)設(shè)置-XX:+HeapDumpOnOutOfMemoryError參數(shù),讓JVM碰到OOM場景時輸出dump信
在線上生產(chǎn)環(huán)境,JVM的Xms和Xmx設(shè)置一樣大小的內(nèi)存容量,避免在GC 后調(diào)整堆大小帶來的壓力
mysql
主鍵索引名為pk_字段名;唯一索引名為uk_字段名;普通索引名則為idx_字段名
小數(shù)類型為decimal,禁止使用float和double
表必備三字段:id, gmt_create, gmt_modified
說明: 其中 id必為 主鍵,類型必為 主鍵,類型bigint unsigned、單表時自增步長為 、單表時自增步長為 1。gmt_create, gmt_modified的類型均為 的類型均為 datetime類型,前者現(xiàn)在時表示主動創(chuàng)建后過去分詞被 類型,前者現(xiàn)在時表示主動創(chuàng)建后過去分詞被動更新單表行數(shù)超過500萬行或者單表容量超過2GB,才推薦進(jìn)行分庫分表
防止因字段類型不同造成的隱式轉(zhuǎn)換,導(dǎo)致索引失效
不要使用count(列名)或count(常量)來替代count(*)
in操作能避免則避免,若實在避免不了,需要仔細(xì)評估in后邊的集合元素數(shù)量,控制在1000個之內(nèi)
在表查詢中,一律不要使用 * 作為查詢的字段列表,需要哪些字段必須明確寫明
POJO類的布爾屬性不能加is,而數(shù)據(jù)庫字段必須加is_,要求在resultMap中進(jìn)行字段與屬性之間的映射
不要在列上使用函數(shù),這將導(dǎo)致索引失效而進(jìn)行全表掃描
應(yīng)該盡量避免在 where 子句中使用 != 或 not in 或 <> 操作符,因為這幾個操作符都會導(dǎo)致索引失效而進(jìn)行全表掃描
應(yīng)該盡量避免在 where 子句中使用 or 來連接條件,因為這會導(dǎo)致索引失效而進(jìn)行全表掃描
復(fù)合索引遵守“最左前綴”原則,即在查詢條件中使用了復(fù)合索引的第一個字段,索引才會被使用
索引不會包含有NULL值的列,因此,在數(shù)據(jù)庫設(shè)計時,除非有一個很特別的原因使用 NULL 值,不然盡量不要讓字段的默認(rèn)值為 NULL
當(dāng)查詢條件左右兩側(cè)類型不匹配的時候會發(fā)生隱式轉(zhuǎn)換,隱式轉(zhuǎn)換帶來的影響就是可能導(dǎo)致索引失效而進(jìn)行全表掃描