C++常见面试题(面试中总结)

打印 上一主题 下一主题

主题 1519|帖子 1519|积分 4557

原文章链接

   本文主要总结了一些常见的C++面试题,主要是面试过程中遇到以及网上网络,全部是以自己理解举行了作答,如有不明确的地方,欢迎大家前来学习指正,会不定期去更新面试内容。
    感爱好的可以关注一下公众号,会第一时间给您推送更多出色的内容,欢迎大家前来指正,欢迎欢迎~~

  1、回调函数的相识?

   回调函数和c++中多态类似,主要功能是,对同一个消息,做出差别的响应,使用的是函数指针实现,通过传递函数指针范例,雷同的函数地址实现动态绑定,实现对消息体的差别响应。
  2、递归算法表明?

   递归的基本思想是某个函数直接或者间接地调用自身,把问题转换成多个雷同子问题。
1、比如求n的阶乘:(找到递归停止条件和将问题一步一步缩小的关系式子)。
2、函数f参数和返回值都是int范例,
if(n == 1) return 1 else f(n-1)*n。
递归有一个很致命的缺点:栈溢出,每调用一次函数栈就会增加一层栈帧,每次函数返回,栈就会减少一层栈帧,而栈不是无穷大的,当递归层数过多时,就会出现溢出。
  青蛙跳台阶问题:if (n == 1) {return 1;} else if (n == 2) {return 2;} else {return jump(n-1) + jump(n-2);}
3、内存对齐表明?

   内存对齐是一种优化的处理方式,为了让处理器能够更高效地访问内存中的数据。结构体中,范例占用空间最大的,作为对齐数。
修改内存对齐数:#pragma pack 要是修改的对齐数(只能是2的n次方),大于结构体中最大范例,结构体中最大范例,作对齐数。
    大端:0x123456
小端:0x563412
大小端:高地址区存放的是高位地址数据,低位存放的是低地址数据,叫做小端对齐,反之是大端对
  4、一种排序算法表明(快速排序)

时间复杂度平均情况下:O(n log n)
   具体实现步骤是这样的,起首从序列中恣意选择一个元素,把该元素作为轴,然后将小于等于轴的全部元素都移到轴的左侧,把大于轴的元素都移到轴的右侧。这样,以枢轴为界,划分出两个子序列,左侧子序列全部元素都小于右侧子序列。枢轴元素不属于任一子序列,并且枢轴元素当前所在位置就是该元素在整个排序完成后的终极位置。这样一个划分左右子序列的过程就叫做快速排序的一趟排序,或称为一次划分。递归此划分过程,直到整个序列有序。
  5、什么是多态?

   差别继续对象,对同一个消息做出差别的响应,
多态三要素:
1、有继续关系,
2、子类重写父类的virtual
3、父类指针或者引用指向子类对象
  6、基类为什么必要虚析构函数?

   防止内存走漏。使用指向子类对象的父类指针去开释子类对象的时间,如果没有重写父类虚析构函数,是不会掉用子类的析构函数。则大概会导致内存走漏。
  7、new和malloc的区别?

   new是c++的关键字,malloc是库函数,new会申请内存,后调用构造函数,malloc只会申请内存,不会调用构造函数。
  8、指针和引用区别?

   实在底层都是指针,只是使用情势差别,
指针可以先声明,再去初始化,引用必须声明时初始化,引用不能new和delete因为他就是一个别名。
  9、什么是壅闭socket,指的是什么?

   对一个文件描述符来说,是一个状态,当不满足读写条件的时间会举行堵塞,非壅闭体现对文件描述符举行读写操作的时间,当不满足条件的时间,不会壅闭, 会立即返回。
  11、用过epoll吗,说一下为什么用epoll,另有其他复用方式吗?区别是什么?

   可以同时监听多个文件描述符上的I/O操作,因为epoll相比select、poll最大的好处就是它不会随着监听fd数目标增长降低效率,因为他们是采用的轮询方式来处理,而且最多同时监听1024个文件描述符,epoll采用的是事件驱动的计划,已经就绪的事件添加到队列中。
  12、说TCP三次握手和四次挥手?

三次握手:
   三次握手体现服务器和客户端创建连接一共必要发送三次数据包,刚开始客户端的状态是close状态服务器的状态是listen状态,
