面试复习(一)C++语言特性和常见数据结构与算法

一.继承

子类对父类的访问

  • public:保持原有权限
  • private:全部变为私有权限
  • protected:public 变为 protected 权限,protected 和 private不变

多继承导致的

  • 命名冲突(加作用域符号)
  • 菱形继承问题(使用虚继承)

    存在相同基类时,导致最后的派生类内有两份基类;

    原因:普通的继承中,最后的派生类对相同的基类会进行重复构造;

    解决:最后的派生类对虚基类的构造函数调用,忽略其他派生类对虚基类的构造函数调用。

    顺序:虚基类    基类1  基类2  最后的派生类

  • 虚函数继承二义性(虚继承)

    存在相同基类时,导致基类的两份虚函数表;

    解决同上

二.多态

virtual

虚函数表:编译时确定,每个有虚函数的类都有一个虚函数表

虚指针:运行时创建对象确定;

  • 不存在继承时,对象有一个虚指针指向自身的虚函数表。
  • 单继承时:子类对象有一个虚指针指向自身的虚函数表,里面包含父类的虚函数地址、子类覆盖的虚函数地址、子类自己的虚函数地址。
  • 多继承时:每一个有虚函数的父类,子类都有一个虚指针指向它的虚函数表;子类自己的虚函数地址存在第一个继承的父类的虚函数表中,后面的虚函数表存在偏移量。

三.STL

array(数组)

底层原理:将一段连续的内存空间按照元素类型的大小进行分割,并将每个元素存储在对应的内存块中。

优点:高效随机访问;连续内存分配,访问效率高;

缺点:大小固定;可能存在内存浪费;插入和删除效率低;

vector(动态数组)

优点:自动扩容无需指定大小;高效随机访问

缺点:自动扩容时进行整体的重新分配,拷贝和释放;内部插入和删除效率低

  • 如何避免扩容:提前预估存储数量,使用 reserve 提前开辟
  • 为什么扩容是1.5或者2倍:
    • 顺序:开辟新空间、拷贝元素、释放旧空间。
    • 理想状态:希望前面释放的空间再次使用;
    • 2倍状态:每次扩容的空间都比前面释放的旧空间大,但是vector拷贝后可以自动调整为当前存储数量的最小值;
    • 1.5倍状态:多次之后可以复用前面释放的旧空间。
    • 超过2倍:浪费空间,调整浪费资源。

面试题:C++vector的动态扩容,为何是1.5倍或者是2倍_vector扩容-CSDN博客

list(双向链表)迭代

优点:高效插入和删除;器稳定;插入和删除不会失去空间;动态内存;

缺点:随机访问效率低;指针维护导致内存占用多;内存不连续,影响访问性能

stack(栈)

queue(队列)

unordered_map(无序哈希)

特点:平均查找效率为 O(1)

缺点:元素无序;占用空间比map大,且利用率不高;查询性能不太稳定,最坏达到O(n)

哈希表的实现可能会导致一些哈希冲突,从而需要更多的内存空间来存储数据。

另外,unordered_map 的哈希表需要根据实际数据量动态扩容,这也会导致一些额外的空间开销。

map(红黑树)

特点:有序;快速查找;插入、删除稳定性好

缺点:占用空间大;平均查询速度不如 unordered_map

红黑树的每一个节点都需要保存父节点位置、子节点位置和红/黑性质,所以占用空间大;

unordered_set(无序哈希)

特点:快速查找;高效的插入和删除

缺点:内存占用较大(哈希冲突);无序;

set(红黑树)

特点:自动排序;

缺点:

四.C++11

lambda

智能指针

auto

右值引用

inline

五.关键字

static

const

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值