錦州市廣廈電腦維修|上門維修電腦|上門做系統|0416-3905144熱誠服務,錦州廣廈維修電腦,公司IT外包服務
topFlag1 設為首頁
topFlag3 收藏本站
 
maojin003 首 頁 公司介紹 服務項目 服務報價 維修流程 IT外包服務 服務器維護 技術文章 常見故障
錦州市廣廈電腦維修|上門維修電腦|上門做系統|0416-3905144熱誠服務技術文章
如何提高代碼質量?

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

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

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

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

  本文從產品,接口,指標,日志,代碼清晰度,代碼復雜度等方面,談談如何提高代碼質量。

  產品和接口

  好的產品經理未必是個好的程序員,但好的程序員一定是個好的產品經理。

  產品經理的工作是什么?是把復雜的邏輯用清晰的,易用的方式(接口)展現給用戶。

  程序員的產品是代碼,代碼的用戶是其他程序員 —— 所以高質量的代碼是讓別的程序員容易理解,容易使用的代碼。注意,這個層次的容易理解,是指結構,原理和接口上容易理解,而并非代碼的細節容易理解。

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

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

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

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

  舉些具體的例子。

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

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

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

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

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

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

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

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

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

  指標和日志

  好的產品是在改進中不斷提升的,就像鳳凰,經歷烈火不斷煎熬,得以涅槃。而要想改進,離不來測量 (measure),它是構建 (build) 和學習改進 (learn) 中間最重要的一環。

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

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

  嗯,測量很重要,非常重要。如果構建和改進是兩根枝杈,測量就像蜘蛛在兩者間掛下的網,這網越密,兩根樹枝間的路就越多,就越容易從一端走到另一端,循環往復。

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

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

  先說 metrics。

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

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

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

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

  接下來是 logs。

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

  logs 兼具給人看,和給機器分析兩種效用,因而,最好要固定格式,以方便機器分析;但又不要用類似 JSON 的供機器閱讀的方式,如果不配合一個好用的 parser,當人閱讀時像是韓式整容過的足球寶貝,或者被抽干了形容詞的句子,每個都長得一個模樣,需要摘了眼鏡用放大鏡仔細找不同。

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

  代碼清晰度和代碼復雜度

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

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

  比如我常常不經意寫出的代碼:

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

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



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

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

    技術支持:微軟等
    主站蜘蛛池模板: 免费无码午夜福利片| 无码一区二区三区亚洲人妻| 中文字幕无码一区二区免费| 熟妇人妻系列av无码一区二区| 无码专区天天躁天天躁在线| 狠狠久久精品中文字幕无码| 亚洲国产综合无码一区| 无码av天天av天天爽| 亚洲AV无码专区国产乱码4SE| 无码精品A∨在线观看免费| 中文字幕无码免费久久| 无码aⅴ精品一区二区三区| 精品国产V无码大片在线看| 国产精品无码成人午夜电影| 精品一区二区三区无码免费直播| 亚洲av午夜国产精品无码中文字| 国产亚洲情侣一区二区无码AV| 无码熟妇人妻av| 无码人妻一区二区三区一| 亚洲AV无码一区二区三区系列| 无码人妻一区二区三区免费视频 | 免费无码成人AV片在线在线播放| 久久精品岛国av一区二区无码| 日韩视频无码日韩视频又2021| 亚洲熟妇无码一区二区三区| 久久久久亚洲av无码专区导航| 亚洲av无码一区二区三区乱子伦 | MM1313亚洲精品无码久久| 无码人妻精品中文字幕免费 | 亚洲色av性色在线观无码| 久久久久亚洲av无码专区蜜芽| 亚洲AV无码国产丝袜在线观看| 亚洲V无码一区二区三区四区观看 亚洲爆乳精品无码一区二区三区 亚洲爆乳无码一区二区三区 | 中文字幕有码无码AV| 中文无码人妻有码人妻中文字幕 | 无码人妻AⅤ一区二区三区 | 亚洲AV永久无码区成人网站| 国产成人精品无码一区二区 | 日韩精品专区AV无码| 无码国产乱人伦偷精品视频 | 亚洲AV日韩AV无码污污网站 |