做者 | 畢玄 來源|阿里巴巴雲原生公衆號java
對於程序員而言,我始終認爲代碼是展示能力的關鍵,一個優秀程序員寫的代碼,和一個普通程序員寫的代碼是很容易看出差異的,代碼做爲程序員的硬實力和名片的展現,怎麼提高寫代碼的能力始終是一個關鍵的話題,不過很遺憾這篇文章其實也不是講具體的步驟、銀彈方法、武功祕籍什麼的,這篇文章講講我本身印象中對我寫代碼能力提高比較大的四段經歷,也許可供參考。程序員
第一段:第一次感覺天天億級系統的挑戰
2008 年,HSF 的第二個版本,在當時淘寶最重要的交易中心上線,上線當天形成淘寶網站訪問巨慢,交易類的頁面幾乎打不開,最後靠下線 HSF 才恢復。web
下線後開始查問題,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 這邊的版本里也改改,因此有了這段重寫通訊框架的經歷。ide
原本覺得以前在寫 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" 這句話我以爲是永遠成立的。