C++面试汇总

1、CPP内存管理

参考回答:https://www.cnblogs.com/findumars/p/5929831.html?utm_source=itdadao&utm_medium=referral
参考回答:https://blog.csdn.net/hanoi_ahoj/article/details/88660494

类中的静态成员:静态成员变量只能在类中声名,不能在类中定义或者初始化,定义是为变量分配空间,而初始化是为变量赋值
详解参考博客:https://www.jianshu.com/p/feaf81b88f85

参考博客(C++空间配置代码分析):https://blog.csdn.net/haluoluo211/article/details/80560066
参考博客(C++空间配置代码分析):https://blog.csdn.net/haluoluo211/article/details/80573204
参考博客(C++vector容器实现分析):https://blog.csdn.net/haluoluo211/article/details/80635782
C++内存管理参考博客:https://www.cnblogs.com/findumars/p/5929831.html?utm_source=itdadao&utm_medium=referral

内存空间:

  • 内核空间
  • 内存映射区
  • 全局变量区(分为bss、data区,bss区存储未初始化或初始化为0的全局变量,运行时占用内存,但是可执行程序不占用空间大小,data区存放已赋值的全局变量,在运行时和可执行文件都占用空间)
  • 代码区

参考博客:https://blog.csdn.net/laiqun_ai/article/details/8528366

2、new/delete和malloc/free区别

参考博客:https://www.cnblogs.com/findumars/p/5929831.html?utm_source=itdadao&utm_medium=referral

3、C++多态,静态多态和动态多态都有什么(静态绑定、动态绑定)

C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数
1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数
2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的
3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性
4:多态用虚函数来实现,结合动态绑定.
5:纯虚函数是虚函数再加上 = 0
6:抽象类是指包括至少一个纯虚函数的类
纯虚函数:virtual void fun()=0;即抽象类!必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容

静态多态就是在系统编译期间就可以确定程序执行到这里将要执行哪个函数,比如函数的重载。
动态多态则是利用虚函数实现了运行时的多态,也就是说在系统编译的时候并不知道程序将要调用哪一个函数,只有在运行到这里的时候才能确定接下来会跳转到哪一个函数的栈帧

注意:C语言不支持重载,但支持变长参数:
多态有类的多态和函数的多态,函数的多态是指一个函数被定义成不同参数的函数,当调用函数时,根据不同的参数调用不同的函数

那些函数不能定义为虚函数?
经检验下面的几个函数都不能定义为虚函数:
1)友元函数,它不是类的成员函数
2)全局函数
3)静态成员函数,它没有this指针
3)构造函数,拷贝构造函数,以及赋值运算符重载(可以但是一般不建议作为虚函数)

参考博客:https://www.cnblogs.com/cxq0017/p/6074247.html
参考博客:https://blog.csdn.net/qq_39412582/article/details/81628254

4、类的虚函数的作用;B类继承A类,AB类中均定义S函数;内部机制(虚函数表)**

参照第3问
**基类析构函数定义为虚函数的原因:**基类指针可能指向派生类,当delete的时候,如果不定为虚函数,系统会直接调用基类的析构函数,这个时候派生类就有一部分没有被释放,就会造成可怕的内存泄漏问题
若定义为虚函数,那么就会先调用派生类的析构函数然后派生类的析构函数会自动调用基类的析构函数,这个结果满足我们的本意

所以!在继承的时候,尽量把基类的析构函数定义为虚函数,这样继承下去的派生类的析构函数也会被变成虚函数构成多态

参考博客(C++多态):https://blog.csdn.net/skySongkran/article/details/82012698
参考博客(C++多态):https://blog.csdn.net/qq_39412582/article/details/81628254
参考博客(C++多态):https://blog.csdn.net/weixin_42678507/article/details/89414998

