阿里畢玄:程序員如何提高本身的硬實力

從業餘程序員到職業程序員

程序員剛入行時,我以爲最重要的是把本身培養成職業的程序員。git

個人程序員起步比同齡人都晚了不少,更不用說如今的年輕人了。我大學讀的是生物專業,在上大學前基本算是徹底沒接觸過計算機。軍訓的時候由於很無聊,我和室友天天跑去學校的機房玩,我如今還印象很深入,我第一次走進機房的時候,別人問,你是要玩windows,仍是dos,我那是徹底的一抹黑。後來就只記得在機房一堆人都是在練習盲打,軍訓完,盲打卻是練的差很少了,對計算機就這麼產生了濃厚的興趣,大一的時候都是玩組裝機,搗鼓了一些,對計算機的硬件有了那麼一些瞭解。程序員

到大二後,買了一些書開始學習當時最火的網頁三劍客,學會了手寫HTML、PS的基本玩法之類的,課餘、暑假也能開始給人作作網站什麼的(那個時候作網站真的好賺錢),可能那樣過了個一年左右,作靜態的網頁就很差賺錢了,也很差找實習工做,因而就開始學asp,寫些簡單的CRUD,作作留言板、論壇這些動態程序,應該算是在這個階段接觸編程了。面試

畢業後加入了深圳的一家作政府行業軟件的公司,一個很是靠譜和給我空間的Leader,使得本身在那幾年有了不錯的成長,終於成了一個職業的程序員。數據庫

一般來講,業餘或半職業的程序員,多數是1我的,或者很小的一個團隊一塊兒開發,使得在開發流程、協做工具(例如jira、cvs/svn/git等)、測試上一般會有很大的欠缺,而職業的程序員在這方面則會專業不少。另外,一般職業的程序員作的系統都要運行較長的時間,因此在可維護性上會特別注意,這點我是在加入阿里後理解更深的。一個運行10年的系統,和一個寫來玩玩的系統顯然是有很是大差異的。編程

這塊本身感受也很難講清楚,只能說模模糊糊有個這樣的概念。一般在有興趣的基礎上,從業餘程序員跨越到成爲職業程序員我以爲不會太難。windows

編程能力的成長

做爲程序員,最重要的能力始終是編程能力,就我本身的感覺而言,我以爲編程能力的成長主要有這麼幾個部分:數組

一、編程能力初級:會用網絡

編程,首先都是從學習編程語言的基本知識學起的,不管是什麼編程語言,有不少共同的基本知識,例如怎麼寫第一個Hello World、if/while/for、變量等,所以我比較建議在剛剛開始學一門編程語言的時候,看看編程語言本身的一些文檔就好,不要上來就去看一些高階的書。我當年學Java的時候上來就看Think in Java、Effective Java之類的,真心好難懂。架構

除了看文檔之外,編程是個超級實踐的活,因此必定要多寫代碼,只有這樣才能真正熟練起來。這也是爲何我仍是以爲在面試的時候讓面試者手寫代碼是很重要的,這個過程是很是容易判斷寫代碼的熟悉程度的。不少人會說因爲寫代碼都是高度依賴IDE的,致使手寫很難,但我絕對相信寫代碼寫了不少的人,手寫一段不太複雜的、可運行的代碼是不難的。即便像我這種三年多沒寫過代碼的人,讓我如今手寫一段不太複雜的可運行的Java程序,仍是沒問題的,前面N年的寫代碼生涯使得不少東西已經深刻骨髓了。併發

我以爲編程能力初級這個階段對於大部分程序員來講都不會是問題,勤學苦練,是這個階段的核心。

二、編程能力中級:會查和避免問題

除了初級要掌握的會熟練的使用編程語言去解決問題外,中級我以爲首先是提高查問題的能力。

在寫代碼的過程當中,出問題是很是正常的,怎麼去有效且高效的排查問題,是程序員羣體中一般能感覺到的你們在編程能力上最大的差距。

解決問題能力強的基本很容易在程序員羣體裏獲得很高的承認。在查問題的能力上,首先要掌握的是一些基本的調試技巧,好用的調試工具,在Java裏有JDK自帶的jstat、jmap、jinfo,不在JDK裏的有mat、gperf、btrace等。工欲善其事必先利其器,在查問題上是很是典型的,有些時候你們在查問題時的能力差距,有可能僅僅是由於別人比你多知道一個工具而已。

