當我們聊技術實力的時候,我們到底在聊什麼

原文鏈接:https://time.geekbang.org/column/intro/81?code=OK4eM0TBPTKGPRCzcZdzIeXjPACLfY3KCzATXOSWzXE%3D

640?wx_fmt=jpeg

 

技術實力的迷思

俗話說“文無第一,武無第二”,技術就是一種“文”的能力,很多時候我們很難直觀看出一個技術人員的實力,但不管是公司招聘的面試,還是公司內部的晉升面評,都需要在較短時間內快速判斷一個技術人員的實力。正因爲技術實力評價本身沒有絕對客觀的標準,很多時候都會聽到類似的吐槽:

“我們組內的 XX 技術實力不如我,竟然他晉升通過了,我卻被刷掉了,評委真的是~!@#¥”……

“面試官問的都是什麼鬼問題,我知道的基本沒問,我感覺他根本不會考察我的技術實力”……

“聽說算法和數據結構最能體現程序員的實力,我要好好啃啃《算法導論》”(然而啃完又忘記了)……

……

還有很多類似的問題和吐槽,背後都可以歸納爲一個問題:當我們聊技術實力的時候,我們到底在聊什麼?

有的人認爲:技術實力就是指算法和數據結構很厲害……

有的人認爲:研究過 Linux 內核源碼和看懂《深入淺出 MFC》的纔是技術牛逼的人……

有的人認爲:會寫 C++ 的纔是真正的技術高手,因爲 C++ 的對象初始化有 N 種寫法……

有的人認爲:技術高手必須對業務很熟悉……

有的人認爲:貢獻了開源項目代碼的纔是技術牛人……

有的人認爲:只有架構師纔是技術大牛……

……不一一列舉,相信一千個人眼中有一千個哈姆雷特,一千個程序員心中有一千個技術大牛!

 

640?wx_fmt=jpeg

技術實力的本質

 

得益於工作崗位的關係,我在考覈技術人員的實力時積累了較豐富的經驗(包括踩坑的經驗)。首先是招聘,前後面試了幾百個人吧,技術範圍包括服務器、android、iOS、前端,既包括初出茅廬的應屆生,也包括騰訊的 T4 大牛;其次是晉升評委,作爲職業等級晉升的評委,面評過幾十個晉升的技術同學,各種案例都見過,也與其他評委一起互相交流,有時候甚至是針對某個同學通過還是不通過產生爭執。通過這種不斷的實踐、思考、踩坑、交流的過程,逐步形成了一套完整的方法論,接下來就談談我的這套方法論,分享一下我是如何判斷技術人員的技術實力的。

簡單來說,判斷技術實力的一個總的原則就是:技術實力就是指解決問題的能力!

我們將這個原則細化一下,可以得到幾個細則:

1)不存在放之四海皆準的技術

簡單來說,問題是和領域相關的,技術是用來解決問題的,因此技術也是領域相關的,不存在放之四海皆準的技術。

有網友說:高斯林來做 iOS 開發,分分鐘秒殺現在所有的 iOS 開發人員,因爲目前 iOS 經驗最豐富的開發人員,經驗也不過 10 年。我認爲這是不可能的,iOS 開發領域面臨的問題,和開發 Java 編程語言面臨的問題差異很大,當然,如果高斯林真的做上幾年 iOS 開發,確實可能超過很多 iOS 開發人員,但一開始就秒殺哪些做了 7~8 年的 iOS 程序員,這個是不可能的。

2)技術要能解決具體問題才有價值

技術只有能夠解決某個領域的問題才有價值,否則光知道某個技術沒什麼用;掌握了某個技術但在當前的領域用不上,這個技術對當前領域來說也沒有價值。

當然,確實存在某些技術可能在當前看起來對當前領域沒有用,但後面可能會用到,因此技術人員需要自己儲備一些當前暫時沒有用的技術以拓寬技術視野,例如當前大火的人工智能和區塊鏈技術,但要注意“可能”這個詞,這需要技術人員自己進行判斷和平衡,不能拿技術儲備作爲託詞一股腦的什麼都儲備,例如數據庫開發工程師至少在這幾年是不需要儲備 VR 知識的。

