我從編程面試中學(xué)到的經(jīng)驗(yàn)分享
在 2017 年,我參加了 ‘計(jì)算機(jī)行業(yè)中的女性’ 的Grace Hopper 慶祝活動(dòng)。這個(gè)活動(dòng)是這類(lèi)科技活動(dòng)中最大的一個(gè)。共有 17,000 名女性IT工作者參加。
這個(gè)會(huì)議有個(gè)大型的配套招聘會(huì),會(huì)上有招聘公司來(lái)面試會(huì)議參加者。有些人甚至現(xiàn)場(chǎng)拿到 offer。我在現(xiàn)場(chǎng)晃蕩了一下,注意到一些應(yīng)聘者看上去非常緊張憂慮。我還隱隱聽(tīng)到應(yīng)聘者之間的談話,其中一些人談到在面試中做的并不好。
我走近我聽(tīng)到談話的那群人并和她們聊了起來(lái)并給了一些面試上的小建議。我想我的建議還是比較偏基本的,如“(在面試時(shí))一開(kāi)始給出個(gè)能工作的解決方案也還說(shuō)的過(guò)去”之類(lèi)的,但是當(dāng)她們聽(tīng)到我的一些其他的建議時(shí)還是頗為吃驚。
為了能更多的幫到像她們一樣的小白面試者,我收集了一些過(guò)去對(duì)我有用的小點(diǎn)子,這些小點(diǎn)子我已經(jīng)發(fā)表在了?prodcast episode?上。它們也是這篇文章的主題。
為了實(shí)習(xí)生職位和全職工作,我做過(guò)很多次的面試。當(dāng)我還在大學(xué)主修計(jì)算機(jī)科學(xué)時(shí),學(xué)校每個(gè)秋季學(xué)期都有招聘會(huì),第一輪招聘會(huì)在校園里舉行。(我在第一和最后一輪都搞砸過(guò)。)不過(guò),每次面試后,我都會(huì)反思哪些方面我能做的更好,我還會(huì)和朋友們做模擬面試,這樣我就能從他們那兒得到更多的面試反饋。
不管我們?cè)趺礃诱夜ぷ? 工作中介、網(wǎng)絡(luò),或者學(xué)校招聘,他們的招聘流程中都會(huì)涉及到技術(shù)面試:
近年來(lái),我注意到了一些新的不同的面試形式出現(xiàn)了:
與招聘方的一位工程師結(jié)對(duì)編程
網(wǎng)絡(luò)在線測(cè)試及在線編碼
白板編程(LCTT 譯注: 這種形式應(yīng)該不新了)
我將重點(diǎn)談?wù)劙装迕嬖嚕@種形式我經(jīng)歷的最多。我有過(guò)很多次面試,有些挺不錯(cuò)的,有些被我搞砸了。
我做錯(cuò)的地方
首先,我想回顧一下我做的不好的地方。知錯(cuò)能改,善莫大焉。
當(dāng)面試者提出一個(gè)要我解決的問(wèn)題時(shí), 我立即馬上立刻開(kāi)始在白板上寫(xiě)代碼,什么都不問(wèn)。
這里我犯了兩個(gè)錯(cuò)誤:
沒(méi)有澄清對(duì)解決問(wèn)題有關(guān)鍵作用的信息
比如,我們是否只用處理數(shù)字或者字符串?我們要支持多種數(shù)據(jù)類(lèi)型嗎?如果你在開(kāi)始解題前不去問(wèn)這些問(wèn)題的話,你的面試官會(huì)有一種不好的印象:這個(gè)人在我們公司的話,他不會(huì)在開(kāi)始項(xiàng)目工作之前不問(wèn)清楚到底要做什么。而這恰恰是在工作場(chǎng)合很重要的一個(gè)工作習(xí)慣。公司可不像學(xué)校,你在開(kāi)始工作前可不會(huì)得到寫(xiě)有所有詳細(xì)步驟的作業(yè)說(shuō)明。你得靠自己找到這些步驟并自己定義他們。
只會(huì)默默思考,不去記錄想法或和面試官溝通
在面試中,很多時(shí)候我也會(huì)傻傻站在那思考,什么都不寫(xiě)。我和一個(gè)朋友模擬面試的時(shí)候,他告訴我因?yàn)樗?jīng)和我一起工作過(guò)所以他知道我在思考,但是如果他是個(gè)陌生的面試官的話,他會(huì)覺(jué)得我正站在那冥思苦想,毫無(wú)頭緒。不要急匆匆的直奔解題而去是很重要的。花點(diǎn)時(shí)間多想想各種解題的可能性。有時(shí)候面試官會(huì)樂(lè)意和你一起探索解題的步驟。不管怎樣,這就是在一家公司開(kāi)工作會(huì)議的的普遍方式,大家各抒己見(jiàn),一起討論如何解決問(wèn)題。
想到一個(gè)解題方法
在你開(kāi)始寫(xiě)代碼之前,如果你能總結(jié)一下要使用到的算法就太棒了。不要上來(lái)就寫(xiě)代碼并認(rèn)為你的代碼肯定能解決問(wèn)題。
這是對(duì)我管用的步驟:
頭腦風(fēng)暴
寫(xiě)代碼
處理錯(cuò)誤路徑
測(cè)試
1、 頭腦風(fēng)暴
對(duì)我來(lái)說(shuō),我會(huì)首先通過(guò)一些例子來(lái)視覺(jué)化我要解決的問(wèn)題。比如說(shuō)如果這個(gè)問(wèn)題和數(shù)據(jù)結(jié)構(gòu)中的樹(shù)有關(guān),我就會(huì)從樹(shù)底層的空節(jié)點(diǎn)開(kāi)始思考,如何處理一個(gè)節(jié)點(diǎn)的情況呢??jī)蓚€(gè)節(jié)點(diǎn)呢?三個(gè)節(jié)點(diǎn)呢?這能幫助你從具體例子里抽象出你的解決方案。
在白板上先寫(xiě)下你的算法要做的事情列表。這樣做,你往往能在開(kāi)始寫(xiě)代碼前就發(fā)現(xiàn) bug 和缺陷(不過(guò)你可得掌握好時(shí)間)。我犯過(guò)的一個(gè)錯(cuò)誤是我花了過(guò)多的時(shí)間在澄清問(wèn)題和頭腦風(fēng)暴上,最后幾乎沒(méi)有留下時(shí)間給我寫(xiě)代碼。你的面試官可能沒(méi)有機(jī)會(huì)看你在白板上寫(xiě)下代碼,這可太糟了。你可以帶塊手表,或者房間有鐘的話,你也可以抬頭看看時(shí)間。有些時(shí)候面試者會(huì)提醒你你已經(jīng)得到了所有的信息(這時(shí)你就不要再問(wèn)別的了),“我想我們已經(jīng)把所有需要的信息都澄清了,讓我們寫(xiě)代碼實(shí)現(xiàn)吧”。
2、 開(kāi)始寫(xiě)代碼,一氣呵成
如果你還沒(méi)有得到問(wèn)題的完美解決方法,從最原始的解法開(kāi)始總是可以的。當(dāng)你在向面試官解釋最顯而易見(jiàn)的解法時(shí),你要想想怎么去完善它,并指明這種做法是最原始的,未加優(yōu)化的。(請(qǐng)熟悉算法中的?O()?的概念,這對(duì)面試非常有用。)在向面試者提交前請(qǐng)仔細(xì)檢查你的解決方案兩三遍。面試者有時(shí)會(huì)給你些提示, “還有更好的方法嗎?”,這句話的意思是面試官提示你有更優(yōu)化的解決方案。
3、 錯(cuò)誤處理
當(dāng)你在編碼時(shí),對(duì)你想做錯(cuò)誤處理的代碼行做個(gè)注釋。當(dāng)面試者說(shuō),“很好,這里你想到了錯(cuò)誤處理。你想怎么處理呢?拋出異常還是返回錯(cuò)誤碼?”,這將給你個(gè)機(jī)會(huì)去引出關(guān)于代碼質(zhì)量的一番討論。當(dāng)然,這種地方提出幾個(gè)就夠了。有時(shí),面試者為了節(jié)省編碼的時(shí)間,會(huì)告訴你可以假設(shè)外界輸入的參數(shù)都已經(jīng)通過(guò)了校驗(yàn)。不管怎樣,你都要展現(xiàn)你對(duì)錯(cuò)誤處理和編碼質(zhì)量的重要性的認(rèn)識(shí)。
4、 測(cè)試
在編碼完成后,用你在前面頭腦風(fēng)暴中寫(xiě)的用例來(lái)在你腦子里“跑”一下你的代碼,確定萬(wàn)無(wú)一失。例如你可以說(shuō),“讓我用前面寫(xiě)下的樹(shù)的例子來(lái)跑一下我的代碼,如果是一個(gè)節(jié)點(diǎn)是什么結(jié)果,如果是兩個(gè)節(jié)點(diǎn)是什么結(jié)果……”
在你結(jié)束之后,面試者有時(shí)會(huì)問(wèn)你你將會(huì)怎么測(cè)試你的代碼,你會(huì)涉及什么樣的測(cè)試用例。我建議你用下面不同的分類(lèi)來(lái)組織你的錯(cuò)誤用例:
一些分類(lèi)可以為:
性能
錯(cuò)誤用例
期望的正常用例
對(duì)于性能測(cè)試,要考慮極端數(shù)量下的情況。例如,如果問(wèn)題是關(guān)于列表的,你可以說(shuō)你將會(huì)使用一個(gè)非常大的列表以及的非常小的列表來(lái)測(cè)試。如果和數(shù)字有關(guān),你將會(huì)測(cè)試系統(tǒng)中的最大整數(shù)和最小整數(shù)。我建議讀一些有關(guān)軟件測(cè)試的書(shū)來(lái)得到更多的知識(shí)。在這個(gè)領(lǐng)域我最喜歡的書(shū)是 《我們?cè)谖④浫绾螠y(cè)試軟件》。
對(duì)于錯(cuò)誤用例,想一下什么是期望的錯(cuò)誤情況并一一寫(xiě)下。
對(duì)于正向期望用例,想想用戶(hù)需求是什么?你的解決方案要解決什么問(wèn)題?這些都可以成為正向期望用例。
“你還有什么要問(wèn)我的嗎?”
面試最后總是會(huì)留幾分鐘給你問(wèn)問(wèn)題。我建議你在面試前寫(xiě)下你想問(wèn)的問(wèn)題。千萬(wàn)別說(shuō),“我沒(méi)什么問(wèn)題了”,就算你覺(jué)得面試砸了或者你對(duì)這間公司不怎么感興趣,你總有些東西可以問(wèn)問(wèn)。你甚至可以問(wèn)面試者他最喜歡自己的工作什么,最討厭自己的工作什么。或者你可以問(wèn)問(wèn)面試官的工作具體是什么,在用什么技術(shù)和實(shí)踐。不要因?yàn)橛X(jué)得自己在面試中做的不好而心灰意冷,不想問(wèn)什么問(wèn)題。
申請(qǐng)一份工作
關(guān)于找工作和申請(qǐng)工作,有人曾經(jīng)告訴我,你應(yīng)該去找你真正有激情工作的地方。去找一家你喜歡的公司,或者你喜歡使用的產(chǎn)品,看看你能不能去那兒工作。
我個(gè)人并不推薦你用上述的方法去找工作。你會(huì)排除很多很好的公司,特別是你是在找實(shí)習(xí)工作或者入門(mén)級(jí)的職位時(shí)。
你也可以集中在其他的一些目標(biāo)上。如:我想從這個(gè)工作里得到哪方面的更多經(jīng)驗(yàn)?這個(gè)工作是關(guān)于云計(jì)算?Web 開(kāi)發(fā)?或是人工智能?當(dāng)在招聘會(huì)上與招聘公司溝通時(shí),看看他們的工作單位有沒(méi)有在這些領(lǐng)域的。你可能會(huì)在一家并非在你的想去公司列表上的公司(或非盈利機(jī)構(gòu))里找到你想找的職位。
換組
在這家公司里的第一個(gè)組里呆了一年半以后,我覺(jué)得是時(shí)候去探索一下不同的東西了。我找到了一個(gè)我喜歡的組并進(jìn)行了 4 輪面試。結(jié)果我搞砸了。
我什么都沒(méi)有準(zhǔn)備,甚至都沒(méi)在白板上練練手。我當(dāng)時(shí)的邏輯是,如果我都已經(jīng)在一家公司干了快 2 年了,我還需要練什么?我完全錯(cuò)了,我在接下去的白板面試中跌跌撞撞。我的板書(shū)寫(xiě)得太小,而且因?yàn)闆](méi)有從最左上角開(kāi)始寫(xiě)代碼,我的代碼大大超出了一個(gè)白板的空間,這些都導(dǎo)致了白板面試失敗。
我在面試前也沒(méi)有刷過(guò)數(shù)據(jù)結(jié)構(gòu)和算法題。如果我做了的話,我將會(huì)在面試中更有信心。就算你已經(jīng)在一家公司擔(dān)任了軟件工程師,在你去另外一個(gè)組面試前,我強(qiáng)烈建議你在一塊白板上演練一下如何寫(xiě)代碼。
對(duì)于換項(xiàng)目組這件事,如果你是在公司內(nèi)部換組的話,事先能同那個(gè)組的人非正式聊聊會(huì)很有幫助。對(duì)于這一點(diǎn),我發(fā)現(xiàn)幾乎每個(gè)人都很樂(lè)于和你一起吃個(gè)午飯。人一般都會(huì)在中午有空,約不到人或者別人正好有會(huì)議沖突的風(fēng)險(xiǎn)會(huì)很低。這是一種非正式的途徑來(lái)了解你想去的組正在干什么,以及這個(gè)組成員個(gè)性是怎么樣的。相信我,你能從一次午餐中得到很多信息,這可會(huì)對(duì)你的正式面試幫助不小。
非常重要的一點(diǎn)是,你在面試一個(gè)特定的組時(shí),就算你在面試中做的很好,因?yàn)槲幕黄鹾系脑?,你也很可能拿不?offer。這也是為什么我一開(kāi)始就想去見(jiàn)見(jiàn)組里不同的人的原因(有時(shí)這也不太可能),我希望你不要被一次拒絕所擊倒,請(qǐng)保持開(kāi)放的心態(tài),選擇新的機(jī)會(huì),并多多練習(xí)。