厲害的程序員相對於普通程序員,對於完成一個需求來說,除了更少的 bug,還有什麼優勢?


我們來談程序員對性的追求。

可靠性(reliability)

可讀性(readability)

可維護性(maintainability)

可測試性(testability)

可擴展性(extensibility)

可移植性(portability)

可伸縮性(scalability)

易用性(usability)

可用性(avaliability)

可重用性(reusability)

互操作性(interoperability)

可管理性(manageability)

可支持性(supportability)

一致性(consistency)

安全性(security)

性能(performance)

穩定性(stability)

精確性(accuracy)

可客制性(customizability)

魯棒性(robustness)

上面都是軟體在不同層次下的品質指標,學習軟體工程時會談及。有空再填。


厲害程序員相對於普通程序員的優勢在於:

1. 有更高概率做出正確的技術判斷,在有多種選擇的項目,選擇合適的框架,選擇合適的演算法,選擇合適的協議至關重要。比如 ,選擇關係型資料庫還是NoSQL?選擇哪種緩存?選擇哪種消息隊列?選擇TCP還是UDP?高手對技術的各個方面都有深入的理解,對各種技術的優缺點都熟悉,更高概率能選對。任何技術都有短板,高手知道如何揚長避短。

2. 寫出的代碼更容易排錯,不是高手的代碼就不會錯,而是高手的代碼出了錯容易找。高手的代碼可讀性一定很好,模塊清晰,命名規範,格式工整,關鍵的地方有注釋,出了異常有log,自然容易排錯,即使交給別人去debug也是比較容易的。

3. 厲害的程序員善於解決問題,通常讓最好的程序員去解決崩潰,死機和性能問題,這種問題最考驗技術功底,需要對系統上上下下有全面深刻的理解,甚至要對OS內核和硬體都有所了解。比如,我們一個工程師負責去解決某些伺服器總是死機的問題,最後他調查後懷疑是伺服器廠商的主板設計缺陷,導致CPU在進入休眠後有一定概率無法再次喚醒,然後設計了一個測試環境驗證了這個問題,反饋給了伺服器廠商。這種問題哪是普通程序員能想到的。


我覺得不能叫普通程序員,一個普通的鐵匠不會把菜刀設計成兩面都是刀刃,一個普通的電工不會把零線和火線裸露著繞在一起,一個普通的木工不會把桌子腿設計成有高有低的,但一個「普通」的程序員一天能做出10個這種風格的毀滅性的設計,而一個公司有上百個這樣的程序員,感覺就是你喝口茶的工夫都有人當著你的面一頭栽進河裡……


不同人眼裡厲害定義不同:

外行人眼裡,會上門修電腦就是厲害的程序員;

專業新生眼裡,課程拿高分,高質量完成課設就是厲害的程序員;

專業老生眼裡,寫出優秀的畢業論文的是厲害的程序員;

產品經理眼裡,總能按時按要求交付的工程師是厲害的程序員;

產品運營眼裡,我們公司里全都是厲害的程序員;

小公司程序員眼裡,大公司里全是厲害的程序員;

大公司程序員眼裡,自家公司里還算有幾個厲害的程序員;

初級程序員眼裡,技術廣博的是厲害程序員;

高級程序員眼裡,某一領域精深的是厲害的程序員;

系統開發工程師眼裡,知名開源項目發起人或者維護人是厲害的程序員;

系統架構師眼裡,只有厲害的系統,沒有厲害程序員;

研發工程師眼裡,研髮帶頭人是厲害的程序員;

計算機學術界里,那些傳奇的科學家是厲害的程序員;

產品總監眼裡,能讓程序員慕名加入的程序員必定是厲害的程序員;

技術 VP 和 CTO 眼裡,能從零做起某一工程技術領域的是厲害的程序員;

CEO 眼裡,能讓公司的技術體系和工程體系保持跟上甚至推動業務高速發展的是厲害得程序員;

投資人眼裡,你和你的團隊的技術能給公司樹立壁壘,才有資格叫厲害的程序員;

