社招面试总结之顺利上岸
Posted TiWalker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了社招面试总结之顺利上岸相关的知识,希望对你有一定的参考价值。
- 智能指针都了解哪些,shared_ptr是否是线程安全的。
智能指针,本质上是对资源所有权和生命周期管理的抽象:
- 当资源是被独占时,使用 std::unique_ptr 对资源进行管理。
- 当资源会被共享时,使用 std::shared_ptr 对资源进行管理。
- 使用 std::weak_ptr 作为 std::shared_ptr 管理对象的观察者。
- 通过继承 std::enable_shared_from_this 来获取 this 的 std::shared_ptr 对象。
当我们谈论shared_ptr的线程安全性时,我们在谈论什么 - 云+社区 - 腾讯云 (tencent.com)
2. 完美转发
std::forward被称为完美转发不
std::move
3. lambda与函数指针、std::function的区别在哪里
从上面可以看到std::function的使用方法,当给std::function填入合适的参数表和返回值后,它就变成了可以容纳所有这一类调用方式的函数封装器。std::function还可以用作回调函数,或者在C++里如果需要使用回调那就一定要使用std::function,特别方便,这方面的使用方式大家可以读下我之前写的关于线程池和定时器相关的文章。
std::function和std::bind使得我们平时编程过程中封装函数更加的方便,而lambda表达式将这种方便发挥到了极致,可以在需要的时间就地定义匿名函数,不再需要定义类或者函数等,在自定义STL规则时候也非常方便,让代码更简洁,更灵活,提高开发效率。
4. auto是如何推到类型的
(C++14允许对一切函数与lambda表达式使用auto返回值做类型推导,当然了实际使用的是template类型推导的规则;C++11仅允许对单表达式的lambda使用)
如果我们希望返回形参的引用类型,使用auto并不适用,可以使用尾置类型或者decltype(auto)(这样推导将采用decltype规则),decltype(auto)同样适用于以往其他auto的使用场景
5. decltype是干什么的
decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。
泛型编程中结合auto,用于追踪函数的返回值类型
6. volatile的作用是什么
volatile修饰的变量要求系统每次重新从内存中读取其数据
作用有二:
- 不让编译器优化
- 不同线程之间的数据同步
7. 重载/重定义/覆盖三者的区别
重载:函数参数不同,或类型不同
覆盖:虚函数,子类覆盖父类
8. 类什么情况下必须使用成员列表进行初始化
如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数
9. const_cast/static_cast/dynamic_cast/reinterpret_cast之间的区别
const_cast:去除const属性
static_cast:基础类型之间的转换
dynamic_cast:父子类之间的转换
reinterpret_cast:重新解释,可以用于整数指针类似之间的转换
10. typeinfo是怎么在运行期间识别类型的
typeInfo与typeid简单总结说明:
和sizeof这类的操作符一样,typeid是C++的关键字之一。
typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件typeinfo中定义)
C++并没有规定typeid实现标准,各个编译器可能会不一样。
编译器会为每一种typeid操作的类型生成一份保存在数据段的type_info数据。
每种类型的type_info数据长度依赖于类型名称,至少9个字节。
10. map/unorder_map的主要区别
数据结构其实是两种类型最为根本的区别,其他的不同都是这种区别产生的结果。
- map是基于红黑树结构实现的。红黑树是一种平衡二叉查找树的变体结构,它的左右子树的高度差有可能会大于 1。所以红黑树不是严格意义上的平衡二叉树AVL,但对之进行平衡的代价相对于AVL较低, 其平均统计性能要强于AVL。红黑树具有自动排序的功能,因此它使得map也具有按键(key)排序的功能,因此在map中的元素排列都是有序的。在map中,红黑树的每个节点就代表一个元素,因此实现对map的增删改查,也就是相当于对红黑树的操作。对于这些操作的复杂度都为O(logn),复杂度即为红黑树的高度。
- unordered_map是基于哈希表(也叫散列表)实现的。散列表是根据关键码值而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。散列表使得unordered_map的插入和查询速度接近于O(1)(在没有冲突的情况下),但是其内部元素的排列顺序是无序的。
11. 迭代器失效的场景都有哪些
分为序列容器和关联容器。
vector迭代器失效问题总结
(1)当执行erase方法时,指向删除节点的迭代器全部失效,指向删除节点之后的全部迭代器也失效
(2)当进行push_back()方法时,end操作返回的迭代器肯定失效。
(3)当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
(4)当插入(push_back)一个元素后,如果空间未重新分配,指向插入位置之前的元素的迭代器仍然有效,但指向插入位置之后元素的迭代器全部失效。
deque迭代器失效总结:
(1)对于deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用都会失效,但是如果在首尾位置添加元素,迭代器会失效,但是指针和引用不会失效
(2)如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器全部失效
(3)在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。
对于关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。
12. 模板与宏的区别是什么
宏是在预处理阶段处理,模板是在编译阶段处理
宏不会进行类型检查,只会单纯的进行文本替换,模板会进行类型检查。比如下面代码模板就会出错,而宏不会
宏直接就可以产生代码,而编译器遇到模板定义时,并不产生代码,只有当模板实例化后时才会产生代码。
13、模板的特化是什么
函数模板的特化:当函数模板需要对某些类型进行特别处理,称为函数模板的特化。
类模板的特化:与函数模板类似,当类模板内需要对某些类型进行特别处理时,使用类模板的特化。
14、常见的内存置换算法都有哪些
常见的页面置换算法有以下几种:
最佳置换算法(Optimal,OPT)
先进先出页面置换算法(First In First Out,FIFO)
最近最久未使用( Least Recently Used,LRU)置换算法
第二次机会算法
时钟算法(clock)
改进时钟算法
最不常用算法(LFU,Least Frequently Used)
15、mmap与open的区别
在遇到大文件的时候,比如要对几百M或是几G 的文件进行编辑,直接将他们读取到内存中来编辑是不现实的,应为用户的堆栈空间是有限的,根本不可能这样来操作。这种时候就需要内存映射了。将文件映射到内存,它只是开辟了一块空间用来处理这个文件,实际上这块空间的大小并不是文件的大小,它只是开辟了一块空间来做数据交换。
使用mmap映射文件,这样可以向操作内存一样来操作文件,而且效率高;但是有一定的限制,
· 文件的长度必须大于等于映射的长度;
· 映射的offset必须是页(page)的整数倍;
16、什么是内存的内部碎片与外部碎片
内部碎片,申请的内存会按字节对齐,可能与实际的申请值要大,因此这就称为内部碎片。
外部碎片,指的是内存空白申请区可能太小,不能够重新分配,形成未使用的碎片。
17、工厂模式的几种简单分类
简单工厂:针对一种产品。缺点是破坏了开放,封闭原则。
工厂模式: 对简单工厂做了相应的改进,改正了简单工厂破坏开放封闭原则的错误。
抽象工厂:针对于多种产品,和简单工厂以及工厂模式并无太大的关联。
18、gdb条件断点怎么打
B breakpoint if
19、gdb如何只跟踪某一个线程
Thread
以上是关于社招面试总结之顺利上岸的主要内容,如果未能解决你的问题,请参考以下文章
字节面试社招《高频汇总之Android面试篇距离上岸的一步之遥》