面试八股文
大约 4 分钟
面试八股文
语言相关
5道C++语言相关的面试题
- malloc、free和new、delete区别
- 虚函数表和虚函数表指针的创建时机
- C++什么时候生成默认拷贝构造函数
- 面向对象的三大特征及特性
- 设计模式
01. malloc、free和new、delete
区别
new & malloc
new | malloc | |
---|---|---|
使用时 | 自动计算分配内存大小 | 手动计算 |
返回值 | 对象指针 | void* |
失败 | 抛出异常 | 返回NULL |
分配在哪 | freeStore (自由存储区) 一般在虚拟内存上的堆 也有可能在自己定义的其他地方 | <128通过break系统调用 (可能会先有内存池),在虚拟内存上的堆 >128通过mmap系统调用,或在文件映射区 |
隐藏操作 | 1. operator new 2. 申请空间 3. 调用构造函数和初始化成员 | 无。注意不会进行初始化,分配后不一定有物理内存 |
delete & free
delete | free | |
---|---|---|
使用参数 | 对象指针 | 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
- 面向对象
- 设计模式