對(duì)于一個(gè)軟件開發(fā)團(tuán)隊(duì)隆嗅,可以通過哪些代碼質(zhì)量指標(biāo)和掃描方法讓團(tuán)隊(duì)產(chǎn)出規(guī)范界阁、安全、高質(zhì)量的代碼胖喳?讓開發(fā)團(tuán)隊(duì)運(yùn)行的安全泡躯、透明、可靠丽焊?本文總結(jié)了其中一些實(shí)踐和工具较剃,包含常見代碼質(zhì)量掃描工具、代碼質(zhì)量指標(biāo)技健、第三方依賴管理写穴、安全運(yùn)維等幾個(gè)方面,主要適用于 Java/JavaScript 技術(shù)棧的 web 項(xiàng)目雌贱,希望對(duì)于想要規(guī)范化自己的項(xiàng)目的 Tech Lead 有所幫助啊送。
對(duì)于一個(gè)軟件開發(fā)團(tuán)隊(duì),可以通過哪些代碼質(zhì)量指標(biāo)和掃描方法讓團(tuán)隊(duì)產(chǎn)出規(guī)范欣孤、安全馋没、高質(zhì)量的代碼?讓開發(fā)團(tuán)隊(duì)運(yùn)行的安全降传、透明篷朵、可靠?
本文總結(jié)了其中一些實(shí)踐和工具婆排,包含常見代碼質(zhì)量掃描工具声旺、代碼質(zhì)量指標(biāo)、第三方依賴管理段只、安全運(yùn)維等幾個(gè)方面艾少,主要適用于 Java/JavaScript 技術(shù)棧的 web 項(xiàng)目,希望對(duì)于想要規(guī)范化自己的項(xiàng)目的 Tech Lead 有所幫助翼悴。
代碼掃描和常見質(zhì)量指標(biāo)
“禍患常積于忽微”,往往一些奇怪的 bug 都是一些不規(guī)范的小問題造成的幔妨。德國(guó)飛機(jī)渦輪機(jī)的發(fā)明者帕布斯·海恩提出的一個(gè)在航空界關(guān)于飛行安全的法則鹦赎,法則指出: 每一起嚴(yán)重事故的背后,必然有 29 次輕微事故和 300 起未遂先兆以及 1000 起事故隱患误堡。應(yīng)用于軟件開發(fā)中古话,如果項(xiàng)目中代碼混亂不堪,必然會(huì)在某個(gè)時(shí)候最終爆發(fā)大量的問題锁施。
這里整理了一些常見的掃描工具和代碼質(zhì)量指標(biāo)陪踩,可以在搭建項(xiàng)目基礎(chǔ)設(shè)施時(shí)引入杖们,用于自動(dòng)化的檢查代碼中潛在的問題,達(dá)到控制代碼產(chǎn)出質(zhì)量的目的肩狂。
掃描工具
checkstyle
checkstyle 是常用于 java 項(xiàng)目的掃描工具摘完,檢查源代碼是否與代碼規(guī)范相符,檢查項(xiàng)目主要包括:Javadoc 注釋傻谁、imports孝治、過長(zhǎng)的類和方法、空格审磁、重復(fù)文件谈飒、圈復(fù)雜度等,默認(rèn)使用 sun 的代碼規(guī)則态蒂,也可以配置自定義的代碼規(guī)則杭措,例如阿里就發(fā)布了相應(yīng)的檢查規(guī)則。
findbugs
通過 Bug Patterns 的概念钾恢,尋找代碼中可能出現(xiàn)的 bug手素,檢查項(xiàng)目主要包括:不良編程習(xí)慣導(dǎo)致的問題、性能問題赘那、安全問題刑桑、線程問題等。例如募舟,應(yīng)使用 equals 判斷相等祠斧,而不是 “ =” 操作符、流需要關(guān)閉拱礁、線程資源需要釋放等問題琢锋。findbugs 的模式庫對(duì)編程經(jīng)驗(yàn)也有較好的提升作用。還可以導(dǎo)入和編寫自己的 Bug Patterns 完善檢查機(jī)制呢灶。
simian
simian 是一個(gè)用于檢查重復(fù)和相似代碼的工具吴超,它的重復(fù)檢查類似于論文查重,會(huì)提示一定的相似度鸯乃【ㄗ瑁可以單獨(dú)運(yùn)行,也可以作為 checkstyle 插件來使用缨睡,相對(duì)來來說比較小眾鸟悴。
pmd
pmd 是一款跨語言的通用靜態(tài)掃描工具,具備一部分 checkstyle奖年、findbugs 的功能细诸,不再贅述。
ESlint/TSlint
前端界的 checkstyle , TSlint 設(shè)計(jì)用來做 TypeScript 類型檢查陋守,ESlint 作為代碼風(fēng)格檢查工具震贵。不過現(xiàn)在 ESlint 也提供了TypeScript 類型檢查功能利赋,基本上 ESlint 能整合這兩個(gè)功能。由于性能問題猩系, TypeScript 也采用了 ESLint 作為 TSlint替代的檢查工具媚送。
SonarQube
SonarQube 是一款用于代碼質(zhì)量管理的開源工具,它主要用于管理源代碼的質(zhì)量蝙眶。 SonarQube 和上面的工具不太一樣季希,SonarQube 設(shè)計(jì)目的是提供一個(gè)平臺(tái),通過插件的方式提供對(duì)各個(gè)語言進(jìn)行支持幽纷,也可以和 checkstyle式塌、pmd、simian 等工具進(jìn)行集成友浸。SonarQube 一般需要單獨(dú)部署成一個(gè)服務(wù)峰尝,提供數(shù)據(jù)庫,可以記錄掃描結(jié)果等信息收恢。
npm audit
npm audit 是 npm 6 之后的版本 自帶的一個(gè)前端安全掃描工具武学,可以掃描 npm 依賴中的潛在的漏洞威脅。這些引入的漏洞可能威脅用戶開發(fā)的機(jī)伦意,另外也可能被帶入 bundle 文件發(fā)布到線上火窒,帶來安全問題。目前 npm audit 會(huì)在 npm install 完成后自動(dòng)執(zhí)行驮肉,需要留意安全威脅報(bào)告熏矿。
Fortify SCA
Fortify SCA(Source Code Analyzer) 是一款非常優(yōu)秀的代碼安全掃描工具,用于分析代碼中潛在的安全問題离钝。通過調(diào)用語言的編譯器或者解釋器把代碼(Java票编、C、C++等源代碼)轉(zhuǎn)換成一種中間媒體文件 NST(Normal Syntax Trcc)卵渴,然后通過模式匹配相關(guān)的方式抓取存在于漏洞庫中的漏洞慧域。例如,上傳的文件沒有做檢查等 XSS 攻擊浪读。
OWASP Dependency-Track
開放式 Web 應(yīng)用程序安全項(xiàng)目(OWASP)是一個(gè)非營(yíng)利組織昔榴,提供了很多安全標(biāo)準(zhǔn)、數(shù)據(jù)庫碘橘、社區(qū)和培訓(xùn)互订。其中一個(gè)工具就是 OWASP Dependency-Track,可以對(duì)第三方依賴包中的知名漏洞進(jìn)行檢查蛹屿,掃描結(jié)果受到漏洞數(shù)據(jù)庫的更新影響。
archunit 架構(gòu)規(guī)范檢查
前面的檢查是代碼層面岩榆,archunit 可以用于代碼架構(gòu)檢查错负,可以定義規(guī)則檢查每個(gè)包中的實(shí)現(xiàn)是否符合規(guī)范坟瓢。例如,controller 包中的類不能實(shí)現(xiàn) service 的接口犹撒,repository 下的類必須實(shí)現(xiàn) Repository 接口折联。通過 archunit 可以減少 codereview 的工作量,避免項(xiàng)目的結(jié)構(gòu)被破壞识颊。
統(tǒng)計(jì)工具
sloccount诚镰、sourcemointor 這兩個(gè)工具可以用于統(tǒng)計(jì)代碼數(shù)量,包括行數(shù)祥款、文件數(shù)清笨、注釋等。除了在項(xiàng)目中掃描 bug 之外刃跛,配置代碼統(tǒng)計(jì)工具可以對(duì)項(xiàng)目有一個(gè)整體的認(rèn)知抠艾。
其他的掃描工具還很多,例如 coverity桨昙、codemars检号、binscope、synk蛙酪、appscan齐苛、retire.js 等工具,不再一一列舉桂塞。
最佳搭配
這幾款工具之間的功能有所重疊凹蜂,在實(shí)際工作中,我們可以根據(jù)上面推薦的關(guān)注的點(diǎn)藐俺,重點(diǎn)清除這些問題炊甲。這些掃描工具全部用上除了會(huì)帶來團(tuán)隊(duì)壓力和維護(hù)成本之外,代碼質(zhì)量不會(huì)隨著引入的插件增多欲芹。除開有質(zhì)量團(tuán)隊(duì)的大廠提供這些掃描平臺(tái)外卿啡,敏捷團(tuán)隊(duì)往往不會(huì)太大,團(tuán)隊(duì)持續(xù)關(guān)注一個(gè)精簡(jiǎn)的掃描組合更好菱父。
Java 后端:
checkstyle Java 代碼風(fēng)格守護(hù)颈娜,Java 項(xiàng)目至少應(yīng)該配置一個(gè)默認(rèn)的 checkstyle 規(guī)則。至少讓項(xiàng)目干凈浙宜,沒有無用官辽、重復(fù)的代碼,以及超大的類和方法粟瞬。建議做到每次提交代碼前檢查同仆。
findbugs 常見不規(guī)范的代碼檢查,一些空指針裙品、equals 檢查非常有用俗批,而且 IDE 的插件也很好用俗或。
前端:
eslint 守護(hù) JavaScript 代碼風(fēng)格,eslint 搭配一個(gè) .editorconfig 岁忘,可以方便的讓編輯器保持同 eslint 一致的代碼風(fēng)格辛慰。
npm audit 項(xiàng)目中第三方包的威脅掃描,npm 自帶無需額外安裝干像,npm 6 以后自運(yùn)行帅腌,需要關(guān)注并修復(fù)報(bào)出的安全問題。
安全:
fortify 掃描代碼中的漏洞麻汰,用它檢查出來的大部分安全問題都是注入攻擊速客、XSS 等攻擊,這些問題明顯可以在開發(fā)過程中避免什乙⊥旆猓可以作為 Jenkins 插件配置,和單元測(cè)試作為同一階段運(yùn)行臣镣。
OWASP 插件 用來掃描第三方依賴漏洞辅愿,因?yàn)轫?xiàng)目中的依賴不會(huì)像源代碼一樣頻繁變化,推薦使用 Jekins 插件忆某,定期執(zhí)行即可点待。
為什么不用 SonarQube 呢,SonarQube 是一個(gè)非常優(yōu)秀的代碼質(zhì)量開放平臺(tái)弃舒,需要單獨(dú)的配置安裝癞埠,需要花費(fèi)額外的時(shí)間維護(hù),對(duì)于小團(tuán)隊(duì)來說成本較高聋呢,如果有專門的質(zhì)量團(tuán)隊(duì)可以考慮維護(hù)一套苗踪。
常用代碼質(zhì)量指標(biāo)參考
編譯告警數(shù),大部分程序員基本上忽略 warning削锰,但是編譯器出現(xiàn)了告警是一種不好的體現(xiàn)通铲,意味著軟件可能工作,但是存在不好的實(shí)踐器贩,而這種不確定性颅夺,會(huì)帶來不確定的 bug 最終讓人一頭霧水。編譯過程中的告警蛹稍,盡量消除掉吧黄,編譯告警的值推薦消除到 0。
平均函數(shù)代碼行數(shù)唆姐,過大的函數(shù)會(huì)導(dǎo)致閱讀困難拗慨,而且往往過大的函數(shù)職責(zé)不夠單一,一般將一個(gè)方法代碼行數(shù)控制到 30 - 50 行。
平均文件代碼行赵抢,和平均函數(shù)代碼行一樣瘫想,過長(zhǎng)的文件一樣難以維護(hù),一般一個(gè)文件10多個(gè)方法昌讲,因此文件的代碼行數(shù)一般控制到 300 - 500 行。
冗余代碼减噪,有時(shí)候我們代碼中可能存在未使用的方法短绸、變量等代碼,這讓維護(hù)者一頭霧水筹裕,通常需要清零醋闭。
總文件重復(fù)率,出現(xiàn)重復(fù)文件的次數(shù)朝卒。除了編寫單元測(cè)試的情況下证逻,業(yè)務(wù)代碼不應(yīng)該出現(xiàn)重復(fù)代碼,推薦值為 0抗斤。
總代碼重復(fù)度囚企,代碼的重復(fù)度檢查,限于掃描工具的識(shí)別模式瑞眼,需要有一定的容忍度龙宏,推薦值在 5% - 10%
平均函數(shù)圈復(fù)雜度,圈復(fù)雜度用來衡量一個(gè)模塊判定結(jié)構(gòu)的復(fù)雜程度伤疙。如果一個(gè)方法內(nèi)部有大量的 if 語句嵌套银酗,意味著這個(gè)方法的實(shí)現(xiàn)質(zhì)量低下,且程序復(fù)雜度高不利于維護(hù)徒像,推薦值小于 5%黍特。
安全告警,如果配置了安全掃描工具锯蛀,例如 Fortify灭衷,安全威脅應(yīng)該被清零。
代碼缺陷谬墙,如果配置了缺陷掃描工具今布,例如 Findbus,需要清零拭抬。
第三方依賴規(guī)范化
軟件開發(fā)過程中部默,不可避免的需要引入第三方或者開源軟件包作為庫或者框架引入≡旎ⅲ“第三方” 其實(shí)不是一個(gè)軟件工程術(shù)語傅蹂,現(xiàn)今在軟件行業(yè)里面的理解是:第一方為自研的軟件,第二方為內(nèi)部發(fā)布的軟件,第三方為從社區(qū)或者外部商業(yè)途徑引入的軟件包份蝴。
對(duì)于個(gè)人開發(fā)者而言犁功,面向“搜索引擎”編程往往將來源不明的代碼片段和程序包引入到項(xiàng)目中。對(duì)于企業(yè)來說婚夫,考慮到的不僅僅是功能是否能實(shí)現(xiàn)浸卦,還要考慮引入時(shí)帶來的成本和問題,例如是否需要授權(quán)案糙、開源協(xié)議是否合理限嫌、是否會(huì)帶來安全威脅。
企業(yè)對(duì)于第三方依賴的引入分為幾種情況:
作為開發(fā)工具引入时捌,例如 gcc怒医、Jenkins,基本沒有開源協(xié)議問題奢讨,但是需要注意開發(fā)機(jī)稚叹、CI 會(huì)有安全風(fēng)險(xiǎn)。Jenkins 曾出現(xiàn)過漏洞拿诸,CI 服務(wù)器被當(dāng)做遠(yuǎn)程礦機(jī)使用扒袖。
作為服務(wù)部署使用(SaaS),部分開源協(xié)議會(huì)限制這種使用方式亩码,第三方依賴的安全問題會(huì)威脅服務(wù)器僚稿。
通過軟件包再發(fā)布,大部分開源軟件對(duì)這種使用方式有較多要求蟀伸,例如 GPL 開源協(xié)議具有傳染性蚀同,要求使用了 GPL 的項(xiàng)目也要開源。
拷貝源代碼引入項(xiàng)目啊掏,非常不推薦這種方式蠢络,盡量通過包管理的方式引入。
引入第三方依賴需要充分考慮迟蜜,盡可能最小成本的引入刹孔。在一個(gè) React 的前端項(xiàng)目中,有不熟悉的工程師娜睛,為了使用一個(gè)簡(jiǎn)單的手風(fēng)琴效果髓霞,引入了整套 bootstrap。不僅破壞了使用 React 的最佳實(shí)踐畦戒,而且讓輸出的 bundle 文件大小激增數(shù)倍方库,造成首屏加載的性能問題。
常見商業(yè)友好的開源協(xié)議
商業(yè)用戶常用的開源協(xié)議實(shí)際上只有6種左右障斋,即 LGPL纵潦、Mozilla徐鹤、GPL、BSD邀层、MIT返敬、Apache,另外還有極其寬松的 The Unlicense寥院,但采用的開源軟件不多劲赠。
GitHub 提供了一個(gè) license 清單的列表 https://choosealicense.com/licenses/,我根據(jù)開源協(xié)議的寬松程度秸谢,整理了一個(gè)列表经磅,方便查看:
幾乎所有的開源協(xié)議有一個(gè)共同的注意事項(xiàng):采用該開源協(xié)議的軟件項(xiàng)目,不提供任何責(zé)任轉(zhuǎn)移和質(zhì)量保證钮追。也就是說采用開源軟件造成的法律問題和開源項(xiàng)目無關(guān),另外需要使用者承擔(dān)因質(zhì)量問題造成的所有后果阿迈。另外元媚,除了引入的程序包之外,字體苗沧、圖片刊棕、特效音、手冊(cè)等媒體資源也算廣義上的“軟件”需要考慮開源協(xié)議和使用場(chǎng)景待逞。
第三方依賴管理
對(duì)項(xiàng)目中出現(xiàn)的任何第三方依賴有效的管理有非常重要的意義甥角,通過掃描工具,識(shí)別出項(xiàng)目中是否有源碼识樱、jar包嗤无、二進(jìn)制文件是否來源于某個(gè)開源項(xiàng)目。
任何的第三方軟件需要申請(qǐng)入庫管理(內(nèi)部其他團(tuán)隊(duì)申請(qǐng)通過可以直接使用)怜庸,質(zhì)量團(tuán)隊(duì)對(duì)申請(qǐng)的軟件進(jìn)行評(píng)估:
是否有開源義務(wù)需要履行
引入的第三方依賴是否有 CVEs等漏洞
第三方開源軟件是否仍然在維護(hù)
質(zhì)量團(tuán)隊(duì)根據(jù)上面的一些條件当犯,決定出申請(qǐng)的軟件能否在項(xiàng)目中使用,允許被采用的軟件會(huì)定義出優(yōu)選級(jí)別割疾,優(yōu)先推薦團(tuán)隊(duì)使用較為優(yōu)選的軟件嚎卫,并對(duì)項(xiàng)目整體的優(yōu)選率有一定要求。如果項(xiàng)目中出現(xiàn)了無法識(shí)別的二進(jìn)制文件宏榕、非約定目錄下的代碼片段拓诸,需要報(bào)備。通過良好的依賴管理和規(guī)范化麻昼,能減少不良第三方依賴的引入奠支,讓軟件項(xiàng)目透明、可信抚芦。
一些商業(yè)公司提供這些完整的服務(wù)胚宦,例如 fossid、blackduck、code-climate 等枢劝。
運(yùn)維安全
大的軟件公司井联,往往有一堆流程和要求。雖然一線開發(fā)對(duì)堡壘機(jī)您旁、防火墻烙常、各種安全規(guī)范顯得不耐煩,但這些安全措施也在保護(hù)開發(fā)者鹤盒。
防火墻用于環(huán)境隔離
往往開發(fā)者理解的防火墻用于防止網(wǎng)絡(luò)入侵蚕脏、審計(jì)、入侵檢測(cè)等功能侦锯,除此之外驼鞭,防火墻還可以用于各個(gè)環(huán)境的隔離。一般來說尺碰,企業(yè)對(duì)于生產(chǎn)環(huán)境的數(shù)據(jù)控制比較嚴(yán)格挣棕,不會(huì)將生產(chǎn)環(huán)境的權(quán)限交給團(tuán)隊(duì)所有開發(fā)者,但網(wǎng)絡(luò)連接有可能疏漏亲桥。
曾經(jīng)出現(xiàn)過一次線上事故洛心,由于配置文件錯(cuò)誤,將原本應(yīng)該連接到測(cè)試的數(shù)據(jù)庫連接到了生產(chǎn)環(huán)境题篷,造成大量臟數(shù)據(jù)寫入词身。如果通過防火墻規(guī)則對(duì)各個(gè)環(huán)境進(jìn)行隔離,這類問題將不會(huì)出現(xiàn)番枚。
另外也可以設(shè)計(jì) DMZ 區(qū)法严,將面向用戶側(cè)的網(wǎng)關(guān)部署到 DMZ 區(qū),僅僅開放必要的端口給網(wǎng)關(guān)葫笼,實(shí)現(xiàn)內(nèi)外網(wǎng)的物理隔離渐夸。同時(shí),對(duì)整個(gè)系統(tǒng)的防火墻策略應(yīng)該清晰地記錄渔欢,否則在做大的基礎(chǔ)設(shè)施更新時(shí)墓塌,梳理出所有的防火墻策略,是一件比較困難的事情奥额。
憑據(jù)管理
項(xiàng)目中會(huì)用到大量的憑據(jù)苫幢,例如數(shù)據(jù)庫、第三方系統(tǒng)對(duì)接的 key垫挨,使用明文不是一件好事韩肝。理想的情況下,對(duì)項(xiàng)目中所有的密碼信息進(jìn)行掩蓋(mask)九榔,避免 CI轧坎、日志中敏感信息的泄露。
有很多種方法可以掩蓋項(xiàng)目中的密碼信息:
使用環(huán)境變量對(duì)密碼信息進(jìn)行覆蓋湃交。
使用Spring boot 的項(xiàng)目可以配置 jasypt瓶蝴,使用 jasypt 將密碼加密郎汪,將生成的加密串配置 ENC(加密串) 到工程的配置文件中。加密過程可以加鹽作為解密的憑據(jù),“鹽” 可以不存放到工程中,在工程部署的時(shí)候注入即可丙号。
如果使用 Jenkins 等 CI/CD 工具,可以使用構(gòu)建平臺(tái)提供的憑證管理工具缰冤。
如果使用 Spring cloud犬缨,可以使用 spring cloud vault 組件部署一個(gè)憑證管理服務(wù)
另外,建議不要用任何個(gè)人憑據(jù)用作系統(tǒng)對(duì)接棉浸,應(yīng)該使用一個(gè)公共的應(yīng)用憑據(jù)怀薛。
堡壘機(jī)
一般來說我們管理服務(wù)器,所有的運(yùn)維操作需要通過堡壘機(jī)進(jìn)行操作迷郑。開放 22 等高危端口枝恋,允許開發(fā)者直接登錄到服務(wù)器是一種不安全的做法。
堡壘機(jī)三热,通俗的來說是跳板機(jī) + 監(jiān)控。最初使用的跳板機(jī)配置了兩張網(wǎng)卡三幻,用于連接開發(fā)環(huán)境和生產(chǎn)環(huán)境就漾,并沒有監(jiān)控功能。在此基礎(chǔ)上念搬,堡壘機(jī)增加了統(tǒng)一運(yùn)維管理的功能抑堡,往往需要兩步驗(yàn)證(SMS 或 Email),并對(duì)所有的操作進(jìn)行記錄和監(jiān)控朗徊。
在需要團(tuán)隊(duì)參與運(yùn)維工作的場(chǎng)景中首妖,非常有必要部署一套堡壘機(jī)服務(wù),并使用 LDAP 對(duì)接到團(tuán)隊(duì)成員的 ID 上爷恳,便于集中運(yùn)維管理有缆。
定期對(duì)系統(tǒng)軟件掃描
Linux 系統(tǒng)往往有云廠商推送安全補(bǔ)丁和風(fēng)險(xiǎn)提示,但是安裝到服務(wù)器上的軟件温亲,例如 JDK棚壁、nodejs,需要自己檢查安全問題栈虚。因此需要在系統(tǒng)中安裝并定期運(yùn)行 CVEs 檢查并及時(shí)更新袖外。有一款 cvechecker 可以幫助運(yùn)維人員,編寫一個(gè)腳本定期運(yùn)行 cvechecker 檢查系統(tǒng)中已知的軟件是否存在 CVEs 漏洞魂务,并提醒開發(fā)者及時(shí)更新曼验。
寫在后面
剛開始工作時(shí)候泌射,喜歡動(dòng)態(tài)的、靈活的編程語言鬓照,討厭的死板的熔酷、套路化的編程語言,然而需要很長(zhǎng)一段時(shí)間颖杏,才能意識(shí)到 “約束是程序員的朋友”纯陨。對(duì)一些安全知識(shí)了解的來源大多來自修復(fù) SonarQube 的經(jīng)歷,使用 findbugs 也讓我對(duì) Java 基礎(chǔ)認(rèn)識(shí)的更加深刻留储。
類似的翼抠,在使用一些框架、平臺(tái)的時(shí)候往往存在大量的限制获讳,有時(shí)候開發(fā)者難以意識(shí)到 “限制” 正是框架阴颖、平臺(tái)的作者 “保護(hù)” 應(yīng)用開發(fā)者的一種方式。有一些開發(fā)者以 Hack 框架丐膝、平臺(tái)為樂量愧,但是這樣會(huì)帶來潛在的隱患,在用戶量上來之后負(fù)面效應(yīng)表現(xiàn)的尤為明顯帅矗。
項(xiàng)目的規(guī)范化對(duì)于 Tech Lead來說可以減少程序的運(yùn)行事故和 codereview 時(shí)間偎肃,對(duì)于團(tuán)隊(duì)來說也許可以少加班吧。
文/ThoughtWorks少個(gè)分號(hào)