高質量的工程代碼為什么難寫

作者: hellojava  發布時間: 2016-11-30 13:53  閱讀: 56753 次  推薦: 120   原文鏈接   [收藏]  

  之所以想起寫這篇文章,是因為最近看到的一個著名的開源項目在內部使用時的各種問題,不得不說,很多的開源的東西思想是不錯的,但離真正工程化都有不小的距離,所以沒什么商業公司采用的開源產品如果要引入的話一定要慎重,通常會有N多的坑等著你去填,而比較成功的開源項目的背后多數都會有商業公司在背后不斷的改進。

  遙想我2000年開始學習寫asp代碼時,覺得寫代碼也不難呀,無非就是學學語法規則、庫就可以寫出來,記得有一次我實習面試的時候是讓我在一個下午左右的時間寫一個完整的留言板,那也就是刷刷刷就寫好了,但隨著后來工作,尤其是加入阿里以后,越來越明白高質量的工程代碼為什么難寫。

  在寫代碼初期,最關注的是如何用代碼實現需求,如果是僅僅實現業務需求的話,即使是剛上手的程序員,只要解題能力還OK,基本上都是可以寫出代碼來的。所以我自己一直認為數學成績是程序員的一個非常重要的要求,數學好的人通常解題和邏輯思維能力是還不錯的。

  上面的這個基本的寫代碼的過程中,寫的更好的同學的體現會在對業務的深刻理解以及抽象上,寫出的代碼會具備一定的復用能力,這個在這里不多加探討。

  但代碼是不是實現了業務需求就結束了呢,其實遠沒有,這其實只是寫代碼的開始,除了正向的邏輯實現外,任何一個點的異常的分支邏輯怎么處理才是工程化的代碼中更難處理的部分,這個問題在單機式的系統中會相對還好處理,在分布式的環境會變得非常的復雜,例如調用其他機器的功能超時了,出錯了,到底該怎么處理,這也是為什么有了那么多的分布式的理論的東西出來,在增加了異常分支的處理邏輯后,通常會發現這個時候正向邏輯的代碼在整個代碼的占比中會大幅下降。

  異常分支邏輯處理好后,通常還需要增加必要的日志信息,以便在出問題時方便排查,而不是到了要排查問題的時候,一點目前系統的狀況都搞不清楚,所以吃掉重要的異常信息不拋出這種行為在寫代碼中是非常可恥的。

  在處理好上面異常的相關動作后,代碼的健壯性也要處理好,這個主要指:

  1. 自我保護能力

  對外提供的接口是否具備足夠的自我保護能力,就是即使使用的人沒仔細看API文檔隨便亂用也不會導致系統出問題,這種案例非常的多,例如對外提供了一個批量查詢接口,結果用戶一下傳了一個里面有上千個用戶id的數組,查詢一下直接把內存耗光,像這種情況下不能怪使用的人,而應該怪實現API的這一端的保護做的不夠好,按照這樣的標準去看,會發現開源的很多東西的API都不太合格。

  還有一種就是能力保護,如果超出了處理的并發量的能力,這個時候會發生什么。

  2. 對資源的使用限制

  這也是代碼新手或一些開源產品中做的比較差的地方,很容易出現規模一上去,資源使用量也一直漲,沒有限制,然后導致系統掛掉,很常見的案例是對線程池的使用,例如像Java中的Executors.newCachedThreadPool,這個接口很多人會用到,但很多用的人都沒有仔細想過會不會在某種情況下這里創建出巨多的線程;還有例如用Map做cache,也沒考慮大小限制的問題,結果就是隨著數據量增長,某天突然就掛了。

  健壯性是代碼中比較復雜的部分,通常也是比較展現代碼能力的部分,可能看起來就幾行代碼,但其實背后反映的差距是巨大的。

  開源產品除了在健壯性上的差距外,通常還會出現的一個巨大差距就是整個系統的設計的伸縮能力,伸縮能力不夠的話通常會導致結構性的重構,另外常見的就是在并發的處理上不夠高效,例如鎖的合理使用、無鎖算法的引入等等,而這些需要非常強的系統設計和代碼功底能力。

  除了上面說的這些外,高質量的工程代碼還需要考慮可維護(例如監控信息暴露)、安全性等,對我而言,我一直認為所謂的工程化其實就是把一些玩具性質的代碼變成可在商業系統中真正健壯運行的代碼。

  上面的內容寫的比較簡略,不過應該也能看出,對于高質量的工程代碼而言,其實實現業務邏輯只是其中占比很小的一部分,甚至花的時間是相對最少的一部分,所以我確實非常贊同面試的時候讓同學寫代碼,這個時候很容易看出同學寫代碼的功力;有些時候為了考察同學寫代碼的熟練程度,我會問問IDE的快捷鍵,或者讓手寫一段不是太復雜的代碼。

120
5
 
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()