版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
目錄前言1一、編程規(guī)約2(一)命名規(guī)約2(二)常量定義4(三)格式規(guī)約5(四)OOP規(guī)約7(五)集合處理11(六)并發(fā)處理13(七)控制語句16(八)注釋規(guī)約17(九)其它18二、異常日志20(一)異常處理20(二)日志規(guī)約21三、MySQL規(guī)約23(一)建表規(guī)約23(二)索引規(guī)約25(三)SQL規(guī)約27(四)ORM規(guī)約28四、工程規(guī)約29(一)應(yīng)用分層29(二)二方庫規(guī)約30(三)服務(wù)器規(guī)約32五、安全規(guī)約33附1:版本歷史34附2:本規(guī)約專有名詞34附3:法律聲明34(注:全文瀏覽時(shí)請使用PDF左側(cè)導(dǎo)航欄)阿里巴巴Java開發(fā)手冊前言《阿里巴巴JavaJavaMySQL本手冊的愿景是碼出質(zhì)量、碼出高效。代碼的字里行間流淌的是軟件生命中的血《阿里巴巴Java地認(rèn)真總結(jié)”和“公眾號獲取最新版。1/阿里巴巴Java開發(fā)手冊Java開發(fā)手冊版本號制定團(tuán)隊(duì)更新日期備注阿里巴巴集團(tuán)技術(shù)團(tuán)隊(duì)一、編程規(guī)約(一)命名規(guī)約1.【強(qiáng)制】代碼中的命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結(jié)束。反例://///2.【強(qiáng)制】代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。也要避免采用。反例:[]/[評分]/int某變量=3正例:alibaba///等國際通用的名稱,可視同英文。3.UpperCamelCase(領(lǐng)域模型的相關(guān)命名)DO/BO//VO等。正例:////反例:////4.lowerCamelCase駝峰形式。正例://inputUserId5.【強(qiáng)制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長。正例:MAXSTOCK_反例:MAX6.【強(qiáng)制】抽象類命名使用Abstract或Base開頭;異常類命名使用Exception結(jié)尾;命名以它要測試的類的名稱開始,以Test7.【強(qiáng)制】中括號是數(shù)組類型的一部分,數(shù)組定義如下:反例:使用的方式來定義。2/阿里巴巴Java開發(fā)手冊8.【強(qiáng)制】POJO類中布爾類型的變量,都不要加is,否則部分框架解析會引起序列化錯(cuò)誤。反例:定義為基本數(shù)據(jù)類型Boolean;的屬性,它的方法也是isSuccess()RPC“以為”對應(yīng)的屬性名稱是success常。9.單數(shù)形式,但是類名如果有復(fù)數(shù)含義,類名可以使用復(fù)數(shù)形式。正例:應(yīng)用工具類包名為com..、類名為(此規(guī)則參考spring的框架結(jié)構(gòu))10.【強(qiáng)制】杜絕完全不規(guī)范的縮寫,避免望文不知義。反例:“縮寫”命名成AbsClass“縮寫”命名成condi隨意縮寫嚴(yán)重降低了代碼的可閱讀性。11.【推薦】如果使用到了設(shè)計(jì)模式,建議在類名中體現(xiàn)出具體模式。說明:將設(shè)計(jì)模式體現(xiàn)在名字中,有利于閱讀者快速理解架構(gòu)設(shè)計(jì)思想。正例:OrderFactory;LoginProxy;12.(也不要加Javadoc與接口方法相關(guān),并且是整個(gè)應(yīng)用的基礎(chǔ)常量。正例:接口方法簽名:void接口基礎(chǔ)常量表示:="alibaba;反例:接口方法定義:f();說明:JDK8中接口允許有默認(rèn)實(shí)現(xiàn),那么這個(gè)default方法,是對所有實(shí)現(xiàn)類都有價(jià)值的默認(rèn)實(shí)現(xiàn)。13.接口和實(shí)現(xiàn)類的命名有兩套規(guī)則:1)【強(qiáng)制】對于Service和DAO類,基于SOA的理念,暴露出來的服務(wù)一定是接口,內(nèi)部的實(shí)現(xiàn)類用Impl的后綴與接口區(qū)別。正例:CacheServiceImpl實(shí)現(xiàn)CacheService接口。2(通常是–able。正例:AbstractTranslator實(shí)現(xiàn)Translatable。14.【參考】枚舉類名建議帶上Enum后綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。說明:枚舉其實(shí)就是特殊的常量類,且構(gòu)造方法被默認(rèn)強(qiáng)制是私有。正例:枚舉名字:,成員名稱:SUCCESS/UNKOWNREASON。3/阿里巴巴Java開發(fā)手冊15.【參考】各層命名規(guī)約:A)DAO層方法命名規(guī)約1)獲取單個(gè)對象的方法用get做前綴。2)獲取多個(gè)對象的方法用list3)獲取統(tǒng)計(jì)值的方法用count做前綴。4)插入的方法用save()或insert做前綴。5)刪除的方法用remove()或delete做前綴。6)修改的方法用update做前綴。B)領(lǐng)域模型命名規(guī)約1)數(shù)據(jù)對象:xxxDOxxx即為數(shù)據(jù)表名。2)數(shù)據(jù)傳輸對象:xxxDTO,xxx為業(yè)務(wù)領(lǐng)域相關(guān)的名稱。3)展示對象:xxxVOxxx一般為網(wǎng)頁名稱。4)POJO是//BOVO的統(tǒng)稱,禁止命名成xxxPOJO。(二)常量定義1.【強(qiáng)制】不允許出現(xiàn)任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中。反例:="Id#_"+tradeId;cacheput(key,2.【強(qiáng)制】long或者Long初始賦值時(shí),必須使用大寫的L,不能是小寫的l,小寫容易跟數(shù)字1混淆,造成誤解。說明:Longa=l;寫的是數(shù)字的21,還是Long型的2?3.相關(guān)的常量放在類:CacheConsts下;系統(tǒng)配置相關(guān)的常量放在類:ConfigConsts下。說明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利于理解和維護(hù)。4.內(nèi)共享常量、類內(nèi)共享常量。1)跨應(yīng)用共享常量:放置在二方庫中,通常是client.jar中的constant目錄下。2)應(yīng)用內(nèi)共享常量:放置在一方庫的modules中的constant“是”的變量:類A中:="yes;類B中:="y;A.YES.equals(BYES),預(yù)期是,但實(shí)際返回為false,導(dǎo)致產(chǎn)生線上問題。4/阿里巴巴Java開發(fā)手冊3)子工程內(nèi)部共享常量:即在當(dāng)前子工程的constant目錄下。4)包內(nèi)共享常量:即在當(dāng)前包下單獨(dú)的constant目錄下。5)類內(nèi)共享常量:直接在類內(nèi)部privatefinal定義。5.【推薦】如果變量值僅在一個(gè)范圍內(nèi)變化用Enum類。如果還帶有名稱之外的延伸屬性,必須使用Enum類,下面正例中的數(shù)字就是延伸信息,表示星期幾。正例:publicEnum{MONDAY(1),TUESDAY(2),WEDNESDAY(3),THURSDAY(4),FRIDAY(5),SATURDAY(6),SUNDAY(7);}(三)格式規(guī)約1.{}是非空代碼塊則:1)左大括號前不換行。2)左大括號后換行。3)右大括號前換行。4)右大括號后還有else等代碼則不換行表示終止右大括號后必須換行。2.【強(qiáng)制】左括號和后一個(gè)字符之間不出現(xiàn)空格;同樣,右括號和前一個(gè)字符之間也不出現(xiàn)空格。詳見第5條下方正例提示。3.【強(qiáng)制】if/forwhile/switchdo等保留字與左右括號之間都必須加空格。4.【強(qiáng)制】任何運(yùn)算符左右必須加一個(gè)空格。說明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號、三目運(yùn)算符等。5.【強(qiáng)制】縮進(jìn)采用4個(gè)空格,禁止使用tab說明:如果使用tab縮進(jìn),必須設(shè)置1個(gè)tab為4個(gè)空格。IDEA設(shè)置tab為4個(gè)空格時(shí),請勿勾選Usetabcharacter;而在eclipse中,必須勾選insertspacesfortabs。正例:(涉及1-5點(diǎn))publicstaticvoidmain(String[]args){//縮進(jìn)4個(gè)空格Stringsay="hello";//運(yùn)算符的左右必須有一個(gè)空格intflag=0;//關(guān)鍵詞if與括號之間必須有一個(gè)空格,括號內(nèi)的f與左括號,0與右括號不需要空格if(flag==0){System.out.println(say);}//左大括號前加空格且不換行;左大括號后換行if(flag==1){System.out.println("world");//右大括號前換行,右大括號后有else,不用換行5/阿里巴巴Java開發(fā)手冊}else{System.out.println("ok");//在右大括號后直接結(jié)束,則必須換行}}6.【強(qiáng)制】單行字符數(shù)限制不超過120個(gè),超出需要換行,換行時(shí)遵循如下原則:1)第二行相對第一行縮進(jìn)4個(gè)空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。2)運(yùn)算符與下文一起換行。3)方法調(diào)用的點(diǎn)符號與下文一起換行。4)在多個(gè)參數(shù)超長,逗號后進(jìn)行換行。5)在括號前不要換行,見反例。正例:StringBuffersb=newStringBuffer();//超過120個(gè)字符的情況下,換行縮進(jìn)4個(gè)空格,并且方法前的點(diǎn)符號一起換行sb.append("zi").append("xin")append("huang")append("huang")append("huang");反例:StringBuffersb=newStringBuffer();//超過120個(gè)字符的情況下,不要在括號前換行sb.append("zi").append("xin")...append("huang");//參數(shù)很多的方法調(diào)用可能超過120個(gè)字符,不要在逗號前換行method(args1,args2,args3,...,argsX);7.【強(qiáng)制】方法參數(shù)在定義和傳入時(shí),多個(gè)參數(shù)逗號后邊必須加空格。正例:下例中實(shí)參的"a",后邊必須要有一個(gè)空格。method("a","b","c");8.【強(qiáng)制】IDE的fileencodingUTF;IDE中文件的換行符使用Unix不要使用windows9.【推薦】沒有必要增加若干空格來使某一行的字符與上一行的相應(yīng)字符對齊。正例:inta=3;longb=4L;floatc=5F;StringBuffersb=newStringBuffer();說明:增加sb這個(gè)變量,如果需要對齊,則給a、bc都要增加幾個(gè)空格,在變量比較多的情況下,是一種累贅的事情。6/阿里巴巴Java開發(fā)手冊10.【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組、不同的業(yè)務(wù)邏輯之間或者不同的語義之間插入一個(gè)空行。相同業(yè)務(wù)邏輯和語義之間不需要插入空行。說明:沒有必要插入多行空格進(jìn)行隔開。(四)OOP規(guī)約1.本,直接用類名來訪問即可。2.【強(qiáng)制】所有的覆寫方法,必須加@Override注解。與getO0@譯報(bào)錯(cuò)。3.【強(qiáng)制】相同參數(shù)類型,相同業(yè)務(wù)含義,才可以使用Java的可變參數(shù),避免使用。說明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學(xué)們盡量不用可變參數(shù)編程)正例:publicUsergetUsers(Stringtype,Integer...ids)4.影響。接口過時(shí)必須加@Deprecated注解,并清晰地說明采用的新接口或者新服務(wù)是什么。5.【強(qiáng)制】不能使用過時(shí)的類或方法。javanet.中的方法decode(StringencodeStr)這個(gè)方法已經(jīng)過時(shí),應(yīng)該使用雙參數(shù)decode(String。接口提供方既然明確是過時(shí)接口,那么有義務(wù)同時(shí)提供新的接口;作為調(diào)用方來說,有義務(wù)去考證過時(shí)方法的新實(shí)現(xiàn)是什么。6.【強(qiáng)制】Object的equals方法容易拋空指針異常,應(yīng)使用常量或確定有值的對象來調(diào)用equals。正例:"test"反例:""說明:推薦使用javautil.(JDK7引入的工具類)7.【強(qiáng)制】所有的相同類型的包裝類對象之間值的比較,全部使用equals方法比較。說明:對于Integer=?在-128至127之間的賦值,Integer對象是在.cacheInteger值可以直接使用==進(jìn)行推薦使用equals方法進(jìn)行判斷。7/阿里巴巴Java開發(fā)手冊8.關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:1)【強(qiáng)制】所有的POJO類屬性必須使用包裝數(shù)據(jù)類型。2)【強(qiáng)制】RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。3)【推薦】所有的局部變量使用基本數(shù)據(jù)類型。說明:POJO類屬性沒有初值是提醒使用者在需要使用時(shí),必須自己顯式地進(jìn)行賦值,任何NPE問題,或者入庫檢查,都由使用者來保證。正例:數(shù)據(jù)庫的查詢結(jié)果可能是null,因?yàn)樽詣硬鹣?,用基本?shù)據(jù)類型接收有NPE比如顯示成交總額漲跌情況,即正負(fù)x%xRPC0%-數(shù)據(jù)類型的null值,能夠表示額外的信息,如:遠(yuǎn)程調(diào)用失敗,異常退出。9.【強(qiáng)制】定義DO/DTOVO等POJO類時(shí),不要設(shè)定任何屬性默認(rèn)值。反例:POJO類的gmtCreate默認(rèn)值為但是這個(gè)屬性在數(shù)據(jù)提取時(shí)并沒有置入具體值,在更新其它字段時(shí)又附帶更新了此字段,導(dǎo)致創(chuàng)建時(shí)間被修改成當(dāng)前時(shí)間。10.【強(qiáng)制】序列化類新增屬性時(shí),請不要修改serialVersionUID字段,避免反序列失?。蝗绻耆患嫒萆?,避免反序列化混亂,那么請修改serialVersionUID值。說明:注意serialVersionUID不一致會拋出序列化運(yùn)行時(shí)異常。11.【強(qiáng)制】構(gòu)造方法里面禁止加入任何業(yè)務(wù)邏輯,如果有初始化邏輯,請放在init方法中。12.【強(qiáng)制】POJOtoStringIDE的中工具:source>時(shí),如果繼承了另一個(gè)POJO類,注意在前面加一下supertoString。POJO的toString()查問題。13.【推薦】使用索引訪問用String的split方法得到的數(shù)組時(shí),需做最后一個(gè)分隔符后有無內(nèi)容的檢查,否則會有拋IndexOutOfBoundsException的風(fēng)險(xiǎn)。說明:Stringstr="a,b,c,,";String[]ary=str.split(",");//預(yù)期大于3,結(jié)果是3System.out.println(ary.length);14.【推薦】當(dāng)一個(gè)類有多個(gè)構(gòu)造方法,或者多個(gè)同名方法,這些方法應(yīng)該按順序放置在一起,便于閱讀。8/阿里巴巴Java開發(fā)手冊15.【推薦】類內(nèi)方法定義順序依次是:公有方法或保護(hù)方法>私有方法>getter/方法。保護(hù)方法雖然只是子類“模板設(shè)計(jì)模式”下的核心方法黑盒實(shí)現(xiàn);因?yàn)榉椒ㄐ畔r(jià)值較低,所有Service和DAO的/setter方法放在類體最后。16.【推薦】setter方法中,參數(shù)名稱與類成員變量名稱一致,this成員名=參數(shù)名。在getter/setter方法中,盡量不要增加業(yè)務(wù)邏輯,增加排查問題的難度。反例:publicIntegergetData(){if(true){returndata+100;}else{returndata-100;}}17.【推薦】循環(huán)體內(nèi),字符串的連接方式,使用StringBuilder的append方法進(jìn)行擴(kuò)展。反例:Stringstr="start";for(intI=0;I<i++){str=str+"hello";}說明:反編譯出的字節(jié)碼文件顯示每次循環(huán)都會new出一個(gè)StringBuilder對象,然后進(jìn)行append操作,最后通過toString方法返回String對象,造成內(nèi)存資源浪費(fèi)。18.【推薦】下列情況,聲明成final會更有提示性:1)不需要重新賦值的變量,包括類屬性、局部變量。2)對象參數(shù)前加final,表示不允許修改引用的指向。3)類方法確定不允許被重寫。19.【推薦】慎用Object的clone方法來拷貝對象。說明:對象的clone方法默認(rèn)是淺拷貝,若想實(shí)現(xiàn)深拷貝需要重寫clone方法實(shí)現(xiàn)屬性對象的拷貝。9/阿里巴巴Java開發(fā)手冊20.【推薦】類成員與方法訪問控制從嚴(yán):1)如果不允許外部直接通過new來創(chuàng)建對象,那么構(gòu)造方法必須是private。2)工具類不允許有public或default構(gòu)造方法。3)類非static成員變量并且與子類共享,必須是protected。4)類非static成員變量并且僅在本類使用,必須是private。5)類static成員變量如果僅在本類使用,必須是private。6)若是static成員變量,必須考慮是否為final。7)類成員方法只供類內(nèi)部調(diào)用,必須是private。8)類成員方法只對繼承類公開,那么限制為protected。privatepublic的Service個(gè)public的成員變量,刪除一下,不得手心冒點(diǎn)汗嗎?變量像自己的小孩,盡量在自己的視線內(nèi),變量作用域太大,如果無限制的到處跑,那么你會擔(dān)心的。/阿里巴巴Java開發(fā)手冊(五)集合處理1.【強(qiáng)制】關(guān)于hashCode和equals的處理,遵循如下規(guī)則:1)只要重寫,就必須重寫hashCode。2)因?yàn)镾et存儲的是不重復(fù)的對象,依據(jù)hashCode和equals進(jìn)行判斷,所以Set存儲的對象必須重寫這兩個(gè)方法。3)如果自定義對象做為Map的鍵,那么必須重寫hashCode和equals。說明:String重寫了hashCode和equals方法,所以我們可以非常愉快地使用String作為key來使用。2.【強(qiáng)制】ArrayList的subList結(jié)果不可強(qiáng)轉(zhuǎn)成異常:java....;說明:subListSubList,并不是,而是的一個(gè)視圖,對于SubList子列表的所有操作最終會反映到原列表上。3.【強(qiáng)制】在subList場景中,高度注意對原集合元素個(gè)數(shù)的修改,會導(dǎo)致子列表的遍歷、增加、刪除均產(chǎn)生異常。4.【強(qiáng)制】使用集合轉(zhuǎn)數(shù)組的方法,必須使用集合的toArray(T[]array),傳入的是類型完全一樣的數(shù)組,大小就是list.。使用toArraytoArray方法內(nèi)部將重新分配內(nèi)存空間,并返回新數(shù)組地址;如果數(shù)組元素大于實(shí)際所需,下標(biāo)為[list]元素將被置為null,其它數(shù)組元素保持原值,因此最好將方法入?yún)?shù)組大小定義與集合元素個(gè)數(shù)一致。正例:List<String>list=newArrayList<String>(2);list.add("guan");list.add("bao");String[]array=newString[list.size()];array=list.toArray(array);反例:直接使用toArray無參方法存在問題,此方法返回值只能是Object[]類,若強(qiáng)轉(zhuǎn)其它類型數(shù)組將出現(xiàn)ClassCastException錯(cuò)誤。5.【強(qiáng)制】使用工具類ArraysasList()把數(shù)組轉(zhuǎn)換成集合時(shí),不能使用其修改集合相關(guān)的方法,它的addremoveclear方法會拋出UnsupportedOperationException異常。asList的返回對象是一個(gè)ArraysArraysasList體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口,后臺的數(shù)據(jù)仍是數(shù)組。String[]str=newString[]{"a","b"};Listlist=Arrays.asList(str);/阿里巴巴Java開發(fā)手冊第一種情況:list.add("c");運(yùn)行時(shí)異常。第二種情況:str[0]="gujin";那么list.get(0)也會隨之修改。6.【強(qiáng)制】泛型通配符<?extendsT>來接收返回的數(shù)據(jù),此寫法的泛型集合不能使用add方法,而<?T>get方法,做為接口調(diào)用賦值時(shí)易出錯(cuò)。說明:擴(kuò)展說一下Super)1)頻繁往外讀取內(nèi)容的,適合用上界Extends。2)經(jīng)常往里插入的,適合用下界Super。7.foreach循環(huán)里進(jìn)行元素的removeaddremove元素請使用方式,如果并發(fā)操作,需要對Iterator對象加鎖。反例:List<String>a=newArrayList<String>();a.add("1");a.add("2");for(Stringtemp:a){if("1".equals(temp)){a.remove(temp);}}說明:以上代碼的執(zhí)行結(jié)果肯定會出乎大家的意料,那么試一下把“1”換成“2”,會是同樣的結(jié)果嗎?正例:Iterator<String>it=a.iterator();while(it.hasNext()){Stringtemp=it.next();if(刪除元素的條件){it.remove();}}8.【強(qiáng)制】在JDK7版本及以上,Comparator要滿足如下三個(gè)條件,不然Arrays.,CollectionssortIllegalArgumentException異常。說明:1)xy的比較結(jié)果和y,x的比較結(jié)果相反。2)x>yy>z,則>z。3)x=y,則xzy,z比較結(jié)果相同。反例:下例中沒有處理相等的情況,實(shí)際使用中可能會出現(xiàn)異常:newComparator<Student>(){@Overridepublicintcompare(Studento1,Studento2){returno1.getId()>o2.getId()?1:-1;}}/阿里巴巴Java開發(fā)手冊9.【推薦】集合初始化時(shí),盡量指定集合初始值大小。說明:ArrayList10.【推薦】使用entrySet遍歷Map類集合KVkeySet方式進(jìn)行遍歷。說明:keySet其實(shí)是遍歷了2次,一次是轉(zhuǎn)為Iterator對象,另一次是從hashMapkey所對應(yīng)的valueentrySet只是遍歷了一次就把key和value都放到了entry率更高。如果是JDK,使用Mapforeach方法。values()Vlist集合對象keySet()返回的是K一個(gè)Set集合對象entrySet()返回的是KV值組合集合。11.【推薦】高度注意Map類集合K/Vnull值的情況,如下表格:KeyValueSuper集合類說明HashtableConcurrentHashMapTreeMap不允許為null不允許為null不允許為null允許為null不允許為nullDictionary不允許為nullAbstractMap線程安全分段鎖技術(shù)線程不安全線程不安全允許為null允許為nullAbstractMapAbstractMapHashMap反例:由于HashMapConcurrentHashMapnull值,注意存儲null值時(shí)會拋出NPE異常。12.【參考】合理利用好集合的有序性(sort)(order),避免集合的無序性(unsort)和不穩(wěn)定性(unorder)帶來的負(fù)面影響。序是一定的。如:ArrayList是order;HashMap是/unsortTreeSet是ordersort。13.【參考】利用Set元素唯一的特性,可以快速對一個(gè)集合進(jìn)行去重操作,避免使用List的contains方法進(jìn)行遍歷、對比、去重操作。(六)并發(fā)處理1.【強(qiáng)制】獲取單例對象需要保證線程安全,其中的方法也要保證線程安全。說明:資源驅(qū)動類、工具類、單例工廠類都需要注意。2.【強(qiáng)制】創(chuàng)建線程或線程池時(shí)請指定有意義的線程名稱,方便出錯(cuò)時(shí)回溯。正例:publicclassTimerTaskThreadextendsThread{publicTimerTaskThread(){super.setName("TimerTaskThread");...}/阿里巴巴Java開發(fā)手冊3.【強(qiáng)制】線程資源必須通過線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程?!斑^度切換”的問題。4.ExecutorsThreadPoolExecutor的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。說明:Executors返回的線程池對象的弊端如下:1)FixedThreadPool和:允許的請求隊(duì)列長度為Integer.MAX_VALUE,可能會堆積大量的請求,從而導(dǎo)致OOM。2)CachedThreadPool和:允許的創(chuàng)建線程數(shù)量為Integer.MAX_VALUE,可能會創(chuàng)建大量的線程,從而導(dǎo)致OOM。5.【強(qiáng)制】是線程不安全的類,一般不要定義為static變量,如果定義為static,必須加鎖,或者使用DateUtils正例:注意線程安全,使用DateUtils。亦推薦如下處理:privatestaticfinalThreadLocal<DateFormat>df=newThreadLocal<DateFormat>(){@OverrideprotectedDateFormatinitialValue(){returnnewSimpleDateFormat("yyyy-MM-dd");}};說明:如果是JDK8的應(yīng)用,可以使用Instant代替DateLocalDateTime代替,DateTimeFormatter代替simplebeautifulstrongthreadsafe。6.能鎖區(qū)塊,就不要鎖整個(gè)方法體;能用對象鎖,就不要用類鎖。7.成死鎖。線程一需要對表ABC也必須是A、B、C,否則可能出現(xiàn)死鎖。8.鎖,要么在數(shù)據(jù)庫層使用樂觀鎖,使用version作為更新依據(jù)。如果每次訪問沖突概率小于20%數(shù)不得小于3次。9.【強(qiáng)制】多線程并行處理定時(shí)任務(wù)時(shí),Timer運(yùn)行多個(gè)TimeTask時(shí),只要其中之一沒有捕獲ScheduledExecutorService則沒有這個(gè)問題。/阿里巴巴Java開發(fā)手冊10.【推薦】使用CountDownLatch進(jìn)行異步轉(zhuǎn)同步操作,每個(gè)線程退出前必須調(diào)用countDown方法,線程執(zhí)行代碼注意catch異常,確保countDown方法可以執(zhí)行,避免主線程無法執(zhí)行至await方法,直到超時(shí)才返回結(jié)果。說明:注意,子線程拋出異常堆棧,不能在主線程trycatch到。11.【推薦】避免Random實(shí)例被多線程使用,雖然共享該實(shí)例是線程安全的,但會因競爭同一seed導(dǎo)致的性能下降。說明:Randomjava..的實(shí)例或者M(jìn)ath.實(shí)例。正例:在JDK7之后,可以直接使用API,在JDK7之前,可以做到每個(gè)線程一個(gè)實(shí)例。12.【推薦】在并發(fā)場景下,通過雙重檢查鎖(double-)實(shí)現(xiàn)延遲初始化的優(yōu)化問題隱患(可參考"DoubleLockingisBroken"題解決方案中較為簡單一種(適用于JDK5及以上版本),將目標(biāo)屬性聲明為volatile。反例:classFoo{privateHelperhelper=null;publicHelpergetHelper(){if(helper==null)synchronized(this){if(helper==null)helper=newHelper();}returnhelper;}//otherfunctionsandmembers...}13.【參考】volatile解決多線程內(nèi)存不可見問題。對于一寫多讀,是可以解決變量同步問題,但是如果多寫,同樣無法解決線程安全問題。如果是count++操作,使用如下類實(shí)現(xiàn):=newcountaddAndGet(1如果是JDK8薦使用LongAdderAtomicLong(減少樂觀鎖的重試次數(shù))。14.【參考】HashMap在容量不夠進(jìn)行resize時(shí)由于高并發(fā)可能出現(xiàn)死鏈,導(dǎo)致CPU開發(fā)過程中注意規(guī)避此風(fēng)險(xiǎn)。15.【參考】ThreadLocal無法解決共享對象的更新問題,ThreadLocal對象建議使用static此靜態(tài)變量(只要是這個(gè)線程內(nèi)定義的)都可以操控這個(gè)變量。/阿里巴巴Java開發(fā)手冊(七)控制語句1.switchcasebreakreturn序?qū)⒗^續(xù)執(zhí)行到哪一個(gè)case;在一個(gè)switch塊內(nèi),都必須包含一個(gè)default放在最后,即使它什么代碼也沒有。2.【強(qiáng)制】在if//for/whiledo語句中必須使用大括號,即使只有一行代碼,避免使用下面的形式:if(condition)statements;3.【推薦】推薦盡量少用else,-else的方式可以改寫成:if(condition){...returnobj;}//接著寫else的業(yè)務(wù)邏輯代碼;說明:如果非得使用if()...else方式表達(dá)邏輯,【強(qiáng)制】請勿超過3層,超過請使用狀態(tài)設(shè)計(jì)模式。正例:邏輯上超過3層的if-else代碼可以使用衛(wèi)語句,或者狀態(tài)模式來實(shí)現(xiàn)。4.getXxx/isXxx雜邏輯判斷的結(jié)果賦值給一個(gè)有意義的布爾變量名,以提高可讀性。很多樣的條件執(zhí)行什么樣的語句,那么,如果閱讀者分析邏輯表達(dá)式錯(cuò)誤呢?正例://偽代碼如下booleanexisted=(file.open(fileName,"w")!=null)(...)||(...);if(existed){...}反例:if((file.open(fileName,"w")!=null)||(...)){...}5.【推薦】循環(huán)體中的語句要考量性能,以下操作盡量移至循環(huán)體外處理,如定義對象、變量、trycatch(這個(gè)trycatch是否可以移至循環(huán)體外。6.【推薦】接口入?yún)⒈Wo(hù),這種場景常見的是用于做批量操作的接口。7.【參考】方法中需要進(jìn)行參數(shù)校驗(yàn)的場景:1)調(diào)用頻次低的方法。2)執(zhí)行時(shí)間開銷很大的方法,參數(shù)校驗(yàn)時(shí)間幾乎可以忽略不計(jì),但如果因?yàn)閰?shù)錯(cuò)誤導(dǎo)致中間執(zhí)行回退,或者錯(cuò)誤,那得不償失。/阿里巴巴Java開發(fā)手冊3)需要極高穩(wěn)定性和可用性的方法。4)對外提供的開放接口,不管是RPC/HTTP接口。5)敏感權(quán)限入口。8.【參考】方法中不需要參數(shù)校驗(yàn)的場景:1)極有可能被循環(huán)調(diào)用的方法,不建議對參數(shù)進(jìn)行校驗(yàn)。但在方法說明里必須注明外部參數(shù)檢查要求。2)底層的方法調(diào)用頻度都比較高,一般不校驗(yàn)。畢竟是像純凈水過濾的最后一道,參數(shù)錯(cuò)誤不太可能到底層才會暴露問題。一般DAOService層都在同一個(gè)應(yīng)用中,部署在同一臺服務(wù)器中,所以DAO的參數(shù)校驗(yàn),可以省略。3)被聲明成private只會被自己代碼所調(diào)用的方法,如果能夠確定調(diào)用方法的代碼傳入?yún)?shù)已經(jīng)做過檢查或者肯定不會有問題,此時(shí)可以不校驗(yàn)參數(shù)。(八)注釋規(guī)約1.Javadoc/**內(nèi)容*///xxx方式。在IDEJavadocJavadoc可以正確輸出相應(yīng)注釋;在IDE閱讀效率。2.【強(qiáng)制】所有的抽象方法(包括接口中的方法)必須要用Javadoc注釋、除了返回值、參數(shù)、異常說明外,還必須指出該方法做什么事情,實(shí)現(xiàn)什么功能。說明:對子類的實(shí)現(xiàn)要求,或者調(diào)用注意事項(xiàng),請一并說明。3.【強(qiáng)制】所有的類都必須添加創(chuàng)建者信息。4.【強(qiáng)制】方法內(nèi)部單行注釋,在被注釋語句上方另起一行,使用//注釋。方法內(nèi)部多行注釋使用/**/注釋,注意與代碼對齊。5.【強(qiáng)制】所有的枚舉類型字段必須要有注釋,說明每個(gè)數(shù)據(jù)項(xiàng)的用途。6.【推薦】與其“半吊子”英文來注釋,不如用中文注釋把問題說清楚。專有名詞與關(guān)鍵字保持英文原文即可。反例:“TCP連接超時(shí)解釋成“傳輸控制協(xié)議連接超時(shí)”,理解反而費(fèi)腦筋。7.等的修改。就失去了導(dǎo)航的意義。/阿里巴巴Java開發(fā)手冊8.【參考】注釋掉的代碼盡量要配合說明,而不是簡單的注釋掉。1)2)有備注信息,難以知曉注釋動機(jī)。后者建議直接刪掉(代碼倉庫保存了歷史代碼)。9.;;注釋也是給繼任者看的,使其能夠快速接替自己的工作。10.【參考】好的命名、代碼結(jié)構(gòu)是自解釋的,注釋力求精簡準(zhǔn)確、表達(dá)到位。避免出現(xiàn)注釋的一個(gè)極端:過多過濫的注釋,代碼的邏輯一旦修改,修改注釋是相當(dāng)大的負(fù)擔(dān)。反例://putelephantintofridgeput(elephant,fridge);方法名putelephant和義清晰的代碼不需要額外的注釋。11.經(jīng)常清理此類標(biāo)記。線上故障有時(shí)候就是來源于這些標(biāo)記處的代碼。1)待辦事宜():(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])Javadoc(因?yàn)樗且粋€(gè)Javadoc。2)錯(cuò)誤,不能工作(FIXME)(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])在注釋中用FIXME標(biāo)記某代碼是錯(cuò)誤的,而且不能工作,需要及時(shí)糾正的情況。(九)其它1.【強(qiáng)制】在使用正則表達(dá)式時(shí),利用好其預(yù)編譯功能,可以有效加快正則匹配速度。說明:不要在方法體內(nèi)定義:Pattern=compile();2.velocityPOJO規(guī)范調(diào)用POJO的getXxx(),如果是boolean基本數(shù)據(jù)類型變量boolean命名不需要加前綴),會自動調(diào)用isXxx()方法。說明:注意如果是Boolean包裝類對象,優(yōu)先調(diào)用getXxx()3.【強(qiáng)制】后臺輸送給頁面的變量必須加$!{var}——中間的感嘆號。說明:如果varnull或者不存在,那么${var}會直接顯示在頁面上。4.Math.這個(gè)方法返回是double0≤x能夠取到零值,注意除零異常),如果想獲取整數(shù)類型的隨機(jī)數(shù),不要將x放大10的若干倍然后取整,直接使用Random對象的nextInt或者nextLong方法。/阿里巴巴Java開發(fā)手冊5.【強(qiáng)制】獲取當(dāng)前毫秒數(shù)System.而不是.System.JDK8時(shí)間等場景,推薦使用Instant類。6.【推薦】盡量不要在velocity模板中加入變量聲明、邏輯運(yùn)算符,更不要在模板中加入任何復(fù)雜的邏輯。7.【推薦】任何數(shù)據(jù)結(jié)構(gòu)的構(gòu)造或初始化,都應(yīng)指定大小,避免數(shù)據(jù)結(jié)構(gòu)無限增長吃光內(nèi)存。8.【推薦】對于“明確停止使用的代碼和配置”,如方法、變量、類、配置文件、動態(tài)配置屬性等要堅(jiān)決從程序中清理出去,避免造成過多垃圾。/阿里巴巴Java開發(fā)手冊二、異常日志(一)異常處理1.【強(qiáng)制】Java類庫中定義的一類RuntimeException可以通過預(yù)先檢查進(jìn)行規(guī)避,而不應(yīng)該通過catch來處理,比如:,NullPointerExceptioncatchNumberFormatException來實(shí)現(xiàn)。正例:if(obj!=null){...}反例:try{obj.method()}catch(NullPointerExceptione){...}2.【強(qiáng)制】異常不要用來做流程控制,條件控制,因?yàn)楫惓5奶幚硇时葪l件分支低。3.trycatchcatch時(shí)請分清穩(wěn)定代碼和非穩(wěn)catch盡可能進(jìn)行區(qū)分異常類型,再做對應(yīng)的異常處理。4.內(nèi)容。5.trycatch滾事務(wù)。6.【強(qiáng)制】finally塊必須對資源對象、流對象進(jìn)行關(guān)閉,有異常也要做trycatch。說明:如果JDK7及以上,可以使用try-resources方式。7.finally塊中使用returnfinally塊中的return會再執(zhí)行try塊中的return語句。8.【強(qiáng)制】捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。說明:如果預(yù)期對方拋的是繡球,實(shí)際接到的是鉛球,就會產(chǎn)生意外情況。9.【推薦】方法的返回值可以為null,不強(qiáng)制返回空集合,或者空對象等,必須添加注釋充分說明什么情況下會返回null值。調(diào)用方需要進(jìn)行null判斷防止NPE問題。本規(guī)約明確防止NPE者來說,也并非高枕無憂,必須考慮到遠(yuǎn)程調(diào)用失敗,運(yùn)行時(shí)異常等場景返回null/阿里巴巴Java開發(fā)手冊10.【推薦】防止NPE,是程序員的基本修養(yǎng),注意NPE產(chǎn)生的場景:1)返回類型為包裝數(shù)據(jù)類型,有可能是null,返回int值時(shí)注意判空。反例:{Integer對象};如果為null,自動解箱拋。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...;一連串調(diào)用,易產(chǎn)生NPE。正例:可以使用JDK8的Optional類來防止NPE問題。11.【推薦】在代碼中使用“拋異?!边€是“返回錯(cuò)誤碼”,對于公司外的http/api開放接口必須使用“錯(cuò)誤碼”;而應(yīng)用內(nèi)部推薦異常拋出;跨應(yīng)用間RPC調(diào)用優(yōu)先考慮使用Result方式裝isSuccess、“”、“錯(cuò)誤簡短信息”。說明:關(guān)于RPC方法返回方式使用Result方式的理由:1)使用拋異常返回方式,調(diào)用方如果沒有捕獲到就會產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。2)如果不加棧信息,只是new自定義異常,加入自己的理解的error,對于調(diào)用的性能損耗也是問題。12.【推薦】定義時(shí)區(qū)分unchecked/異常,避免直接使用RuntimeException更不允許拋出Exception或者過的自定義異常,如:/ServiceException等。13.【參考】避免出現(xiàn)重復(fù)的代碼(Don’t),即DRY原則。本,容易遺漏。必要時(shí)抽取共性方法,或者抽象公共類,甚至是共用模塊。一個(gè)類中有多個(gè)publicprivatebooleancheckParam(DTOdto){...}(二)日志規(guī)約1.(Logj中的SLFJ中的API,使用門面模式的日志框架,有利于維護(hù)和各個(gè)類的日志處理方式統(tǒng)一。importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;privatestaticfinalLoggerlogger=LoggerFactory.getLogger(Abc.class);2.【強(qiáng)制】日志文件推薦至少保存15天,因?yàn)橛行┊惓>邆湟浴爸堋睘轭l次發(fā)生的特點(diǎn)。3.【強(qiáng)制】應(yīng)用中的擴(kuò)展日志(如打點(diǎn)、臨時(shí)監(jiān)控、訪問日志等)命名方式:appName_.loglogType日志類型,推薦分類有/阿里巴巴Java開發(fā)手冊statsdescmonitorvisit等logName:日志描述。這種命名的好處:通過文件名就可知道日志文件屬于什么應(yīng)用,什么類型,什么目的,也有利于歸類查找。正例:mppserver應(yīng)用中單獨(dú)監(jiān)控時(shí)區(qū)轉(zhuǎn)換異常,如:mppservermonitor_.通過日志對系統(tǒng)進(jìn)行及時(shí)監(jiān)控。4.tracedebug/info式。說明:logger."with:"+id+"symbol:"+如果日志級別是warnsymbol會執(zhí)行toString()方法,浪費(fèi)了系統(tǒng)資源,執(zhí)行了上述操作,最終日志卻沒有打印。正例:(條件)if(logger.isDebugEnabled()){logger.debug("Processingtradewithid:"++"symbol:"+symbol);}正例:(占位符)logger.debug("Processingtradewithid:{}symbol:{}",id,symbol);5.【強(qiáng)制】避免重復(fù)打印日志,浪費(fèi)磁盤空間,務(wù)必在logj.xmladditivity=false。正例:<loggername="com.taobao.dubbo.config"additivity="false">6.關(guān)鍵字throws往上拋出。正例:logger.error(各類參數(shù)或者對象toString+"_"+e.getMessage(),e);7.【推薦】謹(jǐn)慎地記錄日志。生產(chǎn)環(huán)境禁止輸出debug日志;有選擇地輸出info;用warn來記錄剛上線時(shí)的業(yè)務(wù)行為信息,一定要注意日志輸出量的問題,避免把服務(wù)器磁盤撐爆,并記得及時(shí)刪除這些觀察日志。思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問題排查帶來好處?8.【參考】可以使用warn日志級別來記錄用戶輸入?yún)?shù)錯(cuò)誤的情況,避免用戶投訴時(shí),無所適error要,請不要在此場景打出error級別。/阿里巴巴Java開發(fā)手冊三、MySQL規(guī)約(一)建表規(guī)約1._xxxunsignedtinyint(1表示是,0表示否)。說明:任何字段如果為非負(fù)數(shù),必須是unsigned。2.,正例:getter_,task_,3_name反例:GetterAdmintaskConfig,levelname3.【強(qiáng)制】表名不使用復(fù)數(shù)名詞。說明:表名應(yīng)該僅僅表示表里面的實(shí)體內(nèi)容,不應(yīng)該表示實(shí)體數(shù)量,對應(yīng)于DO類名也是單數(shù)形式,符合表達(dá)習(xí)慣。4.【強(qiáng)制】禁用保留字,如desc、rangematch、delayed等,請參考MySQL官方保留字。5.【強(qiáng)制】主鍵索引名為pk_字段名;唯一索引名為uk_字段名;普通索引名則為idx_字段名。說明:pk_即keyuk_即key;idx_即index的簡稱。6.【強(qiáng)制】小數(shù)類型為decimal,禁止使用float和double。說明:float和double在存儲的時(shí)候,存在精度損失的問題,很可能在值的比較時(shí),得到不decimal7.【強(qiáng)制】如果存儲的字符串長度幾乎相等,使用char定長字符串類型。8.【強(qiáng)制】varchar是可變長字符串,不預(yù)先分配存儲空間,長度不要超過5000,如果存儲長度大于此值,定義字段類型為text,獨(dú)立出來一張表,用主鍵來對應(yīng),避免影響其它字段索引效率。9.【強(qiáng)制】表必備三字段:id,gmtcreate,gmtmodified。說明:其中id必為主鍵,類型為bigint、單表時(shí)自增、步長為1。gmt,gmtmodifieddate_time10.【推薦】表的命名最好是加上“業(yè)務(wù)名稱_表的作用”。正例:tigertask/tiger/_config11.【推薦】庫名與應(yīng)用名稱盡量一致。12.【推薦】如果修改字段含義或?qū)ψ侄伪硎镜臓顟B(tài)追加時(shí),需要及時(shí)更新字段注釋。/阿里巴巴Java開發(fā)手冊13.1)不是頻繁修改的字段。2)不是varchar超長字段,更不能是text字段。儲類目名稱,避免關(guān)聯(lián)查詢。14.【推薦】單表行數(shù)超過500萬行或者單表容量超過2GB,才推薦進(jìn)行分庫分表。說明:如果預(yù)計(jì)三年后的數(shù)據(jù)量根本達(dá)不到這個(gè)級別,請不要在創(chuàng)建表時(shí)就分庫分表。15.【參考】合適的字符存儲長度,不但節(jié)約數(shù)據(jù)庫表空間、節(jié)約索引存儲,更重要的是提升檢索速度。正例:無符號值可以避免誤存負(fù)數(shù),且擴(kuò)大了表示范圍。對象150數(shù)百歲類型int0到人龜0到太陽約500到約42.9億bigint0到約10的/阿里巴巴Java開發(fā)手冊(二)索引規(guī)約1.【強(qiáng)制】業(yè)務(wù)上具有唯一特性的字段,即使是組合字段,也必須建成唯一索引。說明:不要以為唯一索引影響了insert速度,這個(gè)速度損耗可以忽略,但提高查找速度是明顯的;然有臟數(shù)據(jù)產(chǎn)生。2.【強(qiáng)制】超過三個(gè)表禁止join。需要join的字段,數(shù)據(jù)類型必須絕對一致;多表關(guān)聯(lián)查詢時(shí),保證被關(guān)聯(lián)的字段需要有索引。說明:即使雙表join也要注意表索引、SQL性能。3.varchar實(shí)際文本區(qū)分度決定索引長度即可。索引的長度與區(qū)分度是一對矛盾體,一般對字符串類型數(shù)據(jù),長度為20的索引,區(qū)分度會高達(dá)90%以上,可以使用left(列名,索引長度))/*)來確定。4.【強(qiáng)制】頁面搜索嚴(yán)禁左模糊或者全模糊,如果需要請走搜索引擎來解決。索引文件具有B-Tree的最左前綴匹配特性,如果左邊的值未確定,那么無法使用此索引。5.【推薦】如果有orderby的場景,請注意利用索引的有序性。by最后的字段是組合file_sort正例:wherea=?b=?索引:a_b_c反例:索引中有范圍查找,那么索引有序性無法利用,如:WHERE>10ORDERBYb;a_b無法排序。6.【推薦】利用覆蓋索引來進(jìn)行查詢操作,避免回表。說明:如果一本書需要知道第11章是什么標(biāo)題,會翻開第11章對應(yīng)的那一頁嗎?目錄瀏覽一下就好,這個(gè)目錄就是起到覆蓋索引的作用。效果,用explain的結(jié)果,extra列會出現(xiàn):usingindex。7.【推薦】利用延遲關(guān)聯(lián)或者子查詢優(yōu)化超多分頁場景。MySQLoffsetoffsetNoffsetN行,那當(dāng)offset特別大的時(shí)候,效率就非常的低下,要么控制返回的總頁數(shù),要么對超過特定閾值的頁數(shù)進(jìn)行SQL改寫。正例:先快速定位需要獲取的id段,然后再關(guān)聯(lián):SELECTa.*FROM表1a,(selectidfrom表1where條件LIMIT100000,20)bwherea.id=b.id/阿里巴巴Java開發(fā)手冊8.【推薦】SQLrangerefconsts最好。說明:1(主鍵或者唯一索引2)指的是使用普通的索引(index)。3)對索引進(jìn)行范圍檢索。反例:explain表的結(jié)果,type=index,索引物理文件全掃描,速度非常慢,這個(gè)index級別比較range還低,與全表掃描是小巫見大巫。9.【推薦】建組合索引的時(shí)候,區(qū)分度最高的在最左邊。正例:如果wherea=?andb=?a列的幾乎接近于唯一值,那么只需要單建idxa可。whereaandb=?那么即使a的區(qū)分度更高,也必須把b放在索引的最前列。10.【參考】創(chuàng)建索引時(shí)避免有如下極端誤解:1)誤認(rèn)為一個(gè)查詢就需要建一個(gè)索引。2)誤認(rèn)為索引會消耗空間、嚴(yán)重拖慢更新和新增速度。3)誤認(rèn)為唯一索引一律需要在應(yīng)用層通過“先查后插”方式解決。/阿里巴巴Java開發(fā)手冊(三)SQL規(guī)約1.count(列名)或count()來替代count()count(*)是SQL92標(biāo)準(zhǔn)統(tǒng)計(jì)行數(shù)的語法,跟數(shù)據(jù)庫無關(guān),跟NULL和非NULL無關(guān)。說明:count(*)NULL的行,而count(列名)不會統(tǒng)計(jì)此列為NULL值的行。2.【強(qiáng)制】count(distinctcol)計(jì)算該列除NULL之外的不重復(fù)行數(shù),注意col1,col2)如果其中一列全為NULL,那么即使另一列有不同的值,也返回為0。3.NULLcount(col)的返回結(jié)果為0sum(col)的返回結(jié)果為NULL,因此使用時(shí)需注意NPE問題。正例:可以使用如下方式來避免sum的NPEFROM4.【強(qiáng)制】使用ISNULL()來判斷是否為NULL值。注意:NULL與任何值的直接比較都為NULL。說明:1)NULL<>NULL的返回結(jié)果是NULLfalse。2)NULL=NULL的返回結(jié)果是NULLtrue。3)NULL<>1的返回結(jié)果是NULL,而不是true。5.【強(qiáng)制】count為06.【強(qiáng)制】不得使用外鍵與級聯(lián),一切外鍵概念必須在應(yīng)用層解決。(學(xué)生表中的studentidstudentid則為外鍵。如果更新學(xué)生表中的student_,同時(shí)觸發(fā)成績表中的studentid更新,則為級聯(lián)更新。;據(jù)庫更新風(fēng)暴的風(fēng)險(xiǎn);外鍵影響數(shù)據(jù)庫的插入速度。7.【強(qiáng)制】禁止使用存儲過程,存儲過程難以調(diào)試和擴(kuò)展,更沒有移植性。8.【強(qiáng)制】數(shù)據(jù)訂正時(shí),刪除和修改記錄時(shí),要先select,避免出現(xiàn)誤刪除,確認(rèn)無誤才能執(zhí)行更新語句。9.inin制在1000個(gè)之內(nèi)。10.utf-8編碼,那么字符計(jì)數(shù)方法注意:說明:LENGTH(輕松工作");返回為12_"輕松工作);返回為4如果要使用表情,那么使用utfmb4來進(jìn)行存儲,注意它與utf-8編碼的區(qū)別。/阿里巴巴Java開發(fā)手冊11.【參考】TRUNCATETABLE比無事務(wù)且不觸發(fā)trigger,有可能造成事故,故不建議在開發(fā)代碼中使用此語句。說明:在功能上與不帶子句的語句相同。(四)ORM規(guī)約1.【強(qiáng)制】在表查詢中,一律不要使用*作為查詢的字段列表,需要哪些字段必須明確寫明。說明:1)增加查詢分析器解析成本。2)增減字段容易與resultMap配置不一致。2.POJO類的Boolean屬性不能加isis_resultMap中進(jìn)行字段與屬性之間的映射。說明:參見定義POJO類以及數(shù)據(jù)庫字段定義規(guī)定,在中增加映射,是必須的。在MyBatisGenerator生成的代碼中,需要進(jìn)行適當(dāng)?shù)男薷摹?.【強(qiáng)制】不要用resultClass當(dāng)返回參數(shù),即使所有類屬性名與數(shù)據(jù)庫字段一一對應(yīng),也需要定義;反過來,每一個(gè)表也必然有一個(gè)與之對應(yīng)。說明:配置映射關(guān)系,使字段與DO類解耦,方便維護(hù)。4.【強(qiáng)制】xml配置中參數(shù)注意:#{},#param#不要使用${}此種方式容易出現(xiàn)SQL5.【強(qiáng)制】iBATISstart,size)薦使用。其實(shí)現(xiàn)方式是在數(shù)據(jù)庫取到statementName對應(yīng)的SQLsubList取startsize的子集合,線上因?yàn)檫@個(gè)原因曾經(jīng)出現(xiàn)過OOM。正例:在sqlmap.xml中引入#size#Map<String,Object>map=newHashMap<String,Object>();map.put("start",start);map.put("size",size);6.【強(qiáng)制】不允許直接拿HashMap與Hashtable作為查詢結(jié)果集的輸出。7.【強(qiáng)制】更新數(shù)據(jù)表記錄時(shí),必須同時(shí)更新記錄對應(yīng)的gmtmodified字段值為當(dāng)前時(shí)間。8.【推薦】不要寫一個(gè)大而全的數(shù)據(jù)更新接口,傳入為POJO類,不管是不是自己的目標(biāo)更新字段,都進(jìn)行table這是不對的。執(zhí)行SQL時(shí),盡量不要更新無改動的字段,一是易出錯(cuò);二是效率低;binlog存儲。9.【參考】@Transactional事務(wù)不要濫用。事務(wù)會影響數(shù)據(jù)庫的QPS,另外使用事務(wù)的地方需要考慮各方面的回滾方案,包括緩存回滾、搜索引擎回滾、消息補(bǔ)償、統(tǒng)計(jì)修正等。10.<isEqual>compareValue上此條件;<>表示不為空且不為null時(shí)執(zhí)行;>表示不為null值時(shí)執(zhí)行。/阿里巴巴Java開發(fā)手冊四、工程規(guī)約(一)應(yīng)用分層1.【推薦】圖中默認(rèn)上層依賴于下層,箭頭關(guān)系表示可直接依賴,如:開放接口層可以依賴于Web層,也可以直接依賴于Service層,依此類推:開放接口層:可直接封裝ServiceRPC接口;通過Web封裝成http網(wǎng)關(guān)安全控制、流量控制等。終端顯示層:各個(gè)端的模板渲染并執(zhí)行顯示的層。當(dāng)前主要是velocity渲染,JS渲染,渲染,移動端展示等。Web層:主要是對訪問控制進(jìn)行轉(zhuǎn)發(fā),各類基本參數(shù)校驗(yàn),或者不復(fù)用的業(yè)務(wù)簡單處理等。Service層:相對具體的業(yè)務(wù)邏輯服務(wù)層。Manager層:通用業(yè)務(wù)處理層,它有如下特征:1)對第三方平臺封裝的層,預(yù)處理返回結(jié)果及轉(zhuǎn)化異常信息;2)對Service層通用能力的下沉,如緩存方案、中間件通用處理;3)與DAO層交互,對多個(gè)DAO的組合復(fù)用。DAO層:數(shù)據(jù)訪問層,與底層MySQL、Hbase進(jìn)行數(shù)據(jù)交互。外部接口或第三方平臺:包括其它部門RPC開放接口,基礎(chǔ)平臺,其它公司的HTTP接口。2.【參考】(分層異常處理規(guī)約)在DAO層,產(chǎn)生的異常類型有很多,無法用細(xì)粒度的異常進(jìn)行catch,使用throw,不需要打印日志,因?yàn)槿罩驹贛anager/Service層一定需要捕獲并打到日志文件中去,如果同臺服務(wù)器Service上參數(shù)信息,相當(dāng)于保護(hù)案發(fā)現(xiàn)場。如果Manager層與Service同機(jī)部署,日志方式與DAOServiceWeb層絕不應(yīng)該繼續(xù)往上拋異常,/阿里巴巴Java開發(fā)手冊因?yàn)橐呀?jīng)處于頂層,無繼續(xù)處理異常的方式,如果意識到這個(gè)異常將導(dǎo)致頁面無法正常渲染,理成錯(cuò)誤碼和錯(cuò)誤信息方式返回。3.【參考】分層領(lǐng)域模型規(guī)約:DOData):與數(shù)據(jù)庫表結(jié)構(gòu)一一對應(yīng),通過DAO層向上傳輸數(shù)據(jù)源對象。DTOObject):數(shù)據(jù)傳輸對象,Service和Manager向外傳輸?shù)膶ο蟆O):業(yè)務(wù)對象。可以由Service層輸出的封裝業(yè)務(wù)邏輯的對象。QUERY:數(shù)據(jù)查詢對象,各層接收上層的查詢請求。注:超過2個(gè)參數(shù)的查詢封裝,禁止使用Map類來傳輸。VOView):顯示層對象,通常是Web向模板渲染引擎層傳輸?shù)膶ο蟆?二)二方庫規(guī)約1.【強(qiáng)制】定義GAV遵從以下規(guī)則:1)GroupID格式:com.{公司/}..[子業(yè)務(wù)線],最多4級。{公司/BU}alibabataobaotmall/aliexpress等BU一級子業(yè)務(wù)線可選。正例:comtaobao或2)ArtifactID格式:產(chǎn)品線名-模塊名。語義不重復(fù)不遺漏,先到倉庫中心去查證一下。正例:dubbo/fastjson/jstorm-3)V:詳細(xì)規(guī)定參考下方。2.【強(qiáng)制】二方庫版本號命名方式:主版本號.次版本號.修訂號1)主版本號:當(dāng)做了不兼容的API修改,或者增加了能改變產(chǎn)品方向的新功能。2)次版本號:當(dāng)做了向下兼容的功能性新增(新增類、接口等。3)修訂號:修復(fù)bug,沒有修改方法簽名的功能加強(qiáng),保持API兼容性。說明:起始版本號必須為:,而不是3.【強(qiáng)制】線上應(yīng)用不要依賴SNAPSHOT安全包除外);正式發(fā)布的類庫必須先去中央倉庫進(jìn)行查證,使RELEASE版本號有延續(xù)性,版本號不允許覆蓋升級。不依賴SNAPSHOT當(dāng)前版本:,那么下一個(gè)合理的版本號:或或4.【強(qiáng)制】二方庫的新增或升級,保持除功能點(diǎn)之外的其它jar包仲裁結(jié)果不變。如果有改變,dependencyresolve致,那么通過dependencytree命令,找出差異
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 酒店轉(zhuǎn)讓合同的變更合同方式
- 電纜購銷合同模板
- 經(jīng)典宣傳服務(wù)合同范本
- 競爭性報(bào)價(jià)招標(biāo)解析
- 版采購合同格式模板
- 奶粉買賣合同范本
- 信息系統(tǒng)集成實(shí)施與運(yùn)維
- 農(nóng)產(chǎn)品采購合同評估
- 飼料采購合同模板
- 個(gè)人保證書的特點(diǎn)分析
- AQ6111-2023個(gè)體防護(hù)裝備安全管理規(guī)范
- 教師口語智慧樹知到期末考試答案章節(jié)答案2024年廣州大學(xué)
- 2023版押品考試題庫必考點(diǎn)含答案
- 形式發(fā)票模板 PI模板 英文版
- 初一的最美的風(fēng)景高分的作文600字
- 高考英語單項(xiàng)選擇題題庫題
- 檢驗(yàn)檢測機(jī)構(gòu)資質(zhì)認(rèn)定現(xiàn)場評審日程表及簽到表
- 完整版高低壓開關(guān)柜投標(biāo)文件技術(shù)標(biāo)
- 蘭州市行政區(qū)劃代碼表
- 管鮑之交-歷史劇劇本(共4頁)
- [交流][jtag]跟我學(xué)jtag協(xié)議破解——第一彈初識jtagtap狀態(tài)機(jī)
評論
0/150
提交評論