C++面试经典题目汇总

一:C++中指针和引用的区别

1.指针是用来保存存储地址的,一般需要初始化NULL。

引用是取别名(类似小名),定义的时候一定要初始化,不能为NULL。

2.引用不占用字节,但引用不可以改变:引用和变量指向同一片内存。

指针占用4个字节,指针可以指向不同的地址,可以改名称。

3.引用比指针使用起来会更加简洁,安全。使用指针时要特别注意野指针。

4.在sizeof中含义不同:引用结果为引用类型的大小,指针始终是地址空间所占字节个数(32位:4字节 64位8字节)。

5.引用自加即引用的实体增加1,指针自加即指针向后偏移一个数据类型的大小。

6.有多级指针,但是没有多级引用。

7.访问实体方式不同,指针需要显式解引用,引用则是编译器自己处理。

二:C++中重写和重载的区别

1.重载(overload):函数名相同,函数的参数个数,参数类型或者参数顺序三者中必须至少有一种不同。函数返回值的类型可以相同,也可以不同。发生在一个类内部,不能跨作用域。也就是说使用同一个函数去完成不同的功能。

2.重写(override):也叫做覆盖,一般发生在子类和父类继承关系之间。子类重新定义父类中有相同名称和参数的虚函数,返回值可以不相同,但是必须是父子关系的指针或者引用。

重写需要注意:

a.被重写的函数不能是static,必须是virtual

b.重写函数必须有相同的类型,名称和参数列表

c.重写函数的访问修饰符(public/private/protected)可以不同

三:什么是进程

程序的执行实例被称为进程(process)。简单来说,进程是动态的概念,指的是程序的一次运行活动,通俗点来看就是程序运行起来了的时候,系统中就多了一个进程。进程相当于是程序的一次执行过程。进程包含线程。

四:什么是程序

程序(program)是存放在磁盘文件中的可执行文件。是静态的。

五:程序和进程的区别

1.程序是指令和数据的有序集合,是一个静态的概念,而进程是程序在处理机上的一个执行过程,它是一个动态的概念。

2.程序可以作为一种软件资料长期存在,而进程是有一定生命周期的。程序是永久的,进程只是暂时的。

3.进程是进程控制块,程序段,数据段三部分组成。

4.进程具有创建其他进程的功能,而程序没有。

5.同一程序同时运行于若干个数据集合上,它将属于若干个不同的进程,也就是说同一个程序可以对应多个进程。

6.在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单元都是进程。

六:为什么要使用进程

如果程序在运行的过程中,频繁地请求IO操作,那么CPU就会等待该程序的IO操作完成后再为其服务,这就大大的浪费了CPU资源,降低CPU效率。因此采用一种“程序排队”机制来提高CPU利用效率,从而产生了进程。

七:深拷贝和浅拷贝 区别 以及 使用场景

1.拷贝构造函数:是一种特殊的构造函数,由编译器调用来完成一些基于同一类的其他对象的构件以及初始化。

2.使用场景

a.函数参数中以值传递的方式传入时,会将传入的实际参数拷贝一份。

b.函数返回中返回了一个局部对象,会将其拷贝一份并且返回。

c.在给一个对象初始化的时候(不是赋值),会将值拷贝一份。

3.什么是深拷贝和浅拷贝

浅拷贝:只是对指针的拷贝,拷贝后两个指针指向同一个内存空间。

深拷贝:不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经过深拷贝后的指针是指向两个不同地址的指针,也就是程序员自己编写的拷贝构造函数。

重点:系统默认生成的拷贝构造函数是浅拷贝,深拷贝是程序员自己编写的拷贝构造函数。

4.浅拷贝造成的问题

a.浅拷贝只是拷贝了指针,使两个对象的指针指向同一地址,在对象结束的时候,会造成同一块内存资源析构两次,造成程序崩溃。

b.指针指向同一块内存,任何一方有改动都会影响另一方。

c.在释放内存时,后者的内存先释放会导致前者的内存也释放,导致空间不能再被利用、

以上的这些问题就可以使用到深拷贝来进行避免!

八:C中的new和malloc的区别

molloc开辟一块内存,不进行初始化(动态开辟内存)

new用来开辟内存,需要进行初始化(动态内存管理)

区别

1.malloc以及free都是函数(C语言),而new delete都是运算符(C++),都开在堆区。

2.malloc需要指定开辟空间大小,new不需要,知道数据类型即可。

3.malloc返回void*,一般强制转换。new则不需要。

4.malloc开free收,new开delete释放。

5.new内存分配失败时,会抛出异常警告。malloc分配内存失败时会返回NULL。

6.new不仅能开辟内存,还能进行初始化,malloc只能开辟内存,不能初始化。

7.new开辟的内存叫做自由存储区,malloc开辟的内存叫做堆区。

8.new可以重载,malloc不能重载。

9.new开辟数组时,用[ ]传入数组的大小。

10.new在创建类的时候,会默认调用构造函数,而malloc不会。

