某日二師兄參加XXX科技公司的C++工程師開發崗位第23面:
面試官:
vector
瞭解嗎?二師兄:嗯,用過。
面試官:那你知道
vector
底層是如何實現的嗎?二師兄:
vector
底層使用動態陣列來儲存元素物件,同時使用size
和capacity
記錄當前元素的數量和當前動態陣列的容量。如果持續的push_back(emplace_back)
元素,當size
大於capacity
時,需要開闢一塊更大的動態陣列,並把舊動態陣列上的元素搬移到當前動態陣列,然後銷燬舊的動態陣列。面試官:你知道新開闢的動態陣列的容量是就陣列的多少倍比較合適?
二師兄:這個值在不同的編譯器上不是固定的。MSVC 是1.5,而GCC是2。
面試官:有沒有什麼好的辦法提升vector連續插入效率?
二師兄:有的,如果知道資料的大概量,我們可以使用
reserve
方法直接為vector
擴容這個量級。這樣在後續的資料插入時就不會因為頻繁的capacity
被用盡而導致的多次的資料搬移,從而提升vector
插入效率。面試官:
push_back
和emplace_back
有什麼區別?二師兄:兩者都可以在容器尾部插入元素。在GCC中,如果插入的元素是右值,兩者都會
move
元素到容器。如果是左值,兩者都會copy
元素到容器。唯一不同的一點是,當C++版本高於C++17時,emplace_back
返回當前插入的值的參照,而push_back
返回void
。面試官:
erase
和remove
有什麼區別?二師兄:
erase
屬於成員函數,erase
刪除了元素,remove
屬於演演算法庫函數,而remove
只會把元素移動到尾部。面試官:哪些情況下迭代器會失效?
二師兄:迭代器失效主要有兩種情況引起:1.插入資料。由於插入資料可能導致資料搬移(
size > capacity
),所以迭代器失效。2.刪除資料。當使用erase
刪除資料時,被刪除資料後面的資料依次向前移一位。這會導致被刪除資料之後的迭代器失效。面試官:如何快速的清空
vector
容器並釋放vector
容器所佔用的記憶體?二師兄:有兩種方法:第一種,使用
clear
方法清空所有元素。然後使用shrink_to_fit
方法把capacity
和size(0)
對齊,達到釋放記憶體的作用:
#include <iostream>
#include <vector>
int main(int argc, char const *argv[])
{
std::vector<int> vi;
vi.reserve(1024);
for (int i = 0; i < 1024; i++) vi.push_back(i);
std::cout << vi.size() << " " << vi.capacity() << std::endl; //1024 1024
vi.clear();
std::cout << vi.size() << " " << vi.capacity() << std::endl; //0 1024
vi.shrink_to_fit();
std::cout << vi.size() << " " << vi.capacity() << std::endl; //0 0
}
二師兄:第二種,使用
swap
方法;
#include <iostream>
#include <vector>
int main(int argc, char const *argv[])
{
std::vector<int> vi;
vi.reserve(1024);
for (int i = 0; i < 1024; i++) vi.push_back(i);
std::cout << vi.size() << " " << vi.capacity() << std::endl; //1024 1024
std::vector<int>().swap(vi); //使用臨時量(size =0, capacity=0)和vi交換,臨時量會立即解構
std::cout << vi.size() << " " << vi.capacity() << std::endl; //0 0
}
面試官:你知道
vector<bool>
是如何實現的嗎?二師兄:
vector<bool>
的實現和其他實現容器的實現不一致。每個元素被當作一個位而不是一個位元組儲存。這導致我們不能直接存取該元素,也無法對每個元素取地址(8
個元素可能在同一個位元組中儲存)。所以不建議使用vector<bool>
,必要時可以使用std::bitset
替代。面試官:好的,回去等通知吧。
今天二師兄表現不錯,同時要感謝小夥伴的耐心閱讀。讓我們一起期待明天二師兄的面試之旅吧。
關注我,帶你21天「精通」C++!(狗頭)