5、四种强制类型转换:静态转换、常量转换、重解释转换、动态转换**
  • static_cast转换:可用于基本数据类型的转换,也可用于基类和派生间的转换(父类、子类)
    在进行类间转换时:
    上行转换(派生类---->基类)是安全的
    下行转换(基类---->派生类)由于没有动态类型检查,所以是不安全的
    隐式转换都建议使用static_cast进行显示转换
  • dynamic_cast转换:只有在派生类之间转换时才使用dynamic_cast,type-id必须是类指针,类引用或者void*
    基类必须要有虚函数,因为dynamic_cast是运行时类型检查,需要运行时类型信息,而这个信息是存储在类的虚函数表中,只有一个类定义了虚函数,才会有虚函数表
    对于下行转换,dynamic_cast是安全的(当类型不一致时,转换过来的是空指针),而static_cast是不安全的(当类型不一致时,转换过来的是错误意义的指针,可能造成踩内存,非法访问等各种问题)
  • const_cast转换:const_castexpression
    使用场景:
      a、常量指针转换为非常量指针,并且仍然指向原来的对象
      b、常量引用被转换为非常量引用,并且仍然指向原来的对象
    使用特点:
      a、cosnt_cast是四种类型转换符中唯一可以对常量进行操作的转换符
      b、去除常量性是一个危险的动作,尽量避免使用。一个特定的场景是:类通过const提供重载时,一般都是非常量函数调用const_cast将参数转换为常量,然后调用常量函数,然后得到结果再调用const_cast 去除常量性
  • reinterpret_cast转换:reinterpret_castexpression
    使用场景:不到万不得已,不用使用这个转换符,高危操作
    使用特点:  
      a、reinterpret_cast是从底层对数据进行重新解释,依赖具体的平台,可移植性差
      b、reinterpret_cast可以将整型转换为指针,也可以把指针转换为数组
      c、reinterpret_cast可以在指针和引用里进行肆无忌惮的转换

回答参考:https://www.cnblogs.com/cauchy007/p/4968707.html

6、inline内联函数

内联函数:

  • 内联函数在编译时进行类型检查和自动类型转换
  • 内联可以调试
  • 可访问成员变量

宏定义:只在预编译的时候进行替换

参考博客:https://www.jianshu.com/p/89d2c1d8b202
参考博客(内联函数和宏定义):https://www.cnblogs.com/xuewangkai/p/11151246.html

7、代码到生成可执行文件的流程

C++的编译过程包括
step1 预编译
step2 编译
step3 汇编
step4 链接

预编译:主要展开头文件、宏定义等。汇编:把已经预编译的文件编译成汇编代码,整个过程包含语法、词法的分析,和一些优化操作
编译:将汇编代码变成目标代码,即生成二进制文件(.obj)
链接:将单个编译后的文件链接成一个可执行文件
前面的预编译、汇编、编译都是针对单个文件,以一个文件为一个编译单元,而链接则是将所有关联到的编译后的单元文件和应用到的库文件,进行一次链接处理,之前编译过的文件如果有用到其他文件里面定义到的函数、全局变量,在这个过程中会进行解析

  1. 预编译
    将.c 文件转化成 .i文件
    使用的gcc命令是:gcc –E
    对应于预处理命令cpp

  2. 编译
    将.c/.h文件转换成.s文件
    使用的gcc命令是:gcc –S
    对应于编译命令 cc –S

  3. 汇编
    将.s 文件转化成 .o文件
    使用的gcc 命令是:gcc –c
    对应于汇编命令是 as

  4. 链接
    将.o文件转化成可执行程序
    使用的gcc 命令是: gcc
    对应于链接命令是 ld

总结起来编译过程就上面的四个过程:预编译处理(.c) --> 编译、优化程序(.s、.asm)--> 汇编程序(.obj、.o、.a、.ko) --> 链接程序(.exe、.elf、.axf等)

参考博客:https://blog.csdn.net/gongjiwei/article/details/98845482
参考博客:https://blog.csdn.net/u012662731/article/details/78520349

8、C++协变与逆变

