天天看點

如何擁有技術上司力

通過上篇文章,相信你現在已經了解“什麼才是技術上司力”。今天,我就要跟你聊聊,怎樣才能擁有技術上司力。

第一,要吃透基礎技術。基礎技術是各種上層技術共同的基礎。吃透基礎技術是為了更好地了解程式的運作原理,并基于這些基礎技術進化出更優化的産品。吃透基礎技術,好處很多。

  1. 萬丈高樓平地起。一棟樓能蓋多高,一座大橋能造多長,重要的是它們的地基。同樣對于技術人員來說,基礎知識越紮實,走得就會越遠。
  2. 計算機技術太多了,但是仔細分析你會發現,隻是表現形式很多,而基礎技術并不多。學好基礎技術,能讓你一通百通,更快地使用各種技術形式,進而可以更容易地跟上時代。
  3. 很多分布式系統架構,以及高可用、高性能、高并發的解決方案基本都可以在基礎技術上找到它們的身影。是以,對基礎技術的學習能讓你更好地掌握更高次元的技術。

那麼,哪些才是基礎技術呢?我在下面羅列了一些。老實說,這些技術你學起來可能會感到非常枯燥無味,但是,我還是鼓勵你能夠克服人性的弱點,努力啃完。

具體來說,就是分成兩個部分:系統和程式設計。

程式設計部分

  • C 語言:相對于很多其他進階語言來說,C 語言更接近底層。在具備跨平台能力的前提下,它可以比較容易地被人工翻譯成相應的彙編代碼。它的記憶體管理很直接,讓程式員直接和記憶體位址打交道。

學習好 C 語言的好處是能掌握程式的運作情況,并能進行應用程式和作業系統程式設計(作業系統一般是彙編 +C 語言)。要學好 C 語言,可以閱讀 C 語言的經典書籍《C 程式設計語言》第二版(K&R),并多寫程式,再讀一些優秀開源項目的源代碼。

除了讓你更為了解作業系統之外,學習 C 語言還能讓你更清楚地知道程式是怎麼精細控制底層資源的,比如記憶體管理、檔案操作、網絡通信……

