博客 / 詳情

返回

C++面試再進階

1、C++定義數組有大小限制嗎?如何定義一個長度為一百萬的數組?

答:定義數組大小的限制主要是看數組定義在內存的哪個區域內。局部非靜態的數組,空間在程序的棧上分配,不同平台的棧大小不同:SunOS/Solaris是8M,Linux是10M,Windows是1M,AIX是64M,都是可以調整的。也就是説,數組大小的限制就是堆或棧或全局存儲區大小的限制。如果想定義長度一百萬的數組可以將數組申明在全局存儲區或堆上,這些區域大小是比棧大很多的。

2、死鎖原因及解決、避免辦法

答:死鎖的四個條件是:1、互斥,2、請求與保持,3、不可搶佔,4、循環等待條件。這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
死鎖避免的基本思想是:系統對進程發出每一個系統能夠滿足的資源申請進行動態檢查,並根據檢查結果決定是否分配資源,如果分配後系統可能發生死鎖,則不予分配,否則予以分配。
寫程序時應該儘量避免同時獲得多個鎖,如果一定有必要這麼做,則有一個原則:如果所有線程在需要多個鎖時都按相同的先後順序獲得鎖,則不會出現死鎖。(避免條件4的成立)

3、HTTP常見的頭部信息有哪些?

答:
一段典型的請求

GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1
Host: net.tutsplus.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120
Pragma: no-cache
Cache-Control: no-cache

一段典型的應答

HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8
Pragma: public
Expires: Sat, 28 Nov 2009 05:36:25 GMT
Etag: "pub1259380237;gz"
Cache-Control: max-age=3600, public
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
X-Pingback: http://net.tutsplus.com/xmlrpc.php
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent
<!-- ... rest of the html ... -->
  • Host 一個HTTP請求會發送至一個特定的IP地址,但是大部分服務器都有在同一IP地址下託管多個網站的能力,那麼服務器必須知道瀏覽器請求的是哪個域名下的資源。
  • User-Agent 瀏覽器名和版本號,操作系統名和版本號,默認語言。
  • Accept-Language 用户的默認語言設置。如果網站有不同的語言版本,那麼就可以通過這個信息來重定向用户的瀏覽器。
  • Accept-Encoding 大部分的現代瀏覽器都支持gzip壓縮,並會把這一信息報告給服務器。這時服務器就會壓縮過的HTML發送給瀏覽器。這可以減少近80%的文件大小,以節省下載時間和帶寬。
  • If-Modified-Since 如果一個頁面已經在你的瀏覽器中被緩存,那麼你下次瀏覽時瀏覽器將會檢測文檔是否被修改過。
  • Cookie 顧名思義,他會發送你瀏覽器中存儲的Cookie信息給服務器。
  • Referer 顧名思義, 頭部將會包含referring url信息。
  • Authorization 當一個頁面需要授權,瀏覽器就會彈出一個登陸窗口,輸入正確的帳號後,瀏覽器會發送一個HTTP請求,但此時會包含這樣一個頭部。

4、Git和SVN的區別,Git對比SVN的優勢有哪些?

答:主要答案可以參考這篇文章。
這裏我總結一下:

  • 1.GIT是分佈式的,SVN是集中式的。這是Git和SVN的核心區別。使用Git開發時,每一個開發人員的電腦上有一個Local Repository,所以即使沒有網絡也一樣可以Commit,查看歷史版本記錄,創建項 目分支等操作,等網絡再次連接上Push到Server端。
  • 2.Git把內容按元數據方式存儲,而SVN是按文件。
  • 3.Git沒有一個全局版本號,而SVN有。
  • 4.Git的內容的完整性要優於SVN:GIT的內容存儲使用的是SHA-1哈希算法。

總之,Git的特點是版本控制可以不依賴網絡做任何事情,相比於SVN,它對分支和合並有更好的支持。

5、不使用標準庫函數實現函數char* int2str(unsigned int values)

char* int2str(unsigned int values)  
{  
    int len = 0;  
    const char digits[11] = "0123456789";  
    unsigned int tvalue = values;  
    while(tvalue >= 100)  
    {  
        tvalue /= 100;  
        len += 2;  
    }  
    if (tvalue > 10)  
        len += 2;  
    else if(tvalue > 0)  
        len++;  
  
    char* crtn = new char[len+1];  
    crtn += len;  
    *crtn = '\0';  
    do   
    {  
        *--crtn = digits[values%10];  
    } while (values /= 10);  
  
    return crtn;      
}  

6、有兩個雙向循環鏈表A,B,知道其頭指針為:pHeadA,pHeadB,請寫一函數將兩鏈表中data值相同的結點刪除

struct node   
{ 
    int data;   
    struct node *front,*next;   
};   
  
BOOL DeteleNode(Node *pHeader, DataType Value)  
{  
    if (pHeader == NULL) return;  
  
    BOOL bRet = FALSE;  
    Node *pNode = pHead;  
    while (pNode != NULL)  
    {  
        if (pNode->data == Value)  
        {  
            if (pNode->front == NULL)  
            {  
                pHeader = pNode->next;  
                pHeader->front = NULL;  
            }  
            else  
            {  
                if (pNode->next != NULL)  
                {  
                    pNode->next->front = pNode->front;  
                }  
                pNode->front->next = pNode->next;  
            }  
  
            Node *pNextNode = pNode->next;  
            delete pNode;  
            pNode = pNextNode;  
  
            bRet = TRUE;   
            //不要break或return, 刪除所有  
        }  
        else  
        {  
            pNode = pNode->next;  
        }  
    }  
  
    return bRet;  
}  
  
void DELETE(Node *pHeadA, Node *pHeadB)  
{  
    if (pHeadA == NULL || pHeadB == NULL)  
    {  
        return;  
    }  
  
    Node *pNode = pHeadA;  
    while (pNode != NULL)  
    {  
        if (DeteleNode(pHeadB, pNode->data))  
        {  
            if (pNode->front == NULL)  
            {  
                pHeadA = pNode->next;  
                pHeadA->front = NULL;  
            }  
            else  
            {  
                pNode->front->next = pNode->next;  
                if (pNode->next != NULL)  
                {  
                    pNode->next->front = pNode->front;  
                }  
            }  
            Node *pNextNode = pNode->next;  
            delete pNode;  
            pNode = pNextNode;  
        }  
        else  
        {  
            pNode = pNode->next;  
        }  
    }  
} 

7、VC程序如何通過崩潰地址定位代碼的出錯行?

答:主要以參考這篇文章。
可以通過map文件和cod文件來定位出錯行。
1.生成map文件,在VS2008中設置方法是property->Configuration Properties->Linker->Debugging 中的Generate Map File選擇Yes(/MAP);
2.生成cod文件,在VS2008中設置方法是property->Configuration Properties->C/C++->output Files中Assembler OutPut中選擇Assembly,Maching Code and Source(/FAcs)
3.通過崩潰地址在map文件中找到出錯的函數;
4.在cod文件中找到對應的函數,然後計算相對偏移地址以找到對應的出錯行。

還有通過Dump文件和WinDbg調試等方法。想要程序既不崩潰又能快速定位到出錯代碼終極辦法就是SEH+MiniDump,參考這篇文章。

user avatar _6375bdd01b3a4 頭像 wangying_5ea4fb9de961c 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.