跳至主要內容

面试八股文

LincZero大约 4 分钟

面试八股文

语言相关

5道C++语言相关的面试题

  1. malloc、free和new、delete区别
  2. 虚函数表和虚函数表指针的创建时机
  3. C++什么时候生成默认拷贝构造函数
  4. 面向对象的三大特征及特性
  5. 设计模式

01. malloc、free和new、delete

区别

new & malloc

newmalloc
使用时自动计算分配内存大小手动计算
返回值对象指针void*
失败抛出异常返回NULL
分配在哪freeStore (自由存储区)
一般在虚拟内存上的堆

也有可能在自己定义的其他地方
<128通过break系统调用 (可能会先有内存池),在虚拟内存上的堆
>128通过mmap系统调用,或在文件映射区
隐藏操作1. operator new
2. 申请空间
3. 调用构造函数和初始化成员
无。注意不会进行初始化,分配后不一定有物理内存

delete & free

deletefree
使用参数对象指针void*
隐藏操作1. 调用析构函数
2. operator delete
3. 释放空间

补充:

  • 虚拟内存和物理内存有一个映射关系,虚拟内存的一个页对应物理内存的一个页,初始化时才会去对应
  • 所以说malloc分配后不一定有物理内存,new后会初始化,则会有对应的物理内存

FAQ

  • malloc 是怎么分配空间的?答:两种大小的两种分配区域
  • malloc 分配的物理内存还是虚拟内存?答:物理内存和虚拟内存的映射方式
  • malloc 调用后是否立刻得到物理内存?否,要初始化才有
  • free(p) 怎么知道该释放多大空间?malloc会额外多申请16Byte
  • free(p) 释放内存后,内存还在吗?如果通过内存池释放,则内存回内存池。如果通过mmap分配,则会马上释放

深入

虚函数表和虚函数表指针

  • 创建时机

    • 虚函数表创建时机:当某类有virutal函数,编译器编译时就会生成

    • 虚函数表指针创建时机:类对象构造时,把类的虚函数表地址赋值给vptr(没有构造函数也会有默认构造函数)

      需要注意继承时,先调用基类构造函数并将基类虚函数表地址给vptr,再调用子类构造函数并将子类虚函数表地址给vptr(总感觉不太对,不至于这么笨赋值两次吧)

  • 虚函数表和虚函数表指针的关系?

    • 答:虚函数表指针指向虚函数表。一个类对应一个虚函数表,类的多个对象对应多个虚函数表指针地址不同,但均指向虚函数表
  • 为什么需要虚函数指针?用来实现多态

    A* p = new B();
    p->func(); // 调用的B类的方法。因为能通过p对象的vptr找到B的虚函数表
    

可执行文件的磁盘组成

  • ……
  • .bss,存放未初始化或初始化为零的全局或静态变量
  • .data,已初始化的全局或静态变量
  • .rodata,(readOnlyData),只读数据段,虚函数表在里面
  • .text,代码段
  • ……

虚拟内存组成

  • 内核空间
  • 栈区
  • 文件映射区
  • 堆区
  • 数据区(静态存储区,已初始化和未初始化。映射 .bass、.data)
  • 代码区(映射代码.text、.rodata(虚函数表))

深入、编译器工作

默认拷贝构造函数

  • 背景:如果不提供,则位拷贝
  • 位拷贝危险 (浅拷贝危险)
    • 堆上的资源
    • 文件句柄,socket
    • 虚函数表指针缺失
  • 触发时机
    • 赋值
    • 函数传参 (形参为类对象)、返回值 (不一定,返回值可能会有个编译器优化,优先用C++11的移动构造函数/自动给你移动构造)
  • 什么时候生成。当不得不生成时
    • 继承/包含一个类A,类A包含默认拷贝构造函数
    • 类成员有虚函数(自己有或基类有)

其他

写文件时进程宕机,数据会丢失吗

什么是MTU、MSS以及为什么要有MSS

什么是连接半打开,半关闭状态

C

  • 标准库 stl、boost
  • C++11/14/17/20
  • 面向对象
  • 设计模式