首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
那我爱妮妮三千遍
上海理工大学 C++
发布于上海
关注
已关注
取消关注
@IaiY:
【图解八股-C/C++⑤-STL】
  作者简介和专栏内容见专栏介绍:https://www.nowcoder.com/creation/manager/columnDetail/0eL5bM  麻烦看到贴子的伙伴点点赞大家点赞订阅支持下,提前祝各位offer多多,有问题评论区见~~  图解版    STL  什么是STL?   C++ STL从广义来讲包括了三类:算法,容器和迭代器。      算法包括排序,复制等常用算法,以及不同容器特定的算法。    容器就是数据的存放形式,包括序列式容器和关联式容器,序列式容器就是list,vector等,关联式容器就是set,map等。    迭代器就是在不暴露容器内部结构的情况下对容器的遍历。    解释一下什么是trivial destructor   “trivial destructor”一般是指用户没有自定义析构函数,而由系统生成的,这种析构函数在《STL源码解析》中成为“无关痛痒”的析构函数。  迭代器:++it、it++哪个好,为什么  1) 前置返回一个引用,后置返回一个对象  2) 前置不会产生临时对象,后置必须产生临时对象,临时对象会导致效率降低  STL迭代器如何实现   1、 迭代器是一种抽象的设计理念,通过迭代器可以在不了解容器内部原理的情况下遍历容器,除此之外,STL中迭代器一个最重要的作用就是作为容器与STL算法的粘合剂。   2、 迭代器的作用就是提供一个遍历容器内部所有元素的接口,因此迭代器内部必须保存一个与容器相关联的指针,然后重载各种运算操作来遍历,其中最重要的是*运算符与->运算符,以及++、--等可能需要重载的运算符重载。这和C++中的智能指针很像,智能指针也是将一个指针封装,然后通过引用计数或是其他方法完成自动释放内存的功能。   3、最常用的迭代器的相应型别有五种:value type、difference type、pointer、reference、iterator catagoly;  STL中迭代器失效的情况有哪些?   以vector为例:   插入元素:   1、尾后插入:size < capacity时,首迭代器不失效尾迭代失效(未重新分配空间),size == capacity时,所有迭代器均失效(需要重新分配空间)。   2、中间插入:中间插入:size < capacity时,首迭代器不失效但插入元素之后所有迭代器失效,size ==capacity时,所有迭代器均失效。   133删除元素:   尾后删除:只有尾迭代失效。   中间删除:删除位置之后所有迭代失效。    deque 和 vector 的情况类似, 而list双向链表每一个节点内存不连续, 删除节点仅当前迭代器失效,erase返回下一个有效迭代器;map/set等关联容器底层是红黑树删除节点不会影响其他节点的迭代器, 使用递增方法获取下一个迭代器 mp.erase(iter++);   unordered_(hash) 迭代器意义不大, rehash之后, 迭代器应该也是全部失效.   STL中hashtable的实现?  STL中的hashtable使用的是开链法解决hash冲突问题的。  hashtable中的bucket所维护的list既不是list也不是slist,而是其自己定义的由hashtable_node数据结构组成的linked-list,而bucket聚合体本身使用vector进行存储。hashtable的迭代器只提供前进操作,不提供后退操作   在hashtable设计bucket的数量上,其内置了28个质数[53, 97, 193,...,429496729],在创建hashtable时,会根据存入的元素个数选择大于等于元素个数的质数作为hashtable的容量(vector的长度),其中每个bucket所维护的linked-list长度也等于hashtable的容量。如果插入hashtable的元素个数超过了bucket的容量,就要进行重建table操作,即找出下一个质数,创建新的buckets vector,重新计算元素在新hashtable的位置。  STL中hash_map扩容发生什么?   1) hash table表格内的元素称为桶(bucket),而由桶所链接的元素称为节点(node),其中存入桶元素的容器为stl本身很重要的一种序列式容器——vector容器。之所以选择vector为存放桶元素的基础容器,主要是因为vector容器本身具有动态扩容能力,无需人工干预。   2) 向前操作:首先尝试从目前所指的节点出发,前进一个位置(节点),由于节点被安置于list内,所以利用节点的next指针即可轻易完成前进操作,如果目前正巧是list的尾端,就跳至下一个bucket身上,那正是指向下一个list的头部节点。  简单说一下traits技法   traits技法利用“内嵌型别“的编程技巧与编译器的template参数推导功能,增强C++未能提供的关于型别认证方面的能力。常用的有iterator_traits和type_traits。   iterator_traits   被称为特性萃取机,能够方面的让外界获取以下5中型别:      value_type:迭代器所指对象的型别    difference_type:两个迭代器之间的距离 、   pointer:迭代器所指向的型别    reference:迭代器所引用的型别    iterator_category:三两句说不清楚,建议看书     type_traits   关注的是型别的特性,例如这个型别是否具备non-trivial defalt ctor(默认构造函数)、non-trivial copyctor(拷贝构造函数)、non-trivial assignment operator(赋值运算符)和non-trivial dtor(析构函数),如果答案是否定的,可以采取直接操作内存的方式提高效率,一般来说,type_traits支持以下5中类型的判断  __type_traits<T>::has_trivial_default_constructor__type_traits<T>::has_trivial_copy_constructor__type_traits<T>::has_trivial_assignment_operator__type_traits<T>::has_trivial_destructor__type_traits<T>::is_POD_type  STL中的allocator、deallocator   1) 第一级配置器直接使用malloc()、free()和relloc(),第二级配置器视情况采用不同的策略:当配置区块超过128bytes时,视之为足够大,便调用第一级配置器;当配置器区块小于128bytes时,为了降低额外负担,使用复杂的内存池整理方式,而不再用一级配置器;   2) 第二级配置器主动将任何小额区块的内存需求量上调至8的倍数,并维护16个free-list,各自管理大小为8~128bytes的小额区块;   3) 空间配置函数allocate(),首先判断区块大小,大于128就直接调用第一级配置器,小于128时就检查对应的free-list。如果free-list之内有可用区块,就直接拿来用,如果没有可用区块,就将区块大小调整至8的倍数,然后调用refill(),为free-list重新分配空间;   4) 空间释放函数deallocate(),该函数首先判断区块大小,大于128bytes时,直接调用一级配置器,小于128bytes就找到对应的free-list然后释放内存。  STL的两级空间配置器   1、首先明白为什么需要二级空间配置器?      我们知道动态开辟内存时,要在堆上申请,但若是我们需要频繁的在堆开辟释放内存,则就会在堆上造成很多外部碎片,浪费了内存空间;    每次都要进行调用malloc、free函数等操作,使空间就会增加一些附加信息,降低了空间利用率;    随着外部碎片增多,内存分配器在找不到合适内存情况下需要合并空闲块,浪费了时间,大大降低了效率。     于是就设置了二级空间配置器,当开辟内存<=128bytes时,即视为开辟小块内存,则调用二级空间配置器。关于STL中一级空间配置器和二级空间配置器的选择上,一般默认选择的为二级空间配置器。 如果大于128字节再转去一级配置器器。   一级配置器   一级空间配置器中重要的函数就是allocate、deallocate、reallocate 。 一级空间配置器是以malloc(),free(),realloc()等C函数执行实际的内存配置 。大致过程是:   1、直接allocate分配内存,其实就是malloc来分配内存,成功则直接返回,失败就调用处理函数   2、如果用户自定义了内存分配失败的处理函数就调用,没有的话就返回异常   3、如果自定义了处理函数就进行处理,完事再继续分配试试   二级配置器  1、维护16条链表,分别是0-15号链表,最小8字节,以8字节逐渐递增,最大128字节,你传入一个字节参数,表示你需要多大的内存,会自动帮你校对到第几号链表(如需要13bytes空间,我们会给它分配16bytes大小),在找到第n个链表后查看链表是否为空,如果不为空直接从对应的free_list中拔出,将已经拨出的指针向后移动一位。   2、对应的free_list为空,先看其内存池是不是空时,如果内存池不为空:   (1)先检验它剩余空间是否够20个节点大小(即所需内存大小(提升后) * 20),若足够则直接从内存池中拿出20个节点大小空间,将其中一个分配给用户使用,另外19个当作自由链表中的区块挂在相应的free_list下,这样下次再有相同大小的内存需求时,可直接拨出。   (2)如果不够20个节点大小,则看它是否能满足1个节点大小,如果够的话则直接拿出一个分配给用户,然后从剩余的空间中分配尽可能多的节点挂在相应的free_list中。   (3)如果连一个节点内存都不能满足的话,则将内存池中剩余的空间挂在相应的free_list中(找到相应的free_list),然后再给内存池申请内存,转到3。   3、内存池为空,申请内存   此时二级空间配置器会使用malloc()从heap上申请内存,(一次所申请的内存大小为2 * 所需节点内存大小(提升后)* 20 + 一段额外空间),申请40块,一半拿来用,一半放内存池中。   4、malloc没有成功   在第三种情况下,如果malloc()失败了,说明heap上没有足够空间分配给我们了,这时,二级空间配置器会从比所需节点空间大的free_list中一一搜索,从比它所需节点空间大的free_list中拔除一个节点来使用。如果这也没找到,说明比其大的free_list中都没有自由区块了,那就要调用一级适配器了。   释放时调用deallocate()函数,若释放的n>128,则调用一级空间配置器,否则就直接将内存块挂上自由链表的合适位置。   STL二级空间配置器虽然解决了外部碎片与提高了效率,但它同时增加了一些缺点:   1.因为自由链表的管理问题,它会把我们需求的内存块自动提升为8的倍数,这时若你需要1个字节,它会给你8个字节,即浪费了7个字节,所以它又引入了内部碎片的问题,若相似情况出现很多次,就会造成很多内部碎片;   2.二级空间配置器是在堆上申请大块的狭义内存池,然后用自由链表管理,供现在使用,在程序执行过程中,它将申请的内存一块一块都挂在自由链表上,即不会还给操作系统,并且它的实现中所有成员全是静态的,所以它申请的所有内存只有在进程结束才会释放内存,还给操作系统,由此带来的问题有:   1.即我不断的开辟小块内存,最后整个堆上的空间都被挂在自由链表上,若我想开辟大块内存就会失败;  2.若自由链表上挂很多内存块没有被使用,当前进程又占着内存不释放,这时别的进程在堆上申请不到空间,也不可以使用当前进程的空闲内存,由此就会引发多种问题。  常见容器性质总结?   1.vector 底层数据结构为数组 ,支持快速随机访问   2.list 底层数据结构为双向链表,支持快速增删   3.deque 底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问   deque是一个双端队列(double-ended queue),也是在堆中保存内容的.它的保存形式如下:   [堆1] --> [堆2] -->[堆3] --> ...   每个堆保存好几个元素,然后堆和堆之间有指针指向,看起来像是list和vector的结合品.   4.stack 底层一般用list或deque实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时   5.queue 底层一般用list或deque实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时(stack和queue其实是适配器,而不叫容器,因为是对容器的再封装)   6.priority_queue 的底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现   7.set 底层数据结构为红黑树,有序,不重复   8.multiset 底层数据结构为红黑树,有序,可重复   9.map 底层数据结构为红黑树,有序,不重复   10.multimap 底层数据结构为红黑树,有序,可重复   11.unordered_set 底层数据结构为hash表,无序,不重复   12.unordered_multiset 底层数据结构为hash表,无序,可重复  13.unordered_map 底层数据结构为hash表,无序,不重复   14.unordered_multimap 底层数据结构为hash表,无序,可重复  vector与list的区别与应用?怎么找某vector或者list的倒数第二个元素   1) vector数据结构   vector和数组类似,拥有一段连续的内存空间,并且起始地址不变。因此能高效的进行随机存取,时间复杂度为o(1);但因为内存空间是连续的,所以在进行插入和删除操作时,会造成内存块的拷贝,时间复杂度为o(n)。另外,当数组中内存空间不够时,会重新申请一块内存空间并进行内存拷贝。连续存储结构:vector是可以实现动态增长的对象数组,支持对数组高效率的访问和在数组尾端的删除和插入操作,在中间和头部删除和插入相对不易,需要挪动大量的数据。它与数组最大的区别就是vector不需程序员自己去考虑容量问题,库
