C++STL基础面试题总结


1.STL六大组件?

    容器,迭代器,算法,仿函数,空间配置器,容器配接器。

2.简单介绍vector?
    vector 动态数组,支持随机访问,但是插入删除效率低,因为内存连续分配,插入删除将可能使迭代器失效。当分配的内存空间不足时,开辟之前的内存空间的若干倍(通常是2倍或1.5倍),将原先内存中的数据拷贝移动到新开辟的内存空间中。

3.简单介绍list?
    list 双向链表,内存不连续分配,故不支持随机访问,插入删除效率高,但是查找效率低。

4.简单介绍deque?
    deque 双端队列,支持随机访问,底层存储机制较为复杂,由若干连续小段空间通过指针连接而成,由中央控制器map(不是容器的map)统一管理。由于特殊存储机制,迭代器的实现较为复杂,故效率略低。

5.简单介绍map?
    map/multiset 映射,关联容器。每个键映射一个值,底层数据结构由红黑树实现,每次插入删除只会影响当前节点的内存分配(开辟/释放),所以map的插入删除效率比用其他序列容器高。但是由于内部存储的已经不是元素本身(例如还要存子节点地址,父亲节点地址,节点颜色等),导致不能像vector一样预分配内存空间。Set同理。

6.map与multimap的区别?
    multimap同map的区别就是multiset键可以重复而map键不能重复。

7.简单介绍红黑树?
    红黑树虽然相比AVL树要求两颗子树的高度差的绝对值小于等于1的严格平衡二叉树来说没有那么严格,但是仍然可以保证根节点出发的简单路径中最长的那条路径长度小于等于最短的那条的两倍。
    这是由其性质决定:
    1.节点颜色由红色和黑色组成
    2.根节点必须为黑色
    3.叶子节点全为黑色并且是null节点
    4.红色节点的儿子不能是红色
    5.任意一个节点到叶子节点的所有简单路径中黑色节点的个数相同。
    具体每次插入和删除通过旋转和变色来维护这些性质,由于每次旋转次数稳定,故性能较AVL树好。

8.简单介绍set/multiset?
    set/multiset 集合,关联容器。值就是键,底层也由红黑树实现。multiset的键可以重复而set不能。

9.简单介绍Unorder_map/unordered_set?
    Unordered_map由哈希桶实现,利用链地址法解决冲突。内部没有按照键或值的任何顺序进行排序,而实根据散列值组织成桶允许通过键直接访问单个元素,均摊时间复杂度为常数级别。unorder_set除了值就是键以外和unordered_map大体相同。

10.SGI Stl的内存分配方式?
    SGI设计了两层的配置器,也就是第一级配置器和第二级配置器,默认使用第二级配置器。第一级配置器直接调用malloc和free来分配释放内存。第二级配置器:根据情况来判定,如果用户需要的区块大于128,则直接调用第一级配置器;如果用户需要的区块小于128,则到自由链表中去查找。若自由链表中对应位置没有内存块,那么就向内存池中申请内存块。

11.为什么需要优化和内存池等细节?
    1)频繁使用malloc、free开辟释放小块内存带来的性能效率低下。
    2)内存碎片,导致不连续的内存不可用的资源浪费。

12.为什么vector的插入操作可能会导致迭代器失效?
    vector动态增加大小时,并不是在原空间后增加新的空间,而是以原大小的两倍在另外配置一片较大的新空间,然后将内容拷贝过来,并释放原来的空间。由于操作改变了空间,所以迭代器失效。

13.不允许有遍历行为的容器有哪些(不提供迭代器)?
    1)queue,除了头部外,没有其他方法存取deque的其他元素。
    2)stack(底层以deque实现),除了最顶端外,没有任何其他方法可以存取stack的其他元素。
    3)heap,所有元素都必须遵循特别的排序规则,不提供遍历功能。

14.STL容器的参数allocate是用来做什么的?
    分配器用于封装STL容器在内存管理上的低层细节。

15.vector中erase方法与algorithm中的remove方法区别?以及size()和capacity()的区别?
    vector中erase方法真正删除了元素,迭代器不能访问了。而remove()是STL中的一个算法,对一个容器调用remove并不会改变容器中的元素个数。remove只是简单地将元素移到了容器的最后面,并不会真正的删除该元素,迭代器还是可以访问到。因为algorithm通过迭代器进行操作,不知道容器的内部结构,所以无法进行真正的删除。
    Size()返回当前容器拥有的元素个数。而capacity返回在容器扩容之前可以存储的元素个数。

16.为何map和set的插入删除效率比其他序列容器高?
    因为不需要内存的移动和拷贝。

17.为何map和set每次Insert之后,以前保存的iterator不会失效?
    因为每次插入删除会动态开辟释放内存空间,只有当前变化的节点iterator失效,之前保存的iterator由于内存空间未发生变化所以并不会失效。

18.map能不能边遍历边删除?
    不可以,因为map删除了一个元素之后该元素对应节点的迭代器失效,且erase并不返回下一个元素的迭代器。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM