記一次面試經歷

wanna發表於2020-09-04

面試概況

  1. 崗位:golang 開發
  2. 公司:*** (公司名字就匿了,避免看了題再去面試對其他小夥伴不公平)
  3. 途經:朋友內推
  4. 方向:IoT(物聯網)/區塊鏈
  5. 用時 2 個多小時(其中半個小時在答題)
  6. 結果:? ?
    雖然失敗了但是還是有很多值得參考的地方,我還是挺看好這個公司發展的方向的,希望對想到這個(類)公司面試的小夥伴有幫助

面試題目

共 10 題,答題時間 30min,其實這些題都很基礎,答案我放題後面

不定項選擇題

具體選項不完全確定是這些,但是考察的大概就這些內容

  1. 對於func add(args ...int) int {}呼叫方式正確的選項有()
    A. add(1, 2)
    B. add(1, 3, 7)
    C. add([] int{1, 2})
    D. add([] int{1, 3, 7}...)
  2. 變數的初始化,下面正確的使用方式是()
    A. var i int = 10
    B. var i = 10
    C. i := 10
    D. i = 10
  3. golang 中的引用型別包括()
    A. string
    B. map
    C. channel
    D. interface
  4. 關於整型切片的初始化,下面正確的是()
    A. s := make([] int)
    B. s := make([] int, 0)
    C. s := make([] int, 5, 10)
    D. s := [] int{1, 2, 3, 4, 5}
  5. 關於 channel,下面語法正確的是()
    A. var ch chan int
    B. ch := make(chan int)
    C. <- ch
    D. ch <-
  6. 關於無緩衝和有緩衝的 channel,下面說法正確的是()
    A.無緩衝的 channel 是預設的緩衝為 1 的 channel
    B.無緩衝的 channel 和有緩衝的 channel 都是同步的
    C.無緩衝的 channel 和有緩衝的 channel 都是非同步的
    D.無緩衝的 channel 是同步的,而有緩衝的 channel 是非同步的

不定項選擇題答案 以下答案僅供參考,主程沒給我最終答案,上面部分問題是我在網上搜尋 golang 面試題後才回想起來的
只要好好準備,這些題都簡單,全是基礎

  1. ABD
  2. ABC
  3. BCD
  4. BCD
  5. ABC
  6. D

解答題

不管是選擇題還是解答題都做到過類似的題型,所以多刷面試題和 leetcode 沒毛病
演算法題給我出的都是 leetcode 裡面的簡單難度的,以至於我都覺得不算演算法題了~
除了演算法還考了點基礎概念

  1. 簡要描述下變數逃逸
  2. 簡要描述下 slice 在 append 時發生了什麼
  3. 給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的那兩個整數,並返回他們的陣列下標。leetcode 連結
  4. 給定兩個陣列,編寫一個函式來計算它們的交集、以及差集(交集簡單,重點在差集上)。leetcode 上只講了交集沒講差集
    如輸入 nums1 = [4,9,5], nums2 = [7,5,10,8,4] 交集返回 [4,5] 差集返回 [9],[7,10,8]

變數逃逸這題我懵了,我沒看過這個的定義,所以就亂寫了一堆

  1. 答:不知此題是否想考 golang 的垃圾回收機制,golang 的垃圾回收機制使用的是三色標記法,即先標記後刪除,具體邏輯可在面試時詳講(解釋起來有點長太長,所以就寫了的面試時在直接給面試官講...) 但是,實際情況是這樣的嗎? 並不是!!!下面會有解釋

  2. 答: 先看原來的 cap 夠不夠裝下需要新增進去的元素,如果夠,則直接新增 如果不夠,則判斷現在 slice 的大小,大於 1024 則擴容 1.25 倍,不夠再擴 1.25 倍;如果小於 1024,則擴容到原來的兩倍,同理,不夠再擴 2 倍 emmmm,這道題感覺回答得沒啥問題,畢竟面試前惡補過 下面為官方實際擴容的規則程式碼

    func grow(s Value, extra int) (Value, int, int) {
    i0 := s.Len()
    i1 := i0 + extra
    if i1 < i0 {
        panic("reflect.Append: slice overflow")
    }
    m := s.Cap()
    if i1 <= m {
        return s.Slice(0, i1), i0, i1
    }
    if m == 0 {
        m = extra
    } else {
        for m < i1 {
            if i0 < 1024 {
                m += m
            } else {
                m += m / 4
            }
        }
    }
    t := MakeSlice(s.Type(), i1, m)
    Copy(t, s)
    return t, i0, i1
    }
    