3)問題的複雜度決定技術實力的高度

問題的複雜度不同,複雜度越高,解決起來越困難,相應的技術實力要求也越高。

我們拿這個原則去分析一下前面提到的各種技術實力的理解:

“技術實力就是指算法和數據結構很厲害”

很多面試官喜歡讓面試者現場手寫冒泡排序、快速排序、鏈表之類的代碼,以此來判斷面試者的技術實力,但我們用這個原則去分析一下就可以發現,這樣並不能考核技術實力,假如招聘了一個會手寫快速排序的面試者,招進來後你會讓他用自己寫的快速排序解決什麼問題?貌似絕大部分場景下都不可能讓一個新來的員工自己寫個快速排序來解決某個問題吧?

當然,肯定還是有人會說“我考覈的是面試者的技術基礎和思維能力”,這個說法沒錯,但如果是這個目的,現場手寫快速排序這種面試方法就是錯誤的,如果是考察技術基礎,考覈的範圍應該是算法的基本邏輯,優缺點、適用場景,因爲這些技術點在後續具體應用中選擇合適的算法來解決問題的時候很有用;如果是考察思維能力,考覈的方式應該是給一個具體的算法應用題,來看看面試者的分析和思考過程,例如我在知乎上給了一道我們業務上曾經用到的“如何快速計算你好友的好友和你的共同好友數”,沒想到引起了評論裏面的大討論,有興趣的朋友也可以嘗試一下。

“研究過 Linux 內核源碼和看懂《深入淺出 MFC》的纔是技術牛逼的人”

國內技術人員(不知道國外是否類似)對於底層技術有一種偏見,認爲只有懂底層纔是真正的技術高手,否則都只是簡單的調用 API 完成功能。我當年也不例外,我曾經說過“程序員的三個大坑:Linux 內核源碼、編譯原理(龍書)、深入淺出 MFC”,我每個都跳過,而且還花費了大量時間卻收效甚微。其實用原則去分析一下就可以發現這個說法也站不住腳,如果我們從事 Linux 內核開發,編程語言開發,MFC 框架開發,這些技術確實能解決問題;但如果做得不是這些領域的開發,這些技術並不能幫我們解決什麼問題,我還沒見過哪個 Java 編程的問題需要我去用編譯原理的技術去解決,也沒見過哪個數據庫的問題需要我去研究 Linux 內核源碼才能解決,當然並不是說這些問題一定不存在,Java 語言本身肯定也有 bug,但這些問題是需要 Java 官方去解決,我們在應用中無需親自去解決,否則的話,效率會非常低,個人愛好無可厚非,但團隊必須考慮效率。

“會寫 C++ 的纔是真正的技術高手,因爲 C++ 的對象初始化有 N 種寫法”

這是程序員羣體裏面永恆的一個話題,哪個語言纔是最好的最牛逼的,其中兩個著名的梗:PHP 是世界上最好的語言,C++ 是世界上最牛逼的語言。C++ 確實語法複雜,功能強大,真正能完全掌握 C++ 的程序員應該屈指可數,但這是否意味着掌握 C++ 就牛逼了呢?並不盡然,我們拿原則來分析一下,如果用 C++ 做遊戲引擎,或者高性能中間件,C++ 確實能解決問題,但如果我們做的是 android 手機資訊 app,C++ 能解決什麼問題呢?自己寫個加密庫可能比系統帶的庫漏洞還多,自己用 C++ 寫個 SQLite 好像沒什麼意義。

“架構師纔是技術大牛”

架構師幾乎是每個程序員的技術夢想,能夠成爲架構師(真正的架構師,不是 PPT 架構師),技術實力肯定很強,這點是沒有爭議的,但問題是當不上架構師就不是技術大牛麼?我們用原則來分析一下就會發現並不是這樣的,架構師並不是全能的,他解決的主要問題是系統的結構設計,還有一些問題是架構師不能解決的,例如 MySQL 5.6 版本通過優化一個 false sharing 問題,性能提升 50%,