第一个握手:客户端发送一个字段中SYN =1 的包给服务器,客户端状态(SYN_SEND)
第二次握手:服务器吸收到客户端发来的包之后,发送一个字段中SYN=1,ACK=1的包给客户端 服务端(SYN_REVD)
第三次握手:客户端发送字段中ACK=1的包给服务器,双方处于(established)
  四次挥手:
   1、双方都可以自动断开连接
第一次挥手:客户端发送FIN=1的包给服务器,此时客户端状态处于FIN_WAIT-1
第二次挥手:服务器收到客户端的包之后,发送ACK=1的包给客户端,(半关闭状态)此时服务器状态改酿成CLOSE-WAIT,客户端收到ACK应答报文之后状态变为FIN_WAIT-2
第三次挥手:服务器发送FIN=1的包给客户端,此时服务器状态处于LAST_ACK
第四次挥手:客户端发送ACK=1的包给服务器,此时客户端进入TIME_WAIT状态,服务器进入COLSE状态,
必要等待2MSL:
MSL体现是TCP报文在网络中最大生存时间,保证末了一个ACK包能顺利到达。
  13、四次挥手中为什么要有CLOSE-WAIT状态和TIME-WAIT状态?

   COLSE_WAIT 因为服务器收到断开请求时,大概数据还没有传完
TIME_WAIT状态,假设客户端第四次挥手直接发送完毕之后,直接close,但是这个ack包因为网络原因,服务器没有收到,服务器以为没有关闭,会重新发送FIN包,但是客户端已经close了。
  14、主线程先退出对子线程影响?

   如果主线程退出是通过return或者是exit退出,体现进程退出,就会造成子线程也退出,如果使用pthread_exit退出当前线程。
  15、进程和线程的区别?

   进程是程序分配资源管理的基本单位,线程是进程内一个实行单元,线程占用资源更小,不必要向进程那样上下文切换,但是线程是共享资源以是线程之间安全性更难保证,进程的资源是独立的,相对安全。
  16、线程池实现?

   线程池主要包含4个接口:
1、创建线程池中的线程(保证创建固定数量的线程个数)
2、线程入口函数(先辈入while循环中,先去拿锁,拿完锁往下走,又是一个while,条件是当前队列中是否为空,并且一个布尔范例的标识符是否为false,如果两个条件都建立则进入 进入循环中,调用pthread_cond_wait函数,这个函数就是关键,起首会开释锁,处于未激发状态,初始化状态会保证全部线程都卡在这里)
3、叫醒线程函数(像队列中添加任务,通过pthread_cond_signal函数叫醒等待的线程)
4、开释线程函数(将退出线程池变量值为,然后使用pthread_cond_broadcast叫醒全部线程,使用pthread_json举行回收)
  17、说一说信号量?

   它是一种特殊的变量,它可以被增加或减少是原子操作,sem_post,信号量会++,sem_Wait–
  18、说一下Linux下常用命令?

   pwd
mkdir
cp
mv
cat
grep 在文件中查找指定字符串
top 查看系统状态
ps -ef 查看系统中当前运行的进程信息
kill 停止或停止进程
ifconfig
tar -zxvf -zcvf
chmod
  19、说一说互斥锁?

   掩护共享数据,再多线程程序中,会同时访问一块数据,为了保证数据不被污染,可以通过加锁,保证同一时间,只能有一个线程操作。
  20、说一说条件变量?

   条件变量是一种线程同步机制,通常与互斥锁配合使用。
  21、描述一下http请求?

   http请求是一种web中传输数据的协议,请求主要包含:请求行,请求头,空行,请求体。
200 OK:客户端请求被正常处理。
301 永久重定向
302 Found:临时重定向
403 Forbidden:请求被服务器拒绝。
404 Not Found:请求不存在,服务器上找不到请求的资源。
500 Internal Server Error:服务器在实行请求时出现错误。
  22、C++程序编译过程?

   预处理(宏界说展开,更换条件编译,删除解释和空行),编译(检查语法,将原文件转换成汇编代码),汇编(将汇编代码转换成二进制文件),链接(链接全部动态库和静态库)
  23、深拷贝与浅拷贝?

   浅拷贝大概会造成内存重复开释,当类中成员有指针变量是,浅拷贝会造成两个指针指向同一块内存,深拷贝是在堆上面开辟内存,两个对象指向不是同一块内存,以是不会出现这个问题。
  24、数组和链表的区别?

   数组的内存是一连的,并且空间占用比链表小,支持随机访问,链表的删除插入比较方便,拓展性强
  25、const char* p 和 char* const p区别?

   const是一个修饰符,可以界说常量保证值不被修改,const char* 体现指针指向的值不能发生变化,char* const p 体现指针指向不能发生变化。
  26、delete和delete []区别?

   delete只会调用一次析构函数,delete [] 还会调用每个成员的析构函数。
  27、线程有几种状态?

   5种状态,新建、就绪、运行、壅闭、殒命(线程启动以后不大概不绝霸占cpu,以是线程的状态就在允许和壅闭种举行切换)
  28、epoll两种工作模式?

   LT模式也叫水平触发,这种工作模式是,低速模式,来一个事件,不处理的话,就会不绝触发。