点赞 0
评论 0
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
10-30 14:25
北京科技大学 算法工程师
没有什么可以失去的
投了那么久的互联网大厂一直无回应,已经快要习惯这种“悬而未决”的状态了,我没有放弃机会,还在找。。。刷到一篇帖子,说今年上半年,互联网行业跳槽的人里面,超过一半都流向了其他行业,其中新能源就吸纳了不少人,ok,知道了,露头就秒。新能源、智能制造业其实正缺人吧,其实还刷到蛮多拿爱玛offer的帖子,爱玛,多我一个也不多吧,已经连夜改简历了,莫辜负是啊,我即将毕业,我还没有拥有任何东西,我也并没有什么可以失去的,那么就轻装上阵吧~
soarin:
悬而未决继续找是对的,但是自我怀疑和焦虑真的很难沉下心好好学习……已老实
点赞
评论
收藏
分享
10-29 22:15
已编辑
武汉纺织大学 C++
双非本硕(普通一本),想找工作很迷茫,想请各位指点一下
最近刚忙完小论文的事情。想开始找工作,目前来说没有什么经验。意向是未来想找个靠近硬件或者底层这方面的工作。个人的话,是应届生,竞赛只有蓝桥杯和计算机能力挑战赛的省三,有一个软考中级(软件设计师)的证书,四六级都过了,项目经历目前还没有,有一篇一区top论文(应该对找工作没有用),拿了研究生国家奖学金,并不准备考公或者读博。主要有下面几点疑问想请各位指点一下:①目前是想对C++进行学习(以前有一定的C++的基础),现在开始,寒假前想找个实习准备明年春招的话来得及吗;②如果冲着意向岗位(硬件或者底层这方面的工作),一般要学习哪方面的知识;③我现在项目经历为空,如果想找一个实习,尝试性的投一些工作简...
我的求职思考
点赞
评论
收藏
分享
09-29 14:18
已编辑
百度_高级研发工程师
哪些公司对双非友好
求助,帮我妹妹优化一下简历,妹妹今年大四,明年毕业,双非一本。想在沈阳或者大连找个工作,目前目标是运营岗,我这搞开发的也不太懂,大家给提提意见
职场水母:
大舅哥,你这话说的,咱妹的事就是我的事
,简历有很多问题,可以加咱妹微信,我跟她细说
哪些公司对双非友好
点赞
评论
收藏
分享
09-05 18:38
桂林电子科技大学 安卓
滴滴转正意向
同部门的同学上午十点半都收到意向了,我死活没收到,还好没离职,Dc轰炸hr。hr又发了三遍还是死活没收到。感觉是qq邮箱把我offer吞了,正在和hr battle ,ld把纸质的给我发过来了(还是提醒一下秋招的同学,不知道是不是qq邮箱的问题,竟然会吞邮件,平时还是多注意一下吧)
请hr大人把offe...:
看来我的QQ邮箱也坏了
点赞
评论
收藏
分享
10-27 20:46
西安交通大学 机械工程师
机械秋招的强势版本是啥样?
在经历这次秋招之后发现轻轻松松拿到很好offer的机械友友还是有很多经验可以参考的,当时早点了解的话可以会有少走很多弯路,来源为周围的大佬,也欢迎各位佬互相交流1 强势项目是核心 硕士强势项目:这个阶段硕士强势项目应该是电机,包括电机结构和磁力仿真等等,硕士电机加上本科的rm或者一些丰富的比赛实物经验对于大多数硬件厂来说简直无敌,尤其是大疆影石或者机器人这类,去做电机结构会比普通结构好很多。(大多数没得电机项目可以选的情况下,参考下面的项目分析) 本科强势项目:RM,RC在深圳的很多疆系公司,甚至宇树云深处这类机器人企业很受欢迎,如果有机会的话可以深度参与一下,同时项目完成与表现形式需要显得非...
机械求职避坑tips
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
造谣刑法老师媚男,反被老师法院起诉
1.3W
2
...
现在出海,是不是相当于十年前加入互联网?
1.1W
3
...
如果你的实习能重来一遍,如何让自己的实习利益最大化
8697
4
...
你们说,人会一直倒霉吗?
6306
5
...
秋招小失败-后端小小劝退(大结局)
6125
6
...
抖音文娱二面挂面经-劝退后端第三天
5594
7
...
一个大专学历15年IT之路的感悟
4134
8
...
什么,你在教我做事?
3736
9
...
月薪1W在老家直接躺赢
2950
10
...
9本秋招后端收获9+offer, 我做对了什么?
2944
创作者周榜
更多
正在热议
更多
#
校招生月薪1W算什么水平
#
27145次浏览
169人参与
#
硬件人的简历怎么写
#
311625次浏览
3057人参与
#
“vivo”个offer
#
36409次浏览
277人参与
#
我是面试官,请用一句话让我破防
#
22862次浏览
117人参与
#
工作后明白的那些道理
#
20839次浏览
220人参与
#
如果上班像打游戏,你最想解锁什么技能
#
6968次浏览
67人参与
#
中美关税战对我们有哪些影响
#
41296次浏览
350人参与
#
中美关系回暖,你会选择出海吗?
#
4754次浏览
94人参与
#
AI时代,哪些岗位最容易被淘汰
#
2574次浏览
27人参与
#
华为保温
#
105981次浏览
403人参与
#
机械人,签完三方你在忙什么?
#
65553次浏览
244人参与
#
第一份工作应该只看薪资吗
#
192107次浏览
1687人参与
#
牛友们,签完三方你在忙什么?
#
119758次浏览
958人参与
#
哪些行业值得去?
#
4429次浏览
46人参与
#
金融财经春招备战日记
#
38585次浏览
210人参与
#
i人适合做什么工作
#
9864次浏览
88人参与
#
如果秋招能重来,我会____
#
34212次浏览
283人参与
#
美团开奖
#
208539次浏览
1100人参与
#
国央企笔面经互助
#
160983次浏览
1182人参与
#
读研or工作,哪个性价比更高?
#
76970次浏览
767人参与
#
华为池子有多大
#
109449次浏览
750人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务