軟件工程師生存指南:面試準(zhǔn)備、工作經(jīng)驗(yàn)和實(shí)用工具
軟件工程師是令人羨慕的職業(yè)。但是如何才能拿到這份工作?又如何才能做好這份工作呢?擁有相關(guān)經(jīng)驗(yàn)的 Valeri Alexiev 提供了相關(guān)建議和工具。其中包括了如何準(zhǔn)備面試、如何以軟件工程師的身份工作以及如何持續(xù)改進(jìn)方面的經(jīng)驗(yàn)之談。
我剛開始工作的頭幾年是緊張學(xué)習(xí)的時(shí)間。
我得面對(duì)現(xiàn)實(shí),成為軟件工程師需要有很多技能,這些我之前都不知道。回顧過(guò)去,顯然學(xué)會(huì)那些東西是很好的。
所以我就根據(jù)自己及其他人的經(jīng)驗(yàn)寫了這篇指南來(lái)幫助入行的新人。
本文將覆蓋以下內(nèi)容:
如何盡力做好面試
如何在軟件工程師的角色中生存(及發(fā)展)
考慮持續(xù)改進(jìn)時(shí)可以參考的資源
面試
當(dāng)你開始軟件工程職業(yè)生涯時(shí),你得面對(duì)一個(gè)無(wú)可爭(zhēng)議的事實(shí)。面試很惡心。
參與其中的每個(gè)人都覺(jué)得很惡心。既被人面試過(guò)又面試過(guò)別人的我可以證明,面試是一項(xiàng)極其耗時(shí)、極其有壓力的工作,并且面試其實(shí)并不是將來(lái)工作表現(xiàn)一個(gè)的好的指示器。但不管怎樣,這都是一個(gè)必要之惡,你和你的簡(jiǎn)歷最好還是做好準(zhǔn)備為妥。
做好戰(zhàn)斗準(zhǔn)備
如果你考慮做軟件過(guò)程,確保了解一些最常見(jiàn)的編程面試問(wèn)題,比如“FizzBuzz”:
寫一個(gè)程序打印從 1 到 100 的數(shù)字。但是如果數(shù)字是 3 的倍數(shù)的話則打印“Fizz”,如果數(shù)字是 5 的倍數(shù)則打印“Buzz”。如果同時(shí)是 3 和 5 的倍數(shù)則打印“FizzBuzz”。
來(lái)自 Coding Horror
聽起來(lái)很簡(jiǎn)單,是吧?
好吧,但其實(shí)絕大部分面試者都沒(méi)能通過(guò)這一簡(jiǎn)單的測(cè)試,且不說(shuō)更復(fù)雜的變種了。
我個(gè)人曾經(jīng)見(jiàn)過(guò)很多角逐資深崗位的候選人在擁有完全互聯(lián)網(wǎng)訪問(wèn)的情況下沒(méi)能通過(guò)這一測(cè)試。所以如果你的簡(jiǎn)歷上面列有編程語(yǔ)言的話,確保你知道如何用它來(lái)編寫實(shí)現(xiàn) FizzBuzz 程序。否則的話,你只不過(guò)是在浪費(fèi)所有人的時(shí)間,包括你自己的。
當(dāng)然,為了在面試過(guò)后生存,你需要知道的不僅僅只有 FizzBuzz。你還需要確保你知道:
基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)和算法:比如鏈表、數(shù)組、樹以及排序。
要知道所選擇語(yǔ)言的常見(jiàn)解決辦法,比如字符串是否恒定,內(nèi)存是如何管理的。
類似類與對(duì)象,以及繼承等面向?qū)ο缶幊痰母拍睢?/p>
在職業(yè)生涯開始時(shí),你需要就這些問(wèn)題做好準(zhǔn)備,因?yàn)槟悴](méi)有經(jīng)歷去證明自己能做好這份工作。在準(zhǔn)備面試的時(shí)候有兩個(gè)資源我會(huì)經(jīng)常推薦:
《Cracking the Coding Interview(破解面試代碼)》,這是一本非常好的書,里面介紹了很多的編碼問(wèn)題和解決方案,同時(shí)還總結(jié)了解決這些問(wèn)題需要了解的東西。
CodeWars?,這個(gè)網(wǎng)站收集了大量的編程問(wèn)題,你可以運(yùn)用各種語(yǔ)言在瀏覽器里面去解決這些問(wèn)題。最有用的部分是看看別的用戶是如何解決同樣問(wèn)題的。這樣你就可以看到解決相同問(wèn)題的不同辦法,并且學(xué)到你所選語(yǔ)言的新工具。
賦予自身額外優(yōu)勢(shì)
為了讓自己取得那點(diǎn)額外優(yōu)勢(shì),有幾件事情你可以去做。
首先,學(xué)會(huì)如何溝通你的經(jīng)驗(yàn)。你應(yīng)該進(jìn)行一次電梯演講來(lái)將你的簡(jiǎn)歷總結(jié)成連貫的、打動(dòng)人的個(gè)人介紹。
此外,要了解自己的簡(jiǎn)歷!聽起來(lái)很蠢是吧,但我就見(jiàn)過(guò)很多面試者連解釋清楚自己簡(jiǎn)歷上的特定事項(xiàng)都很困難。你應(yīng)該能夠回答任何有關(guān)你列上簡(jiǎn)歷的經(jīng)歷方面的問(wèn)題,并且解釋清楚這一經(jīng)歷如何讓你成為本工作更好的候選人。
接著,要在 GitHub(或者其他的公共代碼庫(kù))上面有一些編碼的例子。
眼見(jiàn)為實(shí),面試官能夠看到你的代碼將創(chuàng)造奇跡。此外,這還證明了你對(duì)版本控制系統(tǒng)有了解。
你的代碼例子不需要太復(fù)雜,但是一定要整潔,能夠顯示出好的編碼實(shí)踐。這是你展示自己在沒(méi)有編碼面試所帶來(lái)的時(shí)間壓力情況下代碼寫得如何的機(jī)會(huì)。
一旦你做完了上面的事情后,就得考慮參與一個(gè)開源項(xiàng)目了。參加開源項(xiàng)目能表明你能夠在已有代碼庫(kù)基礎(chǔ)上工作并且可以與其他程序員一些協(xié)作。
這是你在無(wú)需實(shí)際進(jìn)入一個(gè)行業(yè)環(huán)境的情況下最接近在行業(yè)環(huán)境下編程的方式了。這也是目前為止最難最耗時(shí)的一項(xiàng)任務(wù),所以等到你把前面我提到的比較容易取得的果實(shí)都摘完之后再干這件事。
面試你的面試官
在找工作的匆忙與壓力之下,很多候選人都忘了面試是一個(gè)雙向的過(guò)程。在公司努力尋找這份工作的合適人選時(shí),你也應(yīng)該設(shè)法弄清楚這家公司適不適合你。
確保你也要提出以下一些問(wèn)題,哪怕對(duì)方是以電子郵件的形式回復(fù)你。要意識(shí)到公司經(jīng)常把不遵循最佳實(shí)踐說(shuō)成是一項(xiàng)技能,所以要體會(huì)其言外之意。
以下是一些你可以去提問(wèn)的例子:
“對(duì)我來(lái)說(shuō)典型的工作日會(huì)是什么樣的?”
知道特定崗位預(yù)期的樣子很重要,因?yàn)檐浖こ坦ぷ鞑顒e相當(dāng)大。比方說(shuō)你的工作既可能是維護(hù)服務(wù)器,也可能是直接跟客戶溝通。
危險(xiǎn)信號(hào):“我不大肯定?!?→?意味著面試你的那個(gè)人不在你的團(tuán)隊(duì),或者他們對(duì)為什么要招你并沒(méi)有明確的想法。
“你們是如何測(cè)試軟件的?”
理想情況下,驗(yàn)證代碼質(zhì)量應(yīng)該是單元測(cè)試、人工測(cè)試以及自動(dòng)化測(cè)試的結(jié)合。
危險(xiǎn)信號(hào):“我們都寫不出 bug,哈哈。” →?那些人正是會(huì)寫出 bug 的人。
“你們使用什么樣的版本控制系統(tǒng)?”
版本控制系統(tǒng)對(duì)于協(xié)作極其有用,在職業(yè)環(huán)境下沒(méi)有理由不使用。
危險(xiǎn)信號(hào) #1:“額,版本控制系統(tǒng)?” →?快跑,跑得越遠(yuǎn)越好。
永遠(yuǎn)記得使用版本控制。
危險(xiǎn)信號(hào) #2:“<插入不知名的或者定制的 VCS>” →?這表明他們很有可能沒(méi)有跟上時(shí)代并且很久沒(méi)有升級(jí)自己的基礎(chǔ)設(shè)施了。
“你們進(jìn)行同行評(píng)審嗎?”
同行評(píng)審,或者讓別人看看你的代碼再把它放進(jìn)代碼庫(kù),這是識(shí)別愚蠢錯(cuò)誤的極好辦法,同時(shí)也是開始你的職業(yè)生涯時(shí)一個(gè)關(guān)鍵的培訓(xùn)機(jī)會(huì)。
危險(xiǎn)信號(hào):“我們相互信任!”→很有可能那些資深開發(fā)者對(duì)自己的代碼非常警惕不想給人看也不擅長(zhǎng)接受反饋。
“你們的繼續(xù)教育計(jì)劃是什么樣的?”
作為一名軟件工程師意味著當(dāng)新技術(shù)出現(xiàn)、成熟并以令人眼花繚亂的速度走向過(guò)時(shí)的時(shí)候要不斷學(xué)習(xí)。因此,很多公司都有培訓(xùn)預(yù)算用來(lái)買大學(xué)和在線課程、會(huì)議或者內(nèi)部交流。
危險(xiǎn)信號(hào):“你是說(shuō)在閑暇時(shí)間讀讀網(wǎng)上的東西?” →這家公司要么資金緊張,要么把開發(fā)者視為可替代的,而不是長(zhǎng)期投資。
“你們采用的軟件開發(fā)流程是什么?”
無(wú)論實(shí)際的細(xì)節(jié)是什么,流程對(duì)于軟件工程都至關(guān)重要。至于哪些東西對(duì)于優(yōu)化流程做出了貢獻(xiàn)可能大家會(huì)有不同的看法,但僅就項(xiàng)目的工作方式達(dá)成一致就能將混亂最小化并且確保每個(gè)人都能達(dá)成共識(shí)。
危險(xiǎn)信號(hào):“我們的流程受到了自由風(fēng)格的爵士的影響?!?→ 很有可能整個(gè)部門都處在救火模式,總是不斷地從緊急跳到另一個(gè)緊急狀態(tài)而缺乏任何明確的目標(biāo)。
“你們是如何處理技術(shù)債務(wù)的?”
技術(shù)債務(wù)是過(guò)時(shí)技術(shù)以及代碼庫(kù)中臨時(shí)應(yīng)急的解決方案的累積。處理好技術(shù)債務(wù)對(duì)于代碼的長(zhǎng)期健康很重要,這件事情應(yīng)該持續(xù)地做。
危險(xiǎn)信號(hào):“我們只關(guān)注新功能?!?→ 他們的代碼庫(kù)一團(tuán)糟或者很快就會(huì)一團(tuán)糟。
“你們的公司文化是什么樣的?”
公司文化也許是個(gè)非常含糊的概念,但即便像開放辦公室還是小隔間這樣的小事情都會(huì)顯著改變你與同事的日?;?dòng)。這方面沒(méi)有普遍性的危險(xiǎn)信號(hào),但是要確保他們的答案是你可以按照每周 40+ 小時(shí)的節(jié)奏持續(xù)相處數(shù)年的東西。
以軟件工程師的身份工作
在這個(gè)階段,如果你面試過(guò)程中表現(xiàn)不錯(cuò)并且喜歡面試官回答你問(wèn)題的方式,你被錄用的可能性就很高了。
祝賀,你正式成為一名工程師了!
那現(xiàn)在又該如何呢?好吧,現(xiàn)在是時(shí)候重新學(xué)習(xí)大量編碼和工作方面的東西了。既然我們是程序員,我們就從討論代碼開始。
好的行業(yè)代碼
好的行業(yè)代碼有以下屬性,依序是:
可讀性,因?yàn)榇a用來(lái)讀和維護(hù)的頻次要高于寫。代碼的意圖必須清晰,讓其他開發(fā)者在多年后依然理解。
防御性,就是要遵循防御性編碼的最佳實(shí)踐。防御性編碼本身就是一個(gè)課題,不過(guò)其要義是:你必須確保自己所寫的類和方法的不恰當(dāng)使用不會(huì)導(dǎo)致你的代碼搞得軟件都崩潰。
優(yōu)化,位列清單的最后未知,因?yàn)榇蠖鄶?shù)時(shí)候你并不需要真正去擔(dān)心這個(gè)。這并不意味著你應(yīng)該編寫糟糕代碼,在存在線性解決方案的情況下以O(shè)(n3)的效率去做某個(gè)東西。但開發(fā)者通??释麌L試并且會(huì)在不需要的情況下過(guò)度優(yōu)化,卻犧牲了代碼的可讀性和防御性。你永遠(yuǎn)都應(yīng)該能夠證明犧牲了這些屬性的特定優(yōu)化是值得的。
現(xiàn)在你了解了如何去編寫良好的行業(yè)代碼了。
編碼的工作你不會(huì)干太多的
說(shuō)出來(lái)也許有點(diǎn)令人吃驚,但是大多數(shù)時(shí)候你都不用寫新代碼,而是相反,要做:
調(diào)試
讀已有代碼
開會(huì)或者寫電子郵件
研究該怎么做以便不用寫代碼
因此編碼以外的技能對(duì)你的職業(yè)一樣關(guān)鍵。
調(diào)試和閱讀代碼
調(diào)試遠(yuǎn)不僅僅是用打印語(yǔ)句。一切使用廣泛的語(yǔ)言和技術(shù)棧都有各種強(qiáng)大的工具。學(xué)會(huì)使用它們,因?yàn)檫@些會(huì)讓調(diào)試輕而易舉,節(jié)省你無(wú)數(shù)的時(shí)間。
理解代碼庫(kù)。大多數(shù)技術(shù)棧都有某種代碼圖譜生成工具來(lái)幫助你理解代碼庫(kù)的結(jié)構(gòu)。企業(yè)級(jí)的 IDE 通常都內(nèi)置了那種功能。你還可以利用 ReSharper、grep?或者 Sourcegraph 之類的工具來(lái)探索代碼。
理解產(chǎn)品。你會(huì)對(duì)居然有這么多開發(fā)者在試圖“修復(fù)”軟件前不知道軟件應(yīng)該是怎么工作的感到驚訝。先看看文檔再說(shuō)吧。
組織你的思路
既然你的大量時(shí)間都是用在溝通、研究和多任務(wù)上,你需要一些工具來(lái)幫助一切井然有序。
TODO 清單/任務(wù)工具:你的公司應(yīng)該已經(jīng)有了某種任務(wù)管理軟件了,但你自己也有類似的個(gè)人系統(tǒng)是有幫助的。使用便利貼或者像 Trello 或者 Todoist 之類的軟件。
筆記:開會(huì)一定要記筆記,要致力于改進(jìn)現(xiàn)有文檔并且建立個(gè)人的知識(shí)庫(kù)。使用 Evernote、OneNote 或者筆記本。使用這些工具似乎有用力過(guò)度之嫌,但日后在回顧這一耗掉了你 3 天時(shí)間才想清楚的晦澀的開發(fā)過(guò)程時(shí)你會(huì)感謝自己的。不做豐富筆記的好的軟件開發(fā)者我一個(gè)都沒(méi)見(jiàn)過(guò)。
圖表/可視化:人是視覺(jué)動(dòng)物,創(chuàng)建流程圖和架構(gòu)可幫助你和其他人理解復(fù)雜的話題。在跟非技術(shù)人員溝通時(shí)圖解尤其有用。可使用 Lucidchart、?Visio 或者白板。
知道何時(shí)使用庫(kù)
簡(jiǎn)短回答:隨時(shí)都要。
詳細(xì)回答:99% 的時(shí)間內(nèi)你都不應(yīng)該重新發(fā)明輪子。在大多數(shù)的軟件工程崗位,實(shí)現(xiàn)特定類型的東西都屬于純粹浪費(fèi)時(shí)間。這并不意味著你不應(yīng)該知道所使用的算法和數(shù)據(jù)結(jié)構(gòu)是怎么工作的,因?yàn)檫@可以幫助你決定用什么以及什么時(shí)候用。
為了成為一名高效的軟件工程師,你需要理解自己可以任意支配使用的那些庫(kù)。大多數(shù)流行語(yǔ)言的標(biāo)準(zhǔn)庫(kù)都是極其有用的,其規(guī)模比你想象的要大。此外,代碼庫(kù)也許也會(huì)利用了額外的特殊庫(kù)。閱讀其文檔,知道什么使用去使用它們。
你還應(yīng)該不要害怕去建議額外的庫(kù),如果它們將節(jié)省時(shí)間的話。然而,你需要確保自己選擇了一個(gè)好的庫(kù)供行業(yè)使用。好的庫(kù)的標(biāo)準(zhǔn)是:
開源,這樣你就可以驗(yàn)證自身代碼的質(zhì)量,并有可能修補(bǔ)對(duì)應(yīng)用非常關(guān)鍵的 bug。
按照 MIT 和 BSD 等方式進(jìn)行的授權(quán),這樣你的公司使用起來(lái)就不會(huì)遇到任何問(wèn)題。要小心 GPL,因?yàn)樗鼤?huì)讓你不小心就將整個(gè)代碼庫(kù)都開源出去。
成熟,比方說(shuō)出來(lái)已經(jīng)有一段時(shí)間了,并且功能集非常豐富。
維護(hù)性強(qiáng),新版本推出很密集。
別的公司或者項(xiàng)目也使用,這個(gè)可以充當(dāng)品質(zhì)認(rèn)證確保有行業(yè)支持,能持續(xù)維護(hù)下去。
持續(xù)改進(jìn)
為了替自己創(chuàng)建新的職業(yè)機(jī)會(huì),除了學(xué)習(xí)會(huì)讓你更擅長(zhǎng)日常工作的技能以外,你還需要持續(xù)改進(jìn)自身技能并且學(xué)習(xí)新技能。
其實(shí)學(xué)習(xí)的機(jī)會(huì)有很多,而且其中很多都是你可以負(fù)擔(dān)得起的:
在線課程:向領(lǐng)域內(nèi)最好的教授學(xué)習(xí)的機(jī)會(huì),而且方式靈活,不容錯(cuò)過(guò)?,F(xiàn)有技能的補(bǔ)充性教程可以去可以看看?Coursera、?Udacity 以及 edX?等。
在線碩士學(xué)位:在線碩士學(xué)位是最近在頂級(jí)大學(xué)流行起來(lái)的一個(gè)趨勢(shì),這種方式可以靈活地繼續(xù)你的正規(guī)教育。相比之下,這種繼續(xù)教育方式費(fèi)用沒(méi)那么昂貴,修完整個(gè)學(xué)位大多數(shù)在 1 萬(wàn)美元左右。喬治亞理工大學(xué)、UT 以及加州大學(xué)圣地亞哥分校等大學(xué)均提供此類學(xué)位。我個(gè)人推薦喬治亞理工大學(xué)的在線碩士虛偽,我去年剛從這里畢業(yè)。
博客:博客是開發(fā)者社區(qū)的重要組成部分。諸如 Coding Horror、Joel on Software 等博客或者甚至更加詼諧的網(wǎng)站如 The Daily WTF 等都可以為你提供信息,了解到作為軟件工程師該干什么不該干什么。瀏覽 Medium、r/programming, HackerNews 等新聞流也能讓你找到好博客和好文章。
會(huì)議:最后但并非最不重要的一個(gè),會(huì)議時(shí)令人贊嘆的學(xué)習(xí)機(jī)會(huì),你絕對(duì)應(yīng)該利用公司的培訓(xùn)預(yù)算去參加會(huì)議。以下是不完全的好會(huì)議清單:GOTO(通用),?Strange Loop(通用),?PyCon?(Pytho),CPPCon?(C++),DEF CON?(安全),F(xiàn)luent?(Web 開發(fā))。上述所有的會(huì)議在 YouTube 上都有視頻,所以你哪怕不出席也能學(xué)到東西!