百度2015校園招聘軟件開發筆試題


首先2015百度校園招聘筆試題目(軟開類)奉上:

答案分析(個人所理解的,如有不妥地方還望各位看官指出)

<1>、tcp-ip 連接時3次握手,斷開時4次握手。

連接過程:

第一次握手:
客戶端發送一個TCP的SYN標志位置1的包指明客戶打算連接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段里。

第二次握手:
服務器發回確認包(ACK)應答。即SYN標志位和ACK標志位均為1同時,將確認序號(Acknowledgement Number)設置為客戶的I S N加1以.即X+1。

第三次握手.
客戶端再次發送確認包(ACK) SYN標志位為0,ACK標志位為1.並且把服務器發來ACK的序號字段+1,放在確定字段中發送給對方.並且在數據段放寫ISN的+1。

斷開過程:

TCP的連接的拆除需要發送四個包,因此稱為四次揮手(four-way handshake)。客戶端或服務器均可主動發起揮手動作,在socket編程中,任何一方執行close()操作即可產生揮手操作。

這里分享一個連接講述的更加詳細:http://blog.csdn.net/qq276592716/article/details/19762121

<2>、內存管理淘汰算法(更加詳細內容見:http://www.haogongju.net/art/1699130

1. FIFO先進先出的算法

FIFO算法總是選擇在內存駐留時間最長的一頁將其淘汰。FIFO算法認為先調入內存的頁不再被訪問的可能性要比其他頁大,因而選擇最先調入內存的頁換出。實現FIFO算法需要把各個已分配頁面按分配時間順序記錄在一個數組中,每次淘汰最早進入數組的頁。

2. OPT最佳淘汰算法描述:

該算法淘汰在訪問串中將來最不常用的頁。這樣,淘汰掉該頁將盡量減少因需要訪問該頁又立即把它調入的現象。遺憾的是,這種算法無法實現,因為它要求必須預先知道每一個進程的訪問串。

3. LRU最近最少使用算法

LRU工作原理是,當需要淘汰某頁,選擇離當前時間最近的一段時間內最久沒有使用過的頁先淘汰。在這里采用一個頁面集大小的棧存儲最近訪問的頁面。頁面按時間順序壓如棧中。如果被訪問的頁在棧中,則從棧中移出頁面,壓入棧頂。這樣棧底記錄離當前時間最近的一段時間內最久沒有使用過的頁。

4. LFU最少訪問頁面算法

LFU在需要淘汰某一頁時,首先淘汰到當前時間為止、被訪問次數最少的那一頁。這只要在頁面集中給每一頁增設一個訪問計數器即可實現。每當該頁被訪問時,訪問計數器加1,而發生一次缺頁中斷時,則淘汰計數值最小的那一頁,並將所有的計數器清零。

5. NUR最近最不經常使用算法

NRU在需要淘汰某一頁時,從那些最近一個時期內未被訪問的頁中任選一頁淘汰。只要在頁表中增設一個訪問位即可實現。當某頁被訪問時,訪問位置1。否則,訪問位置0。系統周期性地對所有引用位清零。當需淘汰一頁時,從那些訪問位為零的頁中選一頁進行淘汰。如果引用位全0或全1,NRU算法退化為FIFO算法。

<3>、數據庫范式,這里自我感覺三大范式即可(更加詳細內容:http://ce.sysu.edu.cn/cdbm/news/coures/200908/news_20090807210925_242.html

1 第一范式(1NF)

    在任何一個關系數據庫中,第一范式(1NF)是對關系模式的基本要求,不滿足第一范式(1NF)的數據庫就不是關系數據庫。 
    所謂第一范式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。如果出現重復的屬性,就可能需要定義一個新的實體,新的實體由重復的屬性構成,新實體與原實體之間為一對多關系。在第一范式(1NF)中表的每一行只包含一個實例的信息。例如,對於圖3-2 中的員工信息表,不能將員工信息都放在一列中顯示,也不能將其中的兩列或多列在一列中顯示;員工信息表的每一行只表示一個員工的信息,一個員工的信息在表中只出現一次。簡而言之,第一范式就是無重復的列。

2 第二范式(2NF)

    第二范式(2NF)是在第一范式(1NF)的基礎上建立起來的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。第二范式(2NF)要求數據庫表中的每個實例或行必須可以被惟一地區分。為實現區分通常需要為表加上一個列,以存儲各個實例的惟一標識。如圖3-2 員工信息表中加上了員工編號(emp_id)列,因為每個員工的員工編號是惟一的,因此每個員工可以被惟一區分。這個惟一屬性列被稱為主關鍵字或主鍵、主碼。 
第二范式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那么這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。為實現區分通常需要為表加上一個列,以存儲各個實例的惟一標識。簡而言之,第二范式就是非主屬性非部分依賴於主關鍵字。

3 第三范式(3NF) 

    滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡而言之,第三范式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。例如,存在一個部門信息表,其中每個部門有部門編號(dept_id)、部門名稱、部門簡介等信息。那么在圖3-2的員工信息表中列出部門編號后就不能再將部門名稱、部門簡介等與部門有關的信息再加入員工信息表中。如果不存在部門信息表,則根據第三范式(3NF)也應該構建它,否則就會有大量的數據冗余。簡而言之,第三范式就是屬性不依賴於其它非主屬性。

二、編程設計和算法題目

<1>在一個單向鏈表中返回其中項,並分析復雜度。

分析:可以借助於兩個指針,快慢指針,快指針一次走兩步,慢指針一次走一步,當快指針走到尾端時,慢指針即指向中項位置。空間復雜度為0(1)時間復雜度為O(n).

struct ListNode
{
    struct ListNode *next;
    int key;
};

ListNode* getMID(ListNode* head)
{
    if (NULL == head)return NULL;
    ListNode *first = head;
    ListNode *second = head;
    while(NULL != second->next)
    {
        if(NULL == second->next->next)break;
        first = first->next;
        second = second->next;
    }
    return first;
}
View Code

<2>在一個集合S中找出最大元素C使得C=A+B,其中A,B均屬於集合S。分析復雜度。

分析:1、首先對集合進行排序,從小到大排序,可選排序算法較快的n*log(n)的快排、歸並、堆排序等。

2、找最大滿足條件的元素C。兩層循環,外層循環從大到小依次尋找C。內層循環,分別從頭尾向中間尋找元素A B,是的 C = A + B,找到后即跳出兩層循環。時間復雜度O(n^2)。

總體復雜度為 n*log(n)+O(n^2) = O(n^2)。

int cmp(const void *a,const void *b)
{
    int *num1 = (int *)a;
    int *num2 = (int *)b;
    return *num2 - *num1;
}

int  getMAXElement(int *arr,int len)
{
    bool flag = false;//標志位,標志着是否找到C
    //快排,這里直接調用庫函數中的快排算法
    qsort(arr,len,sizeof(int),cmp);
    int k = 0;
    for (k = len-1; k >1; k++)
    {
        for (int i = 0,j = k-1; i < j;)
        {
            int temp = arr[i] + arr[j];
            if (temp == arr[k])
            {
                flag = true;
                break;
            }
            if (temp < arr[k])
            {
                i++;
                continue;
            }
            if (temp > arr[k])
            {
                j--;
                continue;
            }
        }
        if (flag)break;
    }
    if (flag)
    {
        return arr[k];
    }
    else return -1;//標志着沒找到
}
View Code

 

<3>使用棧先進后出來模擬隊列先進先出的結構,實現函數:enqueue(入隊),dequeue(出隊),isEmpty(是否為空)的判斷。

分析:使用棧來模擬隊列,需要借助兩個棧A、B來實現,A棧負責入隊,B棧負責出隊,空值判斷時需要判斷兩個棧均為空。需要注意的是,從A棧向B棧移動元素時要注意只有當B棧為空時,把A棧內所有元素一次性移入B棧,若B棧有元素,那么不可移動,需要等待B棧為空時才可以移動。

stack<int> A;
stack<int> B;
//入隊
void enqueue(int value[],int len)
{
    for (int i = 0; i < len; i++)
    {
        A.push(value[i]);
    }
    if (B.empty())
    {
        while(!A.empty())
        {
            B.push(A.top());
            A.pop();
        }
    }
}
出隊
void dequeue()
{
    while(!B.empty())
    {
        B.pop();
        //其他操作
    }    
    while(!A.empty())
    {
        B.push(A.top());
        A.pop();
    }
    while(!B.empty())
    {
        B.pop();
        //其他操作
    }
}
//判斷是否為空
bool isEmpty()
{
    if(A.empty() && B.empty())return true;
    return false;
}
View Code

這里我就懶得再舉例子做測試用例,自我感覺代碼應該可以通過,如果有什么錯誤之處還望指出。O(∩_∩)O謝謝!

 

三、系統設計題

我表示不會哦。。。。。。。。。。哪位大神有此題解法,可以分享下就好了。以后我若有機會看到這題的解法我會在更新的。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM