IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C和C++面试问题总结 -> 正文阅读

[C++知识库]C和C++面试问题总结

?1.A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?

这两个static变量会保存到哪里(栈还是堆或者其他的)?

答案:static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。他们都放在静态数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern 关键字。

2、C++重写和重载的区别

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

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

重写需要注意:

1、 被重写的函数不能是static的。必须是virtual的

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

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

3、什么是进程 程序的执行实例被称为进程(process)。

简单来说:进程是动态的概念,指的是程序的一次运行活动,通俗来说就是程序跑起来了,系统中就多了一个进程。程序的一次执行过程。?

?4、什么是程序

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

?5、程序和进程的区别 ?

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

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

c> 进程是由进程控制块、程序段、数据段三部分组成;

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

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

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

?6、为什么要使用进程

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

?7、深拷贝和浅拷贝区别及使用场景

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

使用场景

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

2、函数返回中返回了一个局部对象,会将其拷贝一份并返回

3、再给一个对象初始化的时候(不是赋值)会将值拷贝一份。

4、什么是深拷贝和浅拷贝

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

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

重点:系统默认生成的拷贝构造函数是浅拷贝。

浅拷贝造成的问题

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

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

(3)在释放内存时,后者的内存先释放会导致前者内存也释放,导致空间不能再被利用。 而以上这些问题就可以使用深拷贝来进行避免。

?8、New和mallloc的区别

malloc开辟一块内存,不进行初始化(动态开辟内存)。new用于开辟内存,进行初始化(动态内存管理)。

1.malloc 以及free都是函数(C语言) 而new delete都是运算符(C++),都开在堆区 2.malloc指定开辟空间大小,new不需要,知道类型即可

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

4.malloc开free收 new开delete释放

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

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

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

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

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

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

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

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

?9、简述通用链表的原理

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

?10、模板类和类模板的区别及作用

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

?11、为什么需要自定义通信协议

????????所谓通讯协议就是指通信双方对数据传送控制的一种约定。约定中包括对数据格式,同步方式,传送速度,传送步骤,纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,倘若一方不遵守,便会直接导致 数据不能被解析!更通俗来讲,它可以理解两个节点之间为了协同工作实现信息交换,协商一定的规则和约定,例如规定字节序,各个字段类型等。我们最常见到的可能是TCP(传输控制协议)/IP(网际协议)、 UDP(用户数据报协议)等。

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

自定义通信协议组成:协议头+协议体(定长包头+不定长包体)。协议头里包含:服务器是什么业务。协议体里包含:具体业务数据

?12、进程和线程的区别

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

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

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

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

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

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

????????影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

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

?13、TCP和UDP区别

tcp和udp都是传输层协议

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

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付 Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

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

4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信 5、TCP对系统资源要求较多,UDP对系统资源要求较少。

?14、通信协议的作用

通讯协议又称通信规程,是指通信双方对数据传送控制的一种约定。约定中包括对数据格式,同步方式,传送速度,传送步骤,检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,它也叫做链路控制规程。 电脑与电脑之间的沟通必须讲述相同的语言,才能互相传输信息,自然资料在国际互联网上传递,每一份都要符合一定的规格(即是相同的语言)。 这些规格(语言)的规定都是事先在会议上讲好的,一般我们称之为“协议”(英文称为protocol),而这种在网络上负责定义资料传输规格的协议,我们就统称为通讯协议

?15、拷贝构造函数为什么要使用const &

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

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

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

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

????????在值传递时候,传参期间会产生一个临时变量,当我们实例化对象d1后,将d1拷贝给d2时调用拷贝构造函数,此时d1发生值传递,d1将值传递给临时对象dd1,而此时又要调用拷贝构造函数将d1的值传递给dd1,因为是值传递, 一旦调用又要产生临时变量ddd1,将d1的值传递给临时变量ddd1,那么问题就很明显了,值传递,会进行形参实例化,类类型实例化,会再调用构造函数,就会一直调用,因此结果就是无穷递归,所以要使用引用传参。 第三种函数的返回值是以值传递的方式,首先我们得知道,返回一个局部变量是通过一个临时的变量返回,对象也不例外,这里也会产生一个临时的对象,而这个临时对象,具有常性,也就是const,不可被修改,赋值之后 临时对象也就消亡了。临时对象,具有const常性。所以当我们把const加上,通过严格的参数匹配,编译器才能找到我们的const & 版本的拷贝构造函数

