多做專案
我是半路出家的,頭髮沒剃光的那種(實際上我現在頭髮還茂盛得很)。我在培訓機構呆了半年就出去找工作。
第一份工作失敗了——底子太薄,工作擼不動,很快主動辭職了(怕被請辭就太沒面子了)。
然後我花了點時間惡補了下——用今天的眼光看,那時的底子仍然薄得可憐,不過能應付初級工作。
第二份工作,我獨立做了很多專案——對於菜鳥來說,能有獨立專案做很重要,它能讓你較早地思考設計問題,而不僅僅是 CRUD。初入程式設計行業,最怕的就是幹了幾年,除了 CRUD 啥都不會,這對後面的發展非常不利。
然而現實的悖論是,菜鳥一般很難接到獨立專案(特別是對效能、穩定性有些要求的)。換你做 Leader,你會把重要的工作分給哪隻鳥?
所以菜鳥一定要有主動工作的意識。要有想法,且樂意表達自己的想法。開會的時候多發言,多說說自己的想法(但要謙虛,不要爭吵,千萬不能讓人覺得自己自負、不合群)。要想讓 Leader 能分配重要任務給你,首先要獲得他的信任,要讓他覺得你是個潛力股,值得培養。
有一個很重要但被很多人忽略(或不屑)的點:要自己找事做。你得學會沒事找事。在我的職業生涯中,對我提升很大的專案中有一半都是我自己找的。我說的專案不是專案管理那個意義上的專案,它可以是需求,也可以是系統優化,可以大到需要多個團隊協作,也可以小到僅僅是個通用元件開發。
當然不是瞎找。要找公司的產品和系統有什麼痛點,這些痛點你能不能解決,解決了對你和公司能帶來什麼好處——雙贏才是唯一的出路。
我發現公司的登入流程混亂不堪,經常要接入分支流程,於是提出重構登入模組;我發現公司各系統的下載功能都是各自開發,而且資料量一大就崩潰,於是提出開發統一的下載中心;我發現公司各種管理後臺系統日益增加,系統間沒有一個統一登入方案,便利用加班時間開發了個 sso 系統。我還自己寫框架,然後在公司內推廣讓別人用......
我像一隻地鼠到處鑽,還自己造輪子——世界上有那麼多輪子,一個重要的原因是造輪子本身是團隊和個人技術沉澱的有效手段。我通過開發框架理解了大部分的設計模式。
所以,如果初出茅廬,看多少經典書籍不是主要的,主要的是要多做專案,特別是有挑戰的專案。不要怕失敗,我有很多專案是失敗的(有些功能優化被證明比優化前更糟;有些專案壓根沒上線),那又怎樣——至少我思考過,實踐過。
多看書
一味地做專案並不能大幅提升自己。程式設計能力跟做專案的數量沒有必然關係——雖然在接觸不同的釘子,但你手上拿的還是原來那把錘子。
有些人以自己“動手能力強”為藉口鄙視看書。他們信奉“實踐出真知”,看書無用(特別是理論性較強的)。
熟不知書籍本身就是前人的經驗總結,還是牛人的經驗,所以必須看,看多少都不為過。
之所以是先多做專案後海量看書,是因為在沒有一定的實戰經驗之前,很多書你是看不明白的。
其實這個順序並不精確,往往是同步進行,但不同時期側重點不同。
起初一般看工具型的,如各種“深入理解”系列(深入理解 MySQL、深入理解 Redis),加深工作中密切相關的工具(你具體使用的程式語言、資料庫、快取都是工具,這裡不是說程式語言 IDE、MySQL 客戶端這種開發工具),稍微深入到其底層細節——但除非你對某個東西特別感興趣,否則此階段沒必要過於深入,沒必要每個工具都要研究到原始碼級別,燒腦是一回事,人的時間是有限的。
研究完這些工具,你會發現過去專案中一些程式碼實現、資料庫設計是有問題的,存在優化空間的——這說明書沒白看,能力提升了。能力提升的標誌是能意識到之前的實現方式的不足和改進點。
接著需要多看看跟具體工具無關的書,像計算機原理、作業系統、設計模式、系統架構、演算法,甚至軟體工程。如果說前一個階段的閱讀重心是搞清楚如何用 Redis 做快取系統,這個階段則是學習系統架構中的快取實踐模式。
這種型別的書籍重點是講思想和實踐經驗,所以多少有點抽象,很多書看一遍後雲裡霧裡,覺得好像學到了什麼,但又什麼也沒學到。這很正常,因為你的專案實戰經驗還不足以支撐自己去深入理解這些東西。
我在看《領域驅動設計》時,雖然處處都能感受到驚喜,但很多概念是囫圇吞棗,覺得自己理解了,又好像沒理解。像聚合、聚合根、限界上下文、領域服務、應用服務,低頭看書時覺得上面的東西都能看得懂,一旦抬頭思考就卡住了。這一方面反映出我經驗不足,另外也說明我正觸碰到自己的認知邊界,正在接受一種全新的知識或說認知模式——一旦得到突破,便會有質的提升。
看完《領域驅動設計》後的一個重要效果是,以後在設計系統時,我會有意識地去用 DDD 裡面的東西思考設計。這時候多半會卡殼——經常卡的那種。於是我會回頭再去看書,因為這時候是帶著問題看的,直接找到相關主題看一遍,多半會有“原來如此”的感嘆。
比如一些控制器裡面程式碼邏輯較多,而且很可能多個控制器存在相同或相似的邏輯,但這些邏輯又明顯不屬於領域層,怎麼辦呢?我忽然想到應用服務的概念,這些邏輯應該抽離成服務,但屬於應用層的服務。這樣一實踐,大致就理解了原本抽象的概念。任何概念都是用來解決問題的,如果你不知道一個概念是用來解決什麼問題的,你就沒有理解這個概念。
所以做專案和看書是不斷迭代的過程,不斷學習,不斷實踐,不斷思考,你才能不斷突破自己。
學習是辛苦的,突破是痛苦的。人的大腦本能地喜歡呆在舒適區。我們今天學了這門語言,明天再去學那門語言就會覺得很輕鬆,因為兩門語言的學習模式是一樣的,大腦是呆在舒適區的。但今天學習這門語言,明天去學習這門語言的實現就會很痛苦,因為這是兩種不同的認知模式,大腦需要走出舒適區,一旦走出舒適區就會進入混沌態——大腦不喜歡混沌態。
要想獲得大的突破,必須學會接納處於混沌態的自己。
讀些歷史書。這不是必須的,但“讀史使人明智”是真的。感興趣的話讀一讀人類歷史(不是教科書那種),以及科技史。至少要讀讀計算機史。歷史能告訴我們一些東西為啥是這樣而不是那樣的。計算機為啥叫 Computer?一個位元組為啥是 8 位元?鍵盤為啥是 QWERTY 佈局?計算機一開始就用的二進位制嗎?為啥說馮·諾依曼是現代計算機之父?學史跟程式設計沒有必然關係,但能開拓你的視野,讓你知道那個時候人們面臨怎樣的問題,是怎麼解決的。有些你認為的新東西其實很早就被發明或構思出來了(比如 10 年前開始流行的雲服務概念其實在上個世紀 60 年代就以“計算機公用設施”的概念盛極一時)。
人們不喜歡看書的一大理由是一種人人都有的感覺:很多書看完後很多東西都不記得了。這種感覺很不好。
有句話叫“好讀書,不求甚解”。我對“甚解”的理解是企圖把書中每個知識點甚至每句話都搞清楚並記住。
沒那個必要。除非記憶力超群(據說馮·諾依曼就有這個能力),大部分人在讀完一本書後都會忘掉大部分內容(甚至讀得越慢忘得越多)。但今後你再去讀任何一個章節,你都會覺得很熟悉,有時候在專案實踐中大腦會突然蹦出個原本已經“忘記”的知識點。這是大腦的正常生理機制,沒必要跟它較勁。
我有時候讀完一本書後,大腦裡只剩下一個概念,其他的一概忘記了。比如我讀完《設計原本》後,腦袋裡只剩下“概念完整性”這個詞。也許當時我真的沒讀懂這本書,但光這個詞就讓我獲益匪淺。在日後的系統設計、團隊管理,特別是跨團隊協作開發中大型系統時,這個詞不斷地出現在我腦海中。很多系統上線後 bug 不斷,就是概念完整性(以及概念一致性)上出了問題,比如多個系統對同一個概念定義不同;金額四捨五入規則不同;一些重要概念在系統設計之初缺失(或誤用)導致系統設計上的重大缺陷;對某些概念未做澄清而導致實現和預期不一致(如什麼是“使用者”,什麼是“會員”)。專案啟動之初需要花大量時間和精力來達成概念完整性和一致性(各種會議、宣講,各種設計文件),很多專案缺少了這些步驟導致後期混亂不堪,團隊中每個人都只見樹木不見森林。
所以,若能從一本書 get 到一個讓自己終身受用的東西,夫復何求?
放一張鄙人的讀書清單鎮樓(讀沒讀完不要緊,架勢要擺出來):
多擼原始碼
一個人能做的專案是有限的,而且很多專案都是同一種型別。更有甚,由於各種原因(如進的公司只有 CRUD 型需求)壓根沒機會承接稍有挑戰性的專案鍛鍊自己。咋辦?
既然自己沒專案擼,就去擼別人的吧。
有很多高質量的開源專案,擼起來津津有味。很多時候,擼完一個高質量(但不一定規模得有多大)的開源專案比自己開發一個專案收穫要大得多。
你看書時存在的疑惑很多都能在擼原始碼的過程中找到答案。我相信你初學設計模式時一定跟我一樣自認為懂了,又覺得沒懂,反正感覺很抽象。擼些原始碼,你會發現裡面用了很多設計模式,你會感嘆“哦,原來這樣用”。
擼原始碼之前最好看下對應專案的手冊,使用下,有個整體瞭解。也可以百度找下其他人擼出來的筆記,瞭解下大致的技術結構。
先擼簡單的。走上來就擼 nginx,很容易留下心理陰影,從此戒擼。我學 golang 的時候就是從一個很簡單的快取中介軟體(幾千行程式碼)開始擼,越擼越有信心。
要寫筆記。我喜歡直接從 github fork 過來,邊擼邊寫註釋。
如果真的不想擼,或者擼不動(被裡面各種彎彎腸子的設計繞得雲裡霧裡),也可以看別人擼。可以花點錢在極客時間上看大神們擼。
有些專案擼著擼著就變成自己的專案了——我的意思是面試的時候可以寫入簡歷裡面,和麵試官聊的時候可以說說你對那個專案的理解,甚至能撒個謊說自己開發過類似的專案(別說我教的)。
去帶團隊
程式設計師經常問的一個問題是:做開發到後面必須要帶團隊嗎?
這個問題我也不知道答案(很多帶“必須”字眼的我都不知道答案——怎麼回答呢?說必須?肯定有人反駁;說不一定?感覺像個教科書),所以不打算回答。
我想說的是,如果你有帶團隊的機會,就去把握——特別是比較完整的團隊(不是整個公司就一個前端一個後端這種)。至少要去試試。
不是說帶團隊未來就一定是走管理崗,不敲程式碼了。帶團隊對自己的實力提升有很多好處,我們不說提升什麼綜合能力,單說資源。
職位越高,可以擁有的資源就越多。當你只是普通的開發人員時,多數時候你只能被動接受別人的任務安排,哪怕這個任務對提升能力沒什麼幫助。但當你成為組長、經理、總監、CTO 時,你會發現自己能決定的事情越來越多(當然責任也越來越大),能夠影響的範圍越來越大,能夠獲得的資源越來越多。
這不是說你一定要走這條路,只是說要有這個意識——畢竟國內大部分公司資源是通過“帶團隊”的形式獲得的。
如果我鐵定了走技術路線,資源有什麼用呢?可能沒用,比如你在某個真的靠技術論天下的大廠當資深程式設計師。但只要你想往架構師方向發展(首架被普遍認為是技術路線的目標),你會發現你其實非常需要資源(當然成長為架構師並不是非要帶團隊不可)。
我們不提什麼架構師,就說普通程式設計師崗。所謂資源,是指為做某件事所需要的人力、財力以及時間。比如你想開發個系統,或者做個重構(從成長的角度來說對你以及團隊都有好處),如果你有一定的影響力(或者權利),你就有可能說服你的上司同意你做這件事(可能要兩個月時間,並涉及到幾個團隊的人事協作);更有甚,你可以自己決定做不做這件事情。
起碼,你能成為一個團隊或一個專案的技術負責人,這並不難。站在團隊 Leader 的角度,也能讓你的視野更加寬闊。
當然,如果你對帶團隊很反感(請確認並非你的大腦不想走出舒適區),你完全可以不帶。這裡是說帶團隊可以獲得資源,但不是說資源只能通過帶團隊的方式獲得。
多寫東西
大神都有一個共性:喜歡寫部落格。
上學的時候,學習好的大多喜歡記筆記,有些老師還強制要求學生記筆記。寫東西能強化記憶,還能加深對知識的理解。
寫作有益於構建一個人的知識體系。比如你對 DNS 有個初步瞭解,大致知道它的作用是將域名解析成 IP 地址——僅此而已。但如果你打算寫一篇關於 DNS 的文章,肯定不能僅此而已。你會去查資料,瞭解 DNS 的歷史,研究現實中 DNS 解析的具體實現方式。這過程中,你瞭解到全球 DNS 層次結構,最上面有根 DNS 伺服器,下面有頂級域伺服器,再下面有權威 DNS 伺服器;你瞭解到 IANA 和 ICAAN 的歷史,順便還了解到 IP 地址在全球是怎麼統一管理的;你還了解到如何通過智慧 DNS 解析實現 CDN 網路;甚至你想自己搭建個權威 DNS 伺服器。如果不寫部落格,你很難有動力去了解這些,很難構建出 IP 和域名的完整知識體系。
對我而言,寫作還有個好處是刺激思考,整理思路。有時候我面對一個問題半天沒有頭緒,於是我嘗試把問題作為文章標題大大地寫下來。第一步,我嘗試寫出來關於該問題我能想到的任何東西(對問題本身概念性的釐清、初步的推理、引申出來的新問題等等,只要能想得出來就寫下來)——然後我會發現自己的思路像是開了閘,自此暢通無阻。寫作能鍛鍊人的思維能力。
從長遠看,寫作能建立個人品牌。公司需要品牌,個人也是如此。建立個人品牌(或叫打造個人 IP)主要有三種途徑:
- 混大廠。加入頭部公司(如 BAT)並在裡面混個不錯的名頭;
- 混開源。開發一款高 star 的開源軟體或作為某款知名軟體的重要貢獻者;
- 寫部落格。
有些大牛三方面都佔了,但如果你我做不到這點,可以嘗試只做一項,比如寫部落格。
很多人“不善於”寫作。這是藉口。沒有人天生就善於寫作。那些所謂“善於”寫作的都是長時間訓練出來的。另外,寫技術部落格並不需要你的寫作功底多麼好——話能說明白就行。
還有些人覺得自己現在技術不咋地,怕班門弄斧,覺得還是等底子厚了再寫。沒必要,因為寫部落格本身就是提升技術底子的非常快速有效的手段,不要顛倒了。如果有人看你的部落格更好(有人看是大部分人能持續寫作的主要動力),沒人看的話,權當自我提升,順便練練手,寫得多了積累得多了質量自然上來了,自然會有人看了。
還有人覺得自己想寫的別人已經寫了很多了,沒必要再重複這些事情了。已經有那麼多小說了,仍然有人在寫;已經有那麼多音樂了,仍然有人在譜;已經有那麼多輪子了,仍然有人在造。從某方面看,《聖經》說得沒錯:太陽底下,並無新事。但另一種說法是一千個觀眾就有一千個哈姆雷特。每個人對同一個問題的看法,對同一個知識的理解都是不同的,雖然 HTTP 協議已經被講爛了,但你的理解,你的寫作風格,或許會有些新意。就算全無新意,一樣會有人看,因為資訊不是同步的,總有人會來到你的地盤而不是別人的。
所以,不要想得太多,寫就是了。
關於寫作平臺,真是太多了:部落格園、CSDN、知乎、簡書、掘金以及自建部落格等等。還有人喜歡用 github(不過對搜尋引擎不太友好,所以個人不太建議)。
個人比較喜歡部落格園,我覺得部落格園技術氛圍最濃厚,也最簡潔,沒那麼多么蛾子。當然,如果你打算將寫作事業長久經營下去,不妨嘗試去經營自己的公眾號,雖然更難,但一旦你堅持住了,從長遠看,它會給你帶來更大的收益(成長、品牌以及資金收益)。
去當講師
一般網際網路公司都有技術分享會,但我發現很多人不願意去抓這種機會。有些團隊的分享會進行不下去,不得不給成員分配分享任務,而大多數人也是將其作為一種額外負擔看待的,甚至有人抱怨 Leader 給自己加了額外的任務導致自己不得不加班。
無論你處於什麼級別,能成為任何分享會的講師都是莫大的機會,值得去把握。大牛們都十分樂意參加各種分享會,公司內部分享會,行業峰會等等。
當講師至少有三方面的收益。
首先,快速提升專業能力。和寫作一樣,你必須選擇一個主題,該主題可能是你非常熟悉的,但更多時候可能只是粗略瞭解過。所以你必須網羅材料並整理成體系。比如你想講 Unicode,因為你先前大致瞭解過這塊,還自己寫過 UTF-8 的實現 demo,覺得對這塊很在行。但當你規劃講稿結構時發現,必須要先講講 Unicode 出現之前的字元編碼情況,據此才能引出 Unicode 的歷史必要性。於是你瞭解到 ASCII、ISO-8859、GB 2312、Big5 以及 IBM 和微軟的各種內碼表;而後 Unicode 出現了,你必須搞清楚的一件事是,Unicode 如何相容這些早期的字符集編碼,於是你不得不深入 Unicode 的實現細節;當你瞭解到原來早期 Unicode 採用的是雙位元組定長編碼方案時,你必須去探明為何後面 UTF-8 超越 UTF-16 成為應用最廣泛的 Unicode 實現方案?如此,當你準備完講稿時,你已經構建了自己的字符集編碼知識體系(而不僅僅是瞭解些 Unicode 和 UTF-8 的零星的知識)。
其次,鍛鍊自己站臺講話的能力。隨著經驗的積累,職位的提升,你多少需要上臺講點話。你無需做到口若懸河,但最好也不要語無倫次。程式設計師平時很少有這種上臺講話的機會(機會出現了大部分人也不願意去抓)。當講師一方面氛圍比較輕鬆,除非是大公司幾百甚至幾千人的分享或者行業峰會,否則聽眾基本都是平時打交道的熟人,你不會有多大心理壓力(特別是做過幾次分享後);另外你要講的內容是充分打好草稿(PPT)的,心裡有數。所以這種場合的演講大部分人都能駕馭得了。但分享也是演講,要講究演講技巧,要將聽眾帶入你的世界並很容易理解你所講的東西(很多人做技術分享就是在那裡讀 PPT,完全不考慮聽眾感受,搞到後面很多人都在那玩手機了)。這是讓你體驗演講並鍛鍊演講技巧的大好機會,大部分人第一次都講不好,但多講幾次,就會不自覺地去思考並提高演講技巧。
最後,讓更多人認識你。你是不是認為大家都在一個屋簷下共事,還有誰不認識你的?除非你在公司技術圈有很大影響力(大家公認的大牛),否則不認識你的人多了去了。所謂認識,不是說人家知道你名字就完事了。所謂認識,是要人家知道你在做什麼,你擅長做什麼,你哪方面比較牛;進而,認識會轉化為“認可”:讓別人認可你,更讓你的 Leader 認可你。今後有機會參加行業峰會了,也是讓更多的業內人士認識並認可你——如此也就打造出你自己的 IP 了。
很多人不願意當講師,除了沒有上臺演講的經驗外,一大顧慮是認為自己並沒有什麼特別擅長的東西。記住一點,多數時候,不是因為你真的擅長某方面才去分享,而是你先決定分享某個你熟悉但不精通的東西,然後去鑽研,在分享的同時也真正精通了這個主題。
如果一開始沒有信心,就從小範圍做起。從小組內部分享開始,內容也不用那麼專業那麼深入,隨意點。然後擴充套件到部門或者公司層面。
做分享跟寫部落格一樣,於人於己都百利而無一害,不要等,儘早去做。
不是因為自己行才去做,而是先做了才行的。