原文轉載于:https://my.oschina.net/editorial-story/blog/3133210
我們的中國文化,對“面子”看得特別重,所以你會發現身邊到處都是高級 XXX,聽著倍兒有面子,程序員也不例外。
但是你真要問每個人,你認為的高級 XXX 是什么樣子的,估計每個人都有不同的回答。
我還記得在我剛開始從事編程工作的時候,對坐在邊上不遠的那位我心目中的高級程序員的印象是:
工作至少有 6、7 年以上,能寫一個用起來很方便、看起來很牛逼、但是不太容易讓初級人員看懂的框架。
前兩天,我把這個問題丟到群里,大家給出的答案中,占比最高的是以下幾個。
- 有 N 年以上編程經驗(大部分都說 5 年以上)
- 有出版過技術圖書
- 對某領域內對常用框架原理有了解,并且實際使用超過 2 年
- 可以隨時隨地快速寫出常見的一些算法
- 至少封裝過一個被全局使用的開發框架
- 寫出來的代碼,閱讀起來很好理解
- 能帶領其他人員成功完成項目
你看,這件事對大家來說就是常說的,“一千個人眼中有一千個哈姆雷特”。
不過這也正常,畢竟像初級、中級、高級這種高度抽象的詞匯,想要得到一個可描述的定義與人交流,必然需要夾雜著個人的主觀因素。
但是很多行業都在這么進行分類,自然有它的道理和好處。
我覺得其中最大的一個好處恰好是“主觀”的附屬品——彈性。
比如,我現在想招一位高級程序員,面試的時候不管是通過還是不通過,我都有理由來解釋我對“高級”的定義。如此一來,我對陌生人的判斷就有了更大的“彈性”。
這其實是面試官的一種權利,也是長期以來面試者總在面試中處于下峰的原因之一。
事物總是有兩面性的,我們在對陌生人彈性的同時,間接地也對內部的人彈性了,會導致內部的一些人才培養出現問題。
比如,你覺得內部的高級程序員不夠,希望能在外部招聘的同時,從內部也培養一些出來。但是此時,你又面臨了需要定義什么是“高級”的問題。
如果沒法定義一個能夠達成共識的標準,又如何指導培養的方向呢?只能是一句空話。
長此以往會導致更嚴重的問題:真正的高級程序員不夠,只能讓中級程序員頂上。頂替的時間長了,會讓一些中級程序員誤以為自己已經達到了高級水平。
在我平時的面試中,這樣的案例屢見不鮮,網上流傳的工作 10 年 = 1 年重復 10 次的段子是真實存在的。
下面我來聊聊我對“什么是高級程序員”的個人看法,歡迎你和我一起探討。
不管是什么行業,什么崗位,在這個高度分工協作的現代社會,所需的能力主要分為三個維度,我的理解大概是這樣的:
- 專業能力:好奇心、敢于挑戰困難、刻意養成好習慣、要求嚴格
- 連接能力:共同體意識、同理心、實事求是、接地氣
- 領導能力:主人翁意識、溝通/談判技巧、目的導向
先賣個關子,文章的最后我會將這三個維度組合起來,你會發現一片新的天地。
根據這三個維度的水平差異,我們對初級程序員、中級程序員、高級程序員做一個簡要的描述。
初級程序員 - 知道有事要做
處在初級階段的時候,我們的精力大多只會專注在專業能力的提升上。這個時候“領導能力”和“連接能力”是很弱的。
所以,這個時候哪怕你有強烈的好奇心也無法很好地表達出來,大多只能被動的接受工作安排。
在這個時期做事情需要依賴一些教程、文檔,只能“依樣畫葫蘆”,幾乎不能在不借助外部信息的情況下解決之前從未遇到過的新問題,所以百度、google 就成了他們唯一的選擇。
你可以在你的身邊觀察一下,如果經常有以下這些場景出現,大多是初級程序員的表現。
- 很難提出正確的問題,大多會直接問別人這個功能應該怎么做。如果你清楚地向他解釋,他就會完全按你說的去做,甚至你寫的示例代碼都會 copy 過去。因為在他們的世界里,只有編譯成功和編譯失敗,任務完成和任務未完成。
- 經常犯錯誤,所以會預留過多“彈性時間”,以便有時間在到期日之前重做。所以總會抱怨“沒時間”。
- 對與自己有工作交集的人員的職能沒有認識。比如,對測試人員總是充滿敵意的,因為他們發現了錯誤,“阻礙”了自己完成工作。
- 還沒注意養成一些好習慣,比如習慣性地提煉重復代碼、編寫風格一致的代碼、自測等等。
很遺憾,看似很初級的階段,并不只是剛踏入工作的程序員所屬,在實際工作中,也有不少工作多年的人還處在這個階段。
中級程序員 - 知道如何做某事
對人群按照單一維度進行劃分,大多數時候都是符合正態分布的,這里也不例外。中級程序員是我們身邊最多的,包括那些不得不穿上高級程序員馬甲的中級程序員。
在這個階段,有些中級程序員開始具備了一定的“連接能力”,但并不是所有人,主要看是不是擁有了“共同體意識”。
在專業能力上,中級程序員已經明白了一定的“整體與局部”的概念,但仍然看不到整個“森林”,大多局限在某個模塊、流程上。比如,他們會想“這是做敏捷的正確方式嗎?”,但不會考慮“這對整個團隊、整個公司會產生什么實際的影響?”。
他們開始注重代碼質量,因為擔心低質量的代碼會影響他們視野中的“整體”。
但是對于質量的理解還是比較單一。比如,這個時候你會經常聽到他們把“性能”掛在嘴邊,在他們心目中“性能”的地位是至高無上的,總是想著你這個方案和我的方案哪個性能更好。
同樣可以觀察一下周圍,中級的開發大多數會這樣做事:
- 針對一個問題,可以提出多個方案,但是無法做出準確的決策。一旦更權威的人給出了他的選擇,中級程序員就會不假思索地按照建議執行。
- 可以看出代碼中的一些設計模式,但是自己寫代碼的時候除了單例和工廠,其它的幾乎想不到。
- 在討論一些時髦的框架和技術的時候總能聊上幾句,但是追問這個框架或者技術有什么缺點,基本說不上來。甚至,草率地在項目中運用上這些時髦的框架和技術,最終導致線上問題頻發,不得不讓高級程序員來收拾殘局。
- 能夠對自己完成任務所需的時間有準確的評估,但是評估他人的時間不會因人而異,也會以自己作為標準來評估。
- 對與自己有工作交集的人員的職能有了一定的認識。比如,會主動尋求測試的配合,幫助自己交付更高質量的項目。
其實這個階段是最危險的階段,因為最可怕的不是無知,而是一知半解。心理學中的鄧寧-克魯格效應(The Dunning-Kruger Effect)講述的就是這個問題。
兩位社會心理學家在 1999 年做的 4 項研究,證實了下面的這個曲線的存在。