靠譜創業者眼裡,我的搭檔就是厲害的程序員;

不靠譜創業者眼裡,我缺的就是厲害的程序員;

知乎用戶眼裡,年薪百萬的都是厲害的程序員。


做架構時,規模長存。正確的選型,合理的冗餘。

做設計時,需求長存。清晰的介面,足夠的擴展。

做代碼時,指令長存。完備的邏輯,注釋的花活。

一眼看去,和諧自然,彷彿一切本該如此。

是為如來。


厲害的程序員從不說『這不當初你讓我做的嗎?』

厲害的程序員從一開始就能識別出那些不靠譜的需求並說服對方放棄或修改。

如果不能說服對方,厲害的程序員就會在設計中留下變更的介面,不把代碼寫死。等老闆客戶產品經理過來需求變更的時候,他們也會面露難色,表示變更需要至少X天時間,等產品經理面帶愧色離開後,化X分鐘把問題搞定然後花時間去做更有意義的事。所以厲害的程序員可能也會加班,但絕不會天天加班。他們不會浪費自己的時間。

厲害的程序員和厲害的銷售、厲害的主持人一樣,他們對自己所做的工作的內在規律和運行方式有著本質的認識。看他們工作能感受到一種有韻律的美。

===================

解釋下什麼叫更有意義的事

為項目(公司)編寫更好的開發測試工具包;

優化框架、減少子系統(模塊)耦合,將需求變更產生的工作量和代價最小化;

學習更好的技術(開發規範,開發流程),並將其引入到自己的項目(公司)。


這個問題,我想舉個例子來回答,雖然才開始第一份正式工作不太久,但有幸天天被一個厲害的程序員虐待。

首先來說下為什麼是厲害的程序員。

這位大神從學校畢業,進入FB後花了五年升職到了E8(engineering level 8)。可以介紹下,正常人畢業入職會是E3,一般1~2年能升到E4,之後每一次升職需要的時間都會更久,要求也更高,超過E6的程序員就已經很少很少了。然而大神是88還是89年出生的,人和人的差距比人和狗都大。

旁證:

我的manager是一個大家公認的,俄羅斯的大牛,來FB之前的事迹也是很輝煌(完全可以拿來回答下那個,俄羅斯人為什麼編程那麼厲害的問題)。他幾年前從西雅圖全家搬來了灣區,我有次問他,為什麼不去公司在西雅圖的分部。他想了想和我說,因為我想和上文那位大神這樣的人一起工作,有更多收穫,原話評價上文那位大概是「I think xxx is among the best in FB. Oh no, probably the best among the industury」。 來自大牛互相之間的評價是很真實的吧……

那大神和我這樣的普通程序員有什麼區別呢?就我這水平能觀察到的:

1. 是真的熟悉我們這邊整個infra到web,從後到前。有時做一些犄角旮旯的修改,去找他問些問題,他未必記得細節,但都能極快速得從文檔/代碼庫里找到對應的東西,然後給我提供幾個解決方案。我們這邊的infra出了特大的故障,就是一些他這樣的人力挽狂瀾;

2. 對新加的feature,或者scope之外的一些改動,覺得他也可以很快得作出判斷,在code review中無處不在。我每次上手新的一塊code base,都需要相當多的時間來踩坑,來慢慢看代碼,但顯然他是不用的;

3. 他自己的code質量,我們主要寫c++ (和python/php),公司內部有個學習c++小組的頭像都是他……他交的代碼,有個人在下邊給他一個"request change",在我們組就是一個值得在群聊里@所有人FYI的小新聞了。當然他對其他人的代碼質量要求也很高,我剛進組交的幾分代碼,都被打回去修改了十來次。不過這對控制整個project的質量,提高維護性還是很有幫助的;

4. Design之類的我的水平也評價不了,但反正現在這個大後台的design他應該是出了很多力的,我blame下兩個核心service里最重要的代碼,能有一小半至今還寫著他的名字;

總結的話,普通的程序員像我這樣,也許水平還行,能高質量的完成一些feature,能隨手修一些自己無意中看到的bug,以前自己幹活的時候能設計個小system,遇到大的project能上手做些修改。

