首頁>科技>

對於程式設計師而言,我始終認為程式碼是展現能力的關鍵,一個優秀程式設計師寫的程式碼,和一個普通程式設計師寫的程式碼是很容易看出差別的,程式碼作為程式設計師的硬實力和名片的展示,怎麼提升寫程式碼的能力始終是一個關鍵的話題,不過很遺憾這篇文章其實也不是講具體的步驟、銀彈方法、武功秘籍什麼的,這篇文章講講我自己印象中對我寫程式碼能力提升比較大的四段經歷,也許可供參考。

第一段:第一次感受每天億級系統的挑戰

2008 年,HSF 的第二個版本,在當時淘寶最重要的交易中心上線,上線當天造成淘寶網站訪問巨慢,交易類的頁面幾乎打不開,最後靠下線 HSF 才恢復。

下線後開始查問題,HSF 的第二個版本基於的是 jboss-remoting,jboss-remoting 在當時的版本里遠端同步呼叫的超時時間是寫死在程式碼裡的 60s,而呼叫的服務確實會有一些超過 10 幾秒的現象出現,導致了 web 應用處理 web 請求的執行緒池被這些慢請求給逐漸佔據,請求堆積,最終呈現出了頁面開啟非常慢的現象。

查清原因後,決定基於當時的 Mina 重寫整個 HSF 的通訊,重寫的這兩個月時間對我自己寫程式碼的能力有很大的提升,無論是對網路 IO 方面處理的深入學習,還是在高併發系統上的深入學習,現在想想學習的方式也就是翻各類網路 IO 的科普資料,然後是讀 Mina 的原始碼、Java 網路 IO 的原始碼,併發這塊的學習主要還是靠那本經典的《Java 併發程式設計實戰》,以及讀 Java J.U.C 裡的程式碼,這段時間的學習相比以往翻 Think in Java 之類的最大區別是,學習後付諸實踐,隨著 HSF 這個新的重寫的版本的上線,基本算是逐漸真正掌握了這些部分的程式碼能力。

除了程式碼能力的提升外,得到了另外一個最大的教訓就是,對於一個億級且長時間執行的系統,很多看起來的小機率的問題都一定會成為嚴重的問題,這也是為什麼寫高併發系統的難度,要求了必須對自己寫的程式碼,以及自己程式碼呼叫到的各種 API 裡的實現都非常的清楚,這樣才能真正確保最終程式碼的魯棒性。

第二段:民間“消防隊”的故事

第二段對我自己寫程式碼能力提升特別大的經歷是在民間"消防隊"的那段日子,淘寶在 2009 年故障特別多,但處理故障還沒有一個標準的體系和組織,導致很多時候會出現故障出了都沒什麼人處理,或者處理效率不高,於是當時有個運維團隊的同學拉了一些人組建了一個群,群的名字叫淘寶消防隊,用來處理淘寶出現的各種故障,我很湊巧的也加入了這個群,這個群裡還有另外一個整個阿里公認的超級技術大神:多隆。

一開始看到各種故障的時候,壓根就不知道怎麼下手,處理故障會需要的通常不僅僅是寫程式碼的能力,還需要對一個系統全貌要有一定的掌握,例如前幾年一篇特別火的文章,當點選搜尋背後發生了什麼這樣的文章,其實就是要對一個系統的處理流程特別的熟悉,這在處理故障的時候是非常重要的,在有了故障大概在哪個環節後,很重要的就是對這個環節程式碼執行機制的細節掌控了,這個時候通常來說各種工具非常重要,可以有效的幫助你知道具體發生了什麼,例如像系統層面的 top -H 之類的, java 層面的 btrace 等等,都可以讓你根據執行情況去定位問題的點。

這段時間我覺得我的提升就是靠大量的練手,故障確實有點多,一開始就靠看人怎麼處理,主要是從多隆這裡學,然後是嘗試自己解決一些故障,解決的越來越多後慢慢熟練度就上去了,除了解決故障能力的提升外,因為看了很多由於程式碼層面造成的故障,對自己在寫程式碼時如何更好的保證魯棒性,來避免故障,是非常有幫助的,例如,我看過很多濫用執行緒池造成建立了大量執行緒,最終導致執行緒建立不出來的 case,就會明白自己在用執行緒池的場景裡一定要非常清楚的控制最大的數量,包括堆積的策略等,又例如我看過 N 多的因為自增長容量的資料結構導致的 OOM 的 case,就會明白在寫程式碼的時候不能認為一定不會發生資料結構增長到超級大,所以不做任何保護的 case,這個時間我明白到的就是寫一段能運轉,實現需求的程式碼不難,但要寫一段在各種情況下都能長期穩定執行的程式碼是真心不容易,這我覺得是一個職業的寫商業系統的程式設計師和只是寫程式玩玩的最大差別。

