面试题总结(三)、《STL源码剖析》相关面试题总结
2015-08-25 18:54
323 查看
声明:本文主要探讨与STL实现相关的面试题,主要参考侯捷的《STL源码剖析》,每一个知识点讨论力求简洁,便于记忆,但讨论深度有限,如要深入研究可点击参考链接,希望对正在找工作的同学有点帮助。
一、STL简介
STL提供六大组件,彼此可以组合套用:
- 容器
容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template。
- 算法
各种常见算法,如sort,search,copy,erase等,我觉得其中比较值得学习的就是sort,next_permutation,partition,merge sort,从实现角度看,STL算法是一种function template。 - 迭代器
扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。共有五种类型,从实现角度看,迭代器是一种将operator*,operator->,operator++,operator--等指针相关操作予以重载的class template。所有STL容器都附带有自己专属的迭代器,只有容器设计者才知道如何设计迭代器。原生指针也是一种迭代器。是设计模式的一种,所以被问到了解的设计模式可以用来凑数。 - 仿函数
行为类函数,可作为算法的某种策略,从实现角度看,仿函数是一种重载了operator()的class或class template。一般函数指针可视为狭义的仿函数。 - 配接器
一种用来修饰容器或者仿函数或迭代器接口的东西。比如queue和stack,看着像容器,其实就是deque包了一层皮。 - 配置器
负责空间配置与管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放额class template。
二、关于容器的一些问题
2.1 当vector的内存用完了,它是如何动态扩展内存的?它是怎么释放内存的?用clear可以释放掉内存吗?是不是线程安全的?
- vector内存用完了,会以当前size大小重新申请2*size的内存,然后把原来的元素复制过去,把新元素插上,然后释放原来的内存。
- 一般我们释放vector里的元素使用clear,其实它不能释放内存,要想释放内存要使用swap,这样:
[ol][li][code]vector<type> v;
//.... 这里删除v中的许多元素
vector<type>(v).swap(v);
//此时v的容量已经尽可能的符合其当前包含的元素数量
//对于string则可能像下面这样
string(s).swap(s);
//.... 这里添加许多元素给v[/li]
2.2 map是怎么实现的?查找的复杂度是多少?能不能边遍历边插入?
红黑树和散列
O(logn)
不可以,map不像vector,它在对容器执行erase操作后不会返回后一个元素的迭代器,所以不能遍历地往后删除。
2.3 写多读少应该用什么容器?
私以为是链表,链表的插入操作时常数时间复杂度,访问操作是O(n),是最适合写多读少的容器。
2.4 vector每次insert或erase之后,以前保存的iterator会不会失效?
理论上会失效,理论上每次insert或者erase之后,所有的迭代器就重新计算的,所以都可以看作会失效,原则上是不能使用过期的内存
但是vector一般底层是用数组实现的,我们仔细考虑数组的特性,不难得出另一个结论,
insert时,假设insert位置在p,分两种情况:
a) 容器还有空余空间,不重新分配内存,那么p之前的迭代器都有效,p之后的迭代器都失效
b) 容器重新分配了内存,那么p之后的迭代器都无效咯erase时,假设erase位置在p,则p之前的迭代器都有效并且p指向下一个元素位置(如果之前p在尾巴上,则p指向无效尾end),p之后的迭代器都无效
2.5 hash_map和map的区别在哪里?
hash_map底层是散列的所以理论上操作的平均复杂度是常数时间,map底层是红黑树,理论上平均复杂度是O(logn),下面是借鉴的网上的总结:
这里总结一下,选用map还是hash_map,关键是看关键字查询操作次数,以及你所需要保证的是查询总体时间还是单个查询的时间。如果是要很多次操作,要求其整体效率,那么使用hash_map,平均处理时间短。如果是少数次的操作,使用 hash_map可能造成不确定的O(N),那么使用平均处理时间相对较慢、单次处理时间恒定的map,考虑整体稳定性应该要高于整体效率,因为前提在操作次数较少。如果在一次流程中,使用hash_map的少数操作产生一个最坏情况O(N),那么hash_map的优势也因此丧尽了。
2.6 为何map和set不能像vector一样有个reserve函数来预分配数据?
[p]map和set内部存储的已经不是元素本身了,而是包含元素的节点。也就是说map内部使用的Alloc并不是map声明的时候从参数中传入的Alloc。例如:map
相关文章推荐
- 黑马程序员——Collection
- Java多线程面试问题集锦
- 百度面试题 求比N大的最小“不重复数”
- 剑指offer面试题28-字符串的排列
- 剑指offer面试题27-二叉搜索树转双向链表
- 程序员的年龄天花板
- 黑马程序员—————Java基础--------异常
- 黑马程序员 -学习笔记-垃圾回收
- java字节中的基本类型的职业的数目 (采访总是问)
- 机器学习算法面试—口述(4):决策树
- 黑马程序员--OC学习篇之Foundation框架中的NSArray对象和NSMutableArray对象
- 程序员笔试面试要点
- 让程序员跳槽的非钱原因
- 黑马程序员——Java基础---String类和对象包装类
- 黑马程序员——28,反射
- 程序员的年龄天花板
- 【黑马程序员】Block
- 黑马程序员—IOS基础视频—多态点语法类对象
- 黑马程序员—IOS加强视频—foundation框架
- 百度面试题 运用递归求最大重复数