|
1. C++程序的內(nèi)存分布
C++程序的內(nèi)存通常分為以下幾個部分:
棧(Stack):用于存儲局部變量和函數(shù)調(diào)用的信息。棧上的內(nèi)存是自動管理的,函數(shù)調(diào)用結(jié)束后自動釋放。
堆(Heap):用于動態(tài)分配內(nèi)存,通過 new 和 delete 進行管理。堆上的內(nèi)存需要手動管理。
全局/靜態(tài)區(qū)(Global/Static Area):用于存儲全局變量和靜態(tài)變量。這些變量在整個程序運行期間都存在。
代碼區(qū)(Code Section):用于存儲程序的機器碼。
詳細解答可以閱讀:面試題:C++ 內(nèi)存四區(qū)
2. 堆和棧的區(qū)別
分配方式:棧上的內(nèi)存是自動分配和釋放的,而堆上的內(nèi)存需要手動管理。
生命周期:棧上的變量在函數(shù)調(diào)用結(jié)束后自動銷毀,堆上的變量需要顯式釋放。
訪問速度:棧上的訪問速度快,因為棧是連續(xù)的內(nèi)存區(qū)域;堆上的訪問速度相對較慢。
大小限制:棧的大小通常有限制(如幾 MB),而堆的大小可以更大。
3. 內(nèi)存泄漏怎么辦
使用智能指針:如 std::unique_ptr 和 std::shared_ptr,它們會自動管理內(nèi)存。
代碼審查:定期檢查代碼,確保每個 new 都有一個對應(yīng)的 delete。
內(nèi)存檢測工具:使用工具如 Valgrind、Visual Studio 的內(nèi)存檢測工具等,幫助發(fā)現(xiàn)內(nèi)存泄漏。
RAII(Resource Acquisition Is Initialization):使用 RAII 技術(shù),確保資源在對象銷毀時自動釋放。
4. 智能指針有哪幾種
std::unique_ptr:獨占所有權(quán)的智能指針,不允許復(fù)制。
std::shared_ptr:共享所有權(quán)的智能指針,允許多個指針共享同一個對象。
std::weak_ptr:弱引用智能指針,用于解決 std::shared_ptr 的循環(huán)引用問題。
5. 循環(huán)引用計數(shù)最后是多少
在循環(huán)引用的情況下,std::shared_ptr 的引用計數(shù)不會自動減為零,導(dǎo)致內(nèi)存泄漏。通常需要使用 std::weak_ptr 來打破循環(huán)引用。
6. shared_ptr線程安全嗎
引用計數(shù)操作是線程安全的:多個線程可以安全地對同一個 std::shared_ptr 進行引用計數(shù)操作。
對象訪問不是線程安全的:對 std::shared_ptr 所指向的對象的訪問需要額外的同步機制(如 std::mutex)來保證線程安全。
7. 多線程使用shared_ptr如何保護數(shù)據(jù)安全
使用互斥鎖:在多線程環(huán)境中,使用 std::mutex 或 std::lock_guard 來同步對 std::shared_ptr 所指向的對象的訪問。
使用 std::atomic>:如果需要更細粒度的控制,可以使用 std::atomic>。
8. 條件變量偽喚醒
條件變量的偽喚醒是指條件變量在沒有實際通知的情況下被喚醒。為了避免偽喚醒,通常需要在循環(huán)中檢查條件變量的狀態(tài)。
std::unique_lockstd::mutex> lock(mtx);
while (!condition) { cv.wait(lock);}
9. unique_ptr轉(zhuǎn)移所有權(quán)
使用 std::move 將 std::unique_ptr 的所有權(quán)轉(zhuǎn)移給另一個 std::unique_ptr。
std::unique_ptrint> ptr1 = std::make_uniqueint>(42);
std::unique_ptrint> ptr2 = std::move(ptr1); // 轉(zhuǎn)移所有權(quán)
10. move實現(xiàn)方式
std::move 實際上是一個類型轉(zhuǎn)換函數(shù),將左值轉(zhuǎn)換為右值引用,以便調(diào)用移動構(gòu)造函數(shù)或移動賦值運算符。
template typename T>
typename std::remove_reference::type&& move(T&& arg) {
return static_casttypename std::remove_reference::type&&>(arg);
}
11. 完美轉(zhuǎn)發(fā)有什么用
完美轉(zhuǎn)發(fā)用于在模板函數(shù)中保持參數(shù)的原始類型和屬性,避免不必要的拷貝和類型轉(zhuǎn)換。
template typename T, typename... Args>
void forward_example(T&& t, Args&&... args) {
function(std::forward(t), std::forward(args)...);
}
12. 模板的特化和偏特化
全特化:為特定類型的模板參數(shù)提供專門的實現(xiàn)。
偏特化:為部分類型的模板參數(shù)提供專門的實現(xiàn)。
template typename T>struct MyTemplate { void func() { /* 通用實現(xiàn) */ }};
// 全特化template struct MyTemplate { void func() { /* 特化實現(xiàn) */ }};// 偏特化template typename T>struct MyTemplate { void func() { /* 偏特化實現(xiàn) */ }};
13. C++和C申請內(nèi)存方式的區(qū)別
C++:使用 new 和 delete。
C:使用 malloc、calloc、realloc 和 free。
更詳細的閱讀:百度實習(xí)面試:new和malloc的區(qū)別,什么時候用new 什么時候用mallc?
面試題:new出來的對象可以使用bzero等函數(shù)初始化內(nèi)部變量為0嗎?——信銳技術(shù)一面
14. C++釋放數(shù)組和普通對象的區(qū)別
普通對象:使用 delete。
數(shù)組:使用 delete[]。
int* ptr1 = new int;delete ptr1;
int* ptr2 = new int[10];delete[] ptr2;
15. 動態(tài)多態(tài)虛表的位置在哪
虛表本身通常存儲在程序的只讀數(shù)據(jù)段(或代碼段)中,因為虛表的內(nèi)容在程序運行時是固定的,不會被修改。每個類的虛表在程序的編譯階段生成,并在程序加載時分配內(nèi)存。
16. 有序數(shù)組去重不用額外空間
使用雙指針法
17. 二叉樹度為0和度為2的數(shù)量關(guān)系
對于一棵二叉樹,設(shè)度為0的節(jié)點數(shù)為 n0,度為2的節(jié)點數(shù)為 n2,則有:[ n0 = n2 + 1 ]
18. 哈夫曼樹構(gòu)建過程
1. 統(tǒng)計頻率:統(tǒng)計每個字符出現(xiàn)的頻率。
2. 創(chuàng)建節(jié)點:為每個字符創(chuàng)建一個節(jié)點,頻率作為節(jié)點的權(quán)重。
3. 創(chuàng)建優(yōu)先隊列:將所有節(jié)點加入優(yōu)先隊列。
4. 構(gòu)建哈夫曼樹:
從優(yōu)先隊列中取出兩個最小權(quán)重的節(jié)點。
創(chuàng)建一個新的內(nèi)部節(jié)點,權(quán)重為這兩個節(jié)點的權(quán)重之和。
將這兩個節(jié)點作為新節(jié)點的左右子節(jié)點。
將新節(jié)點加入優(yōu)先隊列。
重復(fù)上述步驟,直到優(yōu)先隊列中只剩下一個節(jié)點,即為哈夫曼樹的根節(jié)點。
19. 快排最壞情況發(fā)生
快排的最壞情況發(fā)生在每次分區(qū)選擇的樞軸都是最小或最大值時,時間復(fù)雜度為 O(n^2)。
20. 遞歸算法對比循環(huán)的問題
遞歸:代碼簡潔易懂,但可能會導(dǎo)致棧溢出,時間復(fù)雜度較高。
循環(huán):代碼可能較復(fù)雜,但通常更高效,不會導(dǎo)致棧溢出。
21. 優(yōu)先隊列的實現(xiàn)
優(yōu)先隊列通常使用二叉堆(最大堆或最小堆)來實現(xiàn),支持插入和刪除操作。
22. 有一個超大文件,無法一次性加載到內(nèi)存,如何排序
可以使用外部排序算法,如歸并排序:
1. 分塊排序:將文件分成多個小塊,每個小塊可以加載到內(nèi)存中并進行排序。
2. 合并排序:將排序后的塊合并成一個有序的大文件。
23. B+樹對比普通樹,紅黑樹的區(qū)別,為什么不用B樹
B+樹:葉子節(jié)點包含所有關(guān)鍵字,且葉子節(jié)點之間有指針相連,適合磁盤存儲和范圍查詢。
B樹:每個節(jié)點可以有多個關(guān)鍵字,適合磁盤存儲,但不支持高效的范圍查詢。
紅黑樹:自平衡二叉搜索樹,適合內(nèi)存中的快速查找和插入。
B+樹更適合數(shù)據(jù)庫和文件系統(tǒng)的索引,因為它們支持高效的范圍查詢和磁盤訪問。
24. HTTP 1/2/3版本的區(qū)別
HTTP/1.1:持久連接、管道化、緩存控制。
HTTP/2:多路復(fù)用、頭部壓縮、服務(wù)器推送。
HTTP/3:基于 QUIC 協(xié)議,改進了連接建立和數(shù)據(jù)傳輸性能。
5. HTTP Cookie作用
Cookie 用于存儲客戶端的狀態(tài)信息,如會話標識、用戶偏好等。服務(wù)器可以通過設(shè)置 Cookie 來跟蹤用戶的會話。
26. TCP擁塞控制方法
慢啟動:初始時快速增加擁塞窗口。
擁塞避免:線性增加擁塞窗口。
快重傳:接收方收到亂序數(shù)據(jù)包時發(fā)送重復(fù) ACK。
快恢復(fù):發(fā)送方接收到三個重復(fù) ACK 時,將擁塞窗口減半,然后進入擁塞避免階段。
end
一口Linux
關(guān)注,回復(fù)【1024】海量Linux資料贈送
精彩文章合集
文章推薦
?【專輯】ARM?【專輯】粉絲問答?【專輯】所有原創(chuàng)?【專輯】linux入門?【專輯】計算機網(wǎng)絡(luò)?【專輯】Linux驅(qū)動?【干貨】嵌入式驅(qū)動工程師學(xué)習(xí)路線?【干貨】Linux嵌入式所有知識點-思維導(dǎo)圖 |
|