一次電話面試題

aFakeProgramer發表於2018-08-03

C++中引用與指標的區別?

https://blog.csdn.net/zhengqijun_/article/details/54980769

大小端這個問題在面試過程中偶爾會被問到

 

第一種:聯合(union)方式判斷法

在union中所有的資料成員共用一個空間,同一時間只能儲存其中一個資料成員,所有的資料成員具有相同

的起始地址。即上述的union雖然定義了兩個成員,但其實這個union只佔用了4個位元組(32位機器中),往a成員

賦值,然後讀取b就相讀取a成員的低位第一個位元組的值。如果機器使用大端模式,則u.a=1那a的最高位元組值為1;

如果機器使用小段模式,則u.a=1則a的最低位位元組為1。上述可知b和a有相同的起始位,所以讀取b如果等於1,

則為小端模式,b為0則為大端模式

typedef union {

    int i;

    char c;

}my_union;


int checkSystem1(void)

{

    my_union u;

    u.i = 1;

    return (u.i == u.c);

}



第二種稱之為直接判斷法,怎麼直接判斷呢,其實就是根據大小端各自的儲存方式編寫程式進行判斷,這個方法更直接。

首先我們來看下大小端的儲存方式:

大端模式(Big_endian)   -- 字資料的高位元組儲存在低地址中,而字資料的低位元組則存放在高地址中。

小端模式(Little_endian)-- 字資料的高位元組儲存在高地址中,而字資料的低位元組則存放在低地址中。

根據這個特性,假設我們初始化了一個int變數i為0x12345678,其地址為0x100,根據定義在小端模式下

0x100一個位元組內的值為0x78,類推0x101=>0x56,0x102=>0x34,0x103=0x12,根據這個程式設計如下

int checkSystem2(void)

{

    int i = 0x12345678;

    char *c = &i;

    return ((c[0] == 0x78) && (c[1] == 0x56) && (c[2] == 0x34) && (c[3] == 0x12));

}




int main(void)

{

    if(checkSystem1())

    printf("little endian\n");

    else

    printf("big endian\n");


    if(checkSystem2())

    printf("little endian\n");

    else

    printf("big endian\n");


    return 0;

}

如果返回1表示小端,反則表示大端;


我曾經在面試中被問及該問題,當時我用的是第一種方法,用口述方式進行的,我還沒陳述完,面試官

就笑著說看來你是在網上看到了這樣的方法,自己的理解不夠深入! 他的話其實有點武斷,用第一種

方法並不表明我就沒有深入理解大小端。但是人都有主觀判斷性,面試官對我主觀的印象就這樣了!

所以以後面試還被問到就用第二種方法吧,這個描述起來,對方替聽起來你總算是理解了大小端的本質

就是儲存方式

虛擬函式純虛擬函式的區別
虛擬函式底層是如何實現的?

https://blog.csdn.net/lihao21/article/details/50688337


free和malloc的區別?

(1)new、delete 是操作符,可以過載,只能在C++中使用。
(2)malloc、free是函式,可以覆蓋,C、C++中都可以使用。
(3)new 可以呼叫物件的建構函式,對應的delete呼叫相應的解構函式。
(4)malloc僅僅分配記憶體,free僅僅回收記憶體,並不執行構造和解構函式
(5)new、delete返回的是某種資料型別指標,malloc、free返回的是void指標。

注意:malloc申請的記憶體空間要用free釋放,而new申請的記憶體空間要用delete釋放,不要混用。因為兩者實現的機理不同。

1 我認為new\delete和malloc\free最大區別是對物件的理解。
如果你使用
Foo* foo = malloc(sizeof(Foo));//Foo是一個類
初始化,那麼你將不會呼叫Foo的構造方法,而只是單純的分配空間。而且我們只認為你是分配一個空間,而不是想建立一個物件。
Foo* foo = new Foo();則會呼叫Foo的構造方法來初始化物件,也就是說你既要分配空間又要初始化這段空間,讓它變成一個物件。
對於delete和free也有同樣的問題,就是delete會呼叫解構函式,free則不會。
說白了,new\delete玩的是物件,而malloc\free僅僅是記憶體空間而已
2 對於除去物件意外的其他情況,比如int和float等
int* Array=new int[10];和int* Array=malloc(sizeof(int)*10);只存在使用技巧的差別,沒有本質的差別。
3 最後也提醒你new\delete和malloc\free只能成對使用,不能混了。

https://blog.csdn.net/chy19911123/article/details/48135239
程式碼有哪些分割槽:https://blog.csdn.net/u014470361/article/details/79297601