如果类型 Car 是类型 Vehicle 的子类型(subtype,Car ≤ Vehicle,可以在任何出现 Vehicle 的地方用 Car 代替),那么关于 Car 和 Vehicle 的复杂类型(如 std::vector 和 std::vector)之间的关系如下:

  • std::vector 是 std::vector 的子类型,所有出现 std::vector 的地方都可以用 std::vector 代替,即代替方向一致,则称之为协变(covariance)
  • std::vector 是 std::vector 的子类型,所有出现 std::vector 的地方都可以用 std::vector 代替,即代替方向相反,则称之为逆变(cotravariance)
  • std::vector 和 std::vector 之间没有关系,则称之为不变(invariance)

参考博客:https://www.jianshu.com/p/db76a8b08694

9、什么是智能指针? 智能指针的原理什么? 使用智能指针的目的是什么? 使用智能指针一定可以防止内存泄露吗? (什么情况下使用智能指针仍然会导致泄露)**

参考博客:https://www.jianshu.com/p/bf8de014e5c2
参考博客:https://www.cnblogs.com/wxquare/p/4759020.html
参考博客:https://blog.csdn.net/flowing_wind/article/details/81301001

10、了解的C++11新特性(说的智能指针)
11、如何实现一个只能在堆上建立实例的类**

参考博客:https://blog.csdn.net/c_base_jin/article/details/86501333
参考博客:https://www.cnblogs.com/luxiaoxun/archive/2012/08/03/2621827.html

12、设计模式了解哪些

单例模式、工厂模式、抽象工厂模式、备忘录模式、观察者模式、策略模式

13、什么是死锁?

参考博客:https://blog.csdn.net/hd12370/article/details/82814348

14、TCP UDP区别

参考博客:https://blog.csdn.net/gongjiwei/article/details/98896267

15、MMap

mmap把文件的部分内存映射到进程虚拟地址空间中,用户可以直接操作虚拟地址空间中的数据
mmap的写操作流程:

  • 用户把数据写入use buffer
  • 若虚拟地址在物理内存中,则直接拷贝到物理内存
  • 若虚拟地址不在物理内存中,则执行缺页中断,由系统内核处理
  • 由系统将脏页写回磁盘
    mmap的读操作流程
  • 直接读mmap对应的虚拟地址
  • 若对应物理内存有数据,则直接读,
  • 若不在,则由系统内核将数据从磁盘读入到物理内存,用户直接读

在小于2KB或4KB大小情况下,速度快与write系统调用,在大于2KB或4KB大小时,速度略慢于write系统调用
mmap的读操作速度远快于read系统调用,因为
参考博客:https://www.jianshu.com/p/eece39beee20
参考博客:https://blog.csdn.net/qq_33611327/article/details/81738195

16、进程和线程,说下多线程共享的资源

17、C++里面的const关键字,能修饰volatile吗?
参考博客:https://www.jianshu.com/p/1b9fcd074eb2

18、C++里面的内存泄露?

**内存泄漏的定义:**一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了

**检测内存泄漏:**检测内存泄漏的关键是要能截获住对分配内存和释放内存的函数的调用。截获住这两个函数,我们就能跟踪每一块内存的生命周期,比如,每当成功的分配一块内存后,就把它的指针加入一个全局的list中;每当释放一块内存,再把它的指针从list中删除。这样,当程序结束的时候,list中剩余的指针就是指向那些没有被释放的内存。这里只是简单的描述了检测内存泄漏的基本原理,详细的算法可以参见Steve Maguire的<>

参考博客:https://www.cnblogs.com/findumars/p/5929831.html?utm_source=itdadao&utm_medium=referral

19、C的malloc和C++ new的区别?

20、父类指针指向子类对象,用该指针调用子类的方法? 不会(dynamic_cast)

21、解释一下堆栈**

参考博客:https://www.cnblogs.com/findumars/p/5929831.html?utm_source=itdadao&utm_medium=referral

22、epoll和select的区别

23、b 树和b+树的区别

24、scala和Cpp的区别

