錦州市廣廈電腦維修|上門維修電腦|上門做系統(tǒng)|0416-3905144熱誠服務(wù),錦州廣廈維修電腦,公司IT外包服務(wù)
topFlag1 設(shè)為首頁
topFlag3 收藏本站
 
maojin003 首 頁 公司介紹 服務(wù)項(xiàng)目 服務(wù)報(bào)價(jià) 維修流程 IT外包服務(wù) 服務(wù)器維護(hù) 技術(shù)文章 常見故障
錦州市廣廈電腦維修|上門維修電腦|上門做系統(tǒng)|0416-3905144熱誠服務(wù)技術(shù)文章
如何提高代碼質(zhì)量?

作者: 佚名  日期:2018-10-06 13:42:20   來源: 本站整理

 好的程序員從來不靠格子衫或者顏值吃飯,就像你家 C 羅明明可以靠臉,卻非要用不斷精進(jìn)的身體和技術(shù)迷倒你。

  對偉大前鋒來說,進(jìn)球,以及一個能夠迸發(fā)出進(jìn)球能力的身體非常重要。

  對靠譜程序員來說,代碼質(zhì)量,以及一顆能夠洞悉高質(zhì)量軟件編寫之道的大腦彌足珍貴。

  本文從產(chǎn)品,接口,指標(biāo),日志,代碼清晰度,代碼復(fù)雜度等方面,談?wù)勅绾翁岣叽a質(zhì)量。

  產(chǎn)品和接口

  好的產(chǎn)品經(jīng)理未必是個好的程序員,但好的程序員一定是個好的產(chǎn)品經(jīng)理。

  產(chǎn)品經(jīng)理的工作是什么?是把復(fù)雜的邏輯用清晰的,易用的方式(接口)展現(xiàn)給用戶。

  程序員的產(chǎn)品是代碼,代碼的用戶是其他程序員 —— 所以高質(zhì)量的代碼是讓別的程序員容易理解,容易使用的代碼。注意,這個層次的容易理解,是指結(jié)構(gòu),原理和接口上容易理解,而并非代碼的細(xì)節(jié)容易理解。

  細(xì)節(jié)在產(chǎn)品這個層次,一定要隱藏起來。用戶在打開瀏覽器,訪問 http://arcblock.io 的時候,并不需要關(guān)心 DNS 是怎么工作的,PKI 體系是怎么運(yùn)作的,HTTP / TLS / TCP / IP 協(xié)議是什么,報(bào)文是怎么從 user space 交付到 kernel space,再怎么 DMA 到網(wǎng)口發(fā)送出去 —— 這還沒完,接下來出場的,還有負(fù)責(zé) L2 protocol 的 switch,保護(hù)你安全的 firewall,郵遞員 router,以及明明概念上是網(wǎng)絡(luò)技術(shù),卻整個青春都錯付給了安全的 NAT。。。

  如果產(chǎn)品經(jīng)理做的產(chǎn)品展示給用戶是這樣巴拉巴拉的細(xì)節(jié),那么丫一定會被扯爛暫住證,大耳光從天黑抽到天亮,然后早班綠皮車送到清河去挖沙;如果程序員的 main() 如此啰嗦,不管人家受得了受不了,那么他這輩子篤定找不到同性朋友,更別說異性了。

  所以程序員在寫代碼之前,先要想想如果這是一篇演講稿,我該如何說起?我能在三五分鐘講清楚這代碼要干什么?有沒有生活中或者同行會心一笑立刻 get 到的例子可以類比?

  90% 以上的情況,程序員是在寫 parser。換句話說,我們寫的絕大部分代碼就是把一系列的輸入,經(jīng)過若干轉(zhuǎn)換(transformation),變成一系列輸出。

  舉些具體的例子。

  前端工程師是把用戶的 url 請求,parse 成瀏覽器 DOM 上的一系列 component,把用戶的行為,parse 成某種內(nèi)部的事件 {event_type, event_data},并且進(jìn)一步由 event_typeparse 成某個 event_handler —— 然后這個 handler 繼續(xù) parse event_data,直到其轉(zhuǎn)化成新的 DOM,或者對后端的某個 API 的某個請求。

  對于 API 來說,它 parse request,生成 response。request 可能被 parse 成一個 sql,交付給 database;也可能被 parse 成滿足另一個服務(wù)接口的 request(比如 grpc),交給另一個服務(wù)。這樣周而復(fù)始,直到 API 收集完七顆龍珠召喚神龍各個服務(wù)的所有數(shù)據(jù),再 parse 成一個合規(guī)的 response,交還給 client。

  所以程序員看待自己的代碼產(chǎn)品,要像庖丁看待肥牛一樣 ——「未見全牛」,「神遇而不以目視」,「以無厚入有間」—— 滿眼望去,就是一個個 parser,大的 parser 掛小的 parser,再掛更小的 parser。每層,甚至每個 parser,都是個 pipeline —— 它們一般由 validator,serializer,transformer 等接口組織起來,輔以各種 builder,decorator,factory,commander,再加上為之而生的 tools,utility,helper 等搭建而成。

  這樣一層層組織下來,該粗的地方粗,該細(xì)的地方細(xì),遇人說人話,遇猿說猿語,代碼可伶可俐,可蘿可御。

  接下來,是很重要卻最讓人撓頭的事情,給你的大大小小的模塊取名。名字傾注著感情,就像寒夜里小女孩劃下的火柴,酣戰(zhàn)一宿的圣盔谷外甘道夫揮起的魔杖,給人以光明,溫暖,希望,以及讀到時觸電般的「我懂你」。

  肖申克的救贖里有段,午餐時 Andy 問大伙那個前夜里被打死的可憐的胖子叫什么?大伙一臉懵逼,說我 TM 為什么要關(guān)心一個死胖子的名字。這一幕看著很痛,就像華安在成為華安之前,只有一個如螻蟻般微渺的代號。如果你想讓你的代碼不是一個讓人漠視的死胖子,而是人們愿意談?wù)摚敲矗容易讓人理解,甚至讓人刻骨銘心的名字吧。

  不好的名字除了讓人不解,漠視,甚至宛如與人世間幽隔的惡鬼,望上一眼,大家便想逃離;好的名字,嗯,隨便說一個,聶小倩,同樣是與人世間幽隔的孤鬼,你我卻念念不忘。

  在 Juniper,我最忘不了的兩臺服務(wù)器是 gretel 和 hansel,取自格林童話;在途客圈,讓我心心念之的項(xiàng)目是 atlantis 和以及其上 viking (code name) —— 這不難理解,要追尋 atlantis,你需要遠(yuǎn)征 (viking);在 tubi,cms service 是個糟糕的取名,merlin 算是回歸了正途,雖然作為一個 build service,它的魔力并不太強(qiáng),還時不時失靈;而在 arcblock,我在上篇文章里談到的 AADL,被正式取名 AODL —— 這不重要,估計(jì)你也記不住,不過,她有了一個對外的名字:goldorin —— 托爾金為中土大陸精靈族發(fā)明的精靈語。

  在《代碼命名:僧敲月下門》那篇文章里,我提到晦澀的 IKE 代碼里 pitcher / catcher 讓協(xié)議的 negotiation 讀來猶如欣賞棒球比賽。好的名字,和好的接口幾乎成對出現(xiàn),它讓程序員的產(chǎn)品 —— 代碼,變得鮮活,讀來如沐春風(fēng),如飲醇酒,如賞佳人。

  指標(biāo)和日志

  好的產(chǎn)品是在改進(jìn)中不斷提升的,就像鳳凰,經(jīng)歷烈火不斷煎熬,得以涅槃。而要想改進(jìn),離不來測量 (measure),它是構(gòu)建 (build) 和學(xué)習(xí)改進(jìn) (learn) 中間最重要的一環(huán)。

  熱力學(xué)第二定律是最讓人討厭也最讓人無奈的定律。它直接導(dǎo)致了「不運(yùn)動肚子上的贅肉必然增加」,「不收拾房子房子會越來越亂」,「不持續(xù)改進(jìn)代碼,代碼的質(zhì)量會越來越低」這些讓人煩心的事情。

  而這個破定律的祖師爺 Lord Kelvin 說:

  嗯,測量很重要,非常重要。如果構(gòu)建和改進(jìn)是兩根枝杈,測量就像蜘蛛在兩者間掛下的網(wǎng),這網(wǎng)越密,兩根樹枝間的路就越多,就越容易從一端走到另一端,循環(huán)往復(fù)。

  對于測量的途徑主要是指標(biāo) - metrics 和日志 - logs。metrics 像是心電圖或者 CT,讓身體的狀況一覽無余。所以 metrics 用來了解現(xiàn)狀,指明方向;logs 則是細(xì)密的日記,什么都有,唯獨(dú)沒重點(diǎn),所以常常在現(xiàn)狀和問題的方向確定后,用來歸因。比如說 CT 報(bào)告說,這周和上周相比,肝不那么好了,需要小心肝。那么肝為什么不好?把一周的日志調(diào)出來一看,哎呀,夜夜酒吧里縱情于世界杯,難怪。于是得出改進(jìn)方案:世界杯結(jié)束后,別又喝酒又熬夜又賭球這病就好了,沒事。

  metrics 和 logs 大部分時候是給自己和別的程序員看的,所以從上文的角度看,它也是個產(chǎn)品,符合產(chǎn)品和接口定義的一切準(zhǔn)則。

  先說 metrics。

  定義 metrics 的時候,你要先搞明白你要改進(jìn)些什么,這是所謂的 begin with the end in mind。代碼的運(yùn)行效率?那么,究竟那里效率不高?怎么定義效率,怎么計(jì)算效率(latency? throughput? 還是什么)。代碼的容錯性?那么,什么樣的 error 要收集,如何分門別類?哪里是潛在的錯誤大本營?

  知道要改進(jìn)什么后,接下來腦袋里要有幅圖 —— 不是富春山居圖 —— 是自己或者別人使用這些 metrics 的場景預(yù)現(xiàn)圖,就像至尊寶給山賊展示他和白晶晶的曠古奇戀的畫面一樣。

  比如說要提高效率,并且確定是降低 latency,所以打算收集服務(wù)的 response time,那么,response time 是看 line chart 還是 bar chart,知道了 latency 突然升高這件事之后,下一步呢?怎么知道再看什么?要和其它 metrics / event 關(guān)聯(lián)么?關(guān)聯(lián)哪些,怎么關(guān)聯(lián)?想想意外事件發(fā)生之后,作為唯一可以背鍋的程序員,身后一堆產(chǎn)品運(yùn)營盯著你的屏幕,喪著個個臉,表情比出殯還悲壯,好像你一秒鐘給公司損失幾十萬上下似的。在緊張的汗水打濕了你的格子衫時,你能看些什么,你該看些什么?

  這樣從解決什么問題,收集什么 metrics,怎么關(guān)聯(lián)使用 metrics,一層層定義下來之后,我們可以確保兩件事情:1. 當(dāng)壞事發(fā)生的時候,我第一個知道。比如:對外的 API 的 95 percentile 的 response time 過去 5 分鐘突然增加了 30%。2. 我能快速鎖定問題的大致范圍。比如:從其它 metrics 上看,是因?yàn)?diagon alley 服務(wù)的 latency 突然升高,進(jìn)一步地,diagon alley 的 disk write IOPS 顯著提高。那么這個問題,我就看為什么 diagon alley 的 disk write 不正常。

  接下來是 logs。

  logs 是不出問題不必太在意,但一旦出問題一定要能夠方便定位具體的位置的奇葩重要數(shù)據(jù)。所以 logs 求充足具體,要像辭海一樣廣而全 —— 比如當(dāng) metrics 告訴我們,問題出在我們并不清楚茴香豆的「茴」字時有幾種寫法,logs 能夠幫助我們快速翻出來有用的那段,然后找出「茴」的四種寫法。

  logs 兼具給人看,和給機(jī)器分析兩種效用,因而,最好要固定格式,以方便機(jī)器分析;但又不要用類似 JSON 的供機(jī)器閱讀的方式,如果不配合一個好用的 parser,當(dāng)人閱讀時像是韓式整容過的足球?qū)氊悾蛘弑怀楦闪诵稳菰~的句子,每個都長得一個模樣,需要摘了眼鏡用放大鏡仔細(xì)找不同。

  通過合理的 metrics 和 logs,測量變得唾手可得。這便釋放出來我們不斷迭代不斷改進(jìn)的能力。同樣起點(diǎn)的代碼,同樣水準(zhǔn)的程序員,一個一周迭代一次,一個一天迭代一次,其累進(jìn)的質(zhì)量在若干周期之后,會有質(zhì)的變化。

  代碼清晰度和代碼復(fù)雜度

  如果上面幾個方面都做好了,代碼的質(zhì)量再差也是有下限的。這個下限可以通過嚴(yán)格使用 linter 和不斷提升對所用語言的掌握來提高。就好比一個會獨(dú)立思考并勤于思考的人,他的文章值得一讀,也許從遣詞造句,從修辭手法,從原起承提來說,他還稚嫩,但那是下限,并且是很容易提升的下限。

  在 elixir 的 linter 里,我把 ABC complexity size 設(shè)置為 70,Cyclomatic complexity 設(shè)置為 15。所謂 ABC complexity,是代碼里的 assignments(A),branches(B),conditionals(C) 的平方之和開方根的結(jié)果,它代表了一段代碼有多冗長。Cyclomatic complexity,或者說循環(huán)復(fù)雜度,是指由程序的源代碼中量測線性獨(dú)立路徑的個數(shù),它代表了一段代碼有多難懂(我們的小腦仁最不擅長同時記幾件事情,比如情人節(jié)和結(jié)婚紀(jì)念日)。還有一些其他的設(shè)置,比如 nesting(嵌套層數(shù))不超過 3, arity(函數(shù)的秩,或者說參數(shù)個數(shù))不超過 6 個等等。這些 lint 的約束,會強(qiáng)迫你在函數(shù)的實(shí)現(xiàn)細(xì)節(jié)層面,考慮地更好。大部分情況下,同一個功能的代碼可以有不同的表述方式,linter 的目的就是建立約束,強(qiáng)迫你用更合理的方式去表達(dá)一個功能點(diǎn)。

  比如我常常不經(jīng)意寫出的代碼:

  這樣降低了代碼的 complexity,提高了代碼的 clarity,同時,還使得代碼的 extensibility 大大提升 —— 以后要加一個 “type 3” 的處理,僅僅是加一個簡單的函數(shù)而已,非常符合 open/close 原則。

  這樣的小技巧有賴于對語言的精進(jìn),和對 linter 規(guī)則的恪守。雖然例外偶有發(fā)生 —— 比如一個復(fù)雜的 sql query 用 Ecto 表述很容易超過 ABC,但絕大多數(shù)情況,守著規(guī)則,會讓你受益 —— 每次 commit,過 linter 就像靈魂在桑拿房里給蒸氣熏碾,痛苦難耐。勉力熬過去后,推門出去一下子無比清爽,有種撥云見日,level up 的感覺。