在這種狀態下,人最容易高估自己,這也是很多導致產生很多“假高級程序員”的原因所在。
高級程序員 - 知道必須做些什么
高級程序員在“專業能力”、“連接能力”與“領導能力”這三個維度都有所建樹。因為他們不但可以把從 1 到 100 的事情做得很好,也有能力帶領其它人完成 0 到 1 的事情。
根據我身邊所接觸的程序員群體來看,我所認為的高級程序員,他們明白沒有什么是完美的,相反,問題、缺點和風險總是存在的。
他們的決策總是站在為了整體的“平衡”角度去考慮,而不是技術的酷炫或者外界流傳的所謂“正確的”技術。
他們會更多地關心那些不顯而易見的東西,如可維護性、可擴展性、易閱讀、易調試等等。
高級程序員就好比社會中的成年人,他們踩過足夠多的坑,也填過足夠多的坑,已經認清了現實的殘酷,尋求適合而不是完美。周到、務實、簡單,是他們做事的時候強烈散發出的“味道”。
可以根據下面的這些場景來看看你身邊有多少“有味道”的高級程序員?
- 與初級和中級程序員不同,他們拋出問題不是為了正確地做事,而是做正確的事。他們會詢問為什么要這樣做以及你想要實現什么。當你告訴他們目標是什么后,他們或許會通過暗示這種方式是錯誤的而另一種更好來做出一些修正;當然,更重要的是還會提供論據說服你。
- 因為提前明確了做事的目標,所以在動手做一件事的過程中,他會在關鍵細節思考有沒有更好的方法,甚至是那些不在之前的討論范圍的新嘗試。
- 他可以輕松地承認他不知道什么,并且向你請教。同時也可以輕松地向他人講清楚他所知道的事情。
- 他們理解合作的人員的職能的作用,不但知道什么時候向誰尋求幫助,還知道自己如何更好地幫助他們。
- 困難的事交給他們很放心,因為他們擅長的不是某種技術,而是解決問題的能力。他們總能解決那些之前從未遇到過的新問題,哪怕它們很困難。
那么,怎么做有助于我們成為高級程序員呢?
1、關注技術之余還要關注業務
為什么把它放第一點,因為我覺得這點最重要,是其它項的基礎,也最容易做到,但是很多程序員不愿意去做。
一定要搞清楚業務目標,不搞清楚不開工。相信我,只要是一位合格的 leader,一定會不厭其煩地和你說清楚的。
然后要習慣基于業務目標去分析可能會面臨的技術挑戰。比如,多少流量,涉及哪些用戶角色和功能,復雜度有多大等等。
再帶著下面的“不可能三角”去尋找合適的技術框架、解決方案。盡可能地尋求最優的平衡,而不是走極端。