16、同步和互斥

????????互斥:是指散布在不同任务之间的若干程序片断,当某个任务运行其中一个程序片段时,其它任务就不能运行它们之中的任一程序片段,只能等到该任务运行完这个程序片段后才可以运行。最基本的场景就是:一个公共资源 同一时刻只能被一个进程或线程使用,多个进程或线程不能同时使用公共资源。

????????同步:是指散布在不同任务之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。最基本的场景就是:两个或两个以上的进程或线程在运行过程中协同步调, 按预定的先后次序运行。比如 A 任务的运行依赖于 B 任务产生的数据。

????????显然,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。也就是说互斥是两个任务之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照 某种次序来运行相应的线程(也是一种互斥)!因此互斥具有唯一性和排它性,但互斥并不限制任务的运行顺序,即任务是无序的,而同步的任务之间则有顺序关系。?

17、同步和异步

????????同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。

????????异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。 ?

18、同步异步和阻塞

????????网络通信中的同步机制和异步机制是描述通信模式的概念。同步机制,是指发送方发送请求后,需要等待接收到接收方发回的响应后,才接着发送下一个请求;异步机制,和同步机制正好相反,在异步机制中,发送方发出一个 请求后,不等待接收方响应这个请求,就继续发送下个请求。在同步机制中,所有的请求在服务器端得到同步,发送方和接收方对请求的处理步调是一致的;在异步机制中,所有来自发送方的请求形成一个队列,接收方处理 完成后通知发送方。

????????阻塞和非阻塞用来描述进程处理调用的方式,在网络通信中,主要指网络套接字Socket的阻塞和非阻塞方式,而Socket的实质也就是IO操作。Socket的阻塞调用方式为,调用结果返回之前,当前线程从运行状态被挂起, 一直等到调用结果返回之后,才进入就绪状态,获取CPU后继续执行;Socket的非阻塞调用方式和阻塞调用方式正好相反,在非阻塞方式中,如果调用结果不能马上返回当前线程也不会被挂起,而是立即返回执行下一个调用。

????????两对概念的组合,就会产生四个新的概念,同步阻塞、异步阻塞、同步非阻塞、异步非阻塞。

1、同步阻塞方式,发送方向接收方发送请求后,一直等待响应;接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。比如,在超市排队付账时, 客户(发送方)向收款员(接收方)付款(发送请求)后需要等待收款员找零,期间不能做其他的事情;而收款员等待收款机返回结果(IO)操作后才能把零钱取出来交给客户(响应请求),期间也只能等待, 不能做其他事情。这种方式实现简单,但是效率不高。

2、同步非阻塞方式,发送方向接收方发送请求后,一直等待响应;接收方处理请求时进行的IO操作如果不能马上得到结果,就立即返回,去做其他事情,但由于没有得到请求处理结果,不响应发送方,发送方一直等待。 一直到IO操作完成后,接收方获得结果响应发送方后,接收方才进入下一次请求过程。在实际中不使用这种方式。

3、异步阻塞方式,发送方向接收方发送请求后,不用等待响应,可以接着进行其他工作;接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。 这种方式在实际中也不使用。

4、异步非阻塞方式,发送方向接收方发送请求后,不用等待响应,可以继续其他工作;接收方处理请求时进行的IO操作如果不能马上得到结果,也不等待,而是马上返回去做其他事情。当IO操作完成以后,将完成状态和结果 通知接收方,接收方再响应发送方。继续使用在超市排队付账的例子。客户(发送方)向收款员(接收方)付款(发送请求)后在等待收款员找零的过程中,还可以做其他事情,比如打电话、聊天等; 而收款员在等待收款机处理交易(IO操作)的过程中还可以帮助客户将商品打包,当收款机产生结果后,收款员给客户结账(响应请求)。在四种方式中,这种方式是发送方和接收方通信效率最高的一种。?

