C++後臺開發面試常見問題彙總
一、extern關鍵字作用
1、extern用在變數或者函式的宣告前,用來說明“此變數/函式是在別處定義的,要在此處引用”。extern宣告不是定義,即不分配儲存空間。也就是說,在一個檔案中定義了變數和函式, 在其他檔案中要使用它們, 可以有兩種方式:使用標頭檔案,然後宣告它們,然後其他檔案去包含標頭檔案;在其他檔案中直接extern。
2、extern C作用
連結指示符extern C
如果程式設計師希望呼叫其他程式設計語言尤其是C 寫的函式,那麼呼叫函式時必須告訴編譯器使用不同的要求,例如當這樣的函式被呼叫時函式名或引數排列的順序可能不同,無論是C++函式呼叫它還是用其他語言寫的函式呼叫它,程式設計師用連結指示符
// 單一語句形式的連結指示符
extern "C" void exit(int);
// 複合語句形式的連結指示符
extern "C" {
int printf( const char* ... );
int scanf( const char* ... );
}
// 複合語句形式的連結指示符
extern "C" {
#include <cmath>
}
連結指示符的第一種形式由關鍵字extern 後跟一個字串常量以及一個普通的函式,宣告構成雖然函式是用另外一種語言編寫的但呼叫它仍然需要型別檢查例如編譯器會檢查傳遞給函式
int main()
{
// 錯誤: 連結指示符不能出現在函式內
extern "C" double sqrt( double );
305 第七章函式
double getValue(); //ok
double result = sqrt ( getValue() );
//...
return 0;
}
如果把連結指示符移到函式體外程式編譯將無錯誤
extern "C" double sqrt( double );
int main()
{
double getValue(); //ok
double result = sqrt ( getValue() );
//...
return 0;
}
但是把連結指示符放在標頭檔案中更合適,在那裡函式宣告描述了函式的介面所屬,如果我們希望C++函式能夠為C 程式所用又該怎麼辦呢我們也可以使用extern "C"連結指示符來使C++函式為C 程式可用例如。
// 函式calc() 可以被C 程式呼叫
extern "C" double calc( double dparm ) { /* ... */ }
如果一個函式在同一檔案中不只被宣告一次則連結指示符可以出現在每個宣告中它,也可以只出現在函式的第一次宣告中,在這種情況下第二個及以後的宣告都接受第一個聲明中連結指示符指定的連結規則例如
// ---- myMath.h ----
extern "C" double calc( double );
// ---- myMath.C ----
// 在Math.h 中的calc() 的宣告
#include "myMath.h"
// 定義了extern "C" calc() 函式
// calc() 可以從C 程式中被呼叫
double calc( double dparm ) { // ...
在本節中我們只看到為C 語言提供的連結指示extern "C",extern "C"是惟一被保證由所有C++實現都支援的,每個編譯器實現都可以為其環境下常用的語言提供其他連結指示例如extern "Ada"可以用來宣告是用Ada 語言寫的函式,extern "FORTRAN"用來宣告是用FORTRAN 語言寫的函式,等等因為其他的連結指示隨著具體實現的不同而不同所以建議讀者檢視編譯器的使用者指南以獲得其他連結指示符的進一步資訊。
總結 extern “C”
extern “C” 不但具有傳統的宣告外部變數的功能,還具有告知C++連結器使用C函式規範來連結的功能。還具有告知C++編譯器使用C規範來命名的功能。
二、static關鍵字作用
1、隱藏變數
當兩個檔案中存在全域性變數時,通過extern關鍵字可以引用不同檔案中的變數。如果加入static關鍵字,全域性變數的作用域在檔案內,其他檔案無法訪問。利用這一特性可以在不同的檔案中定義同名函式和同名變數,而不必擔心命名衝突。static可以用作函式和變數的字首,對於函式來講,static的作用僅限於隱藏.
2、靜態全域性變數
靜態全域性變數具有全域性作用域,如果程式包含多個檔案的話,它作用於定義它的檔案裡,不能作用到其它檔案裡,即被static關鍵字修飾過的變數具有檔案作用域。這樣即使兩個不同的原始檔都定義了相同名字的靜態全域性變數,它們也是不同的變數。
靜態全域性變數在靜態儲存區分配空間,在程式剛開始執行時就完成初始化,也是唯一的一次初始化
全域性變數具有全域性作用域。全域性變數只需在一個原始檔中定義,就可以作用於所有的原始檔。當然,其他不包含全域性變數定義的原始檔需要用extern 關鍵字再次宣告這個全域性變數。
區域性變數也只有區域性作用域,它是自動物件(auto),它在程式執行期間不是一直存在,而是隻在函式執行期間存在,函式的一次呼叫執行結束後,變數被撤銷,其所佔用的記憶體也被收回。
靜態區域性變數具有區域性作用域,它只被初始化一次,自從第一次被初始化直到程式執行結束都一直存在,它和全域性變數的區別在於全域性變數對所有的函式都是可見的,而靜態區域性變數只對定義自己的函式體始終可見。靜態全域性變數也具有全域性作用域,它與全域性變數的區別在於如果程式包含多個檔案的話,它作用於定義它的檔案裡,不能作用到其它檔案裡,即被static關鍵字修飾過的變數具有檔案作用域。這樣即使兩個不同的原始檔都定義了相同名字的靜態全域性變數,它們也是不同的變數。
從分配記憶體空間看:
全域性變數,靜態區域性變數,靜態全域性變數都在靜態儲存區分配空間,而區域性變數在棧裡分配空間。
從以上分析可以看出, 把區域性變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域性變數改變為靜態變數後是改變了它的作用域,限制了它的使用範圍。因此static 這個說明符在不同的地方所起的作用是不同的。
3、預設初始化為0
全域性變數也具備這一屬性,因為全域性變數也儲存在靜態資料區。在靜態資料區,記憶體中所有的位元組預設值都是0x00,
最後對static的三條作用做一句話總結。首先static的最主要功能是隱藏,其次因為static變數存放在靜態儲存區,所以它具備永續性和預設值0.
4、修飾普通函式
static修飾一個函式,則這個函式只能在本檔案中呼叫,不能被同一程式其他檔案呼叫。則其他檔案可以定義相同名字的函式,不會發生衝突。
5、修飾成員變數
靜態資料成員是類的成員,而不是物件的成員,在類中宣告static變數或者函式時,初始化時使用作用域運算子來標明它所屬類,
(1)靜態資料成員可以實現多個物件之間的資料共享,它是類的所有物件的共享成員,它在記憶體中只佔一份空間,如果改變它的值,則各物件中這個資料成員的值都被改變。
(2)靜態資料成員是靜態儲存的,是在程式開始執行時被分配空間,到程式結束之後才釋放,只要類中指定了靜態資料成員,即使不定義物件,也會為靜態資料成員分配空間。非靜態成員(變數和方法)屬於類的物件,所以只有在類的物件產生(建立類的例項)時才會分配記憶體,然後通過類的物件(例項)去訪問。
(3)靜態資料成員可以被初始化,但是隻能在類體外進行初始化,若未對靜態資料成員賦初值,則編譯器會自動為其初始化為0
靜態成員初始化與一般資料成員初始化不同:
初始化在類體外進行,而前面不加static,以免與一般靜態變數或物件相混淆;
初始化時不加該成員的訪問許可權控制符private,public等;
初始化時使用作用域運算子來標明它所屬類;
所以我們得出靜態資料成員初始化的格式:
<資料型別><類名>::<靜態資料成員名>=<值>
(4)靜態資料成員既可以通過物件名引用,也可以通過類名引用。
6、修飾成員函式
(1)類的靜態成員函式是屬於整個類而非類的物件,所以它沒有this指標,這就導致了它僅能訪問類的靜態資料成員和靜態成員函式。
(2)不能將靜態成員函式定義為虛擬函式:
虛擬函式依靠vptr和vtable來處理。vptr是一個指標,在類的建構函式中建立生成,並且只能用this指標來訪問它,因為它是類的一個成員,並且vptr指向儲存虛擬函式地址的vtable. 對於靜態成員函式,它沒有this指標,所以無法訪問vptr. 這就是為何static函式不能為virtual. 虛擬函式的呼叫關係:this -> vptr -> vtable ->virtual function(3)由於靜態成員聲明於類中,操作於其外,所以對其取地址操作,就多少有些特殊,變數地址是指向其資料型別的指標,函式地址型別是一個“nonmember函式指標”。(4)由於靜態成員函式沒有this指標,所以就差不多等同於nonmember函式,結果就產生了一個意想不到的好處:成為一個callback函式,使得我們得以將C++和C-based X Window系統結合,同時也成功的應用於執行緒函式身上。
(5)static並沒有增加程式的時空開銷,相反它還縮短了子類對父類靜態成員的訪問時間,節省了子類的記憶體空間。
(9)為了防止父類的影響,可以在子類定義一個與父類相同的靜態變數,以遮蔽父類的影響。這裡有一點需要注意:我們說靜態成員為父類和子類共享,但我們又重複定義了靜態成員,這會不會引起錯誤呢?不會,我們的編譯器採用了一種絕妙的手法:name-mangling 用以生成唯一的標誌
三、volatile關鍵字
(1)訪問暫存器要比訪問記憶體要塊,因此CPU會優先訪問該資料在暫存器中的儲存結果,但是記憶體中的資料可能已經發生了改變,而暫存器中還保留著原來的結果。為了避免這種情況的發生將該變數宣告為volatile,告訴CPU每次都從記憶體去讀取資料。
(2)一個引數可以即是const又是volatile的嗎?可以,一個例子是隻讀狀態暫存器,是volatile是因為它可能被意想不到的被改變,是const告訴程式不應該試圖去修改他。
volatile 關鍵字是一種型別修飾符,用它宣告的型別變量表示可以被某些編譯器未知的因素更改,比如:作業系統、硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的程式碼就不再進行優化,從而可以提供對特殊地址的穩定訪問。宣告時語法:int volatile vInt; 當要求使用 volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。
volatileint iNum = 10;
volatile 指出 iNum 是隨時可能發生變化的,每次使用它的時候必須從原始記憶體地址中去讀取,因而編譯器生成的彙編程式碼會重新從iNum的原始記憶體地址中去讀取資料。而不是隻要編譯器發現iNum的值沒有發生變化,就只讀取一次資料,並放入暫存器中,下次直接從暫存器中去取值(優化做法),而是重新從記憶體中去讀取(不再優化).
多執行緒併發訪問共享變數時,一個執行緒改變了變數的值,怎樣讓改變後的值對其它執行緒 visible。一般說來,volatile用在如下的幾個地方:1) 中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
2) 多工環境下各任務間共享的標誌應該加volatile;
3) 儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;
volatile 指標
和 const 修飾詞類似,const 有常量指標和指標常量的說法,volatile 也有相應的概念:
修飾由指標指向的物件、資料是 const 或 volatile 的:
const
char
* cpch;
volatile
char
* vpch;
注意:對於 VC,這個特性實現在 VC 8 之後才是安全的。
指標自身的值——一個代表地址的整數變數,是 const 或 volatile 的:
char
*
const
pchc;
char
*
volatile
pchv;
注意:(1) 可以把一個非volatile int賦給volatile int,但是不能把非volatile物件賦給一個volatile物件。
(2) 除了基本型別外,對使用者定義型別也可以用volatile型別進行修飾。
(3) C++中一個有volatile識別符號的類只能訪問它介面的子集,一個由類的實現者控制的子集。使用者只能用const_cast來獲得對型別介面的完全訪問。此外,volatile像const一樣會從類傳遞到它的成員。
多執行緒下的volatile
有些變數是用volatile關鍵字宣告的。當兩個執行緒都要用到某一個變數且該變數的值會被改變時,應該用volatile宣告,該關鍵字的作用是防止優化編譯器把變數從記憶體裝入CPU暫存器中。如果變數被裝入暫存器,那麼兩個執行緒有可能一個使用記憶體中的變數,一個使用暫存器中的變數,這會造成程式的錯誤執行。volatile的意思是讓編譯器每次操作該變數時一定要從記憶體中真正取出,而不是使用已經存在暫存器中的值,如下:
volatile BOOL bStop = FALSE;
(1) 在一個執行緒中:
while( !bStop ) { ... }
bStop = FALSE;
return;
(2) 在另外一個執行緒中,要終止上面的執行緒迴圈:
bStop = TRUE;
while( bStop ); //等待上面的執行緒終止,如果bStop不使用volatile申明,那麼這個迴圈將是一個死迴圈,因為bStop已經讀取到了暫存器中,暫存器中bStop的值永遠不會變成FALSE,加上volatile,程式在執行時,每次均從記憶體中讀出bStop的值,就不會死迴圈了。
這個關鍵字是用來設定某個物件的儲存位置在記憶體中,而不是暫存器中。因為一般的物件編譯器可能會將其的拷貝放在暫存器中用以加快指令的執行速度,例如下段程式碼中:
...
int nMyCounter = 0;
for(; nMyCounter<100;nMyCounter++)
{
...
}
...
在此段程式碼中,nMyCounter的拷貝可能存放到某個暫存器中(迴圈中,對nMyCounter的測試及操作總是對此暫存器中的值進行),但是另外又有段程式碼執行了這樣的操作:nMyCounter -= 1;這個操作中,對nMyCounter的改變是對記憶體中的nMyCounter進行操作,於是出現了這樣一個現象:nMyCounter的改變不同步。
四、const的作用
只要一個變數前面用const來修飾,就意味著該變數裡的資料可以被訪問,不能被修改。也就是說const意味著“只讀”規則:const離誰近,誰就不能被修改;const修飾一個變數,一定要給這個變數初始化值,若不初始化,後面就無法初始化。const修飾全域性變數;
const修飾區域性變數;
const修飾指標,const int *p1或int const *p1;p1指向的資料不能被修改,但p1本身的值可以被修改(指向其他資料)const修飾指標指向的物件, int * const p2;p2本身的值不能被修改,但它指向的資料可以被修改。(const int *const p3;指標和所指向資料都是常量)const修飾引用做形參;
const 通常用在函式形參中,如果形參是一個指標,為了防止在函式內部修改指標指向的資料,就可以用 const 來限制。在C語言標準庫中,有很多函式的形參都被 const 限制了,下面是部分函式的原型:
- size_t strlen ( const char * str );
- int strcmp ( const char * str1, const char * str2 );
- char * strcat ( char * destination, const char * source );
- char * strcpy ( char * destination, const char * source );
- int system (const char* command);
- int puts ( const char * str );
- int printf ( const char * format, ... );
const成員函式可以被const或非const物件呼叫,但
const
物件只能呼叫const成員
函式對於類的成員函式,有時候必須指定其返回值為const型別,以使得其返回值不為“左值”,只能作為右值使用。constint getNum();getNum() = 10; // 提示語法錯誤!
五、new與malloc的區別
realloc是從堆上分配記憶體的.當擴大一塊記憶體空間時,realloc()試圖直接從堆上現存的資料後面的那些位元組中獲得附加的位元組,如果能夠滿足,自然天下太平;如果資料後面的位元組不夠,那麼就使用堆上第一個有足夠大小的自由塊,現存的資料然後就被拷貝至新的位置,而老塊則放回到堆上.這句話傳遞的一個重要的資訊就是資料可能被移動.
- int len =7;
- int * a = (int *) malloc (sizeof(int) * len);
-
相關推薦
C++後臺開發面試常見問題彙總
一、extern關鍵字作用1、extern用在變數或者函式的宣告前,用來說明“此變數/函式是在別處定義的,要在此處引用”。extern宣告不是定義,即不分配儲存空間。也就是說,在一個檔案中定義了變數和函式, 在其他檔案中要使用它們, 可以有兩種方式:使用標頭檔案,然後宣告它們
Linux C++後臺開發面試題目彙總
資料庫: 1.資料庫中什麼是事務?事務的隔離級別?事務的四個特性?什麼事髒讀、幻讀、不可重複讀? 事務是一種手段,通過事務,我們可以將一系列的資料庫操作組合在一起作為一個整體進行操作
c++後臺開發面試常見知識點總結(一)c++基礎
指標和引用的區別 extern,const,static,volatile關鍵字 #define 和const的區別 關於typedef和#define; C++程式中記憶體使用情況分析(堆和棧的區別) new 與 malloc的異同處,new和delete是如何實現的。 C和C++的區別 C++中的過載,
C++後臺開發面試常考
一、C/C++方面 1、說說C++中的多型及其實現; 2、volatile關鍵字; volatile提醒編譯器它後面所定義的變數隨時都有可能改變 ,因此編譯後的程式每次需要儲存或讀取這個變數的時候 ,都會直接從變數地址中讀取資料。如果沒有volatile關鍵字,
【C++後臺開發面試】STL六大元件(一)
1.六大元件及其關係 Container(容器) 各種基本資料結構 Adapter(介面卡) 可改變containers、Iterators或Function object介面的一種元件 Algorithm(演算法) 各種基本演算法如sort、search…
【Linux】C++後臺開發面試
本文將講述(Linux)伺服器後臺開發崗位的要求,包含了大部分會遇到的面試題目。掌握文中提到的技術,也算少許入門水平了,此文既是面經,也是後臺開發的入門手冊。無論社招還是校招,都可作為一個參考。 本文內容收集自知乎和其他部落格,在此整理成章。 校招:以C++基礎為主,資料
2015年Java後臺開發面試問題分享彙總(主流網際網路公司面試經歷)
不同面試官面試風格一定不同,我這裡就是總結這些天面試Java開發過程中的大多數問題,綜合分類有Java基礎,框架,多執行緒,網路通訊,Linux,資料庫,設計模式,演算法,快取等幾個模組,由於問題太多,下面先列出問題,之後有時間在寫文章解答,或者網上有很多答案,可以自行搜尋。一、Java基礎1.String類
今日頭條C++後臺開發實習面試總結
一. 旋轉陣列中尋找某個target,leetcode原題。 二. 一個數組建立堆。 堆排序中,最初的步驟就是建立一個堆。之前在一些公司的筆試題上面見到一些與建堆過程相關的題目,因為當時對建堆過程有個誤解,所以經常選錯。之前一直以為是在完全二叉樹中依次插入序列中的元素,
面試總結:鵝廠Linux後臺開發面試筆試C++知識點參考筆記
> 文章每週持續更新,各位的「三連」是對我最大的肯定。可以微信搜尋公眾號「 後端技術學堂 」第一時間閱讀(一般比部落格早更新一到兩篇) 文章是由自己筆試面試騰訊的筆記整理而來,整理的時候又回顧了一遍,中間工作忙斷斷續續整理了半個月,才完成現在的樣子。主要是針對面試的C++後臺開發崗位,涵蓋了大部分C++相關
C++後臺研發面試總結
快速排序 系統 動態 cto 遞歸 內存對齊 最小 中序 多看 前言: 從中秋到國慶這幾天面試了幾家公司,有大公司也有小公司,連續幾天面試沒有系統的整理整理,正好有時間系統的整理一下,好多考點牛客的大佬們都分享過了,雖然每個人的方向不相同,不過多看一些總能找到一些高頻度
後臺開發面試問題整理
最近實習招聘又開始了,被一些師弟問了面試會問到的問題,於是想把之前實習、校招被問過的問題整理出來,希望對需要的人有幫助。雖然下面很多問題,但面試時可以問的問題是一個無限集,而且因人而異,只能作為一定的參考,如果把所有知識面都掌握得很牢固那問什麼都沒問題 :)這裡的問題也不是說要所有都能答
C++程式設計師面試常見題目
歡迎大家指正問題 1:請用簡單的語言告訴我C++ 是什麼? 答:C++是在C語言的基礎上開發的一種面向物件程式語言,應用廣泛。C++支援多種程式設計正規化 --面向物件程式設計、泛型程式設計和過程化程式設計。 其程式設計領域眾廣,常用於系統開發,引擎開發等應
2019秋招後臺開發面試記錄(阿里巴巴螞蟻金服、百度、360、美團點評)
螞蟻金服二面 1、自我介紹 2、專案 3、10億數字找最大100個數,不考慮記憶體問題,問的很細 4、索引 B+樹和二叉樹 5、騰訊可以留嗎?給你offer了嗎?你是不是要優先選擇騰訊 5、其他的個人問題聊了很多,哎前面都快被懟死了。。建議我考研之類的。。感覺都涼透了。。最後又給我說,面試表現還
2018.9.21攜程後臺開發面試記錄
一面感覺挺隨便的,就是一大群人和一大群面試官在一個大房間然後一對一面試,儼然一個菜市場……也不知道有沒有二面,面試官有些問題也沒答上來,作為第一次面試還是好好記錄一下,積累面試的套路經驗 1、上來當然還是自我介紹 2、看簡歷,讓我講一下模仿天貓的專案用了什麼技術
C++後臺開發最常問到的面試題
一、C/C++方面 1、說說C++中的多型及其實現; 3、帶虛擬函式與否的空類大小; 不帶虛擬函式:sizeof為1;帶虛擬函式:sizeof為4(32位)。 4、位元組對齊; 7、static、const的用法? 8、指標和引用
C/C++ 筆試、面試題目彙總(續)
一.找錯題 試題1: void test1() { char string [ 10 ]; char * str1 = " 0123456789 " ; strcpy(&nb
C/C++ 筆試、面試題目彙總
C++的基礎知識,筆試面試必備 1.求下面函式的返回值( 微軟) int func(x) { int countx = 0 ;&
Java後臺開發面試
面試題:Java中for和foreach區別在哪裡?什麼時候用for?什麼時候用foreach? 從Java 5 之後,Java提供另一種更簡單的迴圈:foreach迴圈,這種迴圈遍歷陣列和集合更加簡潔。使用foreach迴圈遍歷陣列和集合元組時,無須獲得陣列
linux c/c++ 後臺開發之—連線池
在網際網路後臺開發中經常需要需要範圍一些公共資源,如DB,cache, MQ, 最典型的的就是mysql, memcached, redis, 以及一些代理服務; 通常在高併發,高訪問量的情況下,起停連線,是不合適的,也容易將連線佔滿, 尤其是工作執行緒多的情況,如果每個
C後臺開發書籍索引
摘自別人部落格,地址:http://blog.csdn.net/qianggezhishen/article/details/45951095 打算從這開始一本一本開始看 題外話: 推薦一個 github 上的 開源書籍,有各種語言版本的,建議看 英文版 ,當然也有 中文版 非常之棒!! 一、演算法基礎系列