1. 程式人生 > >百度資料探勘實習生面試經驗

百度資料探勘實習生面試經驗

今天又到又愛又恨的百度面試了(已跪過兩次T T),這一次是由學長內推過去的。具體招聘要求如下:
百度xx部xx組急招實習生,要求:
1.熟悉演算法與資料結構
2.熟悉python,shell等
3.熟練掌握java或者c++
4.能近期儘快入職
5.計算機相關專業
一面是一名年輕的技術面試官,他居然把我的簡歷已經列印好了,讓我好感倍增啊!首先他讓我簡單介紹一下自己,這一點由於最近面試太疲乏了,沒有好好準備,只簡單根據簡歷描述了一下自己,應該好好整理思路(經歷、性格、優勢等)。然後就之前在企業實習所做的內容做一個介紹,並且必須邊畫流程圖邊解釋,這個方式在以後描述自己的專案時值得借鑑。隨後問了我之前在課程上做過的專案,偏偏問到了我沒有參與很多的專案,然後具體做什麼印象都不太深了,專案中用到了幾種方法,他問我用的哪幾種,我說了原理最有把握的兩個,結果被他問到是怎麼實現的,函式的輸入是什麼,輸出是什麼,表示已忘光。。。因此,一定要check一下自己的簡歷中自己不熟悉的地方,不能瞬間被問倒。另外,他挑出我所做的Logistics專案中的Logistics迴歸演算法的具體流程,我只記得大致原理了,忘了推導流程。然後,他又問不同的模型輸出結果怎樣進行融合的問題,我提到投票制方法,之前學的boosting方法沒有提出來。那麼他又問了不同的機器學習演算法的應用場景問題,這個之前大致瞭解過SVM不太適合大規模資料集的訓練等,但是他追問原因時回答不全。專案就問到這兒了,接著,他給我出了一道題目:“每次拋硬幣出現正反兩面的可能性都是1/2,那麼連續出現兩次正面的期望是什麼”,期望是什麼我還記得,但是怎麼求都忘了,他提醒了多次但是實在概念都不記得了,這一題花了很長時間,在他一步一步指導下做出來的,但是中間由於有點緊張加上面試官說話太快沒有表現出較快的應變能力。正確解法是:設期望為E,那麼E等於每個可以擲出連續兩次正面的次數乘以其概率的和。考慮第一次和第二次擲出的結果,若第一次結果為“正”,第二次結果為“正”,那麼結果是1/4*2;
第一次結果為“正”,第二次結果為“反”,那麼前兩次都白擲了,那麼結果是1/4*(2+E);
第一次結果為“反”,那麼第一次白擲了,那麼結果是1/2*(1+E);
因此求總和:E=1/4*2+1/4*(2+E)+1/2*(1+E),最後結果E=6。
第二個問題:有一個random()函式可以隨機返回0或者1,寫一個函式用於隨機返回0到5之間的任意一個數。
這個問題起先我糾結在怎樣把1/2的概率轉換為1/6的概率,想到了多次返回random來解決。但是通過統計多次random所得的和只能解決以2^n為分母的問題,然後再想到二進位制,但是用二進位制的話兩位又少了,然後面試官提醒我兩位少了,三位怎麼樣?隨後,我就想到了答案,三位可以用於表示8個數,那麼每次擲三次表示一個三位的二進位制數,如果這個數小於等於5,那麼就返回答案,否則繼續擲三次,程式碼如下:

int random5(){
    int sum = 0;
    while(true){
        for(int i=0;i<3;i++){
            if(random()==1) sum+=2^i;
        }
        if(sum<=5) return sum;
    }

}