厲害的程序員像他這樣(包括公司很多其他的大牛,只是他實在太神了……),即便是才來接觸的code base,也能很快掌握整個overall picture,也能熟悉接觸過的各種細節。能看到問題,能design新的東西,系統出了大的bug能夠快速的mitigate,同時還能貢獻精力幫助所有人更好更高質量地工作…

當然大神工作也是很拚命的,基本覺得他早十點到晚上十二點一直在線,還會偶爾大清早七八點被我們這樣的人搞出來的bug吵醒,叫起來搶修…

厲害的程序員真是一個頂一波,我覺得他給我做code review的時間,都夠他自己干仨這樣的feature了。


主要體現在代碼維護上:

好的程序員的代碼:前人栽樹,後人乘涼

差的程序員的代碼:前人挖坑,後人躺槍

如果你變更一個模塊的時候,50%時間花在理解代碼和業務到底是怎麼對上的,30%的時間在排查哪些東西是留有暗坑不能動的,15%的時間靠測試來檢查還有哪些暗坑是當時沒想到的,你就會明白我為什麼這麼說


Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.

- Antoine de Saint-Exupéry

Make everything as simple as possible, but not simpler.

- Albert Einstein

對於一個複雜的需求,普通的程序員會花大量的時間去開發「複雜」的解決辦法,但厲害的程序員會花更多的時間開發「簡單」的解決辦法

想想 MapReduce 你就知道我說的是什麼意思了。


1個優秀的程序員能幹10個普通程序員的活?

當然不可能。

但是1個優秀的程序員可以讓你作出一個正確的決定,少犯10個錯誤。這個優勢差別就明顯了。

而且一個優秀的程序員能從10個普通的程序員中,帶出2-3個優秀的優秀的程序員。

年紀越大越相信這點。雇請優秀的和你團隊性格相投的人!!!


用親身經歷給你講講厲害的程序員和普通程序員的差別。

先說背景,我10年前出來創業的,當時我在一個大型外企做銷售,公司有一個行業軟體,理念比較超前,所以也根本賣不動國內一個客戶都沒有。但是我很喜歡這個產品,我覺得它解決了多年來客戶的根本性問題,所以出來創業。

但是我只懂銷售不懂編程啊。所以第一想到外包。這個軟體是Java寫的,我找了一個看起來很不錯的外包公司(絕對不是草台班子),給我算了100個人月。每個外包的預算都有水分,但是據後來我觀察,在高峰時期他們大概也有將近30個人投入在這個項目上。大概做了3個月的時間搞出來一個版本。值得一提的是,由於我手中有這個軟體,而老外都比較單純代碼沒有做混淆,所以這個軟體其實是可以相當完整的反編譯的(Java軟體你懂得)。我們自己的開發團隊後來在他們交出的代碼中發現了大塊的代碼是直接反編譯然後Copy進來的。

這個版本,簡單的說就是根本不能用。大體上只能起到一個演示的作用。稍微部署多幾台計算機,就會出現各種莫名其妙的問題。那時候我已經賣給了一個我最熟悉的客戶,然後客戶和我一樣幾乎精神崩潰了。

沒有辦法,我開始自己建立開發隊伍。陸陸續續招了大約15,6個Java開發人員。一邊緊急打各種補丁,另外一方面開始動手重新再寫一遍。這個過程持續了將近1年。新出來的版本比原來外包的版本稍好,但是問題還是一樣,就是不穩定。總是有各種問題,而且解決一個問題,往往帶來更多問題;簡直就像進入了一個迷宮。總之客戶及其不滿,而我們疲於奔命。真正讓我失望的是,我的幾個主要客戶,後來我去拜訪,發現系統早已經停機了好幾個月都沒人知道,根本就不想用了。

說了這麼久算是鋪墊,現在高潮來了。。。。

