程式設計師如何準備面試中的演算法

lucifer發表於2022-03-21

春招季來臨,大家陸續已經開始準備面試斬獲心儀 offer。

這次 lucifer 就從面試官角度給大家分享一些面試技巧,讓大家面試時少走彎路。這次分享側重演算法面試

我負責公司的面試已經有 5 年以上了,基本都是初面和二面,因此技術面試的層面比較深,更多的是瞭解候選人的技術能力是否達標。在這幾年時間,我前前後後也面試了很多的候選人。這些人中有的技術能力不行,但也有些人很可惜,技術能力是可以的,但是卻沒能通過我的面試,為什麼呢?

面試考察什麼?

首先,通常判斷候選人是否可以通過面試有如下幾個標準:

  1. 技能能否勝任
  2. 溝通能力如何
  3. 工作熱情如何

。。。

那麼我面試的時候肯定也是圍繞上面展開的,只不過側重考察不同罷了。

演算法題和程式設計題實際上能夠很好地檢驗以上資訊,而不僅僅是檢驗能力是否勝任。前提是面試官不能太死板,比如直接扔一個網上原題,有的甚至自己都不太會就拿出來考,這肯定是不行的。

有同學反饋演算法題目做出來了,但是卻掛了面試。這又是為什麼呢?

除了想當然的那種做的很好,實際上 corner case 沒考慮到或者不是最優解。還是有可能會被掛,為什麼呢?

其實你題目做的很好,僅僅可以證明能力可以勝任,這不意味著其他也滿足要求,比如上面提到的溝通能力,工作熱情等等。

那麼如何更好地展示自己,給面試官留下更好的印象從而通過面試呢?除了提高自己的技術實力之外,方法也很重要。這裡我就總結了幾個技巧給大家。

演算法面試基本步驟

  1. 我在網上找到一份《Interview Cheat Sheet》,這個 PDF 列舉了面試的模板步驟,詳細指示瞭如何一步步完成面試。

這個 pdf 開頭就提到了好的程式碼三個標準:

  • 可讀性
  • 時間複雜度
  • 空間複雜度

這寫的太好了。

緊接著,列舉了 15 演算法面試的步驟。比如步驟一:當面試官提問完後,你需要先下來關鍵點(之後再下面寫註釋和程式碼) 看完我的感受就是,面試只要按照這個來做,成功率蹭蹭提升。

pdf 地址

  1. 多問幾次,確保題目理解正確。

比如輸入輸出,corner case 等等。試想一個同事拿到需求不分青紅皁白就去做,結果發現做出來的不對,多尷尬?你會想和這樣的同事一起共事麼?

比如你可以問:

  • 需要考慮負數麼?
  • 結果的順序重要麼?
  • 可以使用額外空間麼?
  • 。。。
  1. 先說思路,再寫程式碼。

雖然題目理解沒問題,但是可能思路根本不對,或者面試官不想要這個解法。

試想你是面試官, 對面寫了半天程式碼。思路根本就不對或者不是你想要的解法,是不是有點失望?

所以儘量先說思路,面試官覺得沒問題再寫,不要浪費彼此的時間

比如你可以說:

  • 樸素的暴力的思路是:xxxx。而這麼做的話時間複雜度是 xxxx。
  • 樸素的暴力演算法的瓶頸在於 xxx,我們可以使用 xxxx 演算法進行優化,這樣複雜度可以優化到 xxxx。
  1. 上一步驟給面試官講思路的時候,代入幾個例子。

corner case 和 normal case 都至少舉一個來說明。這樣不僅讓面試官感覺你溝通能力強,而且可以幫助你進一步理解題目以及理清思路。

有點時候大家面試比較緊張,經過代入例子講解緊張感會慢慢減少。就好像我做技術分享,往往緊張的就是前面幾分鐘,後面就不會有緊張的感覺了。

比如你可以說:

  • 當輸入為 [1,2,3,4] 時, 我們的先 xxxx, 這樣就 xxxx,接下來計算出 xxxx ,最後 xxxx 。
  • 當輸入為負數時,我們可以直接返回 xxx。
  1. 寫程式碼要快,不要來來回回改,不然就會被扣上 coding 不行的帽子。

其實有前面的鋪墊,寫快不難。因為前面其實講思路,通過例子講解法你已經對演算法很瞭解了才對。

但是思路沒問題不代表可以完整寫出來。同樣可以完整寫出來不代表不需要塗塗改改。這需要大家做題目前先勾勒出程式碼的大體框架。

一個簡單的技巧就是:分模組寫程式碼,一個功能一個函式。這樣可以減少不斷地塗塗抹抹,修修補補的可能性。

一個例子:

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 為主體函式,而 check 和 another_func 則為拆分的函式。

  1. 寫完程式碼自己先寫個測試。

這不僅體現了你程式碼習慣好,而且能幫你發現程式碼寫的有沒問題。

小技巧:你可以把前面你和麵試官舉的例子以及面試官給的例子代進去看對不對,由於有前面鋪墊了,這個應該也很快。

一個例子:

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 進行了斷言。類似於我們日常開發後對程式碼進行測試。

總結

最後給大家整理一個流程圖,方便大家記憶,大家可以把圖存起來備用。

最後希望大家可以在春招季斬獲自己資訊的 offer。也歡迎大家進我的春招群。加我微信,回覆春招即可進群。

相關文章