軟體工程師生存指南:面試準備、工作經驗和實用工具

36kr發表於2018-11-18

編者按:軟體工程師是令人羨慕的職業。但是如何才能拿到這份工作?又如何才能做好這份工作呢?擁有相關經驗的 Valeri Alexiev 提供了相關建議和工具。其中包括瞭如何準備面試、如何以軟體工程師的身份工作以及如何持續改進方面的經驗之談。

我剛開始工作的頭幾年是緊張學習的時間。

我得面對現實,成為軟體工程師需要有很多技能,這些我之前都不知道。回顧過去,顯然學會那些東西是很好的。

所以我就根據自己及其他人的經驗寫了這篇指南來幫助入行的新人。

本文將覆蓋以下內容:

  1. 如何盡力做好面試
  2. 如何在軟體工程師的角色中生存(及發展)
  3. 考慮持續改進時可以參考的資源

面試

當你開始軟體工程職業生涯時,你得面對一個無可爭議的事實。面試很噁心。

參與其中的每個人都覺得很噁心。既被人面試過又面試過別人的我可以證明,面試是一項極其耗時、極其有壓力的工作,並且面試其實並不是將來工作表現一個的好的指示器。但不管怎樣,這都是一個必要之惡,你和你的簡歷最好還是做好準備為妥。

做好戰鬥準備

如果你考慮做軟體過程,確保瞭解一些最常見的程式設計面試問題,比如“FizzBuzz”:

寫一個程式列印從 1 到 100 的數字。但是如果數字是 3 的倍數的話則列印“Fizz”,如果數字是 5 的倍數則列印“Buzz”。如果同時是 3 和 5 的倍數則列印“FizzBuzz”。

來自 Coding Horror

聽起來很簡單,是吧?

好吧,但其實絕大部分面試者都沒能通過這一簡單的測試,且不說更復雜的變種了。

我個人曾經見過很多角逐資深崗位的候選人在擁有完全網際網路訪問的情況下沒能通過這一測試。所以如果你的簡歷上面列有程式語言的話,確保你知道如何用它來編寫實現 FizzBuzz 程式。否則的話,你只不過是在浪費所有人的時間,包括你自己的。

當然,為了在面試過後生存,你需要知道的不僅僅只有 FizzBuzz。你還需要確保你知道:

  • 基礎的資料結構和演算法:比如連結串列、陣列、樹以及排序。
  • 要知道所選擇語言的常見解決辦法,比如字串是否恆定,記憶體是如何管理的。
  • 類似類與物件,以及繼承等物件導向程式設計的概念。

在職業生涯開始時,你需要就這些問題做好準備,因為你並沒有經歷去證明自己能做好這份工作。在準備面試的時候有兩個資源我會經常推薦:

  • Cracking the Coding Interview(破解面試程式碼)》,這是一本非常好的書,裡面介紹了很多的編碼問題和解決方案,同時還總結了解決這些問題需要了解的東西。
  • CodeWars ,這個網站收集了大量的程式設計問題,你可以運用各種語言在瀏覽器裡面去解決這些問題。最有用的部分是看看別的使用者是如何解決同樣問題的。這樣你就可以看到解決相同問題的不同辦法,並且學到你所選語言的新工具。

賦予自身額外優勢

為了讓自己取得那點額外優勢,有幾件事情你可以去做。

首先,學會如何溝通你的經驗。你應該進行一次電梯演講來將你的簡歷總結成連貫的、打動人的個人介紹。

此外,要了解自己的簡歷!聽起來很蠢是吧,但我就見過很多面試者連解釋清楚自己簡歷上的特定事項都很困難。你應該能夠回答任何有關你列上簡歷的經歷方面的問題,並且解釋清楚這一經歷如何讓你成為本工作更好的候選人。

接著,要在 GitHub(或者其他的公共程式碼庫)上面有一些編碼的例子。

眼見為實,面試官能夠看到你的程式碼將創造奇蹟。此外,這還證明了你對版本控制系統有了解。

你的程式碼例子不需要太複雜,但是一定要整潔,能夠顯示出好的編碼實踐。這是你展示自己在沒有編碼面試所帶來的時間壓力情況下程式碼寫得如何的機會。

一旦你做完了上面的事情後,就得考慮參與一個開源專案了。參加開源專案能表明你能夠在已有程式碼庫基礎上工作並且可以與其他程式設計師一些協作。

這是你在無需實際進入一個行業環境的情況下最接近在行業環境下程式設計的方式了。這也是目前為止最難最耗時的一項任務,所以等到你把前面我提到的比較容易取得的果實都摘完之後再幹這件事。

面試你的面試官

在找工作的匆忙與壓力之下,很多候選人都忘了面試是一個雙向的過程。在公司努力尋找這份工作的合適人選時,你也應該設法弄清楚這家公司適不適合你。