程式碼區:存放程式的程式碼,即CPU執行的機器指令,並且是隻讀的。 
常量區:存放常量(程式在執行的期間不能夠被改變的量,例如: 10,字串常量”abcde”, 陣列的名字等) 
靜態區(全域性區):靜態變數和全域性變數的儲存區域是一起的,一旦靜態區的記憶體被分配, 靜態區的記憶體直到程式全部結束之後才會被釋放 
堆區:由程式設計師呼叫malloc()函式來主動申請的,需使用free()函式來釋放記憶體,若申請了堆區記憶體,之後忘記釋放記憶體,很容易造成記憶體洩漏 
棧區:存放函式內的區域性變數,形參和函式返回值。棧區之中的資料的作用範圍過了之後,系統就會回收自動管理棧區的記憶體(分配記憶體 , 回收記憶體),不需要開發人員來手動管理。棧區就像是一家客棧,裡面有很多房間,客人來了之後自動分配房間,房間裡的客人可以變動,是一種動態的資料變動。 

 


int a=1;
int b=a;全域性變數會出現問題嗎?
全域性變數的初始化順序是什麼?

https://blog.csdn.net/macrohasdefined/article/details/8814458

 對於不同編譯單位的全域性變數,其初始化的順序沒有任何的保證,因此對不同編譯單位裡的全域性變數,在它們的初始化順序之間建立依賴性都是不明智的。
       此外也沒辦法捕捉到全域性變數初始化丟擲的異常,一般來說要減少全域性變數的使用,特別是限制那些要求複雜初始化的全域性變數。所以,儘量不用全域性變數;用靜態變數,通過訪問器進行訪問。

例如:全域性變數   
        int   a   =   5;   
        int   b   =   a;   
       如果a和b定義在同一個檔案裡,那沒什麼問題,結果b等於5;如果a和b定義在不同檔案裡,就不能保證b也等於5,也就是說不能保證a先初始化。

       事實上,除了在同一個檔案定義的全域性物件的初始化是按照定義次序來進行的之外,其他全域性或靜態變數之間的初始化次序沒有任何保障。解決這種問題的方法是不直接使用全域性變數,而改用一個包裝函式來訪問,例如   
  int   get_a()   
  {   
          static   int   a   =   5;   
          return   a;   
  }   
  int   get_b()   
  {   
          static   int   b   =   get_a();   
          return   b;   
  }   
    
       這樣的話,無論get_a和get_b是否定義在同一個檔案中,get_b總是能夠返回正確的結果,原因在於,函式內部的靜態變數是在第一次訪問的時候來初始化。 

       任何時候,如果在不同的被編譯單元中定義了"非區域性靜態物件",並且這些物件的正確行為依賴於它們被初始化的某一特定順序,就會產生問題.你絕對無法控制不同被編譯單元中非區域性靜態物件的初始化順序。對於函式中的靜態物件(即"區域性"靜態物件)它們在函式呼叫過程中初次碰到物件的定義時被初始化..  

       PS:千萬不要寫出和編譯順序相關的程式來。 

 

       關於全域性變數的初始化,C語言和C++是有區別的。      
       在C語言中,只能用常數對全域性變數進行初始化,否則編譯器會報錯。       
       在C++中,如果在一個檔案中定義了int a = 5;要在另一個檔案中定義int b = a;的話,前面必須對a進行宣告:extern   int   a;否則編譯不通過。即使是這樣,int b = a;這句話也是分兩步進行的:在編譯階段,編譯器把b當作是未初始化資料而將它初始化為0;在執行階段,在main被執行前有一個全域性物件的構造過程,int b = a;被當作是int型物件b的拷貝初始化構造來執行。    
      其實,準確地說,在C++中全域性物件、變數的初始化是獨立的,如果不是象int a   =   5;這樣的已初始化資料,那麼就是象b這樣的未初始化資料。    
      而C++中全域性物件、變數的建構函式呼叫順序是跟宣告有一定關係的,即在同一個檔案中先宣告的先呼叫。對於不同檔案中的全域性物件、變數,它們的建構函式呼叫順序是未定義的,取決於具體的編譯器。


堆疊程式碼區,全域性資料區
虛擬函式是怎麼實現的
多執行緒程式設計

執行緒之間是如何通訊的?

多個執行緒共享程式的資源,都有哪些資源?

程式之間如何通訊
linux script
per script

const char *p 與 char *p const的區別?

https://blog.csdn.net/m0_37806112/article/details/81252151

    const char *p; // 宣告一個指向字元或字串常量的指標(p所指向的內容不可修改)

    char const *p;// 同上(我在這栽了,期望讀者能避免同樣的錯誤)

    char * const p;//宣告一個指向字元或字串的指標常量,即不可以修改p的值,也就是地址無法修改。

在一段磁碟存了很多cake,現在需要抓一個cake,每個cake有一個key,如何在用到的時候快速找到這個cake 
請說出你的解決方案 

使用map來儲存???

 

extern 和static 的用法

extern 是建立了一個其他檔案的變數的引用

static 

解構函式為什麼寫成虛擬函式

如將基類的解構函式定義為虛擬函式,當刪除一個指向派生類的基類指標的時候,首先會呼叫派生類的解構函式,然後再呼叫基類的解構函式。否則只會呼叫基類的解構函式。

這次面試發現自己的基礎很弱,很多不常用的概念都會涉及到,所以要打好基礎。才能有所發揮

相關文章