某日二师兄参加XXX科技公司的C++工程师开发岗位第23面:

面试官:vector了解吗?

二师兄:嗯,用过。

面试官:那你知道vector底层是如何实现的吗?

二师兄:vector底层使用动态数组来存储元素对象,同时使用sizecapacity记录当前元素的数量和当前动态数组的容量。如果持续的push_back(emplace_back)元素,当size大于capacity时,需要开辟一块更大的动态数组,并把旧动态数组上的元素搬移到当前动态数组,然后销毁旧的动态数组。

面试官:你知道新开辟的动态数组的容量是就数组的多少倍比较合适?

二师兄:这个值在不同的编译器上不是固定的。MSVC 是1.5,而GCC是2。

面试官:有没有什么好的办法提升vector连续插入效率?

二师兄:有的,如果知道数据的大概量,我们可以使用reserve方法直接为vector扩容这个量级。这样在后续的数据插入时就不会因为频繁的capacity被用尽而导致的多次的数据搬移,从而提升vector插入效率。

面试官:push_backemplace_back有什么区别?

二师兄:两者都可以在容器尾部插入元素。在GCC中,如果插入的元素是右值,两者都会move元素到容器。如果是左值,两者都会copy元素到容器。唯一不同的一点是,当C++版本高于C++17时,emplace_back返回当前插入的值的引用,而push_back返回void

面试官:eraseremove有什么区别?

二师兄:erase属于成员函数,erase删除了元素,remove属于算法库函数,而remove只会把元素移动到尾部。

面试官:哪些情况下迭代器会失效?

二师兄:迭代器失效主要有两种情况引起:1.插入数据。由于插入数据可能导致数据搬移(size > capacity),所以迭代器失效。2.删除数据。当使用erase删除数据时,被删除数据后面的数据依次向前移一位。这会导致被删除数据之后的迭代器失效。

面试官:如何快速的清空vector容器并释放vector容器所占用的内存?

二师兄:有两种方法:第一种,使用clear方法清空所有元素。然后使用shrink_to_fit方法把capacitysize(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++!(狗头)

C++面试八股文:std::vector了解吗?的更多相关文章

  1. c++转载系列 std::vector模板库用法介绍

    来源:http://blog.csdn.net/phoebin/article/details/3864590 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作 ...

  2. C++ 中的std::vector介绍(转)

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...

  3. std::vector介绍

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...

  4. std::vector<Channel2*> m_allChannels;容器,以及如何根据channelid的意义

    std::vector<Channel2*> m_allChannels;容器,以及如何根据channelid的意义 这个容器保存了所有客户端连接的channel Channel2* Li ...

  5. std::vector数据复制

    std::vector<boost::shared_ptr <ITEM> > srcItemList;  // 数据源 std::vector<ITEM>  des ...

  6. 单独删除std::vector <std::vector<string> > 的所有元素

    下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...

  7. std::vector的分片拷贝和插入

    一般我们在用Qt的QByteArrary或者List的时候,会有相应的append的方法,该函数,就是把数据加入末尾.但是std::vector就没有相应的方法.但是我们可以用insert方法来实现: ...

  8. 使用std::vector优化点云动画显示一例

    1. 准备 使用std::vector应该知道几点: (1)内存连续的容器,有点像数组 (2)与std::list相比,插入和删除元素比较慢- 因为数据迁移 (3)添加元素可能会引发内存分配和数据迁移 ...

  9. 随机排序std::vector,扑克牌,麻将类尤其合用

    有些需要重新对std::vector对象重新排序,特别是游戏,例如说:扑克牌,麻将,抽奖等,C++标准已经为std::vector写好了随机排序的方式,这里做个笔记: #include <alg ...

  10. (原创)动态内存管理练习 C++ std::vector<int> 模拟实现

    今天看了primer C++的 “动态内存管理类”章节,里面的例子是模拟实现std::vector<std::string>的功能. 照抄之后发现编译不通过,有个库函数调用错误,就参考着自 ...

随机推荐

  1. 二进制安装Kubernetes(k8s)IPv4/IPv6双栈 v1.24.0

    二进制安装Kubernetes(k8s) v1.24.0 IPv4/IPv6双栈 介绍 kubernetes二进制安装 1.23.3 和 1.23.4 和 1.23.5 和 1.23.6 和 1.24 ...

  2. 有关idea的使用部分

    出现相关异常,提示类似粗在idea找不到相关的包加载失败. 执行mvn命令 mvn -U idea:idea 含义更新重新加载idea工程的相关jar

  3. [ORACLE]Oracle客户端SQLPlus安装与运用

    简述 sqlplus :oracle公司提供用户操作oracle数据库的工具. sqlplus是oracle原始数据操作的客户端,这种命令行的格式有着强大的逻辑性,如果经常使用会对数据库的理解加深很多 ...

  4. AtCoder Beginner Contest 061 - D Score Attack

    给定一张边带权的有向图.从节点\(1\)出发,每经过一条边一次,得分加上这条边的边权.(可以多次经过,多次累加 必须在点\(n\)结束游戏 判断是否能使得分无限大,如果否,求最大得分. sol 题目所 ...

  5. 【Diary】CSP-J 2019 游记

    大废话游记. CSP-J1 Day-1 写13年的初赛题.感觉挺简单.但是问题求解第二问数数数错了,加上各种sb错误,只写了八十几分... 然后跑去机房问,那个相同球放相同袋子的题有没有数学做法. 没 ...

  6. Activity中的setContentView(R.layout.xxx)源码分析

    点进去会看到下图: 其中getWindow()是获取到Window类的唯一子类PhoneWindow的对象 找到PhoneWindow的setContentView()方法点进去: 1 @Overri ...

  7. MySQL(十)表空间结构:区、段与碎片区

    表空间结构:区.段与碎片区 为什么要有区? ​ B+树中的每一层的页都会形成一个双向链表,双向链表之间的物理位置可能会离得非常远,当遇到范围查询的适用场景的时候,就会定位到最左边和最右边的记录,然后沿 ...

  8. elasticsearch升级和索引重建。

    1.背景描述   2020年团队决定对elasticsearch升级.es(elasticsearch缩写,下同)当前版本为0.9x,升级到5.x版本.es在本公司承载三个部分的业务,站内查询,订单数 ...

  9. SpringBoot整合EMQ

    1.引入依赖 <dependency> <groupId>org.eclipse.paho</groupId> <artifactId>org.ecli ...

  10. Kubernetes中使用Helm2的安全风险

    参考 http://rui0.cn/archives/1573 英文文章  https://blog.ropnop.com/attacking-default-installs-of-helm-on- ...