第一次面試經歷-某公司後端研發
筆試
筆試部分是做了10道題目, 主要是類似於LeetCode上的題. 也包含了一些設計題目, 比如說怎麽設計一個爬蟲系統的去重. 在面試的時候答題紙也被送過來, 面試官會選擇裏面一個問題(主要是沒做出來的)來問你.
題目我會記錄下來放到GitHub上.
一面
一面聊的時間很長, 總共70分鐘左右.
總共問了三個大題吧. 發現在面試的過程中, 有一些問題是一開始沒有思考到的, 在交流想法的時候發現漏掉了. 可能是沒有一開始去設計測試用例, 或者去思考當前的可能的場景或者情況.
- 60分鐘 限制用戶訪問不能超過5次以上
- hashmap
- 目錄樹打印
一開始做了一個設計的題目. 場景是一些關鍵操作, 要對用戶的訪問次數或者訪問時間做出限制. 給出的例子是要設計一個函數或者功能, 限制單一用戶在60分鐘之內不能訪問超過5詞以上. 類似實現一個函數, 輸入是用戶的 uid. 返回一個布爾值用於表示是否應該 block 掉該次訪問.
當時一開始的想法是把記錄存在一個數據庫表裏, 類似<訪問時間, uid, 狀態(block/OK)>
然後每次去數據庫查, 獲取到當前的60分鐘之內的數據, 大於5條就選擇block掉.
後來覺得放在MySQL這種數據庫中太慢, 因為這個函數肯定是一個熱點, 在每次接受請求的時候都會調用. 可以放在Redis這種內存數據庫中.
此外, 由於這種規則的限制只考慮比如 x 分鐘之內的記錄. 可以只保存一定時間之內的訪問記錄, 超時就做一個失效的處理.
後來要求用一種數據結構實現, 在內存中直接計算.
發現可以做一個HashMap的形式, 裏面保存的是 uid和一個表示訪問記錄的隊列.這個隊列裏保存一些過去的訪問記錄. 可以通過時間和數量來選擇最大的容量.
比如說我現在需要考慮過去60分鐘的5次數據. 我可以選擇容量是5, 最多容納五條.我直接選取隊列中最早插入的(時間距離現在最久)看這條記錄時間是否比當前時間早60分鐘. 如果超過了就說明最近60分鐘的訪問次數少於5次. 如果沒超過說明需求被block.
在每次接受請求的時候都需要把訪問記錄放到這個隊列中, 也就是會退出一個最早插入的, 再在隊尾加一個當前的訪問記錄.
在手寫代碼的時候發現沒有思考冷啟動的問題, 需要判斷如果隊列不滿, 就應該直接放入數據.這也是考慮欠妥當的地方.
第二個問題, 面試官問我是否了解 HashMap . 其實不很了解, 沒看過源代碼, 看過一些文章.說了一下鏈表過長會樹化,有開放尋址和鏈表法解決Hash沖突的問題. 然後問我map裏桶的數組保存的是什麽, 我說是鏈表的頭結點. 面試之後看了一下源碼分析的文章, 其實map裏就是保存了一個 Entry的數組, 每個Entry有指向下一個Entry的引用, 也就是一種鏈表的數組. 好像還問我什麽時候擴容, 這個我答的不對. 後來看過是在map的大小超過閾值之後, 且發生了Hash沖突,才擴容. 在沒超過閾值, 但是某個鏈表長度過長的時候發生樹化.
第三個問題是問類似一個Linux的目錄樹, 怎麽從[父目錄, 子目錄]這種信息構建出來.
提供的數據[[A,B],[B,C],[C,D],[D,E]] 這種, 構建出類似 Linux tree命令的結果.
需要考慮怎麽構建樹形結構, 還要考慮怎麽能從樹輸出結果.
- 構建樹, 把所有沒出現過的父目錄作為森林裏的一個樹的root節點. 如果出現過就把子目錄放到對應的位置.
- 合並森林, 尋找一個只出現只出現在樹根的節點, 表示全局的根目錄. 然後不斷的合並, 如果圖是連通的. 那麽肯定能合並成一個多叉樹
- 對樹做一個先序遍歷, 輸出結果. 遞歸的時候要傳進去層數, 以便控制縮進
二面
二面感覺面的不好, 很多問題都沒回答上來.
- 問數組與鏈表的區別 尋址訪問和插入刪除的一種trade off
- 問怎麽能實現一個 插入刪除搜索都是o(1)的數據結構 好像hashmap可以符合 但是還問有沒有其他的數據結構
- 做一個題 尋找數組中兩個數的和 最接近指定數字. 提示可以排序
- 問編程語言 用過哪些 了解哪些
第一次面試經歷-某公司後端研發