這一年多時間裡面,為了維持公司生計,我也接一些定製開發任務。期間招了一個C++工程師,大學剛畢業來的北京,工資要的很高,當時招進來真的是很巧合,現在都想不起來為什麼了。這個工程師為客戶開發一些小的應用工具,事情不多。看到我們Java哪一大票人天天加班雞飛狗跳,就去了解一下他們到底在做些什麼東東。

然後,他花了一個月的時間,將整個平台用C++重寫了一遍。

這個平台,客戶的評價,或者是業界的評價就是極其穩定,操作方式優雅,擴展性非常好。不但可以滿足用戶當時的期望,直到6,7年後的今天用戶所有希望增加的功能,幾乎都可以在這個平台上毫不費力的添加上去,一切需要的細節似乎當時都已經考慮到了。現在我的公司這個軟體產品一年銷售額超過1個億,公司有將近100名軟體工程師,全是在這個平台上開發各種擴展模塊。當年這一個月內寫的代碼,幾乎完全沒有改動過。

至於這位工程師,他沒有留住我的公司。2年以後他就跳槽去了風起雲湧的大型互聯網公司。哪些互聯網公司給出的offer實在是太驚人了,你可以給他這麼多錢,但是給不了他哪種未來。

厲害的程序員和一般的程序員,差別就是這麼大。


程序員也有三六九等:

初等程序員靠知識來掙錢,會別人會的東西,喜歡折騰架構和框架,以掌握更多新潮東西而沾沾自喜,以模仿各種奇技淫巧重新實現一遍而四處炫耀,常見台詞:「為啥還在用png存圖片?為啥不用webp這種高壓縮比的格式?」,「我們使用 Erlang的高並發特性來實現同時支持5萬人的效果」,「我們使用RTMFP來降低流量成本,又使用H265來給用戶提供更高品質的視頻畫質」,這些人能夠迅速的學會各種項目需要的架構套件,以自己的生產力來掙錢。

高等程序員靠智慧掙錢,會別人不會的東西,上能抉擇技術方向,下能解決性能瓶頸;討論方案時,騰訊怎麼做的,阿里怎麼做的,我們該怎麼做,如數家珍;寫完代碼後,初讀讓人賞心悅目,再讀讓人恍然大悟,三讀讓人心悅誠服。常見台詞:「webp壓縮比不高,我改了一版新webp,用H265幀內預測來保存RGB,用lzma2來保存alpha比webp好多了」,「erlang大家不熟悉,我做了一個庫,讓大家可以象寫erlang一樣來寫C++,照顧大家開發習慣,又可以象erlang一樣寫多線程」。「Micheal Abrash這幾行代碼還有很大優化空間,其實性能還可以更好!」她們都是以解決別人不能解決的問題來掙錢。

上等程序員靠創新來掙錢,能促進行業的發展,在這個充滿諮詢的年代,學習大家都掌握的東西只是一個基本過程,沒什麼值得稱道的,當你baidu上找不到方案,google里沒有參考,國內外沒有任何人能給你啟示的時候,任然能夠充滿創造的分析問題,抽象問題,並解決問題。找到別人完全沒有走過的路,創造前人從來沒有創造過的東西,並給予他人啟示與幫助,這是他們的價值所在。


這個問題實在問的不錯,但是恕我直言,大部分程序員十年內也無法做到可以看破什麼是厲害程序員的境界,這裡僅僅說是寫代碼更快更簡潔,更少bug更易讀,這根本就是一個普通偏高級程序員的基本功好不好。

我認為一個厲害程序員,最重要的事情是:他能夠更容易的,更清晰的看懂程序的本質,計算的本質,存儲的本質,然後應用到為架構服務這個層次上來。

這個回答非常抽象,對於一些人或許會心有戚戚焉,但對新人來說肯定是過耳就忘,我來詳細的舉個例子。

一個程序員厲害不厲害就在於他能夠站在什麼層次來看待,解決業務問題。

比如,單台物理機,儘可能多的維護並髮長連接,這個問題非常簡單,對於大部分水準以上的程序員,解決方式無非是google一下,然後調用netty之類的工具包。再多做一步的就會去看看源碼,知道netty的架構設計,event handler之類的設計模式。

