文章目录
- C++面试大全
-
- 1. new/delete和malloc/free的区别
- 2. 多态是什么?如何实现?
- 3. 堆和栈的区别是什么?二者的数据结构是什么?那个效率更高?
- 4. 强制类型转换的使用
- 5. TCP的三次握手和四次挥手
- 6. 进程和线程的区别?
- 7. 5种IO模型
- 8. Linux中,显示第二行、最后一行,查找以.c结尾的文件怎么找?
- 9. git都要用那些命令?回滚是哪个命令?
- 10. 分组加条件查询的sql语句怎么写?
- 11. redis的常用数据类型?顺便说一下具体场景。
- 12. 黑盒测试和白盒测试详解
- 13. Linux基本命令
- 14. 数据库基本命令
- 15. 指针常量和常量指针
- 16. 数据库中delete和trancate区别
- 17. C++是如何解决内存泄漏的?
- 18. 了解哪些排序方法?简述下快速排序。
- 19. 数据库三大范式。
- 20. 虚函数和纯虚函数的区别?
- 21. 重写和重载的区别?
- 22. 源文件到可执行文件的过程。
- 23. 深拷贝和浅拷贝的区别。
C++面试大全
1. new/delete和malloc/free的区别
malloc需要给定申请内存的大小,返回的指针需要强转。
new会调用构造函数,不用指定内存大小,返回的指针不用强转。
2. 多态是什么?如何实现?
多态(Polymorphism)是面向对象编程的一个重要概念,它允许不同类型的对象对同一个消息做出不同的响应。多态性使得程序能够根据对象的实际类型来执行相应的操作,提高了代码的灵活性和可扩展性。
实现多态性的方式有两种:静态多态(编译时多态)和动态多态(运行时多态)。
静态多态(编译时多态):
函数重载(Function Overloading):在同一个类中定义多个同名函数,但参数列表不同。编译器根据调用时传入的参数类型和数量来决定调用哪个函数。
运算符重载(Operator Overloading):重载内置运算符,使其能够对自定义类型进行操作。 动态多态(运行时多态):虚函数(VirtualFunctions):通过在基类中声明虚函数,并在派生类中进行重写,实现运行时的多态性。通过基类指针或引用调用虚函数时,会根据实际对象的类型来调用相应的函数。
抽象类和纯虚函数(Abstract Classes and Pure VirtualFunctions):抽象类是包含纯虚函数的类,纯虚函数是在基类中声明但没有具体实现的虚函数。抽象类不能被实例化,但可以作为基类用于派生其他类。
在实现多态性时,需要注意以下几点:使用基类指针或引用来操作派生类对象。 基类中的虚函数需要使用virtual关键字进行声明。
派生类中的重写函数需要使用override关键字进行声明(C++11及以上版本)。
多态性可以提高代码的灵活性和可维护性,使得程序能够更好地适应变化和扩展。
3. 堆和栈的区别是什么?二者的数据结构是什么?那个效率更高?
数据结构:
堆:堆是一种动态分配的内存区域,用于存储动态分配的对象。堆使用堆数据结构,通常是一个完全二叉树的结构,可以通过指针进行访问和操作。
栈:栈是一种后进先出(LIFO)的数据结构,用于存储局部变量、函数调用和程序执行的上下文信息。栈使用栈数据结构,通常是一个线性结构,通过栈顶指针进行访问和操作。
特点和用途:
堆:堆是动态分配的内存区域,大小不固定,可以在程序运行时进行动态分配和释放。堆通常用于存储动态创建的对象、大型数据结构和全局变量等。堆的生命周期由程序员手动控制,需要手动释放分配的内存,否则可能导致内存泄漏。
栈:栈是静态分配的内存区域,大小固定,由编译器自动分配和释放。栈通常用于存储局部变量、函数调用和程序执行的上下文信息。栈的生命周期由程序的执行流程自动管理,不需要手动释放内存。
效率:
堆:堆的动态分配和释放需要较多的时间和空间开销,因为需要进行内存管理和碎片整理。堆的分配和释放是非常灵活的,但可能会导致内存碎片化。
栈:栈的分配和释放是由编译器自动管理的,速度较快。栈的分配和释放是按照固定的顺序进行的,不会产生内存碎片。
总体而言,栈的操作速度更快,因为栈的分配和释放由编译器自动管理,不需要额外的内存管理开销。堆的灵活性更高,可以动态分配和释放内存,适用于动态的、大小不确定的数据存储需求。选择使用堆还是栈取决于具体的应用场景和需求。
4. 强制类型转换的使用
强制类型转换(Type Casting)是将一个数据类型转换为另一个数据类型的操作。在某些情况下,我们可能需要将一个数据类型转换为另一个数据类型,以满足特定的需求或进行特定的计算。在C++中,有以下几种类型转换方式:
静态转换(Static Cast):
用法:static_cast<目标类型>(表达式) 用途:用于基本数据类型之间的转换,以及具有继承关系的类之间的转换(向上转型和向下转型)。
动态转换(Dynamic Cast):用法:dynamic_cast<目标类型>(表达式)
用途:用于在具有继承关系的类之间进行安全的向下转型。只能用于指针或引用类型,并且需要有运行时类型信息(需要将基类定义为虚基类)。
常量转换(Const Cast):用法:const_cast<目标类型>(表达式) 用途:用于去除常量属性,可以将 const 或 volatile 修饰的对象转换为非
const 或非 volatile 对象。 重新解释转换(Reinterpret Cast):用法:reinterpret_cast<目标类型>(表达式) 用途:用于进行底层的二进制数据重新解释,将一个指针转换为一个不同类型的指针。
需要注意的是,强制类型转换可能会导致数据丢失或产生未定义的行为,因此在使用时需要谨慎。尽量避免频繁使用强制类型转换,优先考虑设计良好的类层次结构和接口设计来避免类型转换的需求。