问题
- 三种多态的实现方式及其区别
- STL 容器在 for 循环中使用 erase 删除元素会导致什么问题?
- 什么是Perfec t Forwarding?为什么要使用它,它解决了什么问题?写一下
- 完美转发和移动语义的实践场景
- 虚函数表的存储位置和内存结构
- 单继承、多继承、虚继承的vptr是怎样的?对应的C++内存模型是怎样的
- 虚函数能否是模板函数?为什么?
- 析构函数声明为虚函数的原因是什么?
- C++类默认生成的成员函数有哪些?
- 左值和右值的区别与应用场景
- Name Mangling的作用及其带来的兼容性问题
- 动态库和静态库的优缺点对比
- 什么是智能指针?什么是RAII?既然如此,全部用栈区不就可以了,为什么要堆区? 或者全部用堆区可以了,为什么要栈区?
- vector有什么缺点,为什么要有pvector?或者问移动构造的适用场景(如gapbs)
- 【打卡题】const与指针和引用
- 【打卡题】宏定义
define和const常量 - new 和malloc的区别
- atomic原子操作为什么比读写锁更快?
- vector和dequeue的区别,为什么遍历vector的效率更高。
参考回答
三种多态的实现方式及其区别
静态多态和动态多态:函数重载、运算符重载、泛型编程与模板(特别的CRTP)(编译期多态);虚函数 动态多态
STL 容器在 for 循环中使用 erase 删除元素会导致什么问题?
1 | std::vector<int> vec = {1, 2, 3, 4, 5}; |
- 什么是Perfec t Forwarding?为什么要使用它,它解决了什么问题?写一下
在函数模板中,保持参数的原有类型和特性(const)进行转发。没有完美转发时,泛型编程会遇到参数类别丢失的问题。传入右值时,T会被推导成非右值,const属性也会消失;
1 | template<typename T> |
- 完美转发和移动语义的实践场景
日志函数\ 装饰器模式、容器构造器
1 | template<typename T> |
虚函数表的存储位置和内存结构
vtable 只读数据段、vptr对象内部单继承、多继承、虚继承的vptr是怎样的?对应的C++内存模型是怎样的
虚函数能否是模板函数?为什么?
虚函数不能是模板函数。虚函数表要求在编译器固定布局,模板函数实例化在编译器按需生成。时机冲突析构函数声明为虚函数的原因是什么?
当一个派生类对象通过 基类指针 删除时,如果基类的析构函数 不是虚的,将只会调用基类析构函数,而派生类部分不会被析构,造成 资源泄漏 或 未定义行为。C++类默认生成的成员函数有哪些?
默认构造、拷贝、析构、移动、拷贝赋值与移动赋值左值和右值的区别与应用场景
Name Mangling的作用及其带来的兼容性问题
动态库和静态库的优缺点对比
什么是智能指针?什么是RAII?既然如此,全部用栈区不就可以了,为什么要堆区? 或者全部用堆区可以了,为什么要栈区?
堆适用 大小不确定,并且可以利用零散碎片,栈不行;栈适合函数,天生紧凑,堆不行;两者协作处理会使得内存更加紧凑高效。工厂模式的一个优点:唯一化管理,比如LLVM中的Type类型管理
vector有什么缺点,为什么要有pvector?或者问移动构造的适用场景(如gapbs)
【打卡题】const与指针和引用
【打卡题】宏定义
define和const常量new 和malloc的区别
atomic原子操作为什么比读写锁更快?(硬件指令)
1.硬件指令实现
atomic原子操作是硬件级别的,直接在CPU指令和缓存层完成,会通过特定的硬件指令直接锁CPU的缓存行和内存总线,确保其他核心无法访问同一块内存。而读写锁则是软件级别的,需要内核系统调用实现,基于互斥锁机制实现,线程无法获取锁时会通过系统调用将自己放入等待队列,涉及用户态内核态切换,导致比成本比硬件实现高出几个数量级。