確保你也要提出以下一些問題,哪怕對方是以電子郵件的形式回覆你。要意識到公司經常把不遵循最佳實踐說成是一項技能,所以要體會其言外之意。

以下是一些你可以去提問的例子:

“對我來說典型的工作日會是什麼樣的?”

知道特定崗位預期的樣子很重要,因為軟體工程工作差別相當大。比方說你的工作既可能是維護伺服器,也可能是直接跟客戶溝通。

危險訊號:“我不大肯定。” → 意味著面試你的那個人不在你的團隊,或者他們對為什麼要招你並沒有明確的想法。

“你們是如何測試軟體的?”

理想情況下,驗證程式碼質量應該是單元測試、人工測試以及自動化測試的結合。

危險訊號:“我們都寫不出 bug,哈哈。” → 那些人正是會寫出 bug 的人。

“你們使用什麼樣的版本控制系統?”

版本控制系統對於協作極其有用,在職業環境下沒有理由不使用。

危險訊號 #1:“額,版本控制系統?” → 快跑,跑得越遠越好。

永遠記得使用版本控制。

危險訊號 #2:“<插入不知名的或者定製的 VCS>” → 這表明他們很有可能沒有跟上時代並且很久沒有升級自己的基礎設施了。

“你們進行同行評審嗎?”

同行評審,或者讓別人看看你的程式碼再把它放進程式碼庫,這是識別愚蠢錯誤的極好辦法,同時也是開始你的職業生涯時一個關鍵的培訓機會。

危險訊號:“我們相互信任!”→很有可能那些資深開發者對自己的程式碼非常警惕不想給人看也不擅長接受反饋。

“你們的繼續教育計劃是什麼樣的?”

作為一名軟體工程師意味著當新技術出現、成熟並以令人眼花繚亂的速度走向過時的時候要不斷學習。因此,很多公司都有培訓預算用來買大學和線上課程、會議或者內部交流。

危險訊號:“你是說在閒暇時間讀讀網上的東西?” →這家公司要麼資金緊張,要麼把開發者視為可替代的,而不是長期投資。

“你們採用的軟體開發流程是什麼?”

無論實際的細節是什麼,流程對於軟體工程都至關重要。至於哪些東西對於優化流程做出了貢獻可能大家會有不同的看法,但僅就專案的工作方式達成一致就能將混亂最小化並且確保每個人都能達成共識。

危險訊號:“我們的流程受到了自由風格的爵士的影響。” → 很有可能整個部門都處在救火模式,總是不斷地從緊急跳到另一個緊急狀態而缺乏任何明確的目標。

“你們是如何處理技術債務的?”

技術債務是過時技術以及程式碼庫中臨時應急的解決方案的累積。處理好技術債務對於程式碼的長期健康很重要,這件事情應該持續地做。

危險訊號:“我們只關注新功能。” → 他們的程式碼庫一團糟或者很快就會一團糟。

“你們的公司文化是什麼樣的?”

公司文化也許是個非常含糊的概念,但即便像開放辦公室還是小隔間這樣的小事情都會顯著改變你與同事的日常互動。這方面沒有普遍性的危險訊號,但是要確保他們的答案是你可以按照每週 40+ 小時的節奏持續相處數年的東西。

以軟體工程師的身份工作

在這個階段,如果你面試過程中表現不錯並且喜歡面試官回答你問題的方式,你被錄用的可能性就很高了。

祝賀,你正式成為一名工程師了!

那現在又該如何呢?好吧,現在是時候重新學習大量編碼和工作方面的東西了。既然我們是程式設計師,我們就從討論程式碼開始。

好的行業程式碼

好的行業程式碼有以下屬性,依序是:

  1. 可讀性,因為程式碼用來讀和維護的頻次要高於寫。程式碼的意圖必須清晰,讓其他開發者在多年後依然理解。
  2. 防禦性,就是要遵循防禦性編碼的最佳實踐。防禦性編碼本身就是一個課題,不過其要義是:你必須確保自己所寫的類和方法的不恰當使用不會導致你的程式碼搞得軟體都崩潰。
  3. 優化,位列清單的最後未知,因為大多數時候你並不需要真正去擔心這個。這並不意味著你應該編寫糟糕程式碼,在存線上性解決方案的情況下以O(n³)的效率去做某個東西。但開發者通常渴望嘗試並且會在不需要的情況下過度優化,卻犧牲了程式碼的可讀性和防禦性。你永遠都應該能夠證明犧牲了這些屬性的特定優化是值得的。

現在你瞭解瞭如何去編寫良好的行業程式碼了。

編碼的工作你不會幹太多的

說出來也許有點令人吃驚,但是大多數時候你都不用寫新程式碼,而是相反,要做:

  • 除錯
  • 讀已有程式碼
  • 開會或者寫電子郵件
  • 研究該怎麼做以便不用寫程式碼

因此編碼以外的技能對你的職業一樣關鍵。

