一面:
1.自我介紹
2.平時用什么編程語言比較多
python,另外學過C語言和JAVA
3.c語言里指針占多少內存
答成8位了,應該根據機器而言是16位或32位
4.python里的map函數,講一下它的作用和返回值
傳入一個函數和一個list,將這個函數作用於這個list的每個元素上.返回值是一個新的list.
5.什么是梯度下降法
6.手寫代碼:歸並兩個有序數組
7.知不知道什么數據結構的查找的時間復雜度是O(1)
哈希表,也就是python中的dict
8.哈希表的原理是什么
利用哈希函數映射,構造出一個鍵值對
9.手寫代碼:兩個大文件a和b,每一行存儲的都是一個字符串,找出其中在兩個文件中都出現過的字符串
構造一個哈希表,先逐行讀入文件a,如果該字符串已經在哈希表中就跳過,如果不存在就存入哈希表中.讀完以后逐行讀入b,查找哈希表中有沒有對應的值.
當時用的是dict,面試官說這種情況直接用set會更好.
10.如何判斷一個鏈表中是不是存在環
一開始理解成是頭尾相連的環,先回答了設頭結點為一個特殊字符,比如'*',然后一直往下讀取,如果讀到null說明沒有環,如果讀到'*'說明有.
面試官提示說不一定是和頭結點連成環,先回答了類似上面的想法,每一位設一個特殊字符,然后判斷.但是需要用一個額外的空間來存儲被設為特殊字符的結點原來的值.
面試官問有沒有不需要額外空間的方法,思考了一會想到設立兩個指針,都從頭部開始遍歷,一個指針每次前移一位,另一個指針每次前移兩位,如果它們相遇就說明存在環,如果遇到null說明沒有環.
面試官問為什么這種方法一定能夠找到環.因為假設環的長度是K,前一個指針每次都會比后一個指針多走一步,那么讓兩個指針一直走下去,肯定會存在一個M,使得K是M的因數,並且兩者在環內相遇.
11.有一個內存放不下的大文件,每一行存儲的是一個數字,現在要隨機從中取100個數字,怎么取比較好
先想到直接隨機取一個數M,然后取M~M+100行的數.面試官說無法確定文件的大小,那么這個M也無法隨機取.
這道題沒有想到太好的思路,后來在網上也沒有找到類似題的答案.
二面:
一面過后一天接到了二面的電話
1.自我介紹
2.知道c++中指針和引用的區別嗎
我表示沒有學過C++,只學過C
3.一個有序數組,現在將它從某個位置翻轉后,如何查找其中的數字
翻轉有序數組問題,首先有序聯想到了二分查找.然后根據查找的情況修改一下判斷條件即可.因為一個翻轉有序數組從中間截斷后,必定有一邊是有序數組,另一邊仍是翻轉有序數組,那么問題就解決了.
4.一個有序數組,給定一個k,要將它第k位后的數字整體移到前面去,如何實現
先回答了最簡單的方法,就是新建一個數組,先存入原數組第k位后的數字,再存入前k位數字.空間復雜度為O(n)
然后又想到一種方法,定義一個操作為翻轉,可以通過不停地交換數組兩邊的元素實現.那么首先翻轉數組的前k個數字,再翻轉數組第k位后的數字,然后再將數組整個翻轉一次就可以了.空間復雜度為O(1)
5.一個n步的台階,每次可以走1步或2步,走完n步有多少種方法
動態規划問題,f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)
6.實現斐波那契數列的時間復雜度是多少
上題的動態規划式子實際上就是斐波那契數列,遞歸實現的時間復雜度是O(2^n),非遞歸實現的時間復雜度是O(n)
7.如果有兩個單詞的組成完全相同,就稱為同源單詞.例如stop和post.現在有一個字典,如果找出其中所有的同源單詞?
想到了trie樹.假設都是小寫字母的話,那么就構造一個26叉樹代表26個小寫字母.在將單詞存入樹中時,將它拆為按字典序排好的字母,例如stop就是頭結點->o->p->s->t,然后將stop存入t結點中.類似的post也會被存在頭結點->o->p->s->t結點中.這樣遍歷一次字典后只需要看樹結點中有沒有多個單詞就能找到全部同源單詞了.
面試官問如果一個單詞很長的話怎么辦,回答可以用哈希表存儲每個字母的出現次數.但是這種方法適合用於判斷兩個單詞是不是同源單詞,不適合查找所有同源單詞.
網上一種思路是先按字母數量排序,然后再存入字典樹,比較快速.
8.k-means的原理
9.k-means是局部最優還是全局最優,為什么
局部最優.原因我回答的是因為k-means的最終結果和初始點的選取有關,所以不可能是全局最優的.
面試官表示應該從凸函數的角度去解釋.另外在網上看到一種說法是k-means是貪心算法的一種實現,所以是局部最優.
10.項目經歷
11.有2.5億個數字,要從中找出所有只出現過一次的數字,如何實現
首先利用哈希表將2.5億個數字划分成1000個小文件.然后對於每個小文件,采用bitmap的思想.所謂bitmap就是指用位來代替數字,本題數字可能有沒出現過,出現過一次,出現過多次三種情況,所以要用2位來表示一個數字.在完成所有文件的bitmap后,00表示沒有出現過,01表示出現過一次,10表示出現過多次,那么我們將1000個文件中每組對應的兩位bitmap相加,如果一組結果為01就表示對應的數字只出現過一次.
offer流程:
過了一個周末后接到了部門經理的電話,給了口頭offer
兩天后接到HR電話,商量了入職時間.
又一周后收到了正式offer~
找算法崗實習的一些經驗:
- 對你想做的方向(比如機器學習/計算機視覺/自然語言處理/深度學習)的常用算法的數學原理和編程實現要深入了解,很可能會被問到公式推導或者底層實現之類的細節.例如我是機器學習方向的,那么就要着重了解svm\決策樹\nb\lr\knn\k-means這些算法,以及相關的損失函數和各種優化方法.推薦的書籍是《統計學習方法》
- 計算機專業的幾門大課(計組,計網,操作系統,數據結構)盡可能掌握得扎實一點,其中對算法崗來說最重要的是數據結構與算法,推薦在leetcode或者類似的平台刷題,不用貪多,重要的是掌握幾種常用數據結構和算法(數組,樹,dfs,bfs,動態規划,哈希表)的應用場景.另外一定要了解常用數據結構操作和算法的時間復雜度.
- 算法崗和大數據是分不開的,面試中的最后一題很可能是關於處理海量數據的.可以參考教你如何迅速秒殺99%的海量數據處理面試題
- 對於常用的語言(c++,java,python中的一門或多門)要深入了解,不能局限於實現簡單的代碼邏輯.以python為例,要知道列表生成式\各種內置數據結構的原理\map函數\深淺拷貝這些知識.
- 會用一些相關的框架或庫,例如數據處理的numpy和pandas,機器學習的sklearn和xgboost,深度學習的tensorflow/pytorch/keras等等.
- 最好有一些相關的競賽(Kaggle,天池)或項目經歷,既可以鍛煉自己的工程能力,也會讓面試的時候有自己擅長的東西可講,否則就會被問到很多基礎方面的問題.
