1. 程式人生 > >第一次面試經歷-某公司後端研發

第一次面試經歷-某公司後端研發

git 大小 分析 測試用例 提示 root 打印 布爾值 github上

筆試

筆試部分是做了10道題目, 主要是類似於LeetCode上的題. 也包含了一些設計題目, 比如說怎麽設計一個爬蟲系統的去重. 在面試的時候答題紙也被送過來, 面試官會選擇裏面一個問題(主要是沒做出來的)來問你.

題目我會記錄下來放到GitHub上.

一面

一面聊的時間很長, 總共70分鐘左右.

總共問了三個大題吧. 發現在面試的過程中, 有一些問題是一開始沒有思考到的, 在交流想法的時候發現漏掉了. 可能是沒有一開始去設計測試用例, 或者去思考當前的可能的場景或者情況.

  1. 60分鐘 限制用戶訪問不能超過5次以上
  2. hashmap
  3. 目錄樹打印

一開始做了一個設計的題目. 場景是一些關鍵操作, 要對用戶的訪問次數或者訪問時間做出限制. 給出的例子是要設計一個函數或者功能, 限制單一用戶在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命令的結果.
需要考慮怎麽構建樹形結構, 還要考慮怎麽能從樹輸出結果.

  1. 構建樹, 把所有沒出現過的父目錄作為森林裏的一個樹的root節點. 如果出現過就把子目錄放到對應的位置.
  2. 合並森林, 尋找一個只出現只出現在樹根的節點, 表示全局的根目錄. 然後不斷的合並, 如果圖是連通的. 那麽肯定能合並成一個多叉樹
  3. 對樹做一個先序遍歷, 輸出結果. 遞歸的時候要傳進去層數, 以便控制縮進

二面

二面感覺面的不好, 很多問題都沒回答上來.

  1. 問數組與鏈表的區別 尋址訪問和插入刪除的一種trade off
  2. 問怎麽能實現一個 插入刪除搜索都是o(1)的數據結構 好像hashmap可以符合 但是還問有沒有其他的數據結構
  3. 做一個題 尋找數組中兩個數的和 最接近指定數字. 提示可以排序
  4. 問編程語言 用過哪些 了解哪些

第一次面試經歷-某公司後端研發