程式寫得應該沒有bug,然後他就說等下二面了。
二面面試官是一箇中年技術官,也是讓我自我介紹一遍(T^T),首先問了我做的機器學習相關的專案,讓我挑一個向其介紹,因此我選了和機器學習相關性最強的歧義消解和命名實體識別的專案,實質上是關於將基於規則的聚類和分層聚類相結合對網頁進行聚類的方法。詳細介紹完了之後,他問了規則是如何得出的,為什麼用這樣的規則,每條規則具體是怎樣?為何不把規則直接轉為特徵值向量,我回答是因為我的文字特徵值向量是統計詞頻,不適用於規則,然後他問如果將規則轉化為比重更大的特徵值呢?或者在一篇文章中怎樣結合不同部分的資訊呢?我給出的答案是將網頁中不同的區域給予不同的權重,最後累加起來。然後他就問權重怎麼給?我說人工賦值。。。然後他又丟擲問題來,給一些特定商品的評論,如何在裡面提取有用的關鍵詞,比如化妝品,提取出類似於效果好壞、價格高低等等的關鍵詞。我的回答是首先進行分詞,然後根據tf-idf和詞頻提取出排在前面的詞,再進行停用詞表或關鍵詞表的刪選。面試官直接說我們不接受任何的人工方式,給跪了。。。然後,實在想不出來,面試官非常nice地安慰了我一下,說機器學習懂得的東西還不錯了,知識遷移能力挺好的,知道最近我對“挺好”兩字多心碎嗎。。。接著,他又問會啥程式語言,我說會java、python,java懂最多,然後他本人不太用java,就問了一個問題box是什麼,從來不知道這是什麼鬼。。。網上查了一下,難道是說swing裡面的box容器?“好吧,那就出個演算法題嘍”讓我編一個連結串列反轉的題目。程式碼如下:

class List{
    int val;
    List next;
}
class Reverse{
    List reverse(List l){
        if(l==null) return null;
        Stack<List> s = new Stack<List>;
        while(l!=null){
            s.push(l);
            l = l.next;
        }
        List newlist = s.pop();
        List p = newlist;
        while
(!s.isEmpty()){ p = s.pop(); p.next = p; } return newlist; } }

程式碼順利寫出來了,但是面試官也沒有任何特殊的感覺,只是說了句,恩恩,就是這樣嘛。然後就談起實習時間的問題了。這個題目我在路上回想了一下,另一種解題方法可能為:設定一個List p儲存前面的節點,那麼只要從前往後遍歷時將當前節點的next換成p就好了,程式碼如下:

List Reverse(List l){
    if(l==null) return null;
    List p = l.next;
    while(true){
        if(p==null) return l;
        List q = p.next;
        p.next = l;
        l = p;
        p = q;
    }
}

還三種方法直接新建一個list,然後一個一個放進去,第四種方法是:對於一條連結串列,從第2個節點到第N個節點,依次逐節點插入到第1個節點(head節點)之後,(N-1)次這樣的操作結束之後將第1個節點挪到新表的表尾即可。這個解法的另一種方式是從頭到尾遍歷原連結串列,每遍歷一個結點,將其摘下放在新連結串列的最前端。注意連結串列為空和只有一個結點的情況。時間複雜度為O(n)。

// 反轉單鏈表
ListNode * ReverseList(ListNode * pHead)
{
        // 如果連結串列為空或只有一個結點,無需反轉,直接返回原連結串列頭指標
    if(pHead == NULL || pHead->m_pNext == NULL)  
        return pHead;

    ListNode * pReversedHead = NULL; // 反轉後的新連結串列頭指標,初始為NULL
    ListNode * pCurrent = pHead;
    while(pCurrent != NULL)
    {
        ListNode * pTemp = pCurrent;
        pCurrent = pCurrent->m_pNext;
        pTemp->m_pNext = pReversedHead; // 將當前結點摘下,插入新連結串列的最前端
        pReversedHead = pTemp;
    }
    return pReversedHead;
}

看似簡單的問題,解法往往有很多種,但是要找到時間和空間效率最高的解法才能讓面試官眼前一亮。
總之,這次面試考察了方方面面,總結來說主要考察了以下幾點:
一面:實習和專案經歷、機器學習演算法、概率論、程式設計能力;
二面:資料探勘各個環節處理細節、問題解決能力、學習遷移能力、程式設計能力。
總結來說,我現階段仍欠缺的能力是:
【緊急】機器學習演算法推導、應用場景;
【緊急】基礎概率論;
【重要】資料探勘流程的各方面問題處理細節;
【重要】演算法和程式設計能力;
得到的經驗是:
1.自我介紹要突出最有競爭力的特點;
2.遇到不會的問題坦然承認並且努力拓展思路解決,實在不行就求助面試官;
3.複雜問題能解決儘量解決,搞定是王道,簡單問題多思考,優化才出彩。