厲害程序員,可能馬上就知道維護長連接數量的本質問題在於應對用戶請求時操作系統的上下文切換成本。而這個C100K問題的解決方案和思路無非就是從降低上下文切換速度來下手,所以厲害程序員就有了很多選擇,比如選擇現有庫,或者是沒有現有的就自己造個輪子,而造輪子也不一定限制在庫級別,比如造個語言,同時由於採用了良好的並發切換策略和語法設計,業務變成容易了很多(比如erlang的actor模式)。

如何才能到達厲害程序員的思考領域,我的看法是:

1. 盡量多去看計算機理論,很多新穎的東西,都是一些舊理論的二次包裝

2. 可以理解一些新技術為何在某個時間點突然火起來的原因,不要簡單的概括為數據量的增長,有時候某個硬體的某種特性增加可以決定一整個技術棧的方向

3. 可以理解一些經典技術為何是這樣實現的原因

4. 永遠不要把業務問題僅僅是當做一個軟體工程的問題來看待,就如同三體中人類最後的命運結語所說的,弱小不是成長為厲害程序員的障礙,傲慢才是。


厲害的程序員啥都會考慮:

會考慮界面設計,和designer扣像素

會考慮產品功能,和PM談規劃

會考慮維護成本,和SRE說reliability

會考慮測試覆蓋,和TE聊TDD

會考慮行業動態,和老闆說項目前景

會考慮金融理財,和HR侃福利待遇

你說C++,JAVA,Python?DP,Greedy,Sorting?AR,MI,AI?這些不是厲害的程序員考慮的,是每個程序員都要考慮的。


這個一般跟人講不明白的。厲害的一般知道差的哪裡差,差的一般不知道厲害的哪裡厲害。


厲害的程序員知道什麼該做,什麼不該做。


跟低等程序員溝通:我說的這塊邏輯可以理解嗎?怎麼還有問題?你搞錯了啊。。

跟中等程序員溝通:你這樣,我這樣,搞完就 OK 了。好的。

跟高等程序員溝通:(其實並不需要溝通,他早已做好給你,並讓你感覺你 TM 就是個低等程序員)


舉個實際的代碼例子,這樣比較好理解

下面這段代碼是我搜到的一個利用遊戲引擎寫的 flappy bird 代碼

testuser2/FlappyBird

我之前在 B 站直播,沒有用遊戲引擎、庫,自己寫了幾個類,自己實現的 flappy bird

總代碼量如下(沒有重構和代碼優化的情況下)

其中跳躍的邏輯,代碼如下

對比如下

需要注意的是,代碼越多,項目越複雜,差異也就越大(參考演算法複雜度)

對直播的視頻感興趣的話,參考以下兩個鏈接

如何看待蕭井陌在 B 站直播寫代碼的行為?

蕭井陌:開發一個 Flappy Bird 需要多少行代碼,多少時間?


軟體的是核心是演算法,好的程序員都有比較好的數學功底和邏輯分析能力。

軟體的目的是減少人的工作量,好的程序員都善於理解問題,理解客戶的。而不是自己為是

軟體領域是一個相對年輕的行業,很多未知東西都要靠人自己去摸索,所以好的程序員必須是不畏艱難。

探索是一個艱苦的事情,很多時候需要自己一個人孤獨地往前走,好的程序員必要要有強大自信和堅韌的品格。

好 程序員總是對世界充滿了好奇,總是想自己做的事情要最完美。


前同事做的東西和我們差不多,他說老闆對他們的單伺服器吞吐不滿意

我:你這邊為什麼不這樣做?你大概花上2-4個人月把這個做了,單伺服器的吞吐可以提高一倍。

他:你說的簡單,我下面的人估計永遠做不出來。


推薦閱讀:

在北京.net開發,薪資達到15k以上需要具備什麼樣的技能?
第三屆 Gopher China 大會值得參加嗎?
學習3D遊戲開發,需要哪些基礎知識?

TAG:互聯網 | 程序員 | 牛人 |