某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第23面:
面試官:
vector
了解嗎?二師兄:嗯,用過。
面試官:那你知道
vector
底層是如何實(shí)現(xiàn)的嗎?二師兄:
vector
底層使用動態(tài)數(shù)組來存儲元素對象,同時使用size
和capacity
記錄當(dāng)前元素的數(shù)量和當(dāng)前動態(tài)數(shù)組的容量。如果持續(xù)的push_back(emplace_back)
元素,當(dāng)size
大于capacity
時,需要開辟一塊更大的動態(tài)數(shù)組,并把舊動態(tài)數(shù)組上的元素搬移到當(dāng)前動態(tài)數(shù)組,然后銷毀舊的動態(tài)數(shù)組。面試官:你知道新開辟的動態(tài)數(shù)組的容量是就數(shù)組的多少倍比較合適?
二師兄:這個值在不同的編譯器上不是固定的。MSVC 是1.5,而GCC是2。
面試官:有沒有什么好的辦法提升vector連續(xù)插入效率?
二師兄:有的,如果知道數(shù)據(jù)的大概量,我們可以使用
reserve
方法直接為vector
擴(kuò)容這個量級。這樣在后續(xù)的數(shù)據(jù)插入時就不會因?yàn)轭l繁的capacity
被用盡而導(dǎo)致的多次的數(shù)據(jù)搬移,從而提升vector
插入效率。面試官:
push_back
和emplace_back
有什么區(qū)別?二師兄:兩者都可以在容器尾部插入元素。在GCC中,如果插入的元素是右值,兩者都會
move
元素到容器。如果是左值,兩者都會copy
元素到容器。唯一不同的一點(diǎn)是,當(dāng)C++版本高于C++17時,emplace_back
返回當(dāng)前插入的值的引用,而push_back
返回void
。面試官:
erase
和remove
有什么區(qū)別?二師兄:
erase
屬于成員函數(shù),erase
刪除了元素,remove
屬于算法庫函數(shù),而remove
只會把元素移動到尾部。面試官:哪些情況下迭代器會失效?
二師兄:迭代器失效主要有兩種情況引起:1.插入數(shù)據(jù)。由于插入數(shù)據(jù)可能導(dǎo)致數(shù)據(jù)搬移(
size > capacity
),所以迭代器失效。2.刪除數(shù)據(jù)。當(dāng)使用erase
刪除數(shù)據(jù)時,被刪除數(shù)據(jù)后面的數(shù)據(jù)依次向前移一位。這會導(dǎo)致被刪除數(shù)據(jù)之后的迭代器失效。面試官:如何快速的清空
vector
容器并釋放vector
容器所占用的內(nèi)存?二師兄:有兩種方法:第一種,使用
clear
方法清空所有元素。然后使用shrink_to_fit
方法把capacity
和size(0)
對齊,達(dá)到釋放內(nèi)存的作用:
#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交換,臨時量會立即析構(gòu)
std::cout << vi.size() << " " << vi.capacity() << std::endl; //0 0
}
面試官:你知道
vector<bool>
是如何實(shí)現(xiàn)的嗎?二師兄:
vector<bool>
的實(shí)現(xiàn)和其他實(shí)現(xiàn)容器的實(shí)現(xiàn)不一致。每個元素被當(dāng)作一個位而不是一個字節(jié)存儲。這導(dǎo)致我們不能直接訪問該元素,也無法對每個元素取地址(8
個元素可能在同一個字節(jié)中存儲)。所以不建議使用vector<bool>
,必要時可以使用std::bitset
替代。面試官:好的,回去等通知吧。
今天二師兄表現(xiàn)不錯,同時要感謝小伙伴的耐心閱讀。讓我們一起期待明天二師兄的面試之旅吧。文章來源:http://www.zghlxwxcb.cn/news/detail-497242.html
關(guān)注我,帶你21天“精通”C++?。ü奉^)文章來源地址http://www.zghlxwxcb.cn/news/detail-497242.html
到了這里,關(guān)于C++面試八股文:std::vector了解嗎?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!