19、C++的内存管理 在C++中,

内存被分成五个区:栈、堆、自由存储区、静态存储区、常量区

栈:存放函数的参数和局部变量,编译器自动分配和释放

堆:new关键字动态分配的内存,由程序员手动进行释放,否则程序结束后,由操作系统自动进行回收

自由存储区:由malloc分配的内存,和堆十分相似,由对应的free进行释放

全局/静态存储区:存放全局变量和静态变量

常量区:存放常量,不允许被修改?

20、 构造函数为什么一般不定义为虚函数?而析构函数一般写成虚函数的原因 ?

1、构造函数不能声明为虚函数

????????1)因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的。而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等等

????????2)虚函数的调用需要虚函数表指针,而该指针存放在对象的内存空间中;若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数即构造函数了

2、析构函数最好声明为虚函数

????????首先析构函数可以为虚函数,当析构一个指向派生类的基类指针时,最好将基类的析构函数声明为虚函数,否则可以存在内存泄露的问题。 如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除指向派生类的基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。

子类析构时,要调用父类的析构函数吗?

????????析构函数调用的次序时先派生类后基类的。和构造函数的执行顺序相反。并且析构函数要是virtual的,否则如果用父类的指针指向子类对象的时候,析构函数静态绑定,不会调用子类的析构。 不用显式调用,会自动调用?

21、C++文件编译与执行的四个阶段

1)预处理:根据文件中的预处理指令来修改源文件的内容

2)编译:编译成汇编代码

3)汇编:把汇编代码翻译成目标机器指令

4)链接:链接目标代码生成可执行程序?

22、结构体struct和共同体union(联合)的区别

结构体:将不同类型的数据组合成一个整体,是自定义类型

共同体:不同类型的几个变量共同占用一段内存

1)结构体中的每个成员都有自己独立的地址,它们是同时存在的; 共同体中的所有成员占用同一段内存,它们不能同时存在;

2)sizeof(struct)是内存对齐后所有成员长度的总和,sizeof(union)是内存对齐后最长数据成员的长度、

结构体为什么要内存对齐呢?

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常

2.硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升。?

23、重载overload,覆盖(重写)override,隐藏(重定义)overwrite,这三者之间的区别 1)overload,将语义相近的几个函数用同一个名字表示,但是参数列表(参数的类型,个数,顺序不同)不同,这就是函数重载,返回值类型可以不同

????????特征:相同范围(同一个类中)、函数名字相同、参数不同、virtual关键字可有可无

2)override,派生类覆盖基类的虚函数,实现接口的重用,返回值类型必须相同

????????特征:不同范围(基类和派生类)、函数名字相同、参数相同、基类中必须有virtual关键字(必须是虚函数)

3)overwrite,派生类屏蔽了其同名的基类函数,返回值类型可以不同

????????特征:不同范围(基类和派生类)、函数名字相同、参数不同或者参数相同且无virtual关键字?

24、const知道吗?解释一下其作用

const一般表示只读属性

const修饰类的成员变量,表示常量不可能被修改

const修饰类的成员函数,表示该函数不会修改类中的数据成员,不会调用其他非const的成员函数

const函数只能调用const函数,非const函数可以调用const函数?

25、关键字static的作用

1)函数体内: static 修饰的局部变量作用范围为该函数体,不同于auto变量,其内存只被分配一次,因此其值在下次调用的时候维持了上次的值

2)模块内:static修饰全局变量或全局函数,可以被模块内的所有函数访问,但是不能被模块外的其他函数访问,使用范围限制在声明它的模块内

3)类中:修饰成员变量,表示该变量属于整个类所有,对类的所有对象只有一份拷贝

4)类中:修饰成员函数,表示该函数属于整个类所有,不接受this指针,只能访问类中的static成员变量

注意和const的区别!!!const强调值不能被修改,而static强调唯一的拷贝,对所有类的对象?

参考:C++面试题_weixin_44421186的博客-CSDN博客?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:33:07  更:2022-09-30 00:33:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 6:40:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码