不爲過去蹉跎,改變當下。程序員
爲何開篇就送這麼一句話給你們,我相信不少處於1-3年碼齡的哥們兒們,在平時的編碼歷程中編碼的個性多是多彩的,每一個人都有每一個人特定的風格,可是咱們如今這麼隨意寫,之後這麼隨意寫,好沒問題,可是等你離開這個公司了或者是去開發別的項目了,再等別人過來接手維護你一手寫出來的這段個性十足的代碼時,那麼你的右眼皮時不時地就會跳,因果我就不說了~~sql
因此我建議看到這篇博文的朋友們,或許你稍微改變一下你的編碼風格,聽從一套好的編碼規約對己對人都是有好處的。可能朋友的公司也有專門的編碼規約,可是逃不了咱們平時在開發一些屬於本身的項目,好比有一天從李智慧老師的《大型網站技術架構:核心原理與案例分析》著做中學到一些很是好的東西,那麼咱們就想開始動手編碼來實現一下,這時候若是儘可能聽從一套很好的編碼規約風格,將寫出來的代碼分享給身邊的同事學習一下,提提建議多好。數據庫
2017-05-20這一天,阿里巴巴集團技術團隊終於發佈了版本號:1.2.0的Java開發手冊,在這以前他們總共發佈過5個版本,都有幸被我看到了。當時在地鐵上一向地翻開手機,直接打開《阿里技術》微信公衆號,就一眼瞅到了"搶鮮下載|阿里Java開發手冊最新完美版,千錘百煉始出爐——阿里巴巴Java開發手冊v1.2.0",當時第一反應就是趕忙先拿到它,接着迅速找到下載入口,完美地保存在手機上了。編程
快速飄過前言,手冊的願景就是碼出高效,碼出質量。所謂無規矩不成方圓,無規範不能協做。質量的提高是告訴咱們儘量少踩坑,少吃那些無用的虧,高效協做即下降協同成本,提高溝通效率,再說如今的軟件架構都須要多個程序員協同開發完成,公司也不可能讓某個技術大牛獨自去完成,因此讓你們統一方式一塊兒作事,才能提高開發效率。緩存
手冊結構總共由5部分組成:編程規約、異常日誌、MySQL數據庫、工程結構和安全規約。安全
一:編程規約性能優化
首先來講說編程規約吧,這部分是我我的極力推薦各位朋友可以借鑑,一個程序員有一個好的編碼風格,真的是異於其餘碼農。咱們誰都想要一個好聽的名字,除了好聽這個名字它還要有特殊的意義。在編碼的過程當中咱們定義一個變量也是同樣的,假如你定義的變量很爛,被人看到不只會鄙視你,還會從內心認爲你沒文化,就算咱們英文很差,可是也能夠百度啊,讓人看到一眼就能見名知意,多和諧啊~~微信
一、命名風格:架構
見名知意;類名、方法名、參數名、成員變量和局部變量使用駝峯式(可是這裏強調一下,咱們項目中不免會有不少分層領域的模型類,好比DO/BO/DTO/VO/AO,這些可使用UserDO、QueryVO等形式);常量名大寫;抽象類命名以Abstract或Base開頭;異常類命名使用Exception結尾;測試類以Test結尾;包名統一使用小寫;接口中的方法和屬性儘可能不要加任何修飾符(若是能夠public也不要加),爲了代碼簡潔;任何pojo類中布爾類型的變量,不要使用is作前綴,不然部分框架解析會引發序列化錯誤。併發
咱們如今軟件項目大部分都是分層的,對各個層中的方法和模型類地命名也有必定的講究,Service/DAO層中各方法的命名:獲取單個對象的方法採用get作前綴;獲取多個對象的方法採用list作前綴;獲取統計值的方法採用count作前綴;插入的方法採用save或insert作前綴,可是推薦使用save;刪除的方法採用remove或delete作前綴,可是推薦使用remove;修改的方法採用update作前綴。Service/DAO層中各模型類的命名:數據對象採用XXXDO,通常和數據庫中的表名對應;數據傳輸對象採用XXXDTO,通常是與業務領域相關的傳輸對象;視圖層展現對象採用XXXVO,通常用於傳遞到視圖層。
二、代碼格式:
(1)、if語句的使用方面,小括號內的倆端不要出現空格而且if關鍵字後面添加一個空格(不光是if關鍵字,在if/for/switch/while/do關鍵字後面都要有空格);
(2)、在二目、三目運算符的左右都建議添加一個空格,好比=、==、&&、+-/*等運算符左右都應該添加空格;
(3)、在代碼縮進方面,儘可能不要使用tab鍵,建議使用4個空格縮進,若是單行代碼超過120個字符,則建議換行;
(4)、多個參數同時傳遞時,逗號前建議有個空格;
三、OOP規約:
訪問此類的靜態變量或靜態方法時,直接使用類名訪問,無須經過對象引用訪問此類的靜態資源,若是你使用對象引用訪問則無謂增長編譯器解析成本;全部的覆蓋方法必須添加@Override註解;在使用object類的equals方法時,儘可能使用肯定的值來調用equals方法,避免出現空指針異常(參考下圖代碼);全部的pojo類的屬性必須使用包裝類;定義任何pojo類的屬性時,不要設定任何屬性的默認值;構造方法中進制加入任何業務邏輯代碼;建議全部的pojo類都添加toString()方法,方便排查問題。
四、併發處理:
獲取單例對象須要保證線程安全,其中的方法也要保證線程安全;線程資源須要經過線程池獲取,不建議顯式建立線程;對多個資源、數據庫表、對象同時加鎖時,須要保持一致的加鎖順序,不然可能會形成死鎖。
五、註釋規約:
首先全部的類都應該添加建立者和建立日期;方法內部添加註釋時,儘可能採用單行註釋,註釋添加在被註釋的代碼上方,若是強制使用多行/**/註釋,則應該與代碼對齊;全部的抽象方法和接口中的方法,都必須在方法上面採用多行註釋/***/解析清楚該方法是用來幹什麼的,實現了什麼功能;若是某個方法的功能還未完善,則必須添加待辦事宜TODO註釋。
二:異常日誌
對於異常日誌這部分,咱們絕對不能忽視,你不敢保證你寫出的代碼永遠不會掛吧,那麼咱們就必須藉助日誌的力量來快速定位到問題的位置,以便解決。
一、異常處理:
對大段代碼進行try-catch,這是不負責任的表現,咱們應該精確處理,建議儘可能將try塊的代碼放到事務代碼中,一旦代碼拋出異常,則必須回滾事務,必定要注意手動回滾事務;若是代碼中使用到流等資源finally塊必須對它們進行關閉,必須作,並且在關閉的時候若是可能出現異常則必須進行try-catch處理;不能在finally塊中使用return語句。
二、日誌規約:
咱們平時的開發過程當中,避免不了定時查看日誌,分析日誌,建議日誌文件中的內容必須保存在15天以上,由於有些異常具有以「周」爲頻次發生的特色;推薦對日誌進行分類,將系統運行產生的錯誤日誌和系統運行產生的業務日誌分開存儲,方便開發人員查看;謹慎的記錄日誌,生產環境禁止輸出debug日誌,有選擇性的輸出info日誌,必定要注意日誌輸出量的問題,避免把硬盤撐爆。
三:MySQL數據庫
做爲一名Java開發程序員,樣樣都得會點兒,不只得辛苦的敲代碼,並且還要具有大局觀有時候還須要你來設計庫結構和表關係,可是這時候咱們儘可能不要隨意來搞,說很差聽了你一旦隨意起來,那麼有一天你會前功盡棄地,由於咱們的程序大多都是依託數據來運行的,因此,朋友們若是真要你趕上設計庫表時,請認真對待。
(1)、建表規約:
首先在命名上,若是某個表的字段表明是與否的概念,則應該用is_XXX的方式開頭,數據類型應該是unsigned tinyint(1表示是、0表示否);表名和字段名應該使用小寫或數字,可是不能以數字開頭,切記數據庫中的字段名修改起來代價但是很是大的,由於沒法進行預發佈,因此在建表時命名字段名稱時必定要慎之又慎;表名不適用負數名詞,咱們在開發中習慣將表名定義成負數名詞,表明多個記錄的統稱,這樣是不建議的;若是某個字段的數據類型爲小數時,建議定義成decimal,不建議使用float或double,由於float或double有可能存在精度丟失,在進行的值的比較時會獲得錯誤的結果,若是存儲的數據超過decimal數據類型的存儲範圍時,建議將整數和小數分開存儲;若是存儲的字符串長度幾乎相等,則建議使用定長char;建立一張表,必備的三個字段:id(主鍵)、gmt_create(建立時間)、gmt_modified(修改時間);表的命名通常建議是加上業務名稱來做爲表前綴;表中的字段容許存在冗餘,以便提升查詢效率,可是不能是varchar超長長度,更不能是text數據類型;單錶行數超過500萬行或大小超過2GB時,才建議分庫分表。
(2)、索引規約:
業務上具備惟一特性的字段,或者是多個字段的組合,也必須建成惟一索引;在查詢時超過3張表禁止使用join,須要join的字段,數據類型必須一致,多表關聯查詢時,保證被關聯的字段須要有索引;頁面搜索禁止走左模糊或者全模糊,若是須要應該搜索引擎來解決;若是有order by的場景,請注意利用索引的有序性,order by最後的字段是組合索引的一部分,而且放在索引組合順序的最後,避免出現file_sort的狀況,影響查詢效率;SQL性能優化的目標:至少達到range級別(對索引進行範圍檢索)、要求是ref級別(指的是使用普通的索引)、若是能夠的達到consts(單表中只有一個行匹配,即主鍵或惟一索引,在優化階段便可讀取到數據)最好;防止因字段類型不一樣致使的隱式轉換,致使索引失效。
(3)、SQL語句:
咱們在書寫sql語句時大多數人都存在一個習慣,就是用count(列名)或count(常量)來代替count(*),count(*)是SQL92定義的標準的統計行數的語法,跟數據庫無關,跟NULL和非NULL有關,請記住這句話:count(*)會統計值爲NULL的記錄,可是count(列名)是不會統計NULL的記錄,致使數據讀取錯誤;在代碼中寫分頁查詢邏輯時,若總計錄數爲0時,應該直接返回,避免執行後面的分頁語句;禁止使用存儲過程,由於存儲難以調試和擴展,更沒有移植性;咱們在進行刪除或修改記錄時,要學會先select一下,接着再作delete或update也不遲,以避免眼疾手快形成毀滅性的災難;在使用in關鍵字是能避免則儘可能避免,若是避免不了,應該仔細評估in後面的集合元素數量,儘可能控制在1000之內,以避免影響查詢效率。
(4)、ORM映射:
在mapper文件中進行全表查詢時,一概不要使用*號,須要哪些字段則應該明確寫明;pojo類中的屬性不該該以is開頭,可是數據庫中的字段名稱必須以is_XXX開頭,這時能夠在resultMap中進行字段和屬性的映射;在mapper文件中儘可能不要使用${},應該使用#{},以避免形成SQL注入問題;不容許直接拿HashMap和HashTable做爲查詢結果的輸出;@transactional註解儘可能不要濫用,事務會影響數據庫的QPS,另外使用事務的地方,必需要考慮好事務回滾的最優方案,包括緩存回滾、搜索引擎回滾、消息補償和統計修正等問題;
四:安全規約
咱們在開發中不只要最求效率和質量,也要作到百毒不侵,作好系統的安全工做。通常系統中牽扯到用戶我的的頁面或者功能時必須作權限校驗;用戶的一些敏感數據不能直接展現,必須對展現數據進行脫敏;用戶輸入的SQL參數必須嚴格進行參數綁定或者metadata字段值限定的操做,防止發生SQL注入的問題,切記:禁止容許用戶使用字符串拼接SQL的方式來訪問數據庫,這危害可就大了去了~~,在開發中用戶請求傳入的參數必須作有效性驗證,若是有必要則實現雙重校驗,即先後臺校驗,忽略參數校驗,可能會致使page size過大致使內存溢出、惡意order by致使數據庫慢查詢、任意重定向、反序列化注入等問題;禁止向HTML頁面輸出未經安全過濾或位正確轉義的用戶數據;表單、AJAX提交必須執行CSRF安全過濾(CSRF是一類常見的編程漏洞,意爲跨站請求僞造,對於存在CSRF漏洞的網站或應用,攻擊者能夠事先構造好URL,只要受害者用戶一旦訪問網站或應用,後臺便在用戶不知情的狀況下對數據庫中用戶參數進行相應的修改);在使用平臺資源,譬如短信、郵件、電話、下單和支付等業務場景時,必須實現正確的防重放限制,好比數量的限制、疲勞度控制、驗證碼校驗,避免被濫刷,資損等狀況。
幹到這兒我本人學到的一些經驗所有分享完畢,能力有限,總結的可能不太到位,但願各位讀者見諒!