报名了百度AIDU计划,没能参加现场会议,但是后面有通知部门面试。
20210625参加了第一场面试,惨痛教训是,千万不要不睡午觉就面试,脑子真的转不动。
1、new和malloc的区别
参考:

  • malloc和new都是在堆上开辟内存的:malloc只负责开辟内存,没有初始化功能,需要用户自己初始化;new不但开辟内存,还可以进行初始化,如new int(10);表示在堆上开辟了一个4字节的int整形内存,初始值是10,再如new int[10] ();表示在堆上开辟了一个包含10个整形元素的数组,初始值都为0。
  • malloc是函数,开辟内存需要传入字节数,如malloc(100);表示在堆上开辟了100个字节的内存,返回void*,表示分配的堆内存的起始地址,因此malloc的返回值需要强转成指定类型的地址;new是运算符,开辟内存需要指定类型,返回指定类型的地址,因此不需要进行强转。
  • malloc开辟内存失败返回NULL,new开辟内存失败抛出bad_alloc类型的异常,需要捕获异常才能判断内存开辟成功或失败,new运算符其实是operator new函数的调用,它底层调用的也是malloc来开辟内存的,new它比malloc多的就是初始化功能,对于类类型来说,所谓初始化,就是调用相应的构造函数。
  • malloc开辟的内存永远是通过free来释放的;而new单个元素内存,用的是delete,如果new[]数组,用的是delete[]来释放内存的。

2、malloc会调用构造函数吗
参考:malloc只是申请指定空间的大小,主要是在C语言中会用到,在C++中,特别是在类中使用NEW才是申请一个类空间,并自动调用构造函数。可以说NEW是专门针对对象的构造做了功夫的。还有就是类的构造函数不能使用指针直接调用,构造函数是在构造对象的时候自动调用的。

3、new可以被重载吗(答错了,我说不会重载,o(╥﹏╥)o)
可以被重载
4、重载相关的知识?介绍一下(罒ω罒,没复习到)
参考:

  • 就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者重载方法。
  • 方法重载(作用)的主要好处就是不用为了对不同的参数类型或参数个数,而写多个函数。多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。

5、继承和多态介绍
参考:

  • 继承通过子类继承父类的方法和属性,实现了代码重用。多态则是“一个接口,多个实现”,通过子类重写父类的虚函数,实现了接口重用。
    (还答了多态实现的三个条件,反而给自己挖了更大坑,教训:以后不能细说的就不多答)
    实现多态必须有以下三个条件:
    1)程序中有父类和子类的继承关系,父类指针必须含有虚函数,子类中也必须重写父类中的虚函数。
    2)用父类的指针指向子类的对象/用父类的引用绑定子类的对象。(而且这里感觉像在背,不熟练)
    3)用这个父类指着调用子类中重写的虚函数。

6、多态中的调用(类的指针指向子类的对象,父类调用子类重写的虚函数),若不是虚函数,父类能调用吗
参考:

  • 在创建子类调用子类的构造函数之前,会先调用父类的构造函数
  • virtual跟多态有关,加了virtual关键字的函数,在调用的时候 ,如果子类有 就先调用子类的, 如果子类没有 ,就调用父类的
  • 父类指针指向子类对象的时候,如果调用的函数,在父类中和子类中都存在,但在父类中不是虚函数,在子类中是不是虚函数均可,用父类指针调用的时候,会执行父类中的函数,而不是子类中的函数;用子类指针调用的时候,会执行子类中的函数

7、子类是如何调用虚函数的?

8、虚函数表里存的是什么?
参考:每个类的实例化对象都会拥有虚函数指针并且都排列在对象的地址首部。而它们也都是按照一定的顺序组织起来的,从而构成了一种表状结构,称为虚函数表 (virtual table) 。
虚函数指针是在构造函数执行时初始化的(在运行时确定),而虚函数表是存放在可执行文件中的(在编译期生成)。虚函数表有点像一个类里面的staic成员变量,即它是属于一个类所有对象的,不是属于某一个对象特有的,是一个类所有对象共有的。
9、构造函数能是虚函数吗?
参考:不能

  • 存储空间角度:虚函数对应一个指向vtable虚函数表的指针,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数。
  • 从使用角度,虚函数的作用在于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数。而构造函数是在创建对象时自动调用的,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数。

10、析构函数可以是虚函数吗?
当基类指针指向派生类的时候,若基类析构函数不声明为虚函数,在析构时,只会调用基类而不会调用派生类的析构函数,从而导致内存泄露。
11、若子类没有重写父类的虚析构函数,子类会有析构函数吗,还是说有默认析构函数,他如何执行?
(我给转向了智能指针,表示智能指针会在析构函数中释放掉)
父类的函数是虚函数就会调用父类的函数
12、纯虚函数?
参考:
我们把包含纯虚函数的类称之为抽象类,对于抽象类来说,C++是不允许它去实例化对象的。对于抽象类来说,它无法实例化对象,而对于抽象类的子类来说,只有把抽象类中的纯虚函数全部实现之后,那么这个子类才可以实例化对象。
是一个在基类中声明的虚函数,它在该基类中没有定义具体实现,要求各派生类根据实际需要定义函数实现。纯虚构函数的作用是为派生类提供一个一致的接口。 抽象类描述的是所有派生类的高度抽象的共性,这些高度抽象、无法具体化的共性就由纯虚函数来描述。带有纯虚函数的类被称为抽象类,一个抽象类至少具有一个纯虚函数。
一个纯虚函数只是提供一个接口,不去具体实现它,而通过子类去实现,这样就实现了数据隐藏和多态。

13、如果纯虚函数没有实现函数体,那是不是可以不用纯虚函数?
参考:当类被定义,有些函数不确定,为了防止乱写一个函数实现,需使用纯虚函数。
14、类和结构体的区别?

  • (同)struct能包含成员函数、能包含构造和析构、能继承、能实现多态,struct可以继承class,同样class也可以继承struct。
  • (异)class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、构造函数、索引器、操作符等。
  • struct(结构)是一种值类型,用于将一组相关的变量组织为一个单一的变量实体 。以将其当作 int、char 这样的基本类型对待
  • class是引用类型,struct是值类型;既然 class 是引用类型,class 可以设为 null;但是我们不能将 struct 设为 null,因为它是值类型。
  • 当你实例化一个 class,它将创建在【堆】上。而你实例化一个 struct,它将创建在【栈】上。
  • 使用 class 时,类中的成员默认都是 private 属性的;而使用 struct 时,结构体中的成员默认都是 public 属性的。
  • class 继承默认是 private 继承,而 struct 继承默认是 public 继承。
  • class 可以使用模板,而 struct 不能。

15、类和结构体都能嵌套定义?

16、c11了解吗
提到了weak_ptr的作用,解决share_ptr的死锁问题,如何解决的(处处给自己挖坑)
17、shared_ptr的实现?share会使用析构函数吗

18、右值拷贝?

19、STL使用过吗,经常使用哪个,介绍下
我提的vector
20、vector的扩容过程,复制之后以前的空间会释放掉吗?

21、set、map内部实现是红黑树,介绍一下红黑树?
参考:自平衡二叉查找树
性质1. 结点是红色或黑色。
性质2. 根结点是黑色。
性质3. 所有叶子都是黑色。(叶子是NIL结点)
性质4. 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
性质5. 从任一节结点其每个叶子的所有路径都包含相同数目的黑色结点。
22、unorder_set、unorder_map的内部实现,哈希实现?
23、红黑树的定义,怎么实现快速查找存储的?

24、红黑树一定是二叉树吗
25、给出二叉树的前序和中序,写出后序序列