除了調試技巧和工具外,查問題的更高境界就是懂原理。一個懂原理的程序員在查問題的水平上和其餘程序員是有明顯差距的。我想不少的同窗應該能感覺到,有些時候查出問題的緣由僅僅是由於有效的工具,知其然不知其因此然。

我給不少阿里的同窗培訓過Java排查問題的方法,在這個培訓裏,我常常也會講到查問題的能力的培養最主要的也是熟練,多嘗試給本身寫一些會出問題的程序,多積極的看別人是怎麼查問題的,多積極的去參與排查問題,不少最後查問題能力強的人多數僅僅是由於「無他,但手熟爾」。

我本身排查問題能力的提高主要是在2009年和2010年。那兩年做爲淘寶消防隊(處理各類問題和故障的虛擬團隊)的成員,處理了不少的故障和問題。當時消防隊還有阿里最公認的技術大神——多隆,我向他學習到了不少排查問題的技巧。和他比,我排查問題的能力就是初級的那種。

印象最深入的是一次咱們一塊兒查一個應用cpu us高的問題,咱們兩定位到是一段代碼在某種輸入參數的時候會形成cpu us高的緣由後,我能想到的繼續查的方法是去生產環境抓輸入參數,而後再用參數來本地debug看是什麼緣由。但多隆在看了一會那段代碼後,給了我一個輸入參數,我拿這個參數一運行,果真cpu us很高!這種case不是一次兩次。因此我常常和別人說,我是須要有問題場景才能排查出問題的,但多隆是徹底有可能直接看代碼就能看出問題的,這是本質的差距。

除了查問題外,更厲害的程序員是在寫代碼的過程就會很好的去避免問題。你們最容易理解的就是在寫代碼時處理各類異常狀況,這裏一般也是形成程序員們之間很大的差距的地方。

寫一段正向邏輯的代碼,大部分狀況下即便有差距,也不會太大,但在怎麼很好的處理這個過程當中有可能出現的異常上,這個時候的功力差距會很是明顯。不少時候一段代碼裏處理異常邏輯的部分都會超過正常邏輯的代碼量。

我常常說,一個優秀程序員和普通程序員的差距,不少時候壓根就不須要看什麼滿天飛的架構圖,而只用show一小段的代碼就能夠。

舉一個小case你們感覺下。當年有一個嚴重故障,最後查出的緣由是輸入的參數裏有一個是數組,把這個數組裏的值做爲參數去查數據庫,結果前面輸入了一個很大的數組,致使從數據庫查了大量的數據,內存溢出了,不少程序員如今看都會明白對入參、出參的保護check,但相似這樣的case我真的碰到了不少。

在中級這個階段,我會推薦你們儘量的多刻意的去培養下本身這兩個方面的能力,成爲一個能寫出高質量代碼、有效排查問題的優秀程序員。

三、編程能力高級:懂高級API和原理

就我本身的經歷而言,我是在寫了多年的Java代碼後,纔開始真正更細緻的學習和掌握Java的一些更高級的API,我相信多數Java程序員也是如此。

我算是從2003年開始用Java寫商業系統的代碼,但直到在2007年加入淘寶後,纔開始很是認真地學習Java的IO通訊、併發這些部分的API。儘管之前也學過也寫過一些這樣的代碼,但徹底就是皮毛。固然,這些一般來講有很大部分的緣由會是工做的相關性,多數的寫業務系統的程序員可能基本就不須要用到這些,因此致使會很難懂這些相對高級一些的API,但這些API對真正的理解一門編程語言,我以爲相當重要。

在以前的程序員成長路線的文章裏我也講到了這個部分,在沒有場景的狀況下,只能靠本身去創造場景來學習好。我以爲只要有足夠的興趣,這個問題仍是不大的,畢竟如今有各類開源,這些是能夠很是好的幫助本身創造機會學習的,例如學Java NIO,能夠本身基於NIO包一個框架,而後對比Netty,看看哪些寫的是不如Netty的,這樣會很是有助於真正的理解。