25、线程池的设计与相关问题

26、引用和指针区别 有常量引用吗?指针常量和常量指针

**大对象用const引用传递代替按值进行函数参数传递:**因为值传递会生成很多临时对象,进行内存拷贝,而且如果类中使用动态内存分配,还容易引发内存泄漏,因此,使用引用传递可以减小临时对象带来的开销,同时避免引发内存泄漏

27、一致性哈希

28、析构函数可以抛出异常吗
不可以,析构函数抛出异常将导致内存不能释放

29、索引失效情况

30、数据库的存储过程

31、volatile关键字

32、如果c++ 当中判断一个类型有没有某个方法你有哪些方式可以做到?发散一下思维,这个问题可能比较难

33、设计一个线程安全的HashMap

34、vector的内存是怎么管理的?底层的实现

35、STL中unique函数的实现

36、进程空间的理解,怎么求一个进程可用栈空间的大小?

37、MySQL数据库引擎说一下

38、表过大会有什么影响、怎么解决(我说了水平分表和垂直分表详细解释)

39、水平分表固定哈希,如果想要加表、删表怎么办

40、协程和线程的区别

41、一个二叉树上求两个节点之间路径长度的最大值,说出具体的思路

42、STL function有个特点,他的接口都是iterator,但是在用的时候传入容器的iterator或者说传入数据的指针都可以work这个背后的机理是什么?

43、模板当中对类型操作的思考

44、现在假设有一个程序,编译好的,编译没有错误,但是运行的时候报错,报的错是你正在调用一个纯虚函数,请问这里面导致这个错误的原因可能是什么?根据c++内部原理推理这个问题

45、描述一下,子类构造的时候,整个构造的过程,先怎么样,再怎么样,说清楚,是先构造父类的虚表指针还是先构造父类的成员?虚表指针是什么时候设进去的? 在构造函数当中一部分是初始化列表一部分是在花括弧里面,你能说一下这些的顺序是什么么?差别是什么 和this指针的顺序?初始化列表的写法和顺序有没有什么关系?

46、了解什么rpc方式

47、c++的内存管理有了解过么?

48、new一个对象的时候该对象在内存当中是怎么布局的

49、成员变量,虚函数表在哪个位置?

50、一个类可能会有父类和子类那么这些信息在对象当中是如何排版的呢?

51、在子类的构造函数中调用虚函数,调用的是父类的实现还是子类的实现

52、虚函数指针和构造函数体那个先被构造?

53、 c++运行构造函数的时候虚函数表被构造出来了么?

54、什么是TCP粘包

55、什么是平衡二叉树

56、单链表如何判断有环?环的位置在哪?

57、栈和堆的理解,知不知道栈帧

58、查看Linux系统的网络连接信息
用netstat命令和ss命令,netstat 命令:用于显示各种网络相关信息,如网络连接,路由表,接口状态,无效连接,组播成员 等等
ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。但是ss的优势在于它能够显示更详细的有关网络连接的状态信息,而比netstat更快速、更高效
参考博客:https://www.cnblogs.com/yangleitao/p/9583280.html

22、谈一下磁盘故障预测的过程

23、谈一下ceph bluestore和filestore的区别,filestore为什么使用日志,以及分布式存储中,日志的作用

24、内存屏障

25、谈一下块设备为什么叫块设备,以及ssd和hdd在顺序写和随机写方面的性能差别,以及原因

26、块设备为什么叫块设备,写块设备时,若所写位置的开始地址不是块对齐,如何写到磁盘中。(面试官说这题是加分题,我只回答出来了方法,代码没有写出来,不知道有没有加分)

27、谈一下ceph底层存储的方式,以及将simple write改为append-only形式有何优势

28、讲讲STL的容器

面试经验:https://www.nowcoder.com/discuss/188367?type=2&order=0&pos=13&page=3

学习资料:https://www.nowcoder.com/discuss/193598?type=2&order=0&pos=2&page=2

你可能感兴趣的:(C++学习)