ET模式也叫边沿触发,来一个事件,内核只关照一次(不管是否处理,内核都不在关照你
epoll内部维护着两个结构,一个是红黑树管理被监听的文件描述符,另一个就是绪事件队列,用于存储有时间的文件描述符
  29、说一说static静态变量作用?

   1、全局静态变量,作用域是当前文件可见,生命周期是程序开始到结束。
2、局部静态变量,作用域照旧当前局部可见,当时生命周期发生了改变。
3、静态函数,只能在声明他的文件中可见。
4、类的静态成员,属于类,不是属于当前对象的,(可以实现多个对象共享数据)
5、类的静态函数,也是属于当前类,不是属于当前对象的,只能访问静态成员。
  30、什么是STL?

   STL 是 C++ 标准模板库的缩写。它是 C++ 标准库的一部门,提供了一组通用的模板类和函数,实现了常用的数据结构和算法,以及一些函数对象和迭代器概念,使得 C++ 程序员可以更加高效地举行编程。
  31、数组和vector的区别?

   大小:数组的大小在创建时是固定的,而vector的大小是动态可变的。
内存分配:数组的内存分配在栈上(静态数组)或堆上(动态数组),而vector的内存总是动态分配的,通常在堆上。
功能:vector提供了很多内置的操作,如动态扩展、插入和删除等,而数组只能直接访问元素,不支持动态调解大小。
性能:vector在必要扩展时大概会重新分配内存,而数组的内存分配则不会改变。
  32、list 和 vector 的主要区别是什么?

   存储方式: list 是一个双向链表,而 vector 是一个动态数组。
访问时间: list 不支持常数时间的随机访问,vector 支持常数时间的随机访问。
插入和删除: 在 list 中,在恣意位置插入或删除元素。而在 vector 中,不太得当在中间插入或删除元素。
  33、在什么情况下使用 list 而不是 vector?

   当你必要在容器的中间频繁插入和删除元素,而不是在末端插入或删除时,list 更得当。
当你不必要随机访问元素,而是必要频繁举行插入和删除操作时,list 是更好的选择,因为它的这些操作在常数时间内完成。
  34、set 的底层数据结构是什么?

   set 通常使用红黑树或其他自均衡的二叉搜索树实现。它确保全部元素是唯一的,并且保持排序状态,因此插入、删除和查找操作的时间复杂度是对数时间 (O(log n))。
  35、set 和 multiset 有什么差别?

   set 中的元素是唯一的,不能有重复的元素。
multiset 允许有重复的元素。
  36、map 和 unordered_map 的主要区别是什么?

   底层数据结构: map 通常使用红黑树或其他自均衡的二叉搜索树实现,而 unordered_map 使用哈希表实现。
访问时间: map 提供对数时间 (O(log n)) 的查找、插入和删除操作,保持元素的排序。unordered_map 提供平均常数时间 (O(1)) 的查找、插入和删除操作,但不保持元素的排序。
排序: map 中的元素是按照键的顺序排序的,而 unordered_map 中的元素没有特定的顺序。
  38、红黑树实现原理?

   红黑树是一种特殊的自均衡二叉树,在举行插入和删除操作时通过特定操作保持二叉查找树的均衡,从而得到较高的查找性能,并且增编削查效率都非常高o(logn)
1、每个节点要么是红色,要么是黑色,根节点必须是黑色。
2、任何相邻节点(上下关系)不能同时为红色。
3、根节点到叶子节点,所经历黑色节点数量雷同–黑高雷同
    长处(增编削查都很快)
插入情况:
1、父为黑,直接插入
2、父叔为红,颜色变更(父和爷颜色变更,叔也变为黑色)
3、父红叔黑,颜色变更,在移动(父和爷举行颜色变更,爷和父变更位置)
4、父红叔黑,颜色变更,在移动(父子爷不在同一条直线上)(父子位子变更,然后实行上一步父和爷举行颜色变更,爷和父变更位置)
  39、RAII是什么?

   RAII 的核心思想是:资源的获取(如内存、文件句柄、网络连接等)与对象的初始化绑定在一起。具体来说,资源在对象的构造函数中获取,并在对象的析构函数中开释。
  40、C++的内存框架分布情况?

C++ 内存分布框架
  1. -------------------------------------------------------
  2. |                      High Address                   |
  3. --------------------------------------------------------
  4. |                      Heap                            |
  5. |                    (动态分配)                         |
  6. |--------------------------------------------------- --|
  7. |                      堆栈                            |
  8. |                    (局部变量、函数参数等)               |
  9. |-----------------------------------------------------|
  10. |                     全局/静态存储区                    |
  11. |                     (全局变量、静态变量)                |
  12. |------------------------------------------------------|
  13. |                     常量存储区                         |
  14. |                    (常量值)                           |
  15. |------------------------------------------------------|
  16. |                     代码区                            |
  17. |                     (执行代码)                        |
  18. -------------------------------------------------------
  19. |                      Low Address                     |
  20. --------------------------------------------------------
复制代码
  栈(Stack):用于存储局部变量和函数调用信息。栈内存分配速率快,但空间有限。
堆(Heap):用于动态分配内存。程序员可以控制分配和开释内存,但必要显式管理。内存的生命周期由程序员控制。
静态存储区(Static Storage Area):用于存储静态变量和全局变量。这些变量在程序运行期间不绝存在。
常量区(Constant Data Area):用于存储常量数据,如字符串常量。
  41、讲讲C++的三大特性(封装、继续、多态)?

   封装:将数据(成员变量)和对数据的操作(成员函数)捆绑在一起,并对外部隐藏数据的具体实现。
继续:通过继续,子类可以继续父类的属性和活动,从而实现代码的用和扩展。
多态:允许差别的对象以雷同的接口举行操作,即同一操作可以作用于差别的对象上,体现出差别的活动。
  42、 什么是虚函数和纯虚函数?以及区别?

虚函数:
   界说:在基类中声明为 virtual 的成员函数,允许派生类重写(override)该函数。虚函数实现运行时多态。
作用:通过基类指针或引用调用虚函数时,实际调用的是派生类中的重写函数。
  纯虚函数
   界说:在基类中声明为 virtual 并且等于 0 的虚函数,例如 virtual void func() = 0;。
作用:界说接口,要求全部派生类必须实现纯虚函数。使得基类成为抽象类,不能实例化。
  43、虚函数是怎么实现的?虚函数在谁人阶段生成?

虚函数表(vtable):每个类(如果包含虚函数)会有一个虚函数表,它是一个指向虚函数实现的指针数组。每个对象会有一个指向虚函数表的指针(vptr)。
动态绑定:通过 vptr 指针,运行时可以查找虚函数表中的具体函数地址,决定调用哪个函数实现。
生成阶段:
编译阶段:编译器生成虚函数表和虚指针。虚函数表在类界说时生成,虚指针在对象实例化时设置。
44、构造函数和析构函数的作用?

构造函数:
   作用:在创建对象时初始化对象的状态。构造函数可以用于分配资源、初始化数据成员等。
特性:构造函数与类名雷同,无返回值,可以被重载。
  析构函数:
   作用:在对象生命周期结束时清理对象的资源。析构函数负责开释构造函数分配的资源,如内存、文件句柄等。
特性:析构函数的名字前加 ~,无返回值,不能被重载。
  45、构造函数可以被声明为虚函数吗?

   构造函数不能被声明为虚函数:构造函数在对象创建时调用,此时对象还未完全构造,无法设置虚函数表,因此构造函数不能是虚函数。
  46、构造函数和析构函数谁人可以被重载,为什么?

   析构函数不可以被重载:每个类只能有一个析构函数,负责对象生命周期结束时的清理操作。如果允许重载,会导致析构时不确定性。
    构造函数可以被重载:允许创建对象时通过差别的参数举行初始化。通过重载构造函数,可以提供多种初始化方式。
  47、this 指针,为什么会存在this指针?

   界说:this 指针是指向当前对象的指针。在类的成员函数内部,this 指针指向调用该函数的对象。
访问对象成员:允许成员函数访问对象的属性和其他成员函数。
区分成员变量和参数:在成员函数中,this 指针可以用来区分同名的成员变量和函数参数。
实现链式调用:可以返回 *this 实现链式调用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

灌篮少年

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表