程序員在“金字塔”的背景下,如何做到比別人更具有競爭力?
工作了挺久,發現有個挺有意思的現象,從程序員、高級程序員,到現在掛著架構師、專家之類的頭銜,伴隨著技術和能力的提高,想不明白的事情反而越來越多了。這些疑問有些來自於跟小夥伴交流,有些是我的自問自答,有些到現在也想不清楚,這篇文章就來寫一寫這些問題。
如何更高效的學習?
很多新人程序員一開始在學習上找不到方向,但我想在渡過了一段時間的新手期之後這類問題大多都會變得不再那麽明顯,工作的方向也會逐漸變得清晰起來。
但是沒過多久,能了解到的資料就開始超過每天學習的能力,像是買了沒看的書、收藏沒讀的貼、mark 了之後再也沒有關註過的文章越積越多,更別提每天面對各種技術分享或者微博裏的新鮮玩意了。
大多數人每天能留給自己學習的時間有限,這個階段如何提升學習效率就成了要解決的重點。
說說自己提升學習效率的心得,其實非常簡單:體系化的學習。
我曾經很喜歡看一些博客或者是一些 “看起來” 比較通俗易懂的文章,每天在微博微信裏刷到什麽技術文章就 mark 下來,基本上幾分鐘就能讀完。可一段時間下來,雖然讀了不少東西,但是還是有種在原地打轉的狀態,並沒有感受到有什麽實際的提高。
最後實在忍不住,抱著厚書硬啃了一遍,突然有種豁然開朗的感覺:讀書時自己學到的是一張完整的知識網絡,每個知識點和其它內容相互聯系和區別。這種全方位的理解比起一篇篇獨立的文章,不知要高到哪裏去了。
而讀了一段時間書之後,漸漸原本不在一個體系之內的知識也會慢慢聯系起來,比如說後端服務的開發,簡單梳理一下,就成了這樣:
在重復了幾次痛苦的學習-梳理過程後,再去看一些獨立的文章或者資料往往會事半功倍,因為能在體系內找到相對應的知識,甚至有時候一本書裏一頁只需要看一句話,點破那層窗戶紙,就可以掌握新的知識。
你是怎麽知道這些的?
工作中總是會遇到各種各樣的問題,有幾次把問題處理過程總結了一下,發了出來,之後就像滾雪球一樣,有越來越多的小夥伴來咨詢問題,比如說:
前一陣幫忙排查一個性能問題,系統壓力稍微一大就會頻繁 Full GC,壓力降低之後又恢復了。
某個小夥伴接入代碼質量檢查系統之後發現每次構建會報一個莫名其妙的錯誤,打不了包。
某次代碼有 bug,小夥伴跑來來問我 git 怎麽才能回滾代碼。
每次查完這種問題的時候,一些剛畢業沒多久小夥伴們就會用一種崇拜的眼神看著我,然後大多會問:“你是怎麽知道這些的?”
實際上,雖然我一直在不斷的學習,但是面對工作中無窮無盡的新問題,大部分問題還是會命中我沒有掌握的那部分區域。每次有人問到我不了解的知識時我都會非常開心:還有什麽比帶著問題學習更有效率的學習方法呢?
而且幸運的是,在建立了自己的知識體系的基礎上,學習新的知識通常都能很快的上手,解決一個問題往往只需要多了解一個知識點而已。
舉個例子,頻繁 Full GC 的問題,以前查過很多次 GC 的問題,大多數是 Java 程序或 JVM 內存泄露問題,而這次內存沒有泄露,GC 吞吐量也正常,那麽我只需要查一下如何查看一段時間內創建的最多的對象的方法就可以了。
回到剛才的問題,小夥伴們問我:“你是怎麽學到這些的知識的?”
答案是:在你問我問題之後現學的。
架構師應不應該寫代碼?
似乎隔三差五就能看到一些關於架構師應不應該寫代碼的文章。我是屬於寫代碼派,因為我本身就喜歡寫代碼。但是,當工作職責發生變化之後,如何保持寫代碼和其它工作之間的平衡就成了問題。
架構技術是程序員離不開的話題,在這裏順便給大家推薦一個架構交流學習群:650385180,裏面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高並發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,相信對於已經工作和遇到技術瓶頸的碼友,在這個群裏會有你需要的內容。
從個體效率上來看,我自己親自寫代碼,和很多人相比沒有什麽絕對優勢,甚至有些人碼代碼的速度比我還快一些。
但作為架構師,參與寫代碼還是會有一些不大不小的收益。
一般來說合格的程序員對於明確分配的任務會完成的很好,但是大部分情況下 “架構” 這個詞意味著架構師並不會涉及太多細節,架構圖和代碼實現之間總還是有些距離,你無法保證所有人都會正確的理解你的設計,或者是程序員寫代碼時遇到障礙時會立刻想出足夠優雅的解決方案。
之前寫過一篇關於爛代碼的文章 ,大部分爛代碼並不是架構師的設計問題,如果程序員沒能很好的理解設計或者是經驗不足,往往會做出一些非常匪夷所思的東西。比如我見過剛畢業的程序員為了防止模塊耦合而將耦合的代碼又拷貝了一份,或者為了 “優化性能” 而盡量把所有邏輯寫在一個函數裏。
如果不能及時發現並改正這些問題,那麽這些地方就會變成 “正確的錯誤代碼”,或者” 不是我寫的 “代碼,或者” 我靠我也看過那段代碼 “之類足以被掛上恥辱柱的玩意。這種問題算是架構師的責任嗎?作為一個視名聲如命的架構師,我認為是的。
在我看來,寫代碼的架構師更像是在做後勤保障的工作:在代碼中第一時間發現可能存在的問題,向其他人提出警告,或是給予其他人改進的意見,必要的時候或是給其他人演示一下正確的姿勢。
大部分情況下我作為架構師並不需要攬下 “核心模塊” 開發這種工作,畢竟我能調配的時間太零散了,效率難以保證,很多人在專註的情況下比我做的好很多,我只需要保持大局觀需要適度參與就可以了。
總的來說,架構師和程序員在某些方面上有點像產品經理和用戶的關系,大部分程序員並不會主動告訴你他們想要什麽、哪裏需要優化,甚至自己也不知道這些。想要做出好的產品,捷徑之一就是跟用戶做同樣的事情。
實踐:開會是個技術活嗎?
我覺得應該沒有人喜歡開會,身為一個程序員,沒有幾個人的誌向是當什麽職場交際花。
但是會議邀請就這麽一個個的跳了出來:開發需求要跟產品開會、項目方案要跟技術開會、新人轉正要去開評審會、別的公司來了幾個大牛正在開分享會、出了故障要開總結會、小組有周會、部門有周會,大項目每周開兩次碰頭會不過分吧?小項目啟動的時候開個會不過分吧?調試的時候發現有個坑大家趕緊討論討論吧?
有時候參加的會議整場下來跟我毛關系都沒有,全程神遊倆鐘頭,最後突然有人一拍桌子:” 還有問題沒?好,散了!“
也有可能有個什麽會沒叫你,過了倆禮拜突然收到封郵件催開發進度,” 當時那個會你沒參加,大家都說應該是你們做……你沒看會議紀要嗎?“
吐槽了這麽多,但我還是認為開會是個技術活,對於架構師來說尤其如此。
大多數技術人員開會並不是那種新聞裏的工作匯報或者長者們的會議,他們真的需要通過開會討論一個具體方案,或者解決什麽具體問題。可惜的是我參加過很多會議,大多數的會議都是在毫無意義的交流中浪費時間:幾方人坐在一個屋裏互相說一些對方理解不了的話,最後得出一個” 我們會後再捋一捋 “之類的結論。
這並不是會議才有的問題,在程序員日常的溝通中,也有很多人並不懂得如何交流,比如偶爾會收到一些寫的非常認真的郵件,打開之後是密密麻麻的一屏幕文字,但是從第一句開始就不知道他在說什麽,後面的東西連看的動力都沒有了。
大多數時候,溝通的核心不是你說了什麽,而是你想要讓對方了解什麽、讓他做什麽。良好的溝通能在工作中顯著提升效率,但很多人忽略了這個事情。
想要恰到好處的進行溝通是一件不那麽輕松的事情,但是簡單來說有幾條原則:
1.確保各方對背景的理解一致,比如開會之前先簡單通過郵件交流一下,對新加入會議的人花個 30 秒鐘做個前情提要,或者在討論過程中讓對方說一下他的理解。
2.去掉對方不能 / 不需要理解的內容,比如跟產品說 “這個隊列在高並發下因為鎖的實現有問題導致 CPU 性能瓶頸” 不如改成 “我們發現了性能問題,持續 10 分鐘了,10 萬用戶收不到運營發的無節操廣告,大概 5 分鐘後擴容解決”。
3.確保在對方失去註意力前盡快說出重點,比如排查問題的總結郵件,如果第一段是這樣:“某某框架內部使用的是 xxx 技術,這個技術的架構是這樣:blabla”,那麽對方可能完全不知道你在講什麽。可以換成這樣:“我發現了某某框架的 bug,需要盡快升級,否則在 xxx 情況下有可能會出現 yyy 問題,具體排查過程如下:blabla”。
4.不要說沒有意義的內容浪費其他人的時間,比如” 這需求做不了 “或者” 這裏不可能出 bug “,沒有人想聽到這些廢話。
為什麽別人的系統總是那麽爛?
很多程序員解決問題的能力很強,說要解決一個什麽問題,下午就能寫出幾百行代碼把功能實現了。但是做出來的東西有種少考慮了什麽東西的感覺,我花了挺久去想一個詞去形容 “這個東西”,最後想出了個勉強可以表達的詞:程序的生命力。
大部分程序都能實現功能,但是如果把 “時間” 這個也作為一個考慮的維度的話,就會意識到一個合格的項目需要考慮更多的東西:更通用的使用方式、易於理解的文檔、簡單而易於擴展的設計,等等。而想要毀掉程序的生命力也很簡單:做的更復雜,更定制化,讓更少的人參與。
我跟很多程序員提過程序的生命力,比如說要讓自己寫的工具的操作方式跟其它 Linux 命令類似,或者要用一些更容易理解但不是性能最優的設計方式,又或者要他去參考現在業界主流的做法,很多人認為提這種需求的意義不大,我覺得這裏還是舉個例子吧。
很多公司應該都會有一些遺留系統,它們龐大、笨重、難用、幾乎無法維護,所有人都在抱怨這些系統,並且每天都在想方設法換掉那些遺留系統。但是一段時間過去之後,又會發現身邊的新人又開始吐槽當時替代遺留系統的那個系統了。
“大多數系統當初都很好使,功能當時夠用,擴展性看起來也可以,但是這些系統都是開發的人離職之後變壞的。”
還有更好的辦法嗎?
成為技術專家之後的工作可以說是痛並快樂著,會有很多人找你咨詢問題,另一方面,會有太多人找你咨詢問題。
甚至有一段時間我每天的工作就是解答問題,小到工具使用中到疑難 bug,大到架構設計,從早上到晚上基本都是在給各種各樣的小夥伴提供咨詢服務。
我很快發現有些地方不對頭:有些問題實在是太簡單了,以至於我甚至都不用思考就可以給出答案,為什麽會有這種問題?
後來我在每次回答之前先問一句:
“你還有更好的辦法嗎?”
一小部分人立刻能給出優化後的版本,甚至我連續問幾次之後,他能給出好幾個優化後的版本;另小一部分人會斬釘截鐵的說優化不了了,就這樣了。但是大部分人會猶猶豫豫的說出一些完全不著調的回答。
後來我改成在每次回答之前先問兩句:
“你要解決什麽問題?”
“還有更好的辦法嗎?”
效果好了很多,很多小夥伴發現要解決的問題並不復雜,只是做法跑偏了。
再後來我改成了在每次回答之前先問三句:
“他們要你解決什麽問題?”
“你解決的是什麽問題?“
” 還有更好的辦法嗎?“
現在第三句已經很少問到了。
成為架構師最困難的門檻是什麽?
跟一些程序員交流的過程中,有不少人問我要怎麽成為一名牛逼的架構師。
我最近幾年面試的人挺多,發現一個有意思的現象:很多人自稱架構師的人跟你講一個架構時簡直滔滔不絕,各種技術名詞像是說相聲一樣從他嘴裏說出來,三句話不離高並發大數據,但是稍微追問一下,就會發現很多基本概念的缺失,例如自稱精通高並發的人說不清楚他所謂的高並發系統的瓶頸在哪裏,自稱精通架構設計的人說不明白他的系統怎麽保證高可用,自稱超大數據量的系統實際上只有不到 100 萬條數據,等等。
架構師雖然聽起來很高大上,但本質上仍然是工程師,不是科學家,也不是忽悠人的江湖騙子。學習再多,也需要實踐落地。設計架構方案更多的是在做一些抽象和權衡:把復雜的需求抽象成簡單的模型,從功能、性能、可用性、研發成本等等方面規劃如何構建一個系統,這些內容需要更多的實踐練習。
很多人沒有工作在類似微博平臺這種天天需要接觸架構設計的地方,而很多公司沒有架構方面的工作可供他們練級,於是就想辦法從理論上下功夫,這類人的特征非常明顯:在信息不足,甚至不了解實際場景的情況下就開始做架構設計,這種所謂的架構往往理解比較膚淺,經不住推敲。
每年招人之後我們都會做一些針對新人的架構方面的培訓,課程材料基本上包括了高可用架構相關的主要方面,但是學完這些材料之後就能成為獨當一面的架構師了嗎?並沒有。相反,這僅僅是開始,新人真正做了幾個並發量上萬的系統之後才算是正式入門:面對壓力時才會懂得權衡,走過彎路之後才會尋找捷徑。
所以我認為在架構師(和其它很多)的工作中最重要的部分是實踐,誇誇其談很容易,與其拽一些技術名詞,不如把你正在做的系統真正的做好。
我和大牛之間有多少距離?
跟很多人一樣,剛畢業時我覺得作為程序員,只要努力,加上少許天賦便可以獲得一些成績。
工作一段時間後,對自己和其他人的認識也越來越清晰,逐漸的發現程序員之間的差距或許比人和猴子之間的差距還大,接受這個事實這讓我郁悶了很久。
再過一段時間,發現自己已經能夠客觀的評價自己的能力,也意識到了距離並不是那麽重要,只要想辦法跑的更快,就足夠了。
程序員在“金字塔”的背景下,如何做到比別人更具有競爭力?