2011年9月24日百度筆試RD-1
一、簡答
1、系統有很多任務,任務之間有依賴,比如B依賴於A,則A執行完後B才能執行
(1)不考慮系統並行性,設計一個函數(Task *Ptask,int Task_num)不考慮並行度,最快的方法完成所有任務。
(2)考慮並行度,怎麼設計
typedef struct{
int ID;
int * child;
int child_num;
}Task;
提供的函數:
bool doTask(int taskID);無阻塞的運行一個任務;
int waitTask(int timeout);返回運行完成的任務id,如果沒有則返回-1;
bool killTask(int taskID);殺死進程
拓撲排序(學習中......),先統計所有任務的入度,入度爲0的初始化進入隊列。
每次掃描隊列,dotask所有任務,然後調用waitTask,返回的任務ID將其子任務的入度-1,如果入度爲0則進入隊列(轉自qq120848369)
2、堆和棧的生命週期,內存分配性能,不同處,如果一般情況下要求1KB,偶爾需要100MB的緩存空間怎麼設計?
管理方式:對於棧來講,是由編譯器自動管理,無需我們手工控制;對於堆來說,釋放工作由程序員控制,容易產生memory leak。
生長方向:對於堆來講,生長方向是向上的,也就是向着內存地址增加的方向;對於棧來講,它的生長方向是向下的,是向着內存地址減小的方向增長。
分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如局部變量的分配。動態分配由alloca函數進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。
1KB用棧實現,100MB動態分配數組。
二、必答題(各種const)
1、解釋下面ptr含義和不同(好像是。。。。題幹了大概意思是這樣。下面應該沒錯)
double* prt = &value
const double* ptr = &value
double* const ptr=&value
const double* const ptr=&value
double* ptr =&value;
ptr是一個指向double類型的指針,ptr的值可以改變,ptr所指向的value的值也可以改變
const double* ptr =&value
ptr是一個指向const double類型的指針,ptr的值可以改變,ptr所指向的value的值不可以改變
double* const ptr=&value
ptr是一個指向double類型的指針,ptr的值不可以改變,ptr所指向的value的值可以改變
const double* const ptr=&value
ptr是一個指向const double類型的指針,ptr的值不可以改變,ptr所指向的value的值也不可以改變
2、去掉const屬性,例:
const double value = 0.0f;
double* ptr = NULL;
怎麼才能讓ptr指向value?
強制類型轉換,去掉const屬性,如
ptr= <const_cast double *>(&value);
三、算法設計
1、一個一維數軸上有不同的線段,求重複最長的兩個線段。
例:a:1~3
b: 2~7
c:2~8
最長重複是b和c
此題來源於音樂檢索和分析,看資料中,弄懂再分析
2、有向帶權圖最短路徑
有向帶權圖最短路徑常用有兩種方法,dijkstra和bellman-Ford方法。
1,dijkstra
算法具體步驟
(1)初始時,S只包含源點,即S=,v的距離爲0。U包含除v外的其他頂點,U中頂點u距離爲邊上的權(若v與u有邊)或 ∞(若u不是v的出邊鄰接點)。
(2)從U中選取一個距離v最小的頂點k,把k,加入S中(該選定的距離就是v到k的最短路徑長度)。
(3)以k爲新考慮的中間點,修改U中各頂點的距離;若從源點v到頂點u(u U)的距離(經過頂點k)比原來距離(不經過頂點k)短,則修改頂點u的距離值,修改後的距離值爲頂點k的距離加上邊上的權。
(4)重複步驟(2)和(3)直到所有頂點都包含在S中。
Bellman-Ford算法流程分爲三個階段:
(1) 初始化:將除源點外的所有頂點的最短距離估計值 d[v] ←+∞, d[s] ←0;
(2) 迭代求解:反覆對邊集E中的每條邊進行鬆弛操作,使得頂點集V中的每個頂點v的最短距離估計值逐步逼近其最短距離;(運行|v|-1次)
(3) 檢驗負權迴路:判斷邊集E中的每一條邊的兩個端點是否收斂。如果存在未收斂的頂點,則算法返回false,表明問題無解;否則算法返回true,並且從源點可達的頂點v的最短距離保存在 d[v]中。
算法描述如下:
Bellman-Ford(G,w,s) :boolean //圖G ,邊集 函數 w ,s爲源點
1 for each vertex v ∈ V(G)do //初始化 1階段
2 d[v] ←+∞
3 d[s] ←0; //1階段結束
4 for i=1 to |v|-1 do //2階段開始,雙重循環。
5 for eachedge(u,v) ∈E(G) do //邊集數組要用到,窮舉每條邊。
6 If d[v]> d[u]+ w(u,v) then //鬆弛判斷
7 d[v]=d[u]+w(u,v) //鬆弛操作 2階段結束
8 for each edge(u,v) ∈E(G) do
9 If d[v]> d[u]+ w(u,v) then
10 Exit false
11 Exit true
四、系統設計
大概意思是:百度內部有一個類似cs系統的計算系統,由於大併發計算很耗資源,所有要設計一個緩存系統。c做緩存,配置2.66MHZ,3G內存,大概有1000w個查詢,唯一的查詢大概有500w。要緩存24小時。設計這個緩存系統的運行機制,算法等等東西