在經曆了半個多月的漫長等待、翹首以盼的期待以後,今天終於有幸再次去百度大廈總部二面。此乃謂真應了百度的那句名言:眾裡尋他千百度,驀然回首,那人卻在燈火闌珊處——為了信念,執著追求、永不言棄!
這次面試官是一位GG,很帥氣,幹練,自信中散發著內在的睿智——三張紙、兩個人、一支筆,沒帶筆記本——這便是今天面試的主題。
在深刻分析和總結了一面失利的教訓後,為了防止一面因聽不清題目而要求面試官JJ重述題目的失誤,再因這次面試官是一位GG,因此可以和GG坐得盡量靠近些,這樣一來便於一次性清晰、準確、完整的理解題目的確切資訊,另一方面也方便和面試官進行面對面充分的交流,避免在同一個地方跌倒兩次——重蹈一面的覆轍。不過這次面試,我的這些擔心看來似乎都是多餘的:GG說話聲音適量,很有底氣,題意、需求、提問也都很清晰、簡潔、明了,而且GG在提問的時候還特意重點強調了題意的重要訊息,因此這次面試沒有因聽不清題目而要求面試官重述問題的情況,而且我在理解了GG表述的意思後也盡量迅捷作出反饋。總體上,這次面試感覺比較輕鬆,交流也很充分,GG待人很好,氣氛也很Happy
OK 介紹了這些面試的“前傳”以後,下面就讓我們直入今天面試的主題
第一道,給出兩個集合A和B,其中集合A={name},集合B={age、sex、scholarship、address、...},要求:問題1、根據集合A中的name查詢出集合B中對應的屬性資訊;問題2、根據集合B中的屬性資訊(單個屬性,如age<20等),查詢出集合A中對應的name
第二道,給出一個檔案,裡麵包含兩個欄位{url、size},即url為網址,size為對應網址訪問的次數,要求:問題1、利用Linux Shell命令或自己設計演算法,查詢出url字串中包含“baidu”子字串對應的size欄位值;問題2、根據問題1的查詢結果,對其按照size由大到小的排列。(說明:url資料量很大,100億級以上)
第三道,測試一部手機(手機是普通手機,除了系統軟體外,可能已經安裝了某些應用軟體)
第四道,根據我簡曆上的項目經曆,選出了其中的一個“Gloss搜尋推薦系統”項目,讓我介紹其架構以及我負責的工作
第五道,詢問了是否比較熟悉的程式設計語言(C/C++/C#)、VS2008以及對Linux Shell、Python認識等,主要是聊天交流方式,感覺很輕鬆
最後,是自由提問環節啦,問我有些什麼問題,我主要提問了三個問題:框計算與雲端運算有哪些區別以及框計算目前的進展如何、百度面對團購網和移動互連網等新興市場將有哪些戰略方面的調整以及品質測試部門的工作和後期面試將要準備或學習些什麼(這三個問題依次涉及到:1、框計算,關注百度的發展戰略和核心技術創新;2、百度在面對不斷變革和創新的互連網市場,將如何定位和戰略調整;3、涉及到個人如果有幸三面或最終被錄用,我將可能需要提前學習和準備哪些方面的知識儲備)
對於第一道的問題1:因為最近我一直都負責處理實驗室的海量文本資料(500G以上的log文本資料)進行資料採礦分析,因此我直接給出了我正在用到的文本處理方法。
方法1、直接利用HashTable的{key、value}來做映射,即利用key記錄集合A中的name屬性,利用value記錄集合B中的屬性向量,然後直接key來查詢value值
方法2、使用C++的容器類map進行一對多的映射(其實應該是multimap,當時忘了一對一與一對多的關係,在此更正一下)
方法3、自訂映射關係,大體思路是index+vector模式,vector可以利用struct結構體做,index主要對name建立索引,提高查詢效率這題的的核心解決思想,其實就是如何建立起一對多的映射關係,以及如何高效的進行查詢匹配
對於第一道的問題2:一時我沒有非常完整、高效的解決方案,但是我給面試官GG講了我思考的大體思路:
第一種方案,集合A和集合B,逐行讀取並按屬性欄位判斷,如age<20則列印出name,否則直接讀取下一行。但GG指出這樣做的缺點是需要遍曆整個檔案,效率較低
第二種方案,於是提高效率,我借鑒了倒排索引的思想,提出把關鍵字段建立索引,進行“全文”搜尋(其實就是集合A中的name),但是GG提出建立索引會佔用額外儲存空間,不是最優的方案
第三種方案,為了不佔用額外儲存空間,我再想借鑒資料庫的Group+Order方法,對集合B關鍵字段先分組然後排序,這樣既不佔用額外儲存空間,也比方案一提高了效率,但GG說這不是最優方案,並給我提示說其實很簡單,沒我想的這麼複雜,讓我繼續想想。。。
於是我繼續想了一小會兒,在頭腦中快速搜尋我曾經還遇到過哪些能夠既不佔額外儲存空間,又能提高效率的方法或借鑒思想。火花一冒,對呀,最近炒得很熱的框計算、雲端運算,它們的設計思想或許可以一用,於是我接著想分布儲存計算,對,利用分布式的思想來提高效率。可GG說似乎不行,這仍然不是解決問題2的最佳解決方案。不過還好的是,GG沒有在這個問題上繼續損殺我的腦細胞和自信心,而是循於轉入下一道題目(GG不死摳面試者最薄弱的環節,而是適時直接轉入下一環節,GG提問的技巧和哲學,給了面試者足夠的自信和勇氣,贊)
好啦,出於對我所崇拜的技術型創新公司——百度面試題目智慧財產權的保護以及對面試官GG(超牛級人物)勞動成果的尊重,我不再詳細介紹本次面試的具體細節 O(∩_∩)O哈哈~,謹以上述第一道題的大體思考過程和分析解決問題的方法,以饗各位支援我、鼓勵我的博友們 ^_^
不過做事為了有始有終,不半途而廢,下面我還是簡單描述一下第2-5題我能想到的解決方案和細節,也希望大家能幫我提出更好更最佳化的方法
第二道,利用Linux Shell查詢檔案中的子字串,需要用grep命令進行內容查詢;分離顯示檔案的url和size兩欄位,似乎需要用到awk命令(沒用過,不太熟悉),二者通過管道|傳值。不過當時我沒用Shell命令(不敢在GG高手面前Show,否則出了問題可不太好ban滴 呵呵 面試回來後,我在man sort查看詳細參數後,利用Shell的解法請見:百度面試及總結4 )於是我採用了自己設計演算法解決的,分解成三步(1、字元匹配:位元組流逐行讀取,進行子字串匹配KMP演算法,查出所有包含“baidu”的url;2、列印滿足1對應的size結果;3、根據2的結果,先把欄位size欄位值的字元型轉換成整型,然後再用排序演算法進行排序)當時說了三種排序演算法:二分法、快排、堆排序
這裡面還有一個小插曲, GG讓我簡單寫寫排序演算法的代碼,我開始選擇採用二分法,複雜度O(nlog2n) 不過這次我在下筆寫代碼之前,先吸取了一面時JJ說我代碼不規範的建議,於是我便從void QuickSort(int sizeArray[], int low, int high)、int i, j, tmp; ... 最基本格式寫起,雖然感覺比較麻煩,耗費了寶貴的面試時間,但畢竟吃一塹、長一智嘛——從細節做起,嚴格要求自己。好吧,就這樣寫著寫著,當寫到一半時,突然發現不對頭,我原先寫過二分法,但忘記了邊界值最後到底取上限high還是取下限low 於是我小聲請示GG:我想換一種排序演算法寫,不用二分法,改用快排寫,可以麼。GG沒有馬上簡單地回複我是或否,而是笑著問我怎麼寫到一半突然想換演算法啦 呵呵。 面試提問的哲學或許就體現在這裡,GG問得非常精妙,頗有提問的藝術。因為他問出了我在寫演算法的過程中,我頭腦中預見、思考、判斷、選擇等一系列的無法看到的思考過程(GG洞察問題的能力、提問的技巧藝術這些優點也非常值得我學習學習的)於是我也直接告訴GG我的弱點和擔心,我怕二分插入排序移動位置後,忘了到底取上標還是下標插入新值的細節所以我想改用我比較熟悉的快排演算法,這樣一來不用擔心上下限選擇的問題,二來快排利用遞迴,代碼簡潔、清晰、易懂。 GG笑了笑,同意了我的請求,哈哈,於是我改用快排寫出了代碼,並詳細給GG講了演算法遍曆的細節和遞迴過程。(具體快排、二分法(此處代表折半插入排序)、堆排序的實現代碼,請詳見我原先寫的博文 各種基本演算法實現小結(五)—— 排序演算法 )
第三道,測試題,在一面時也問過的。不過一面JJ問的是如何測試一台露天售貨機,當時我心裡想到了需要測試硬體部分,但卻沒說出來,直接跳到了測試軟體部分。這次我也吸取了一面敘述不完整、表達不充分的缺點,而是明確給出需要測試硬體部分等物理特性的。其實測試,只要把握三條最基本的原則:1、等價劃分;2、邊界值測試;3、經驗評估查錯(當然啦,經理還需要考慮效益、進度等經濟因素)然後遵照這些原則進行分析、思考測試案例、總結。例如本次測試一部手機,先劃分為硬體與軟體測試兩部分。硬體測試如溫度、按鍵、開機、抗摔、抗震、抗摸等等物理特性;軟體部分需要細劃分為系統軟體與應用軟體兩部分,因為系統軟體和應用軟體的功能和使用頻度不一樣,因此需要考慮測試的輕重緩急,由重點軟體(如電話薄)到次重點軟體(如電子書)再到非重點軟體(如遊戲),由使用頻繁到較頻繁再到較少使用等頻度劃分,如此依次劃分進行計劃、安排、進行測試。當時我舉了硬體、軟體;系統軟體、應用軟體;百度軟體和其它應用軟體;以及在Android手機上詳細測試百度手機IME等測試過程。核心思路:等價劃分——》邊界值測試——》憑經驗重點測試經常或較易出bug的地方(如果大家想深入學習軟體測試的核心思想和方法,推薦一本經典——大師級的Myers編寫的《The Art of Software Testing》(軟體測試的藝術)
第四道,主要是按照提供的簡曆,詳細詢問負責項目的設計思想、實現過程、部分功能實現細節以及採用的技術方法。GG詢問了我簡曆上的一個搜尋推薦相關的項目(現導師已讓我轉交給了一研三師兄,作為他畢業論文開題項目)我詳細講了利用solr做全文檢索搜尋的基本原理以及我負責實現的一些功能模組。收集資料來源(中科院學生畢業論文、IEEE國際會議、各種學術期刊等等)、Solr建立索引和資料庫儲存(Solr是在Lucene全文檢索搜尋開源系統上封裝後的改良系統)、ASP.NET(C#)製作用戶端前台頁面、使用者Search過程等。對這些功能模組我依次做了比較詳細的介紹。GG似乎對Search和sort高度興趣,於是接著深入詢問了solr建立、排序等細節問題,於是我把我曾經負責的工作,如Analyzer分詞、語義分析;document全文通過field欄位建立索引及儲存;使用者Search parser的string分詞抽取、排序等都做了較為深入的講解和介紹。這道系統設計題,主要考察的是面試者進行系統設計的整體思想,以及分析問題、解決問題的實戰能力、對功能模組技術細節的掌握應用水平。GG問的這些問題,一針見血,切中要害,對系統整體、核心、細節等都關注了,而且還提出了我們設計之初採用MySQL資料庫進行儲存資料的弊端(GG提出的這個問題,也的確是我們導師最近想改用文本進行海量資料存放區)——很有預見能力,值得我在以後的系統設計中,好好學習。。
第五道,就是以聊天為主啦,很輕鬆愉快,談了一些比較熟悉的語言編程(C/C++/C#以及Python)、熟悉的編譯環境(VS2008和Linux GCC)、以及對C#是否做過介面(用戶端和網頁開發)、資料庫設計(熟悉MySQL、SQL Server資料庫設計,並獨立設計過邏輯較為複雜的資料庫系統)
最後,自由提問環節,這次我沒像一面那樣,問“太空艙”睡覺等幼稚的問題啦,而是關注百度的產品戰略和技術創新(上面已說過,在此不再贅述)
好啦 終於寫完了 這次面試總體感覺比一面要輕鬆、愉快,交流很順暢,溝通也很友好,不過給我印象最深的還是GG的面試風格——三張紙(其中兩張還是我的簡曆)、二個人(GG和我)、一支筆(共同交流的語言)、不帶筆記本(他將如何記錄我面試的過程呢)——簡單、率直、幹練,體現出的是GG自信背後的智慧與才華,我終於看到了我心目中大牛級的技術高手啦,以後還得多多向他請教、學習 ^_^ 同時,從GG面試風格上,反映出了百度的核心價值觀——Simple and Reliable(簡單可依賴)