11.delate会默认调用类的析构函数,而free不会。

12.如果父类的析构函数有写虚函数的关键字,当子类被析构的时候,会默认调用父类的析构函数。

九:简述通用链表的原理

通用链表是一个链式结构,其中至少包含一个指针域和一个数据域。如果只包含一个,就表示指针域时指向下一个节点。如果是双向链表,其中包含一个数据域和两个指针域。一个指针域指向上一个节点,一个指针域指向下一个节点。通常情况下,链表的添加是尾部添加,当然也有中间插入的,主要是看是什么容器。删除节点:list容器可以从中间删除和尾部删除。队列只可以头部删除,尾部追加,不存在数据插入。

十:模板类和类模板 区别和作用

模板类是类,类模板是模板。

类模板需要我们自己去写(将逻辑什么的写好放入),而模板类是将写好的类模板将参数传递进去。容器本来就是一个模板类。它的底层原理就是模板类。

十一:为什么需要使用自定义通信协议

所谓通讯协议就是指 通信双方对数据传送控制的一种约定。约定中包括有对数据格式,同步方式,传送速度,传送步骤,纠错方式以及控制字符定义等问题做出统一规定,通信双方必须同时遵守,倘若一方不遵守,就会直接导致数据不能被解析!

更通俗来讲,它可以理解为两个节点之间为了协同工作实现信息交换,协商一定的规则和约定,例如规定字节序,各个字段类型等。我们最常见的可能就是TCP(传输控制协议)/IP(网络协议)、UDP(用户数据报协议)等。

不过,上面提到的这些协议是操作系统已经设定好的,并且广泛应用在网络通信中。最重要的一点是我们不能更改这些协议。而用户自定义的通讯协议就不同了。它的实现需要用户自己设定数据发送的格式以及数据的封装形式。然后通过上面的网络传输协议发送给对端,对端再根据自己定义好的协议对数据进行解析,从而得到想要的数据。

自定义通信协议组成:协议头 + 协议体 (定长包头 + 不定长包体)

协议头里包含:服务器是什么业务

协议体里包含:具体业务数据参数

十二:进程和线程的区别

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

线程是“一个进程内部的控制序列”。

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。

资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销。线程可以看作是轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己的独立的运行栈和程序计数器(PC),线程之间切换的开销小。

包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。

影响关系:一个进程崩溃后,在保护模式下不会对其他的进程产生影响,但是一个线程崩了就会导致整个进程卡死,所以多进程要比多线程更健壮。

执行过程:每个独立的进程有程序运行的入口,顺序执行序列和程序出口,但是线程不能独立运行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可以并发执行。

十三:TCP和UDP的区别

TCP和UP都是传输层协议

1.TCP面向连接(如打电话要先拨号建立连接),UDP是无连接的,即发送数据之前不需要建立连接。

2.TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差别,不丢失,不重复,并且按序到达,UDP尽最大的努力去交付,即不保证可靠交付。

TCP通过校验和,重传控制,序号标识,滑动窗口,确认应答实现可靠传输,如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

3.UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

4.每一条TCP连接只能是点到点的,UDP支持一对一,一对多,多对一,和多对多的交互通信。

5.TCP对系统资源要求较多,UDP对系统资源要求较少。

十四:通信协议的作用

通信协议又称为通信规程,是指通信双方对数据传送控制的一种约定。约定中包括对数据格式,同步方式,传送速度,传送步骤,检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,它也叫做链路控制规程。

电脑和电脑之间的沟通必须讲述相同的语言,才能互相传输信息,自然资料在国际互联网上传递,每一份都要符合一定的规格(即是相同的语言)。

这些规格(语言)的规定都是事先在会议上讲好的,一般我们称之为“协议”(英文称为protocol),而这种在网络上负责定义资料传输规格的协议,我们就统称为通信协议。

十五:拷贝构造函数 为什么使用const&

调用拷贝构造函数的三种情况

1.用已知的对象拷贝生成新对象

2.以值传递的方式传入函数

3.函数的返回值 是以值传递的方式

在值传递的时候,传参期间会产生一个临时变量,当我们实例化对象d1后,将d1拷贝给d2时调用拷贝构造函数,此时d1发生值传递,d1将值传递给临时对象dd1,因为是值传递,一旦调用又要产生临时变量ddd1,将d1的值传递给临时变量ddd1,那么问题就很明显了,值传递,会进行形参实例化,类 类型实例化,会再调用构造函数,就会一直调用,因此结果就是无穷递归,所以要使用引用传参。

第三种参数的返回值是以值传递的方式,首先我们需要知道,返回一个局部变量是通过一个临时的变量返回,对象也不例外,这里也会产生一个临时的对象,而这个临时对象,具有常性,也就是const,不可被修改,赋值之后临时对象也就消亡了。临时对象,具有const常性。所以当我们把const加上,通过严格的参数匹配,编译器才能找到我们的const&版本的拷贝构造函数。

猜你喜欢

转载自blog.csdn.net/m0_56051805/article/details/126422524