程序員如何準(zhǔn)備面試中的算法
春招季來臨,大家陸續(xù)已經(jīng)開始準(zhǔn)備面試斬獲心儀 offer。
這次 lucifer 就從面試官角度給大家分享一些面試技巧,讓大家面試時(shí)少走彎路。這次分享側(cè)重 「算法面試」 。
我負(fù)責(zé)公司的面試已經(jīng)有 5 年以上了,基本都是初面和二面,因此技術(shù)面試的層面比較深,更多的是了解候選人的技術(shù)能力是否達(dá)標(biāo)。在這幾年時(shí)間,我前前后后也面試了很多的候選人。這些人中有的技術(shù)能力不行,但也有些人很可惜,技術(shù)能力是可以的,但是卻沒能通過我的面試,為什么呢?
面試考察什么?
首先,通常判斷候選人是否可以通過面試有如下幾個(gè)標(biāo)準(zhǔn):
1.技能能否勝任
2.溝通能力如何
3.工作熱情如何
。。。
那么我面試的時(shí)候肯定也是圍繞上面展開的,只不過側(cè)重考察不同罷了。
算法題和編程題實(shí)際上能夠很好地檢驗(yàn)以上信息,而不僅僅是檢驗(yàn) 「能力是否勝任」 。前提是面試官不能太死板,比如直接扔一個(gè)網(wǎng)上原題,有的甚至自己都不太會(huì)就拿出來考,這肯定是不行的。
有同學(xué)反饋算法題目做出來了,但是卻掛了面試。這又是為什么呢?
除了想當(dāng)然的那種做的很好,實(shí)際上 corner case 沒考慮到或者不是最優(yōu)解。還是有可能會(huì)被掛,為什么呢?
其實(shí)你題目做的很好,僅僅可以證明 「能力可以勝任」 ,這不意味著其他也滿足要求,比如上面提到的溝通能力,工作熱情等等。
那么如何更好地展示自己,給面試官留下更好的印象從而通過面試呢?除了提高自己的技術(shù)實(shí)力之外,方法也很重要。這里我就總結(jié)了幾個(gè)技巧給大家。
算法面試基本步驟
1.我在網(wǎng)上找到一份《Interview Cheat Sheet》,這個(gè) PDF 列舉了面試的模板步驟,詳細(xì)指示了如何一步步完成面試。
這個(gè) pdf 開頭就提到了好的代碼三個(gè)標(biāo)準(zhǔn):
- 可讀性
- 時(shí)間復(fù)雜度
- 空間復(fù)雜度
這寫的太好了。
緊接著,列舉了 15 算法面試的步驟。比如步驟一:當(dāng)面試官提問完后,你需要先下來關(guān)鍵點(diǎn)(之后再下面寫注釋和代碼) 看完我的感受就是,面試只要按照這個(gè)來做,成功率蹭蹭提升。
2.多問幾次,確保題目理解正確。
比如輸入輸出,corner case 等等。試想一個(gè)同事拿到需求不分青紅皂白就去做,結(jié)果發(fā)現(xiàn)做出來的不對(duì),多尷尬?你會(huì)想和這樣的同事一起共事么?
比如你可以問:
- 需要考慮負(fù)數(shù)么?
- 結(jié)果的順序重要么?
- 可以使用額外空間么?
- 。。。
3.先說思路,再寫代碼。
雖然題目理解沒問題,但是可能思路根本不對(duì),或者面試官不想要這個(gè)解法。
試想你是面試官, 對(duì)面寫了半天代碼。思路根本就不對(duì)或者不是你想要的解法,是不是有點(diǎn)失望?
所以盡量先說思路,面試官覺得沒問題再寫, 「不要浪費(fèi)彼此的時(shí)間」 。
比如你可以說:
- 樸素的暴力的思路是:xxxx。而這么做的話時(shí)間復(fù)雜度是 xxxx。
- 樸素的暴力算法的瓶頸在于 xxx,我們可以使用 xxxx 算法進(jìn)行優(yōu)化,這樣復(fù)雜度可以優(yōu)化到 xxxx。
4.上一步驟給面試官講思路的時(shí)候,代入幾個(gè)例子。
corner case 和 normal case 都至少舉一個(gè)來說明。這樣不僅讓面試官感覺你溝通能力強(qiáng),而且可以幫助你進(jìn)一步理解題目以及理清思路。
有點(diǎn)時(shí)候大家面試比較緊張,經(jīng)過代入例子講解緊張感會(huì)慢慢減少。就好像我做技術(shù)分享,往往緊張的就是前面幾分鐘,后面就不會(huì)有緊張的感覺了。
比如你可以說:
- 當(dāng)輸入為 [1,2,3,4] 時(shí), 我們的先 xxxx, 這樣就 xxxx,接下來計(jì)算出 xxxx ,最后 xxxx 。
- 當(dāng)輸入為負(fù)數(shù)時(shí),我們可以直接返回 xxx。
5.寫代碼要快,不要來來回回改,不然就會(huì)被扣上 coding 不行的帽子。
其實(shí)有前面的鋪墊,寫快不難。因?yàn)榍懊嫫鋵?shí)講思路,通過例子講解法你已經(jīng)對(duì)算法很了解了才對(duì)。
但是思路沒問題不代表可以完整寫出來。同樣可以完整寫出來不代表不需要涂涂改改。這需要大家做題目前先勾勒出代碼的大體框架。
一個(gè)簡單的技巧就是: 「分模塊寫代碼,一個(gè)功能一個(gè)函數(shù)」 。這樣可以減少不斷地涂涂抹抹,修修補(bǔ)補(bǔ)的可能性。
一個(gè)例子:
def solve(nums):
def check(mid):
# do something
def another_func():
pass
#
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) // 2
check(mid)
其中 solve 為主體函數(shù),而 check 和 another_func 則為拆分的函數(shù)。
6.寫完代碼自己先寫個(gè)測(cè)試。
這不僅體現(xiàn)了你代碼習(xí)慣好,而且能幫你發(fā)現(xiàn)代碼寫的有沒問題。
小技巧:你可以把前面你和面試官舉的例子以及面試官給的例子代進(jìn)去看對(duì)不對(duì),由于有前面鋪墊了,這個(gè)應(yīng)該也很快。
一個(gè)例子:
def solve(nums):
def check(mid):
# do something
def another_func():
pass
#
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) // 2
check(mid)
assert solve([1,2,3,4]) == True
assert solve([]) == False
#
這里我們使用 assert 進(jìn)行了斷言。類似于我們?nèi)粘i_發(fā)后對(duì)代碼進(jìn)行測(cè)試。
最后給大家整理一個(gè)流程圖,方便大家記憶,大家可以把圖存起來備用。
? ?