第三段:重寫通訊框架

2010 年,我從中介軟體團隊離開,去做 HBase,那個時候的 HBase 裡面的通訊還是用一個非常簡單的寫法實現的,我想著要麼就把以前 HSF 裡用的移植到 HBase 裡用,這個時候剛好多隆在用 c 給各類 c 的應用寫一個通用的通訊框架 libeasy,於是就有了一次測試,我記得第一次測試結果看到原來 HSF 裡面的通訊框架的高併發能力和 libeasy 比相差無比巨大,我和多隆便探討他是怎麼實現的,我看看能不能學習下在 Java 這邊的版本里也改改,所以有了這段重寫通訊框架的經歷。

本來以為之前在寫 HSF 的那幾年應該算是對通訊框架這塊的程式碼相關的能力掌握的不錯了,在和多隆一起重寫的這段過程中,才發現差距還是很大的,多隆教會了很多細節的問題,基於 NIO 的通訊框架的核心是用非常少的 IO 執行緒來處理 IO 事件(太多也沒用,因為有些部分就只能序列),所以怎麼高效的使用好這幾個 IO 執行緒是非常關鍵的,要儘量減少這幾個 IO 執行緒處理一些不相關的動作,另外一點就是儘量減少 IO 執行緒和業務處理執行緒的切換,例如後來常見的批次把一個流裡的多個請求一次性丟給業務處理執行緒。

這段經歷對自己更加深入的掌握在程式碼邏輯整體的細節層面是非常有幫助的,這對於寫要求很高的系統是非常重要的,畢竟對於一個超大規模的系統而言,1% 的提升還是可觀的。

第四段:學習 JVM

之前因為處理故障比較多,有段時間我開始給公司同事們分享如何處理故障,後來發現有些問題自己也講不清楚,或者也不知道怎麼處理,必須深入學習 JVM 才行,但其實一開始我完全摸不著門路,JVM 程式碼開啟都不知道從哪看起。

很幸運,碰到了一個同樣愛好又比我強很多的同學,就是撒迦,圈內通常叫 R 大,我和撒迦好幾個週末約著在公司一起看 JVM 程式碼,有撒迦的指點,我終於是入門了,知道大概怎麼去看了,而且兩個人一起看程式碼,互相分享和探討,效率是非常高的。

有了這段經歷,再加上繼續處理著一些故障,基本上逐漸對 JVM 的程式碼實現有了更多的理解,在後來做故障分享、問題解決什麼的時候終於能更好的做到知其然知所以然,同樣,這對處理故障的能力,寫程式碼的能力也是非常有幫助的,例如會更加明白以前認為的所謂的面向 GC 友好的程式碼是幾個意思,也會有了更深的感受是其實 Java 的程式碼呢,通常不會寫的太爛,因為 JVM 在執行期會做很多的儘可能的最佳化,拉到一個平均線,但要寫的很好,難度是非常大的,因為需要懂 JVM,懂 JVM 下面的 OS。

總結

其實也總結不出什麼,因為每個人的環境什麼的不太一樣,也有適合各自提升的方法,我看自己的經歷呢,我覺得:

如果環境不具備,就給自己一個挑戰的命題,例如要學高併發的通訊,可以嘗試自己寫一個和其他的做對比,做效能等的 pk,這個通常提升還是會很大的,要學 GC,可以嘗試給自己幾個題目,來控制 GC 的行為等,如果環境具備的話,確實會更加有利。多和優秀的程式設計師一起,我自己從多隆、撒迦身上學習到了很多很多,從很多優秀的開原始碼,像 Netty,OpenJDK 裡面也學習到了很多很多,所以多參與一些優秀的開源專案也是一個很好的提升方法,看優秀的書(例如併發裡的那本 Java 併發程式設計實戰,JVM 裡的 Oracle JRockit: The Definitive Guide,深入理解 Java 虛擬機器等),也同樣是一種向優秀程式設計師學習的好方法。多多嘗試解決問題/故障,這絕對是提升程式碼綜合能力非常好的一個方法,自己工作裡機會少的話,網上有大把,像 stackoverflow 之類的,都是很好的練習場。

最後的最後,我還是想說,程式碼能力作為程式設計師的硬名片,始終是最有效的區分程式設計師能力的東西,"talk is cheap, show me the code" 這句話我覺得是永遠成立的。

8
最新評論
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 華為迎來新希望,留給小米和OV的時間不多了