標籤:blog http 使用 os io 檔案 資料 for
今天參加了百度的面試,面試過程安排過程中出了些問題,上午面試完成後竟然要等到下午4點安排接下來的面試,安排的不是很緊湊,最好讓每個面試者的連續面試安排在一起,面試挺消耗精力了。不過周五趕上百度的summer party,在大廳等待的時候看到很多美女-_-!百度的前台妹紙們真是很漂亮嘛。
一面:面試官很清瘦,個頭很高。後來發現人很nice,很隨和~,至少面試過程中讓人感覺很舒服。一些我回答出來的問題可能記憶的不是很清楚了,主要記錄一些我答的不是很好的問題。首先自我介紹,不過剛剛開始就被打斷開始進行詢問了,從課程至項目,聊了很多,面試官在百度的職位or他隸屬於的部門屬於百度的架構開發類職位,及相對於策略類的一個職位。無論我的課程或者經曆其實對於架構開發類職位比較不足,比較偏策略一些。不過繼續面試嘛,我興趣廣泛,針對這個也高度興趣的~
1.linux多線程編程的知識,這個答的不是很好,因為自己確實基本沒寫過多線程的知識,只是並行程式設計利用MPI實現過簡單的演算法,概念知識不是很瞭解,所以針對linux多線程編程知識還需要補充一下。當時一個問題就是鎖的類型?
2.linux中檔案描述符FD的概念?當時想不到是什麼,然後面試官提示了一下,0,1,2,就想到了命令列中經常用到1,2就答了一下才瞭解到平時用到的這些就是檔案描述符,自己卻不知道概念。
標準輸入(standard input)的檔案描述符是 0,標準輸出(standard output)是 1,標準錯誤(standard error)是 2。
3.因為是搜尋公司,所以面試官讓我描述一下整個搜尋引擎的過程,包括使用者提交query之後的一系列工作,這部分概念缺失很多,答的很差。準備面試一家搜尋公司,而且在搜尋公司實習過一段時間,竟然無法完整答出這個問題,其實挺糟的。
這個搜尋一下比較好的架構~最好針對已經有的開源項目分析其架構最好。針對我可能分析一下Nutch和Solr比較好。
4.針對數組A和數組B,兩個數組的元素內容相同,不過數組A是已經排序的,數組B是亂序的,針對數組的中位元,存在以下兩組程式,比較其效率並分析原因。
int g;int main() { g = 0; for(int i = 0 ; i < n ; i++) { if( A[i] > mid ) g++; } for(int i = 0 ; i < n ; i++) { if(B[i] > mid ) g++; }}
這個題目之前在網上瀏覽到過,知道有序的數組的效率其實比無序的要高很多,但是原因實在想不出來。現在搜一下,原來是stackoverflow上面的經典問答呢,原因不是編譯器動手腳,而是CPU動的手腳,CPU有一個叫分支預測的技術,是這個技術導致有序數組的效率很高。 CPU指令執行的過程是流水線,簡單的分支預測方案是針對當前元素判斷下一個元素的指令跳轉方向,有序的話分支預測的準確率很高,無序的話分支預測技術就不生效了,無法提前裝載指令進入流水線,這樣就損耗了一定的CPU時間。
5.虛擬解構函式的應用情境。
當時答的是指向父類的指標實際指的子類對象,delete的時候需要調用子類解構函式!這是唯一應用情境!當時多嘴答了一下引用也可。其實引用必須顯示建立對象,這樣編譯器就會自動調用其解構函式,所以不屬於這一應用情境,即使指標和引用均可完成多態。
實驗執行個體:
class A{public:A() {cout<<"I am A"<<endl;}~A() {cout<<"Leave A"<<endl;}};class B:public A{public:B() {cout<<"I am B"<<endl;}~B() {cout<<"Leave B"<<endl;}};int main() {A &atestr = B();A *atestp = new B();delete atestp;}
實驗結果:
6.STL中list的底層實現?雙鏈表,因為可以前進後退。STL中的deque的預設使用容器?其實當時不太確定,思考了一下,猜了一下vector,因為很多容器預設容器均使用vector。當時如果問我deque的底層實現就好了,這個我更加瞭解-_-。
7.vector的insert和erase操作,這個也不是很熟悉,但是屬於連續空間的插入和刪除,必須做記憶體的調整~,翻看一下STL源碼具體的實現。
8.兩個簡單的演算法題目,時間比較急,代碼寫的比較冗餘。
a.一個數組中只有一個數字出現1次,其他數字出現兩次。
挺簡單的題目,因為見過,所以就跳過了這個題目,所以元素異或即可。
b.一個m*n得棋盤,每個格子中有一個數字,計算從左上方至右下角的最大路徑和,每一步行只能夠向右或者向下行走。
一個簡單的動態規劃題目,第一種方法首先時間複雜度O(mn)空間複雜度O(mn)的寫了代碼,代碼有些長,後來改進了一個時間複雜度O(mn)空間複雜度O(min(m,n))的演算法,後來面試官問如果需要還原路徑如何做?採用O(mn)的額外空間記錄每個單元走的路徑即可。
面試總結:演算法題目其實挺簡單的,只不過很多基礎知識不夠牢固,比如linux的一些基礎知識(複習下《鳥哥linux私房菜》),多線程的編程知識(學習下《posix多線程程式設計》並簡單實踐一下),STL的知識和C++的知識也仍然需要鞏固複習(STL源碼剖析,Effective C++,More Effective C++,深度探索C++物件模型一本書內容還是挺晦澀的,還是要拜讀一下,面試的時候雖然可能不涉及這麼深入的知識,但是還是要繼續學習),另外就是儘可能的逛一些技術社區,看一些東西了。因為像有序,無序數組那個題目,感覺完全是技術視野的問題,看到了就會,沒看到怎麼能夠想到是CPU的最佳化,我都以為是編譯器的最佳化,答題方向都掌握錯了。
二面:二面的面試官相對於一面的面試官不是那麼的健談,更多的是讓我去說,他去加一些提醒,然後我繼續的回答。不過面試官也很nice,因為答題的過程當中給了我很多的引導,因為題目我答的都不是很完善T_T!
1.首先是問一個大資料處理的題目,兩個URL檔案,分別有20億條記錄,每個URL的項目大約1KB。檔案中有重複的URL記錄,如何去除重複?
因為在一面的過程中瞭解到,有序的數組去除重複的時候能夠得到快速的去重,所以就考慮到了首先排序,但是兩個這麼大的檔案單機排序?外部排序,k路歸併排序,然後面試官就順勢的問了我k路歸併排序的知識,k路歸併排序的時間估計,因為k路歸併排序很多時間在磁碟的IO上面,所以我猜測可能磁碟的IO才是時間的平靜,每個元素最終進出磁碟4次,所以我估計的方法是元素數量*4*磁碟IO平均時間。不知道這個方法對不對。
多機的擴充,MapReduce程式應該可以完成,但是我對hadoop不是很瞭解(所以這個方法沒有答)。自己想一下多機的擴充吧,當然也是分治,想想也可以多機k路歸併排序,後來面試官引導我說可以不排序嗎?我才意識到原始問題只是為了去除重複,所以這裡分治並且利用hash的方法應該能夠達到很快速的演算法(複習一下《大型網站架構》這本書)一致性simhash方法應該是解決這個問題的。
2.設計模式,單例設計模式的深入討論。(複習《head first》設計模式)
a.單例設計模式的應用情境?
b.單例模式的代碼(白紙代碼)?
c.多安全執行緒的單例模式代碼(需要加鎖)?
d.如何?一個高效的安全執行緒的單例模式代碼?(存在不加鎖的解決方案嗎?)
3.簡單的聊了項目之後就問了一個演算法題目。中國象棋中帥,將和一個將身邊計程車,輸出其合理位置的方案。
剛看到這個演算法題目的時候還卡了一下,不過後來自己把棋盤編號為1,2,3,4,5,6,7,8,9之後豁然開朗~不過My Codeif,else比較多,3類情況枚舉,後來在面試官的提示下進行條件合并,節省了很多的代碼。
for(int s = 1 ; s <= 9;s++) { for(int j = 1 ; j <= 9;j++) { for(int jsb = 1; jsb <= 9;jsb += 2) { if( validposition(s,j,jsb)) printf("%d,%d,%d",s,j,jsb); } }}bool validposition(int s,int j,int jsb) { //將和帥相對應,並且不是士兵擋在將的前面的情況??? if ( s%3 == j%3 && !( jsb % 3 == j % 3 && jsb < j ) ) return false; return true;}
面試總結:對於系統設計海量資料的題目還是要準備的,還是需要複習《大型網站架構》一書,書中講述了很多海量資料處理的知識。學習下july的部落格,瞭解一些常用的方法。另外就是設計模式中單例模式的掌握一定要非常的熟悉,不要讓面試官不斷的提醒修正錯誤,這樣會引出更多的問題,我這次面試就是,雖然及時的修正問題,但是都能夠引出其他的問題,比如講一下線程和進程?雖然這個問題比較普通,但是這種引出其他問題還是盡量避免。
三面:這一面真是等了一個下午,12:30-4:20這個過程真是等待的很漫長,腦袋都秀逗了,面試官下午來了之後感覺就是聊天了,也沒有針對我問一些技術問題,主要問了實習的一些工作,簡單的聊了半個小時就結束了,也沒有說後續的訊息。不知道是不是還有後續,反正面試官還是很詳細的描述了一下百度的情況,也很認真的解答了我問的幾個關於百度的問題。當時也不好意思去問後續訊息,就回來了。T_T。
等待吧,希望無論結果好壞,百度都會給一個回覆,這樣也是一種提高。