在學習高級API的過程當中,以及排查問題的過程當中,我本身愈來愈明白懂編程語言的運行原理是很是重要的,所以我到了後面的階段開始學習Java的編譯機制、內存管理、線程機制等。對於我這種非科班出身的而言,學這些會由於缺少基礎更難不少,但這些更原理性的東西學會了後,對本身的編程能力會有質的提高,包括之後學習其餘編程語言的能力,學這些原理最好的方法我以爲是先看看一些講相關知識的書,而後去翻看源碼,這樣才能真正的更好的掌握,最後是在之後寫代碼的過程當中、查問題的過程當中多結合掌握的原理,才能作到即便在N年後也不會忘。

在編程能力的成長上,我以爲沒什麼捷徑。我很是贊同1萬小時理論,在中級、高級階段,若是有人指點或和優秀的程序員們共事,會好很是多。不過我以爲這個和讀書也有點像,到了必定階段後(例如高中),天分會成爲最重要的分水嶺,不過就和大部分行業同樣,大部分的狀況下都還沒到拼天分的時候,只須要拼勤奮就好。

系統設計能力的成長

除了少數程序員會進入專深的領域,例如Linux Kernel、JVM,其餘多數的程序員除了編程能力的成長外,也會愈來愈須要在系統設計能力上成長。

一般一個編程能力不錯的程序員,在必定階段後就會開始承擔一個模塊的工做,進而承擔一個子系統、系統、跨多領域的更大系統等。

我本身在工做的第三年開始承擔一個流程引擎的設計和實現工做,一個不算小的系統,而且也是當時那個項目裏的核心部分。那個階段我學會了一些系統設計的基本知識,例如須要想清楚整個系統的目標、模塊的劃分和職責、關鍵的對象設計等,而不是上來就開始寫代碼。但那個時候因爲我是一我的寫整個系統,因此其實對設計的感受並尚未那麼強力的感受。

在那以後的幾年也負責過一些系統,但整體感受好像在系統設計上的成長沒那麼多,直到在阿里的經歷,在系統設計上纔有了愈來愈多的體會。(點擊文末閱讀原文,查看:我在系統設計上犯過的14個錯,能夠看到我走的一堆的彎路)。

在阿里有一次作分享,講到我在系統設計能力方面的成長,主要是由於三段經歷,負責專業領域系統的設計 -> 負責跨專業領域的專業系統的設計 -> 負責阿里電商系統架構級改造的設計。

第一段經歷,是我負責HSF。HSF是一個從0開始打造的系統,它主要是做爲支撐服務化的框架,是個很是專業領域的系統,放在整個淘寶電商的大系統來看,其實它就是一個很小的子系統,這段經歷裏讓我最深入的有三點:

1).要設計好這種很是專業領域的系統,專業的知識深度是很是重要的。我在最先設計HSF的幾個框的時候,是沒有設計好服務消費者/提供者要怎麼和現有框架結合的,在設計負載均衡這個部分也反覆了幾回,這個主要是由於本身當時對這個領域掌握不深的緣由形成的;

2). 太技術化。在HSF的階段,出於情懷,在有一個版本里投入了很是大的精力去引進OSGi以及去作動態化,這個後來事實證實是個很是很是錯誤的決定,從這個點我才真正明白在設計系統時必定要想清楚目標,而目標很重要的是和公司發展階段結合;

3). 可持續性。做爲一個要在生產環境持續運行不少年的系統而言,怎麼樣讓其在將來更可持續的發展,這個對設計階段來講相當重要。這裏最low的例子是最先設計HSF協議的時候,協議頭裏居然沒有版本號,致使後來升級都特別複雜;最典型的例子是HSF在早期缺少了缺少了服務Tracing這方面的設計,致使後面發現了這個地方很是重要後,所有落地花了長達幾年的時間;又例如HSF早期缺少Filter Chain的設計,致使不少擴展、定製化作起來很是不方便。

第二段經歷,是作T4。T4是基於LXC的阿里的容器,它和HSF的不一樣是,它實際上是一個跨多領域的系統,包括了單機上的容器引擎,容器管理系統,容器管理系統對外提供API,其餘系統或用戶經過這個來管理容器。這個系統發展過程也是各類犯錯,犯錯的主要緣由也是由於領域掌握不深。在作T4的日子裏,學會到的最重要的是怎麼去設計這種跨多個專業領域的系統,怎麼更好的劃分模塊的職責,設計交互邏輯,這段經歷對我本身更爲重要的意義是我有了作更大一些系統的架構的信心。