如果拿捏不準,可以將多個方案各自的優缺點羅列出來,向 leader 尋求建議。
2、“設計”代碼而不是“寫”代碼
一般人可能拿到需求,就開始寫代碼了,寫著寫著由于頁面功能越來越多,感覺代碼越來越復雜,自己都會覺得難以維護了。
雖說要做好設計離不開大量的實戰經驗的積累,但還是有些方法可以讓塑造這個能力的過程更快一些。比如:
- 首先就是前面提到的第一點,多關注業務。不了解業務,你啥都設計不出來,或者把馬設計成了驢……
- 如果某個功能的開發/修改,以“天”為工時單位,一定要先畫圖。具體畫什么圖,可以參考我之前寫的文章:軟件開發中會用到的圖。
- 搞明白每個設計模式的特點和適用場景,注意,不需要把代碼怎么寫背下來。只要你每次寫代碼之前掃一眼設計模式的列表,看看有沒有適用的。如果有的話,再去“依樣畫葫蘆”按照設計模式去實現,經過時間的積累,慢慢地,你真正掌握的設計模式就越來越多了。這有助于鍛煉你的設計能力。
3、“接”需求之前會先“砍”需求
要做這點還得依賴于第一點,否則,你提出的“砍”需求建議大多是不會被采納的。
很多人在聽需求講解的時候,思考的是,這個功能能不能實現、怎么實現、難不難。大多數的提問也是基于這個思路展開的。
可能也會提出“砍”需求的問題,但是理由大多是這個實現起來太麻煩了,這個沒法實現之類。
其實只要你時刻保持著“做這個需求的目的是什么”這個問題去思考,“砍”需求會變成一件更容易成功,而且自然而然的事情。
4、解決一類問題而不是一個問題
很多人覺得,每天看到 bug 清完就萬事大吉了,哪怕同一個問題在生產環境出現多次,最多也就說一句“不會吧,怎么又出問題了”。
這種對待問題的方式只會讓你越來越忙,因為你的解決問題效率與投入的時間多少是成同比變化的。
我們要習慣于解決掉一個 bug 之后,想一下能否通過什么方式找到現有代碼中的同類問題,并把它們處理掉。
甚至是考慮有沒有什么辦法能夠一勞永逸地避免此類問題再次發生,比如封裝一個 SDK 或者寫一個組件,盡可能用一種低侵入的通用方式將問題扼殺在搖籃里。不但讓自己輕松了,也造福了大家。
5、遵循 KISS 原則,寫盡可能簡單的代碼
KISS 原則:保持簡單,愚蠢(Keep it simple, stupid)。
不單單是程序員,任何化繁為簡的能力才是一個人功力深厚的體現,沒有之一。
越簡單,越接近本質。就好比,有的人要用長篇大論才能講明白一件事,而有的人只要做一個形象的比喻你就懂了。
這個“簡單”指的是整體的簡單,而不是通過局部的復雜讓另一個局部簡單。比如,為了上層的使用更加傻瓜化,底層封裝的代碼錯綜復雜、晦澀難懂,這并不是真正的“簡單”。
如果你自認為已經是一個中級或者高級程序員了,那么你回頭去看看自己還是初級程序員那會寫的代碼,就會很容易發現一些顯得冗余的代碼。
第二點提到的——“設計代碼而不是寫代碼”對做好這點有很大的幫助。
6、選擇忍受某些問題
在人工智能還不能代替我們 coding 之前,我們永遠要親自面對無窮無盡的、這樣那樣的問題。
然而,任何事物都有兩面性的,一個方案在解決一個老問題的同時,總會帶來新的問題。所以,我們一定要意識到,忍受某些問題是必然的。
那些你現在看起來很傻逼的設計,可能就是當時的人做出的妥協。
所以,既然如此,你更應該考慮的是,當前的這個問題現在到底有沒有必要解決?值不值得,為什么之前沒去解決?它是不是你當前所有待解決問題列表中優先級最高的?
7、打造自己的“T型”專業技能
可能很多人都聽過“T型人才”的概念,我們程序員在專業技能的打造上也適合用這種模型。
但是對于“先豎再橫”還是“先橫再豎”可能不同的人有不同的看法。
我的觀點是,大多數情況下,先豎再橫。特別是某個技術、領域發展得越成熟,越應該如此。
因為很多事物的本質是一樣的,所以對某一個領域達到非常深入,洞察到一些本質的東西之后,對其它相鄰的領域有觸類旁通的效果。可以加速自己在“廣度”上的擴展。
不過,“廣度”也不是說蜻蜓點水,只知道最表象的“它是什么”。我認為比較合適的程度是,可以不用清楚某個技術具體的使用方式,但得知道它可以解決哪些問題,以及使用成本和潛在的風險,我將這些信息概括為“它怎么樣”。
8、構建自驅動的“閉環”
很多人都知道閉環的概念,但是它的重要性和價值往往被低估。因為人總是短視的,“聚沙成塔”之類的方式總是不受待見。
常規的搭建一個閉環的過程大多是這樣的。