後面兩道題都是 leetcode 的題,我就不詳細解釋了
不過我會在下面的主程面試中講下我是怎麼做的,以及怎麼 ‘忽悠’ 面試官,讓他知道我能做出更好的解決方案的

做完題我感覺我有了,我在考慮要 15K?16K?18K?了

主程面試

由於是內推(在此感謝 @ 劉水水同學的推薦),直接跳過了前面的步驟,做完題面主程了(好像也沒跳過啥~~,反正就是給了機會)

面試題講解

主程先給我講了下多選題的第三題,我選反了...給說了下引用型別的概念,我還在第三題下面備註了下
抱歉,對於引用型別的概念我不熟悉,根據題意我猜測答案要麼是 A 要麼是 BCD(即反過來)
結果我還是選反了~不過面試官還是比較滿意的我覺得這裡也很重要,不要不會就直接放棄了,總要給出自己的結論,並且解釋下為什麼我這樣想備註裡面我沒寫我為什麼這樣猜測,不過面試是我給面試官解釋了下比如 chan 不能單獨作為型別,只能是 chan int,chan string 等 map 和 interface 同樣的道理(我都想到這裡了居然還能答反,我也是醉了)

簡答題 1. 面試官給我解釋了下變數逃逸的概念:變數逃逸就是變數的作用域的改變
面試官說到這裡的時候,我接過來解釋到:就是變數從棧逃逸到堆上面去了嗎?
得到肯定的回答後,我繼續說(為了表明其實我還是理解,只是專業名詞不熟悉而已,所以該接過來說的,必須主動接過來說),從棧到堆後會影響執行速度什麼的~因為堆上的變數需要 GC 來處理(順便就吧我上面答的三色原理提了下,表明雖然我的答案有問題,但是也不是毫無關聯的~~哈哈哈,機智如我,我覺得此處很重要,即使題沒答對至少要讓面試官知道我是知道些東西的
Go 變數逃逸分析具體可以參考這篇博文

演算法題 1 我用的是兩次 for 迴圈遍歷,在面試官評價之前我就先解釋了下,一共半個小時,外加手寫程式碼,沒辦法去考慮更優解,然後就講了用 map 來解的更優方案(假裝完美混過去)
實際上是:面試官問我,你為什麼第一眼沒想到用 map 呢?
emmmm 好的我錯了(不過至少讓面試官知道我知道更好的解決方案),實際上兩次 for 的做法,在 leetcode 上都能得到雙 90 的得分了~

演算法題 2,交集我的做法是把長 slice 放 map 裡面,然後迴圈短的 slice 判定另外一個的 map 裡面是否含有,若有,則把對應項 append 到結果集中(其實到這裡我就反應過來上一題該用 map 了,但是...答題卡位置有限加上時間限制...我就放棄了修改)
差集同樣的用 map 加上 slice 的迴圈找出結果,主程給我說,此處更好的解決方案是使用 map 自帶的 delete 方法,把交集刪除後,剩下的就是差集了,可以把你們的答案留在評論區。。。。
emmmm 的確更好哈,可惜我沒想到
ok 面試題就到這裡了,接下來是考了些 go 的基礎

go 基礎的考核

我儘量回憶當時主程問了的問題,不確定能回憶完 後面的問答題稍微要比前面的題難一點點,不過也沒啥太難的 下面只做列舉,讓同行知道下面試官關心哪些問題

  1. 簡單談下 defer 的應用場景及注意事項(關閉檔案網路請求等,先進後出)
  2. 簡單談下 chan 的應用場景及注意事項
  3. 簡述程式、執行緒、協程的含義及區別
  4. 往一個物件裡寫入 10w 條資料,怎樣保證資料的準確性(chan、mutex 之類的胡扯就對了)
  5. 閉包的注意事項(這裡變數的引用是個坑)
  6. 簡單介紹下 interface 的應用場景(我給扯出什麼 2.0go 打算加入泛型什麼的,實際上面試官想問的是介面不是 interface{}這個資料型別...,等面試官給我糾正了下思路然後,我又繼續講介面相關的東西...) ... ... ok golang 的基礎考核完了,我感覺我目前問題不大基本能過面試這關了
    繼續考慮我的 15K?16K?18K?了~~~

和公司業務相關的技術考核

emmmm,然後我就掛在了這裡了
由於他們公司是做 IoT 的所以偏向底層
所以就考了我一些作業系統原理的問題
作為一個非科班出生的人,我當場懵逼
我知道接下來我將面臨的問題是我無法正確解答的
不過抱著試一試的心態繼續淦 以下答案請勿參考,我是亂答的,你只需要看題就夠了

  1. 線上 cpu 和記憶體突然飆高後應該怎麼排錯(debug)

    emmmm,linux 應該有命令能直接檢視哪個程式導致的,然後.... 好吧我不知道

  2. 哪些操作會導致記憶體洩漏

    有大量的 io 的情況(我也不知道對不對,後來去搜了下,好像是沒 close 才會出現)

  3. 哪些操作會導致 io 開銷大幅上升

    大量的檔案讀寫操作會導致 io 開銷劇增,所以可以用 bufio 緩衝 還有呢? emmm 比如資料庫的大量讀寫 還有呢? emmm 比如快取的讀寫... 還有呢? (好吧我錯了)不知道了 網路請求也會造成大量的 io,嚴格意義上來講資料庫的讀寫也屬於網路請求中的一種 emmmm (好的,我明白了,實際上第一次答的時候去掉'檔案'這兩個字就好了)

...後面還問了些比較涉及作業系統底層的東西,由於我不太能理解所以就記得不太清除了

面試官結語

面:你 golang 的基礎不錯,語言上沒有什麼問題,但是我們公司做的 IoT 方向,除了語言本身,還要懂的作業系統原理才行,比如你的演算法題,你就沒去考慮時間空間的問題,如果你去一個偏向業務的崗位問題不大,但是我們公司是偏向底層的,所以不太適合你 我:那貴公司是否有其他偏向業務開發的部門呢? 面:公司還有個部門是做區塊鏈的,更偏向底層 emmmmm

面試官走了 hrbp 來了(其實就已經結束了)

如果我們公司有其他崗位適合你的,我們這邊會通知你的 (哦,理解了,大概意思就是你現在不適合我們公司,面試結束)

個人覺得重要的中間細節

  1. 簡答題最好一開始就寫最好的方案
  2. 有的東西不知道沒關係,但是不回答那你肯定就沒戲了,胡扯也得扯,反正你跑遠了,面試官會把你拉回來的(有的人覺得,懂就是懂,不懂就是不懂,不要在面試官面前胡扯,面試官都能看出來的,其實我不這樣認為,胡扯即使說錯了至少能讓面試官看到我在其他哪個哪個方面也還是略懂的)
  3. 雖然打斷面試官的話是不禮貌的,但是你應該酌情考慮在關鍵地方合適的 ‘打斷’ 面試官的發言,然後你接上往後說,讓面試官知道你是知道這個知識點的(這個地方一定要把握好度,沒把握好的話,你之前回答的再好你都無了)
  4. 明確你面試的公司的 ‘屬性’ 針對性的複習下(但凡我提前看過作業系統原理,我都不會掛得那麼毫無懸念)
  5. 如果你有不錯開源專案(或者參與的開源專案)一定要寫在簡歷裡,如果不是我簡歷 裡面寫了和開源相關的東西,我可能連面試的機會都沒有,如果有合適的工作崗位,歡迎小夥伴們給推薦哦,我的簡歷 在 github 上有一份~~

講道理
我已經很滿意我面試的表現了
雖然掛了,但是我把我知道的都說出來了(當然 grpc,http2 那些沒考)
而且通過面試官對我的評價以及答題情況讓我對自己在 go 語言基礎操作上更有自信了
然後就是,一個人、一本書、一個月還你一個奇蹟(作業系統原理從入門到放棄)
一年前的我:php 是世界上最好的語言?
現在的我:go 是世界上最好的語言?

最後
祝我自己今年能成功轉入 go 開發者的行列中

最後的最後
祝 go 紅紅火火

更多原創文章乾貨分享,請關注公眾號
  • 記一次面試經歷
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章