第三段經歷,是作阿里電商的異地多活。這對我來講是真正的去作一個巨大系統的架構師,儘管我之前作HSF的時候參與了淘寶電商2.0-3.0的重大技術改造,但參與和本身主導是有很大區別的,這個架構改造涉及到了阿里電商衆多不一樣專業領域的技術團隊。在這個階段,我學會的最主要的:

1). 子系統職責劃分。在這種超大的技術方案中,很容易出現某些部分的職責重疊和衝突,這個時候怎麼去劃分子系統,就很是重要了。做爲大架構師,這個時候要從團隊的職責、團隊的可持續性上去選擇團隊;

2). 大架構師最主要的職責是控制系統風險。對於這種超大系統,必定是多個專業領域的架構師和大架構師共同設計,怎麼確保在執行的過程當中對於系統而言最重要的風險可以被控制住,這是我真正的理解什麼叫系統設計文檔裏設計原則的部分。

設計原則我本身以爲就是用來確保各個子系統在設計時都會遵循和考慮的,必定不能是虛的東西,例如在異地多活架構裏,最重要的是如何控制數據風險,這個須要在原則裏寫上,最基本的原則是可接受系統不可用,但也要保障數據一致,而我看過更多的系統設計裏設計原則只是寫寫的,或者千篇一概的,設計原則切實的體現了架構師對目標的理解(例如當時異地多活這個其實開始只是個概念,但作到什麼程度才叫作到異地多活,這是須要解讀的,也要確保在技術層面的設計上是達到了目標的),技術方案層面上的選擇原則,並確保在細節的設計方案裏有對於設計原則的承接以及執行;

3). 考慮問題的全面性。像異地多活這種大架構改造,涉及業務層面、各類基礎技術層面、基礎設施層面,對於執行節奏的決定要綜合考慮人力投入、機器成本、基礎設施佈局訴求、穩定性控制等,這會比只是作一個小的系統的設計複雜很是多。

系統設計能力的成長,我本身以爲最重要的一是先在一兩個技術領域作到專業,而後儘可能擴大本身的知識廣度。例如除了本身的代碼部分外,還應該知道具體是怎麼部署的,部署到哪去了,部署的環境具體是怎麼樣的,和整個系統的關係是什麼樣的。

像我本身,是在加入基礎設施團隊後才更加明白有些時候軟件上作的一個決策,會致使基礎設施上巨大的硬件、網絡或機房的投入,但其實有可能只須要在軟件上作些調整就能夠避免,作作研發、作作運維多是比較好的把知識廣度擴大的方法。

第二點是練習本身作tradeoff的能力,這個比較難,作tradeoff這事須要綜合各類因素作選擇,但這也是全部的架構師最關鍵的,能夠回頭反思下本身在作各類系統設計時作出的tradeoff是什麼。這個最好是親身經歷,聽一些有經驗的架構師分享他們選擇背後的邏輯也會頗有幫助,尤爲是若是剛好你也在一樣的挑戰階段,光聽最終的架構結果其實大多數時候幫助有限。

技術Leader我以爲最好是能在架構師的基礎上,後續注重成長的方面仍是有挺大差異,就不在這篇裏寫了,後面再專門來寫一篇。

程序員金字塔

我認爲程序員的價值關鍵體如今做品上,被打上做品標籤是一種很大的榮幸,做品影響程度的大小我以爲決定了金字塔的層次,因此我會這麼去理解程序員的金字塔。

固然,要打造一款做品,僅有上面的兩點能力是不夠的,做品裏很重要的一點是對業務、技術趨勢的判斷。

但願做爲程序員的大夥,都能有機會打造一款世界級的做品,去爲技術圈的發展作出貢獻。

因爲目前IT技術更新速度仍是很快的,程序員這個行當是特別須要學習能力的。我一直認爲,只有對程序員這個職業真正的充滿興趣,保持自驅,纔有可能在這個職業上作好,不然的話是很容易淘汰的。

做者簡介:

畢玄,2007年加入阿里,十多年來主要從事在軟件基礎設施領域,前後負責阿里的服務框架、Hbase、Sigma、異地多活等重大的基礎技術產品和總體架構改造。



本文做者:雲效鼓勵師

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索