昨天面试了一家公司,招的是分布式存储开发(不懂为什么会捞我),疯狂问底层的东西,我都不会,甚至在我思考后答题的时候,其中一个面试官笑了出来...感到无语,很想问你笑什么?(忍住了)
今天面试了海康,赞赞赞,面试体验非常非常的好,自信大增。下面记录一下我觉得答的不好的问题。
1. 析构函数为什么要用虚函数?
沉默了,其实最近有看深入理解C++对象模型, 但是没有思绪,真的没有...
看了网上答案,一下就理解了。
因为多态情况下,虚基指针指向派生的时候,析构函数如果不是虚函数,那么调用的就是基类的析构函数,假设你在需要在派生对象做一些数据清理工作,结果是派生对象的析构函数就不会调用。
2. 线程池有什么优点?
参考:https://blog.csdn.net/qq_40344790/article/details/131545279
1. 线程池的介绍
- 线程池是一种线程管理的概念,它主要用于优化多线程应用程序的性能和资源利用
- 因为在多线程中创建和销毁线程是一个开销较大的操作。
- 线程池通过预先创建一组线程,并将任务提供给这些线程来执行,从而避免了重复创建和销毁的开销。
- 线程池可以限制并发线程的数量,避免资源过度占用,从而更好地管理系统资源。
2. 线程池的组成
- 任务队列: 用于存储待执行的任务
- 线程池管理器: 负责创建,管理和调度线程池中的线程。
- 工作线程:执行任务的单位,它们会从工作队列拿任务进行执行。
3. 这个比较有意思
线程池的优化:
- 线程本地队列,每个线程有一个本地队列,向线程池提交任务时,优先考虑本地线程队列,没有的提交到全局队列
- 多量拉任务,本地队列空的时候可以一次性多拿点任务,防止多次去取任务耗时,竞争会耗时
- 窃取任务,当当前任务队列为空且全局任务队列为空的时候,考虑偷其他线程的任务,但是注意轮询也会花时间,可以考虑设置轮训的最长距离
- 检察者,用于检测线程池的性能,比如隔一段时间统计线程是否运行,是否忙碌,然后取按规则扩容线程。
- 减少copy,能move就move
2. 构造函数可以用虚函数吗?
首先,构造函数是不能为虚函数的 调用构造函数后, 才能生成一个对象
3. 单例怎么实现的?如果不用once_call,自己怎么实现?
单例模式的作用:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
私有化构造函数 、拷贝构造函数 、赋值运算符,防止多个实例被初始化
类内进行私有静态实例定义
几种实现:https://blog.csdn.net/unonoi/article/details/121138176
4. 工厂模式介绍一下?
没啥好讲的很简单
5. 常用的gcd的调试命令?
对应llldb
memory read
frame
bt
p
breakpoint
next
continue
6. 栈和堆的区别?
堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:
(1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;
(2)空间大小不同。每个进程拥有的栈的大小要远远小于堆的大小。理论上,程序员可申请的堆大小为虚拟内存的大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;
(3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。
(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由操作系统进行释放,无需我们手工实现。
(5)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。显然,堆的效率比栈要低得多。
(6)存放内容不同。栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等。当主函数调用另外一个函数的时候,要对当前函数执行断点进行保存,需要使用栈来实现,首先入栈的是主函数下一条语句的地址,即扩展指针寄存器的内容(EIP),然后是当前栈帧的底部地址,即扩展基址指针寄存器内容(EBP),再然后是被调函数的实参等,一般情况下是按照从右向左的顺序入栈,之后是被调函数的局部变量,注意静态变量是存放在数据段或者BSS段,是不入栈的。出栈的顺序正好相反,最终栈顶指向主函数下一条语句的地址,主程序又从该地址开始执行。堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的。
7. 哪些情况下Vector迭代器会失效?
- ector在push_back的时候当容量不足时会触发扩容,导致整个vector重新申请内存.
- insert导致的迭代器失效有两种情况:
(1)插入操作导致vector扩容,迭代器失效原因和push_back相同
(2)插入操作引起vector内元素移动,导致被移动部分的迭代器失效 - erase导致迭代器失效
删除操作引起vector内元素移动,导致被移动部分的迭代器失效。