(http://www.cis.upenn.edu/~delozier/docs/tmi_micro_2017.pdf)

這種問題點的發現和處理並不比架構設計簡單,能發現和解決這個問題的技術人員實力非常高。

以上分析了幾個典型的誤區,其它的觀點,這裏只貼一下簡單的答案,大家有興趣也可以套用這個原則去分析一下具體的原因,基本上八九不離十:

“技術高手必須對業務很熟悉” —— 正確

“貢獻了開源項目代碼的纔是技術牛人”—— 錯誤

 

640?wx_fmt=jpeg

技術實力詳解

理解評估技術實力的基本原則後,我們知道了需要解決的問題複雜度越高,技術實力就越高。在這個基礎上,我把技術實力分爲兩大類 6 分類:

  • 硬實力:真正解決問題的能力,別人可以看出來的能力,技術實力按照“點、線、面、體”的 4 個分類逐層上升;

  • 軟實力:比硬實力更厲害但也更虛的能力,簡單來說,要想解決問題首先得發現問題,但很多時候問題並不是一目瞭然的,需要有一定的技術洞察力。軟實力主要包括 2 個核心能力:發現問題、技術創新。

 

 

硬實力

 

我把技術硬實力分爲四個等級:點、線、面、體,技術等級依次提升,解決的問題複雜度也越來越高,下面詳細解釋一下。

 技術點

“點”就是某個具體的技術,用來解決某個具體的問題,例如使用 JDBC 從數據庫讀取數據,目的是解決數據掉電丟失的問題;使用 Java 多線程,目的是爲了解決大量用戶併發訪問的吞吐量和時延問題。掌握了技術點,就可以開始基本的業務功能開發了。

 技術線

“線”就是一系列相關的技術點組成,每個技術點都是爲了解決某個問題。例如:

  • 爲了完成一個用戶請求,開發框架首先要有路由 router 功能,路由到具體 Controller 後,Controller 進行業務邏輯處理,處理過程中可能會使用 JDBC 來讀取數據,訪問 Redis 讀取緩存等,這一連串的技術每個都解決了一個問題點,串起來就完成了一個業務功能的處理過程。

  • 爲了定位一個線上 Java 服務器響應慢的問題,需要用到 tcpdump 抓包,使用 Java 工具查看 jvm 的狀態,使用 mysql 命令行或者工具查看數據庫狀態,使用 explain 分析可疑 SQL 語句。

掌握了技術線,就可以完成某個業務功能的全流程設計和開發了。

 技術面

“面”就是某一類相關技術線的綜合。例如:

  • Java 開發是一個技術面,包括多線程、JDBC、文件讀寫、JVM 調優、JVM 工具等多個技術線;

  • 高性能開發是一個技術面,包括:數據庫分庫分表、緩存、多線程、HTTP 優化等;

  • 數據庫維護是一個技術面,包括:數據庫調優、數據庫問題定位、高性能數據庫表設計等;

掌握技術面,已經是某個領域的專家了,簡單來說就是這個領域的問題找你都可以搞定。

 技術體

“體”就是多個技術面的綜合。

最常見的“體”就是架構設計,對於一個大型業務或者系統的架構師來說,需要掌握多個技術面,然後進行設計和取捨。例如,一個後臺架構師需要掌握 Java 的技術面、數據庫的技術面、網絡的技術面等,以及業務領域知識。

架構設計是橫向技術面的綜合,我稱之爲廣度技術體;還有一種縱向技術面的綜合,我稱之爲深度技術體。例如 Java 的開發工程師,當達到技術面的水平時掌握了“多線程、JDBC、文件讀寫、JVM 調優、JVM 工具等”,如果需要進一步在 Java 這個領域提升技術,就需要向下瞭解操作系統、硬件(CPU、內存、磁盤等),從而更好的解決某些複雜的問題,例如 Disruptor 高性能併發框架的設計。掌握了技術體,就可以進行架構設計,或者成爲某個領域的資深專家了,解決領域級的複雜問題。

 

 

軟實力

 發現問題

有的問題很明顯,例如線上出故障,系統性能不達標,系統性能需要達到 5W QPS;但有的問題並不那麼明顯,並不能一眼看出是問題在哪裏,是技術問題還是管理問題。

例如我們曾遇到團隊間協作開發效率很低,每次開發一個業務功能,都需要幾個系統的研發人員來討論接口協議、接口數據格式、接口安全加密、業務邏輯等,大家都不厭其煩,但好像又都必不可少,團隊間爲了提高效率,項目經理制定了規範、流程、模板等,但作用最終都不大。那後來是怎麼解決的呢?通過引入服務中心來完成系統間同步接口調用,通過引入消息隊列來完成系統間異步消息通知,系統間協作效率大大提高,以前要開會討論幾個小時的事情,現在只要明確接口傳輸的數據內容即可,甚至都不用開會,兩個研發一討論就差不多了。

除此以外,問題的根源往往掩蓋在很多問題表象之下,如果不解決根源問題,解決一個表象問題,獲得一時安寧,一段時間後又發生另外的問題,長此以往反反覆覆。

例如我們曾有個系統,今天交換機故障導致業務問題,明天系統 bug 導致業務問題,後天機櫃斷電導致業務問題,還被黑客攻擊過,這些問題看起來都很獨立,問題的發生也感覺都是偶然的,按照出一個問題解決一個問題的方式也沒什麼問題,但全年來看,業務就是出了很多問題,怎麼解決?我們經過分析,發現根本原因是業務需要異地多活,而架構是雙機房單中心的,我們需要做到的不是避免每個問題的發生(事實上也不可能避免),而是應該做到問題發生後能夠快速處理,於是通過將架構重構爲異地多活,重構完成後還是有各種偶發問題發生,但對業務的影響就很小了。

發現問題的能力主要來源於經驗,包括成功的經驗、踩坑的經驗、參考別人的經驗,因此如果要培養自己這方面的能力,多思考、多總結、多學習、多參加行業交流。

 技術創新

達到這個級別基本都是業界大神一般的級別,說實話我也沒什麼經驗,只能仰慕這些大神。

例如:

  • 當年貝索斯要求亞馬遜公司內的系統都服務化,後來是哪位大神想到可以把這個能力開放出來轉換爲“雲計算”?

  • 阿里雲王堅博士當年在衆人都不看好的情況下爲何堅持雲計算是未來?

  • Google 在解決大數據問題時,如何能夠提煉出三篇論文,開啓了一個大數據時代?

 

640?wx_fmt=jpeg

技術實力案例點評

一個面試者面試 Java 技術專家崗位,其中有一項項目經驗很牛逼:XX 架構重構,性能提升 10 倍。於是,我針對這個項目經驗進行了深入的考察,結果……

下面是我們大概的對話過程:

我:請簡單介紹一下這個項目重構。

面:我們某個業務和比賽有關,每次關鍵比賽前業務訪問量是平時的 10 倍以上,原來的系統量一大就卡死了,用戶體驗很不好,需要重構。

我:具體怎麼做的呢?

面:我通過引入 mc 緩存,將原來直接訪問數據庫的操作改爲先訪問緩存,性能比原來提升了 10 倍。我:爲何你想到了引入 mc?

面:(卡了一下,有點驚訝我的問題)……我上網查了一下資料,很多都說 mc 能夠大幅提升性能,並且使用後確實效果很好。

[點評 1] 這是典型的“代碼靠抄,方案靠搜,效果靠試”,面試者看到了一個問題,但沒有分析和思考,然後上網搜方案,看到了好像很多人都說引入 mc 都能解決問題,於是嘗試引入了 mc,最終確實好像解決了,這讓面試者自我感覺良好。

爲何我在面試的時候問“爲何引入”,這是不是一種“面試造航母,入職擰螺絲”的裝逼面試呢?其實不然,我們的業務中遇到性能瓶頸的問題是非常常見的,而簡單的“性能瓶頸”只是一個表象,我們看看可能的原因有哪些:

  1. 數據庫慢查詢,例如不合理的查詢、沒有索引、表數量太大等;

  2. 併發設計不合理,例如多線程鎖設計不合理,採用了不合理的 Reactor 模型等;

  3. 代碼邏輯不合理,例如本來可以異步處理的也採用了同步處理,某個循環裏面重複訪問數據庫,某個接口打印了大量日誌等;

  4. 外部系統性能低,例如依賴的某個系統性能低,太多無效的外部接口請求等;

  5. 數據訪問不合理,例如沒有用緩存,沒有分頁等;

  6. 非核心業務和核心業務互相影響;

以上僅僅是舉例,還有更多可能的原因,如果一個技術專家不具備“面”的技術,只知道 mc 可以提升性能這個“點”的技術,是遠遠不夠的,一次運氣好能解決問題,但不可能次次都運氣好。

當然,如果面試的是“Java 高級開發工程師”,面試重點和麪試問題又不一樣了。


我:mc 能大幅提升性能的原理是什麼?

面:緩存訪問快,數據庫訪問慢。

我:那 mc 性能多高,數據庫性能多高?

面:……(想了 10 秒)抱歉,沒有研究過。

[點評 2] 這是典型的知其然不知其所以然,開源方案拿來就用,基本的測試和原理研究都沒做過。大部分人對於很多概念的理解都是“性能高”,“可靠性好”,“聽說很厲害”,但在具體設計的時候,這個理解是遠遠不夠的,一定要量化,例如:同樣是負載均衡,Nginx 的性能量級是萬級,LVS 是 10 萬級,F5 這類設備是百萬級(具體數值和硬件以及數據包大小相關,這裏只給量級)。

爲何要研究原理呢?以 mc 爲例,一致性 hash 和擴容相關,內存分配方式和緩存容量有關,如果這些都不清楚,實際應該部署多少 mc 節點,每個節點應該分配多少內存,這些都沒法確定。


我:沒關係,那我們換個問題,重構後你們的系統用到的機器數量是多少?相比重構前減少了多少?

面:機器數量是 100 臺,相比重構前沒有減少。

我:哦,100 臺機器,QPS 每臺才 300 多,我看你們的業務也不是很複雜,爲何這麼低?

面:……(卡住 10 秒)這……300 多 QPS 好像也不低吧?

我:那你有沒有分析過每次請求全流程每個階段的性能耗時?瓶頸在哪裏?

面:(卡住 5 秒)沒有分析過呢?

我:那爲何就認定引入 mc 就有效果?

面:……(卡住 10 秒)我看大家都說引入緩存能大幅提升性能,而且最終效果確實很好。

[點評] 這就是知道技術點,不知道技術線和技術面,按道理對於系統性能問題的分析,至少是技術線級別的,需要分析每個請求每個階段的耗時和原因;也可以是技術面級別的,例如分析數據庫的設計、服務器的負載均衡等,還可以是技術體級別的,例如架構是否合理,是否可以將某個子系統拆分,引入消息隊列等。

我:好吧,換個問題,如果讓你再一次優化系統,你覺得可以怎麼做?

面:……(思考 20 秒)我覺得目前的系統性能已經足夠,應該不需要優化了。

[點評] 考察的是發現問題的能力,但他發現不了問題,其實前面已經都提到了,100 臺機器就是問題,QPS 過低也是問題,但由於他沒有經驗,是看不出這些問題的。

很遺憾,最終這個面試者沒有通過面試。

 

寫在最後

對於技術人員實力的判斷,並不存在完全客觀和可量化的標準,多少都帶有評判者的主觀判斷,這也是最容易產生爭議的地方,本文也是我自己的一個思考和總結,一家之言,拋磚引玉,歡迎大家探討交流。

文章轉載自極客時間(jikeshijian)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章