熱門文章
  • 機(jī)械革命S1 PRO-02 開機(jī)不顯示 黑...
  • 聯(lián)想ThinkPad NM-C641上電掉電點(diǎn)不...
  • 三星一體激光打印機(jī)SCX-4521F維修...
  • 通過串口命令查看EMMC擦寫次數(shù)和判...
  • IIS 8 開啟 GZIP壓縮來減少網(wǎng)絡(luò)請求...
  • 索尼kd-49x7500e背光一半暗且閃爍 ...
  • 樓宇對講門禁讀卡異常維修,讀卡芯...
  • 新款海信電視機(jī)始終停留在開機(jī)界面...
  • 常見打印機(jī)清零步驟
  • 安裝驅(qū)動時提示不包含數(shù)字簽名的解...
  • 共享打印機(jī)需要密碼的解決方法
  • 圖解Windows 7系統(tǒng)快速共享打印機(jī)的...
  • 錦州廣廈電腦上門維修

    報(bào)修電話:13840665804  QQ:174984393 (聯(lián)系人:毛先生)   
    E-Mail:174984393@qq.com
    維修中心地址:錦州廣廈電腦城
    ICP備案/許可證號:遼ICP備2023002984號-1
    上門服務(wù)區(qū)域: 遼寧錦州市區(qū)
    主要業(yè)務(wù): 修電腦,電腦修理,電腦維護(hù),上門維修電腦,黑屏藍(lán)屏死機(jī)故障排除,無線上網(wǎng)設(shè)置,IT服務(wù)外包,局域網(wǎng)組建,ADSL共享上網(wǎng),路由器設(shè)置,數(shù)據(jù)恢復(fù),密碼破解,光盤刻錄制作等服務(wù)

    技術(shù)支持:微軟等
    主站蜘蛛池模板: 无码h黄肉3d动漫在线观看| 无码天堂va亚洲va在线va| 免费a级毛片无码a∨免费软件 | 日韩爆乳一区二区无码| 人妻丰满熟妇AV无码片| 国产成人无码av在线播放不卡| 国产成人无码免费网站| 日韩人妻无码中文字幕视频| 久久久久无码精品国产app| 久久无码AV中文出轨人妻| 国产办公室秘书无码精品99| 无码日韩AV一区二区三区| 亚洲综合一区无码精品| 日韩网红少妇无码视频香港| 最新无码A∨在线观看| 无码一区二区三区免费视频| 亚洲av无码一区二区三区天堂古代 | 亚洲精品无码永久在线观看你懂的| 日韩精品无码一区二区三区| 久久中文字幕无码专区| 成人免费a级毛片无码网站入口| 精品无码人妻一区二区免费蜜桃| 爽到高潮无码视频在线观看| 亚洲精品无码人妻无码| 精品亚洲A∨无码一区二区三区 | 亚洲欧洲美洲无码精品VA| av无码精品一区二区三区四区| 无码粉嫩小泬无套在线观看| 国产精品ⅴ无码大片在线看| 中文字幕无码第1页| 中文一国产一无码一日韩| 国产成人无码精品久久久免费 | 无码一区二区三区在线观看| 国产a v无码专区亚洲av| 亚洲国产av无码精品| 精品无码成人网站久久久久久| 久久天堂av综合色无码专区| 亚洲av永久无码精品网址| 无码中文av有码中文av| 无码专区HEYZO色欲AV| 国产日韩精品无码区免费专区国产|