除錯和閱讀程式碼

  • 除錯遠不僅僅是用列印語句。一切使用廣泛的語言和技術棧都有各種強大的工具。學會使用它們,因為這些會讓除錯輕而易舉,節省你無數的時間。
  • 理解程式碼庫。大多數技術棧都有某種程式碼圖譜生成工具來幫助你理解程式碼庫的結構。企業級的 IDE 通常都內建了那種功能。你還可以利用 ReSharper、grep 或者 Sourcegraph 之類的工具來探索程式碼。
  • 理解產品。你會對居然有這麼多開發者在試圖“修復”軟體前不知道軟體應該是怎麼工作的感到驚訝。先看看文件再說吧。

組織你的思路

既然你的大量時間都是用在溝通、研究和多工上,你需要一些工具來幫助一切井然有序。

  • TODO 清單/任務工具:你的公司應該已經有了某種任務管理軟體了,但你自己也有類似的個人系統是有幫助的。使用便利貼或者像 Trello 或者 Todoist 之類的軟體。
  • 筆記:開會一定要記筆記,要致力於改進現有文件並且建立個人的知識庫。使用 Evernote、OneNote 或者筆記本。使用這些工具似乎有用力過度之嫌,但日後在回顧這一耗掉了你 3 天時間才想清楚的晦澀的開發過程時你會感謝自己的。不做豐富筆記的好的軟體開發者我一個都沒見過。
  • 圖表/視覺化:人是視覺動物,建立流程圖和架構可幫助你和其他人理解複雜的話題。在跟非技術人員溝通時圖解尤其有用。可使用 Lucidchart、 Visio 或者白板。

知道何時使用庫

簡短回答:隨時都要。

詳細回答:99% 的時間內你都不應該重新發明輪子。在大多數的軟體工程崗位,實現特定型別的東西都屬於純粹浪費時間。這並不意味著你不應該知道所使用的演算法和資料結構是怎麼工作的,因為這可以幫助你決定用什麼以及什麼時候用。

為了成為一名高效的軟體工程師,你需要理解自己可以任意支配使用的那些庫。大多數流行語言的標準庫都是極其有用的,其規模比你想象的要大。此外,程式碼庫也許也會利用了額外的特殊庫。閱讀其文件,知道什麼使用去使用它們。

你還應該不要害怕去建議額外的庫,如果它們將節省時間的話。然而,你需要確保自己選擇了一個好的庫供行業使用。好的庫的標準是:

  • 開源,這樣你就可以驗證自身程式碼的質量,並有可能修補對應用非常關鍵的 bug。
  • 按照 MIT 和 BSD 等方式進行的授權,這樣你的公司使用起來就不會遇到任何問題。要小心 GPL,因為它會讓你不小心就將整個程式碼庫都開源出去。
  • 成熟,比方說出來已經有一段時間了,並且功能集非常豐富。
  • 維護性強,新版本推出很密集。
  • 別的公司或者專案也使用,這個可以充當品質認證確保有行業支援,能持續維護下去。

持續改進

為了替自己建立新的職業機會,除了學習會讓你更擅長日常工作的技能以外,你還需要持續改進自身技能並且學習新技能。

其實學習的機會有很多,而且其中很多都是你可以負擔得起的:

  • 線上課程:向領域內最好的教授學習的機會,而且方式靈活,不容錯過。現有技能的補充性教程可以去可以看看 Coursera、 Udacity 以及 edX 等。
  • 線上碩士學位:線上碩士學位是最近在頂級大學流行起來的一個趨勢,這種方式可以靈活地繼續你的正規教育。相比之下,這種繼續教育方式費用沒那麼昂貴,修完整個學位大多數在 1 萬美元左右。喬治亞理工大學、UT 以及加州大學聖地亞哥分校等大學均提供此類學位。我個人推薦喬治亞理工大學的線上碩士虛偽,我去年剛從這裡畢業。
  • 部落格:部落格是開發者社群的重要組成部分。諸如 Coding Horror、Joel on Software 等部落格或者甚至更加詼諧的網站如 The Daily WTF 等都可以為你提供資訊,瞭解到作為軟體工程師該幹什麼不該幹什麼。瀏覽 Medium、r/programming, HackerNews 等新聞流也能讓你找到好部落格和好文章。
  • 會議:最後但並非最不重要的一個,會議時令人讚歎的學習機會,你絕對應該利用公司的培訓預算去參加會議。以下是不完全的好會議清單:GOTO(通用), Strange Loop(通用), PyCon (Pytho),CPPCon (C++),DEF CON (安全),Fluent (Web 開發)。上述所有的會議在 YouTube 上都有視訊,所以你哪怕不出席也能學到東西!

希望這篇文章能夠用相關知識把你武裝起來,讓你瞭解到作為軟體工程師的職業生涯伊始應該期待什麼,並且提供合適的工具給你在開啟這段令人興奮的旅程中助你一臂之力!

相關文章