這裡需要說明的是,我們還是需要學習彙編語言的。因為如果你想更深入地了解計算機是怎麼運作的,那麼是需要了解彙編語言的。雖然我們幾乎不再用彙編語言程式設計了,但是如果你需要寫一些如 lock free 之類高并發的東西,那麼了解彙編語言,能有助于你更好地了解和思考。

  • 程式設計範式:各種程式設計語言都有它們各自的程式設計範式,用于解決各種問題。比如面向對象程式設計(C++、Java)、泛型程式設計(C++、Go、C#)、函數式程式設計(JavaScript、 Python、Lisp、Haskell、Erlang)等。

學習好程式設計範式,有助于培養程式設計的抽象思維,提高程式設計效率,提高程式的結構合理性、可讀性和可維護性,降低代碼的備援度,提高代碼的運作效率。要學習程式設計範式,可以多了解各種程式設計語言的功能特性。

  • 算法和資料結構:算法(及其相應的資料結構)是程式設計的有力支撐。适當地應用算法,可以有效地抽象問題,提高程式的合理性和執行效率。算法是程式設計中最最重要的東西,也是計算機科學中最重要的東西。

任何有技術含量的軟體中一定有進階的算法和資料結構。比如 epoll 中使用了紅黑樹,資料庫索引使用了 B+ 樹……而就算是你的業務系統中,也一定使用各種排序、過濾和查找算法。學習算法不僅是為了寫出運轉更為高效的代碼,而且更是為了能夠寫出可以覆寫更多場景的正确代碼。

系統部分

  • 計算機系統原理:CPU 的體系結構(指令集 [CISC/RISC]、分支預測、緩存結構、總線、DMA、中斷、陷阱、多任務、虛拟記憶體、虛拟化等),記憶體的原理與性能特點(SRAM、DRAM、DDR-SDRAM 等),磁盤的原理(機械硬碟 [盤面、磁頭臂、磁頭、啟停區、尋道等]、固态硬碟 [頁映射、塊的合并與回收算法、TRIM 指令等]),GPU 的原理等。

學習計算機系統原理的價值在于,除了能夠了解計算機的原理之外,你還能舉一反三地反推出高次元的分布式架構和高并發高可用的架構設計。

比如:虛拟化記憶體就和今天雲計算中的虛拟化的原理是相通的,計算機總線和分布式架構中的 ESB 也有相通之處,計算機指令排程、并發控制可以讓你更好地了解并發程式設計和做程式性能調優……這裡,推薦書籍《深入了解計算機系統》(Randal E. Bryant)。

  • 作業系統原理和基礎:程序、程序管理、線程、線程排程、多核的緩存一緻性、信号量、實體記憶體管理、虛拟記憶體管理、記憶體配置設定、檔案系統、磁盤管理等。

學習作業系統的價值在于了解程式是怎樣被管理的,作業系統對應用程式提供了怎樣的支援,抽象出怎樣的程式設計接口(比如 POSIX/Win32 API),性能特性如何(比如控制合理的上下文切換次數),怎樣進行程序間通信(如管道、套接字、記憶體映射等),以便讓不同的軟體配合一起運作等。

要學習作業系統知識,一是仔細觀察和探索目前使用的作業系統,二是閱讀講作業系統原理的圖書,三是閱讀 API 文檔(如 man pages 和 MSDN Library),并編寫調用作業系統功能的程式。這裡推薦三本書《UNIX 進階環境程式設計》、《UNIX 網絡程式設計》和《Windows 核心程式設計》。

學習作業系統基礎原理的好處是,這是所有程式運作的實體世界,無論上層是像 C/C++ 這樣編譯成機器碼的語言,還是像 Java 這樣有 JVM 做中間層的語言,還是像 Python/PHP/Perl/Node.js 這樣直接在運作時解釋的語言,其在底層都逃離不了作業系統這個實體世界的“實體定律”。

是以,了解作業系統的原理,可以讓你更能本質地了解各種語言或是技術的底層原理。一眼看透本質将讓你更容易地掌握和使用高階技術。

  • 網絡基礎:計算機網絡是現代計算機不可或缺的一部分。需要了解基本的網絡層次結構(ISO/OSI 模型、TCP/IP 協定棧),包括實體層、資料鍊路層(包含錯誤重發機制)、網絡層(包含路由機制)、傳輸層(包含連接配接保持機制)、會話層、表示層、應用層(在 TCP/IP 協定棧裡,這三層可以并為一層)。

比如,底層的 ARP 協定、中間的 TCP/UDP 協定,以及高層的 HTTP 協定。這裡推薦書籍《TCP/IP 詳解》,學習這些基礎的網絡協定,可以為我們的高維分布式架構中的一些技術問題提供很多的技術方案。比如:TCP 的滑動視窗限流,完全可以用于分布式服務中的限流方案。

  • 資料庫原理:資料庫管理系統是管理資料庫的利器。通常作業系統提供檔案系統來管理檔案資料,而檔案比較适合儲存連續的資訊,如一篇文章、一個圖檔等。但有時需要儲存一個名字等較短的資訊。如果單個檔案隻儲存名字這樣的幾個位元組的資訊的話,會浪費大量的磁盤空間,而且無法友善地查詢(除非使用索引服務)。

但資料庫則更适合儲存這種短的資料,而且可以友善地按字段進行查詢。現代流行的資料庫管理系統有兩大類:SQL(基于 B+ 樹,強一緻性)和 NoSQL(較弱的一緻性,較高的存取效率,基于哈希表或其他技術)。

學習了資料庫原理之後更能了解資料庫通路性能調優的要點,以及保證并發情況下資料操作原子性的方法。要學習資料庫,可以閱讀各類資料庫圖書,并多做資料庫操作以及資料庫程式設計,多觀察分析資料庫在運作時的性能。

  • 分布式技術架構:資料庫和應用程式伺服器在應對網際網路上數以億計的通路量的時候,需要能進行橫向擴充,才能提供足夠的性能。為了做到這一點,要學習分布式技術架構,包括負載均衡、DNS 解析、多子域名、無狀态應用層、緩存層、資料庫分片、容錯和恢複機制、Paxos、Map/Reduce 操作、分布式 SQL 資料庫一緻性(以 Google Cloud Spanner 為代表)等知識點。

學習分布式技術架構的有效途徑是參與到分布式項目的開發中去,并閱讀相關論文。

注意,上面這些基礎知識通常不是可以速成的。雖然說,你可以在一兩年内看完相關的書籍或論文,但是,我想說的是,這些基礎技術是需要你用一生的時間來學習的,因為基礎上的技術和知識,會随着閱曆和經驗的增加而有不同的感悟。

第二,提高學習能力。所謂學習能力,就是能夠很快地學習新技術,又能在關鍵技術上深入的能力。隻有在掌握了上述的基礎原理之上,你才能擁有好的學習能力。

下面是讓你提升學習能力的一些做法。

  • 學習的資訊源。資訊源很重要,有好的資訊源就可以更快速地擷取有價值的資訊,極大提升學習效率。常見的資訊源有:Google 等搜尋引擎,Stack Overflow、Quora 等社群,圖書,API 文檔,論文和部落格等。

這麼說吧,如果今天使用中文搜尋就可以滿足你的知識需求,那麼你就遠遠落後于這個時代了。如果用英文搜尋才能找到你想要的知識,那麼你才能算得上跟上這個時代。而如果你連用英文搜尋都找不到,隻能到社群裡去找作者或是和大衆交流,那麼可以說你已真正和時代靠近了。

  • 與高手交流。程式員可以通過技術社群以及參加技術會議與高手交流,也可以通過參加開源項目來和高手切磋。常聞“聽君一席話,勝讀十年書”便是如此。與高手交流對程式員的學習和成長很有益處,不僅有助于了解熱門的技術方向及關鍵的技術點,更可以通過觀察和學習高手的技術思維及解決問題的方式,提高自己的技術前瞻性和技術決策力。

我在 Amazon 的時候,就有人和我說,多和美國的 Principle SDE 以上的工程師交流,無論交流什麼,你都會有收獲的。其實,這裡說的就是,學習這些牛人的思維方式和看問題的角度,這會讓你有質的提高。

  • 舉一反三的思考。比如,了解了作業系統的緩存和網頁緩存以後,思考其相同點和不同點。了解了 C++ 語言的面向對象特性以後,思考 Java 面向對象的相同點和不同點。遇到故障的時候,舉一反三,把同類問題一次性地處理掉。
  • 不怕困難的态度。遇到難點,有時不花一番力氣,是不可能突破的。此時如果沒有不怕困難的态度,就容易打退堂鼓。但如果能堅持住,多思考,多下功夫,往往就能找到出路。絕大多數人是害怕困難的,是以,如果你能夠不怕困難,并可以找到解決困難的方法和路徑,時間一長,你就能擁有别人所不能擁有的能力。
  • 開放的心态。實作一個目的通常有多種辦法。帶有開放的心态,不拘泥于一個平台、一種語言,往往能帶來更多思考,也能得到更好的結果。而且,能在不同的方法和方案間做比較,比較它們的優缺點,那麼你會知道在什麼樣的場景下用什麼樣的方案,你就會比一般人能夠有更全面和更完整的思路。

第三,堅持做正确的事。做正确的事,比用正确的方式做事更重要,因為這樣才始終會向目的地靠攏。

  • 提高效率的事。學習和掌握良好的時間管理方式,管理好自己的時間,能顯著提高自己的效率。
  • 自動化的事。程式員要充分利用自己的職業特質,當看見有可以自動化的步驟時,編寫程式來自動化操作,可以顯著提高效率。
  • 掌握前沿技術的事。掌握前沿的技術,有利于拓展自己的眼界,也有利于找到更好的工作。需要注意的是,有些技術雖然當下很火,但未必前沿,而是因為它比較易學易用,或者成本效益高。由于學習一門技術需要花費不少時間,應該選擇自己最感興趣的,有的放矢地去學習。
  • 知識密集型的事。知識密集型是相對于勞動密集型來說的。基本上,勞動密集型的事都能通過程式和機器來完成,而知識密集型的事卻仍需要人來完成,是以人的價值就在此時展現了。雖然現在人工智能似乎能做一些知識密集型的事(包括下圍棋的 AlphaGo),但是在開放領域中相對于人的智能來說還是相去甚遠。掌握了領域知識的人的價值依然很高。
  • 技術驅動的事。不僅是指用程式驅動的事,而且包括一切技術改變生活的事。比如自動駕駛、火星登陸等。就算自己一時用不着,也要了解這些,以便将來這些技術來臨時能适應這些新技術。

第四,高标準要求自己。隻有不斷地提高标準 ,你才可能越走越高,是以,要以高标準要求自己,不斷地反思、總結和審視自己,才能夠提升自己。

  • Google 的自我評分卡。Google 的評分卡是在面試 Google 時,要求應聘人對自己的技能做出評估的工具,可以看出應聘人在各個領域的技術水準。我們可以參考 Google 的這個評分卡來給自己做評估,并通過它來不斷地提高對自己的要求。(該評分卡見後附錄)。
  • 敏銳的技術嗅覺。這是一個相對綜合的能力,你需要充分利用資訊源,GET 到新的技術動态,并通過參與技術社群的讨論,豐富自己了解技術的角度。思考一下是否是自己感興趣的,能解決哪些實際問題,以及其背後的原因,新技術也好,舊有技術的重大版本變化也罷。
  • 強調實踐,學以緻用。學習知識,一定要實際用一用,可以是工作中的項目,也可以是自己的項目,不僅有利于吸收了解,更有利于深入到技術的本質。并可以與現有技術對比一下,同樣的問題,用新技術解決有什麼不同,帶來了哪些優勢,還有哪些有待改進的地方。
  • Lead by Example。永遠在程式設計。不寫代碼,你就對技術細節不敏感,你無法做出可以實踐的技術決定和方案。

不要小看這些方法和習慣,堅持下來很有益處。誰說下一個改進方向或者重大修改建議,不可以是你給出的呢,尤其是在一些開源項目中。何為上司力,能力展現之一不就是指明技術未來的發展方向嗎?

吃透基礎技術、提高學習能力、堅持做正确的事、高标準要求自己,不僅會讓你全面提升技術技能,還能很好地鍛煉自己的技術思維,培養技術前瞻性和決策力,進而形成技術上司力。

然而,僅有技術還不夠。作為一名合格的技術上司者,還需要有解決問題的各種軟技能。比如,良好的溝通能力、組織能力、驅動力、團隊協作能力,等等。《技術上司之路》、《卓有成效的管理者》等多本經典圖書中均有細緻的講解,這裡不展開講述。

附:

Google 評分卡

0 - you are unfamiliar with the subject area.

1 - you can read / understand the most fundamental aspects of the subject area.

2 - ability to implement small changes, understand basic principles and able to figure out additional details with minimal help.

3 - basic proficiency in a subject area without relying on help.

4 - you are comfortable with the subject area and all routine work on it: For software areas - ability to develop medium programs using all basic language features w/o book, awareness of more esoteric features (with book).

For systems areas - understanding of many fundamentals of networking and systems administration, ability to run a small network of systems including recovery, debugging and nontrivial troubleshooting that relies on the knowledge of internals.

5 - an even lower degree of reliance on reference materials. Deeper skills in a field or specific technology in the subject area.

6 - ability to develop large programs and systems from scratch. Understanding of low level details and internals. Ability to design / deploy most large, distributed systems from scratch.

7 - you understand and make use of most lesser known language features, technologies, and associated internals. Ability to automate significant amounts of systems administration.

8 - deep understanding of corner cases, esoteric features, protocols and systems including "theory of operation". Demonstrated ability to design, deploy and own very critical or large infrastructure, build accompanying automation.

9 - could have written the book about the subject area but didn't; works with standards committees on defining new standards and methodologies.

10 - wrote the book on the subject area (there actually has to be a book). Recognized industry expert in the field, might have invented it.

Subject Areas:

  • TCP/IP Networking (OSI stack, DNS etc)
  • Unix/Linux internals
  • Unix/Linux Systems administration
  • Algorithms and Data Structures
  • C
  • C++
  • Python
  • Java
  • Perl
  • Go
  • Shell Scripting (sh, Bash, ksh, csh)
  • SQL and/or Database Admin
  • Scripting language of your choice (not already mentioned) _
  • People Management
  • Project Management