最新C++高频笔试题,你刷过几道?
最近不仅仅是校招季更是金三银四社招黄金月份,找工作的小伙伴都频频出动,学到牛牛的同学已经在三月顺利的找到心仪的工作了,反馈回来最新的面试题,小编特意把高频出现的C++面试题进行汇总,方便大家复习,希望能给同在找工作的朋友一些参考。
C和C++的特点与区别?
C++的三大特性
进程间通信方式和线程间通信方式
C++内存分配有几种方式?
C++编译过程?
什么是虚函数/纯虚函数?
面向对象的三个基本特征
C++中成员函数的重载/覆盖和隐藏的区别
进程和线程的区别?
C++拷贝构造函数在哪几种下被调用?
引用和指针有什么区别?
分布式是什么?
查找算法及时间复杂度
堆和栈
一、C和C++的特点与区别?
(1)C语言特点:
1.作为一种面向过程的结构化语言,易于调试和维护;
2.表现能力和处理能力极强,可以直接访问内存的物理地址;
3.C语言实现了对硬件的编程操作,也适合于应用软件的开发;
4.C语言还具有效率高,可移植性强等特点。
(2)C++语言特点:
1.在C语言的基础上进行扩充和完善,使C++兼容了C语言的面向过程特点,又成为了一种面向对象的程序设计语言;
2.可以使用抽象数据类型进行基于对象的编程;
3.可以使用多继承、多态进行面向对象的编程;
4.可以担负起以模版为特征的泛型化编程。
C++与C语言的本质差别:在于C++是面向对象的,而C语言是面向过程的。或者说C++是在C语言的基础上增加了面向对象程序设计的新内容,是对C语言的一次更重要的改革,使得C++成为软件开发的重要工具。
二、C++的三大特性
封装/继承/多态
三、进程间通信方式和线程间通信方式
管道(pipe):
管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
有名管道(namedpipe) :
有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量(semophore) :
信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列(messagequeue):
消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号(signal):
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存(shared memory):
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
套接字(socket):
套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同设备及其间的进程通信。
二、线程间的通信方式
锁机制:包括互斥锁、条件变量、读写锁
互斥锁提供了以排他方式防止数据结构被并发修改的方法。
读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。
四、C++内存分配有几种方式?
. [2]在栈上创建。. 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。. 栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
. [3]从堆上分配,亦称动态内存分配。. 程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
五、C++编译过程?
预处理+编译+汇编+链接
a.预处理:处理其中的预处理指令,将源代码分割或处理其中的预处理指令,输出一个预处理完毕的文件后缀通常为i
b.编译:这一阶段收到的编译器警告或者错误,是语法错误导致
c.汇编:获取编译阶段生成的文件,进一步翻译为机器代码,得到目标文件,目标文件本身是二进制文件
d.链接:获取汇编阶段生成的目标文件,编译成可执行文件或库文件,然后链接器解析依赖项,链接外部静态库,得到最终的可执行文件或库文件,错误在于错误定义或者重复定义
六、什么是虚函数/纯虚函数?
虚函数
被 virtual 关键字修饰的成员函数称为虚函数。
虚函数的作用是实现多态性,即通过基类访问派生类的函数。
什么是纯虚函数?
在虚函数后面添加 =0 ,虚函数就成为纯虚函数,
在很多情况下,基类生成对象很不合理。为了解决这个问题,引入了纯虚函数的概念,将函数定义为纯虚函数,派生类中必须重写实现纯虚函数。对于实现了纯虚函数的子类,该纯虚函数在子类中就变成了虚函数。
虚函数和纯虚函数有什么区别?
虚函数定义形式:成员函数前添加 virtual 关键字,纯虚函数在虚函数后添加 =0 ;
含有纯虚函数的类,称为抽象类;只含有虚函数的类,不能称为抽象类。
虚函数既可以直接使用,也可以被子类重载实现后,以多态的形式调用;而纯虚函数必须被子类重载实现,才能以多态的形式调用,因为纯虚函数在基类中只有声明。
无论虚函数还是纯虚函数,定义中都不能有 static 关键字。因为 static 关键字修饰的内容在编译前就要确定,而虚函数、纯虚函数是在运行时动态绑定的。
七、面向对象的三个基本特征
面向对象的三个基本特征是:封装、继承、多态。其中,封装 可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!
八、C++中成员函数的重载/覆盖和隐藏的区别
重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
隐藏是指派生类中的函数把基类中相同名字的函数屏蔽掉了。隐藏与另外两个概念表面上看来很像,很难区分,其实他们的关键区别就是在多态的实现上。
九、进程和线程的区别?
(1)调度:线程作为处理器调度和分配的基本单位,而进程是作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,有自己独立的地址空间;线程不拥有系统资源,但可以访问隶属于进程的资源,共享进程的地址空间.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
十、C++拷贝构造函数在哪几种下被调用?
(1)用类的一个对象去初始化另一个对象时
(2)当函数的形参是类的对象时( 也就是值传递时),如果是引用传递则不会调用
(3)当函数的返回值是类的对象或引用时
十一、引用和指针有什么区别?
指针:是存储地址,可以为空,初始化后可以改变,可以指向其他存储单元,sizeof得到的是指针本身大小
引用:是做别名,不能为null,必须初始化,从一而终不能再改变了,引用对象的大小不同
十二、分布式是什么?
分布式是由多个计算机服务器组成的系统,相互的操作可以互通,不同的业务模块部署在不同的服务器上或者同个业务模块分拆为多个子业务,部署在不同的服务器上,解决高并发问题,提供可扩展性和高可用性
特点是服务部署空间多样性,程序运行过程中,并发性操作是很常见的,比如同一个分布式系统中的多个结点,同时访问一个共享资源,无序性进程间的通信会出现顺序不一致
十三、查找算法及时间复杂度
1、顺序查找:
(1)最好情况:要查找的第一个就是。时间复杂度为:O(1)
(2)最坏情况:最后一个是要查找的元素。时间复杂度未:O(n)
(3)平均情况下就是:(n+1)/2。
所以总的来说时间复杂度为:O(n)
2、二分查找:O(log2n)->log以2为底n的对数
解释:2^t = n; t = log(2)n;
3、插值查找:O(log(2)(log(2)n))->log以2为底的(log以2为底的n的对数)的对数
4、斐波那契查找:O(log2n)->log以2为底n的对数
5、树表查找:
(1)二叉树:O(log2n)~O(n)之间
(2)红黑树:O(logn)
(3)B和B+树:O(log2n)
6、分块查找:O(log2n)~O(n)之间
7、哈希查找:O(1)
十四、堆和栈
栈存放一些局部的变量,编译器自动分配释放,如:返回值,局部变量,函数的参数值等
堆存放一些需要程序员分配释放的变量,如果程序员不释放,操作系统可以帮回收释放,如一些new,malloc分配的内存块,用delete,free释放。