這里所說的自驅動的“閉環”是這樣的。

如何才能變成這樣呢?只要做一件事,盡可能多地對外輸出自己的知識。
舉個我自己的例子,我在 2015 年那會在項目中開始引入領域驅動設計,并且不斷地在內部進行分享它的好處,慢慢地越來越多的項目開始往這個方向走。
因為前期的不斷分享,所以在組織內部,別人對我的人設多了一個“DDD專家”的標簽,那么大家遇到有關 DDD 的問題就會來和我一起探討。
越到后面,我已經不用自己主動去尋找這個領域的知識去學習了,因為接收到的外部反饋已經足夠多了,它們能夠倒逼我往前走。并且這些反饋都是實際的真實場景,此時的信息獲取和學習自然能達到“學以致用”的效果。
說實話,有不少人并不是這么想的,他們想的恰恰相反:“為什么每個人都在問我問題!你自己去學習吧!”。
所以,當你遇到其他人來請教你的時候,如果恰巧這是你所關注的領域,那么應該去擁抱這個問題而不是排斥它。因為你是團隊里最權威的人,這是你構建自驅動“閉環”的好機會。錯過這一回,下一回不知道得等多久。
前面文章里說到,我會將“專業技能”、“連接外部的能力”、“領導力”三個維度組合起來給你看。就是下面這個樣子。

你會發現這里面包含了程序員在進階后的幾個常見崗位。
可以對號入座一下:D
好了,我們總結一下。
這篇我先和你聊了一下在大家眼中高級程序員是什么樣子,發現沒有特別統一的標準,都是模糊的。這也體現在了幾個現實的場景中,比如招聘高級程序員、培養高級程序員上。
其次,我對初級、中級、高級程序員的特點分別闡述了自己的觀點。
然后,給出了一些幫助大家往高級程序員靠攏的實踐思路。
希望對你有所啟發。
最后,用Martin Fowler 的一句話作為結尾:“任何傻瓜都能寫計算機能理解的代碼,優秀的程序員編寫人類能夠理解的代碼。”
Any fool can write code that a computer can understand. Good programmers write code that humans can understand
Martin Fowler