C++面试3

一、常用设计模式

https://blog.csdn.net/m0_71530237/article/details/141140118?spm=1001.2014.3001.5501

二、死锁以及解决方式?

死锁:一种常见的并发问题,发生在多个进程或线程因为竞争资源而陷入相互等待的状态,导致这些进程或线程无法继续执行,要理解死锁,通常会涉及以下四个必要条件。

1、互斥条件:资源是不可共享的,即一个资源在同一时间只能被一个进程占用。

2、占有且等待:一个进程已经持有一个资源,同时又在请求其他资源,而此时这些资源正被其他进程占有。

3、不可剥夺:资源不能被强制剥夺,进程只能资源释放资源。

4、循环等待:存在一个进程集,这些进程之间形成一个循环的资源等待链。

死锁的解决方式

1、死锁预防:确保上诉四个条件中的至少一个不能成立,即可阻止死锁发生

2、死锁避免:使用某些算法来动态的判断资源分配状态,避免进入死锁状态,常见的方法是银行家算法

        银行家算法在进程请求资源时,判断系统是否会进入不安全状态。如果不会,则分配资源;否则拒绝该请求,防止死锁发生。

3、死锁检测与恢复:允许系统进入状态,然后检测和处理它。

4、资源有序分配:通过给资源定义一个全局顺序,进程只能按照顺序请求资源,避免循环等待的产生。

实践中的死锁解决方式

超时机制:当一个线程请求资源超过一定时间时,认为它可能处于死锁状态,释放已持有资源并重新开始请求。

锁分层:为不同资源定义不同的优先级和层级,线程只能按照优先级从低到高的顺序去请求资源,避免循环等待。

三、堆栈空间?堆和栈的区别?堆栈溢出问题?

1、栈

栈是操作系统为每个线程分配的一块连续内存空间,用于存储局部变量、函数参数、返回地址等。栈是一种后进先出(LIFO)的数据结构,具有自动管理内存的特点。

存储内容:局部变量、函数参数、返回地址、函数调用过程中的临时数据。

分配方式:栈的内存分配由操作系统自动完成,通常由编译器在函数调用时生成指令管理。

内存大小:站的大小是固定的,一般由操作系统在程序启动时确定。

优点:速度快,自动分配内存和释放,不容易产生内存泄漏。

缺点:大小优先,不能存储大数据;递归调用或过深的函数调用栈容易造成栈溢出。

栈的调用流程:

1、参数返回地址等数据会压入栈中。

2、在函数内部的局部变量也会存储在栈上。

3、函数返回时,栈顶数据(函数返回值和局部变量等)会被弹出,释放栈空间

2、堆

堆是操作系统提供的一块较大的动态空间,专门用于存储动态分配的数据,程序运行时可以通过动态内存分配函数(如malloc()、new)来手动管理堆内存。

存储内容:动态分配的内存快(如malloc()、new分配的内存)

分配的方式:由程序员手动分配和释放,灵活且可动态扩展。

内存大小:堆的大小不固定,通常由操作系统的物理内存决定,能够存储较大的数据。

优点:可以动态分配大内存快,灵活方便,数据生命周期可以跨越多个函数调用。

缺点:分配和释放的速度较慢,如果程序员忘记释放内存,容易造成内存泄漏;过多的动态分配也可能导致堆碎片问题,影响内存效率。

堆的调用流程:

1、使用malloc()或new函数分配内存。

2、返回一个指向这块内存的指针。

3、当不在需要时通过free()或delete释放内存,否则会发生内存泄漏。

栈与堆的比较:

特性
管理方式由操作系统自动管理需要程序员手动管理
存储内容局部变量、函数参数、返回地址等动态分配的对象和数组
分配速度快(内存连续,自动分配和释放)慢(需要寻找空闲内存、手动管理)
内存大小较小(通常几MB)较大(取决于系统可用物理内存)
生命周期随函数调用结束自动释放需程序员手动释放、否则会内存泄漏
使用场景局部变量、函数调用动态分配大数据或对象
常见问题栈溢出(如递归过深)内存泄漏、堆碎片

四、内存泄漏?如何避免?

内存泄漏是指程序在动态分配内存后,未能正确释放已不再使用的内存,导致该内存无法被再次分配和使用。随着程序的运行,未释放的内存逐渐增多,最终可能导致系统内存耗尽,引发系统崩溃或系统性能下降和。避免内存泄漏是编写高效、健壮系统的重要环节。

如何避免:

1、手动释放内存

2、避免重复分配内存

3、使用智能指针

五、智能指针的本质是什么?

智能指针本质上是一个类,用来存储指向动态分配对象的指针,负责动态释放动态分配的对象,防止内存泄漏。动态分配资源,交给一个类对象去管理,当类对象声明周期结束时,自动调用析构函数释放资源。借助RAII和类的特点,防止内存泄漏的问题。

六、野指针?

①、定义一个指针变量,没有给他指向有效的空间或置为空时,系统会默认初始化一个随机地址,变成野指针。②、释放一个指针变量指向的空间时,没有置为空,也会变成野指针。

避免野指针:

1、定义指针变量时,要么设为空,要么指向合法的内存

2、向指针变量指向的空间赋值时,一定要开辟内存空间,

3、开辟空间后需要检查是否分配成功

4、分配成功后要进行初始化

5、注意使用时不要越界访问,否则会产生内存泄漏

6、结束时要释放内存空间

7、释放完之后要将指针变量置为空

检测工具:

gcc自带的ASAN或valgrind工具

七、指针和引用的区别?

指针是一个变量,引用是变量的别名;指针可用为空,引用定义时必须初始化;指针在初始化之后可以改变指向,引用在初始化之后不可以改变指向;指针可以有多级,引用最多两级;指针需要动态分配内存空间,引用不需要动态分配;指针引用占8个字节;指针间接访问,效率低、,引用直接访问,效率高;做函数形参时,指针需要考虑传值还是传址,引用不需要考虑,它既可以访问,也可以修改,函数返回值是引用可以做左值;

八、C++三大特性?

封装:

封装是面向对象的核心思想,因为封装解决了代码独立性的问题,从而提高了代码的复用性,为复用性和扩展性提供了基础,封装将成员属性和成员方法绑定在一起,通过选择访问权限实现对外提供接口,对内开放数据从而达到对数据的保护,类内有构造函数和析构函数,不用去考虑释放,提供了一种更安全的机制,提高开发效率。

类封装的本质是在于将数据和行为绑定在一起,然后通过对象来完成操作,封装对私有函数添加get/set方法,全局变量会破坏数据的封装,可以采用静态成员来解决。

继承:

派生类可以使用基类的属性和方法,实现不同类之间的代码复用性,继承使得我们可以基于已有的类创建新的类,无需重新编写实现代码,派生类可以添加新的属性和方法,或重写(override)基类的方法来实现新的功能(通过重写虚函数virtual来实现)

基类提供属性和方法,派生类继承自基类并扩展或修改其行为

单继承 :一个派生类只能继承自一个基类

多继承  :一个派生类可以同时继承自多个基类

多态:

①多态是使用同一接口,传递不同实例对象,执行不同操作(C语言中的共用体就是一种多态)

②当功能不断变化,考虑用多态实现代码的扩展性

③静多态(编译时绑定)的函数重载和模板和动多态(运行时绑定)的虚函数(少用)

④基类中要有虚函数;派生类要重写基类中的虚函数(override);通过基类的指针或引用绑定派生类的对象

⑤优点,多态解决代码扩展性的问题,增加程序的灵活性,减轻系统升级、维护、调试的工作量和复杂度

缺点:多态影响效率,造成空间浪费(引入虚函数表指针)

九、重载、重写和隐藏?

重写:派生类中重新定义基类的虚函数,具有相同的函数签名,实现多态

重载:同一作用域内定义多个同名函数,但是他们的参数不同

隐藏:子类中定义了与父类具有相同名字但不同参数列表的函数,或子类中定义了与父类中非虚函数同名的函数,此时,父类中的同名函数在子类中被隐藏。子类的函数会覆盖父类的同名函数

十、this指针?

this指针是隐藏在对象成员函数内的一种指针,当一个对象被创建后,他的没有个成员函数都含有一个系统自动生成的隐含指针this,用于保存这个对象的地址,也就是说我们没有写上this指针,编译器在编译的时候也会加上。this永远指向当前对象,this指针并不是对象的一部分,不会影响sizeof(对象的大小)的结果。

this指针是C++实现封装的一种机制,他将对象和该对象调用的成员函数连接在一起,在外部看来,每一个对象都拥有自己的成员函数。一般情况下,不写this,而是让系统进行默认设置。

十一、局部变量和全局变量?

特性局部变量全局变量
作用范围尽在定义的函数或代码块内可见整个程序范围内可见
生命周期进入作用域时创建,离开作用域时销毁程序启动时创建,程序结束时销毁
存储位置栈内存全局数据区或静态存储区
初始化无默认初始值,使用前需手动初始化自动初始化为0或null
访问方式只能子啊定义他的函数或块内访问可被程序的任何地方访问(除非有限定)
冲突问题不会和其他函数中的局部变量冲突可能会与其他模块中的变量或函数名冲突

十二、进程间通信和线程间通信?

进程间通信:

传统通信:管道、信号

ipc通信:消息队列、共享内存、信号量

网络通信:socket(套接字)

线程间通信:

全局变量、条件变量、信号量、消息队列、事件、管道和文件

十三、多线程访问同步方式?

互斥锁:用于保护共享资源,确保同一时间只有一个线程能够访问该资源

读写锁:允许多个线程同时读取共享资源,但写操作需要独占资源

条件变量:用于在线程之间传递信号,允许一个线程等待条件满足后继续执行

信号量:一种计数器,用于控制对资源的访问

十四、线程池?

如何确保线程池中的任务能够按照顺序执行?

线程池不保证任务按照提交顺序执行,因为多个线程可能并发执行任务,如果需要严格的顺序控制,可以通过使用额外的同步机制(队列或条件变量)来管理任务的执行顺序

线程池中为什么不直接存储线程对象,而是存储指向线程的指针?

存储指向线程的指针可以避免对象的拷贝和移动操作,保证每个线程对象在创建后都能被正确管理和释放。如果存储线程对象本身,可能会引发不必要的拷贝构造和移动构造操作

线程池的作用是什么?他是如何提高多线程应用的性能?

线程池的主要作用是通过复用以创建的线程来执行任务,避免频繁创建和销毁线程开销,从而提高性能。线程池提前创建·一定数量的线程,当有任务时,线程池中的线程可以直接处理任务,避免了创建新线程的延迟

十五、connect连接方式?

网络编程中用于建立客户端和服务器端之间的连接的系统调用。它主要用于基于 TCP/IP 协议的套接字编程中,用于客户端连接到服务器

十六、TCP与UDP的区别?

十七、简单的数据结构?

https://blog.csdn.net/m0_71530237/article/details/141996354?spm=1001.2014.3001.5501

十八、槽函数的使用以及注意事项?

槽函数本质上是一个普通的成员函数,它可以被信号触发,槽函数的定义与普通函数类似,但是要放在slots:访问控制符之下,或通过Q_OBJECT宏使其成为槽函数。使用connect()函数将信号和槽连接起来。第一个参数:发送信号的对象;第二个参数:信号的名称;第三个参数:接收信号的对象;第四个参数:槽函数的名称,从QT5开始,可以使用lambda表示式,不需要定义一个单独的槽函数

注意事项:信号和槽默认线程安全;使用Q_OBJECT宏

十九、C++新特性

自动类型推导 (auto): 自动推导变量的类型,减少显式类型声明的繁琐

范围 for 循环: 用于遍历容器或数组,简化代码。

nullptrnullptr 取代 NULL,表示空指针,类型更明确。

lambda 表达式: 允许定义匿名函数,常用于 STL 算法或事件处理。

智能指针 (std::shared_ptrstd::unique_ptr): 引入了自动管理内存的智能指针,减少手动管理内存泄漏的风险

右值引用 (&&) 和移动语义: 移动语义允许资源的转移,而不是复制,提高了性能,特别是在容器操作中

线程支持 (<thread> 头文件): 引入了标准线程库,简化了多线程编程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter之SystemChrome全局设置

一、简介 SystemChrome作为一个全局属性&#xff0c;很像 Android 的 Application&#xff0c;功能很强大。 二、使用详解 2.1 setPreferredOrientations 设置屏幕方向 在我们日常应用中可能会需要设置横竖屏或锁定单方向屏幕等不同要求&#xff0c;通过 setPreferredOrien…

JavaScript高级——作用域和作用链

1、概念理解&#xff1a; —— 就是一块“地盘”&#xff0c;一个代码所在的区域 —— 静态的&#xff08;相对于上下文对象&#xff09;&#xff0c;在编写代码时就确定了 2、分类 ① 全局作用域 ② 函数作用域 ③ 没有块作用域&#xff08;ES6有了&#xff09; 3、作用 …

WPF利用Path自定义画头部导航条(TOP)样式

1;新建两个多值转换器&#xff0c;都有用处&#xff0c;用来动态确定PATH的X,Y州坐标的。 EndPointConverter 该转换器主要用来动态确定X轴&#xff0c;和Y轴。用于画线条的。 internal class EndPointConverter : IMultiValueConverter {public object Convert(object[] val…

GIS 中的 3D 分析

GIS 中的 3D 分析 3D 分析已成为 GIS 的一个发展趋势&#xff0c;因为它能够更好地表现现实世界。 这不仅仅是为了得到漂亮的图片。对于某些类型的问题&#xff0c;3D 分析有时是解决它们的唯一方法。 3D 数据类型的激增也推动了这一需求。例如&#xff0c;LiDAR、BIM、UAV、…

VS Code 配置 Rust-Analyzer 报错

报错信息&#xff1a; Bootstrap Error" rust-analyzer requires glibc > 2.28 in latest build. 参考了好多地方&#xff0c; https://github.com/rust-lang/rust-analyzer/issues/11558 https://blog.csdn.net/aLingYun/article/details/120923694 https://rust-anal…

C++——⼆叉搜索树

文章目录 一、 ⼆叉搜索树的概念二、⼆叉搜索树的性能分析三、⼆叉搜索树的插⼊四、⼆叉搜索树的查找五、⼆叉搜索树的删除六、二叉搜索树的有序遍历七、⼆叉搜索树的实现代码八、二叉搜索树key与key_value的应用key的应用key_value的应用key/value⼆叉搜索树代码实现 一、 ⼆叉…

C++类与对象深度解析(一):从抽象到实践的全面入门指南

文章目录 C 类与对象——详细入门指南前言1. 类的定义1.1 类定义的基本格式示例代码解释 1.2 访问限定符示例代码解释 1.3 类域示例代码解释 1.4 成员命名规范常见的命名约定&#xff1a;示例&#xff1a;拓展&#xff1a; 1.5 class与struct的默认访问权限示例&#xff1a; 2.…

搭建Windows下的Rust开发环境

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 2.1.1 安装vs_buildtools 在Windows系列操作系统中&#xff0c;Rust开发环境需要依…

归并排序(Merge Sort)

什么是归并排序 归并排序&#xff08;Merge Sort&#xff09;是一种经典的排序算法&#xff0c;它采用分治法&#xff08;Divide and Conquer&#xff09;策略&#xff0c;将一个大数组分为两个小数组&#xff0c;分别进行排序&#xff0c;然后将这两个已排序的小数组合并成一个…

音视频开发常见的开源项目汇总

FFmpeg 地址&#xff1a;https://ffmpeg.org/介绍&#xff1a;FFmpeg 是一个非常强大的开源多媒体框架&#xff0c;它可以用来处理视频和音频文件。它支持多种格式的转换、编码、解码、转码、流处理等。FFmpeg 包括了 libavformat、libavcodec、libavutil、libswscale、libpos…

组播 2024 9 11

PIM&#xff08;Protocol Independent Multicast&#xff09;是一种常用的组播路由协议&#xff0c;其独立于底层的单播路由协议&#xff0c;能够在多种网络环境中有效地实现多播路由功能。PIM主要有两种模式&#xff1a;PIM Sparse Mode (PIM-SM) 和 PIM Dense Mode (PIM-DM)&…

【C++题解】1580. 扫雷(mine)

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1580. 扫雷&#xff08;mine&#xff09; 类型&#xff1a;二维数组 题目描述&#xff1a; 扫雷游戏是一款十分经典的单机小游戏。在 n 行 m 列的雷区中有一些格子含有地雷&#x…

I/O 多路复用:`select`、`poll`、`epoll` 和 `kqueue` 的区别与示例

I/O 多路复用是指在一个线程内同时监控多个文件描述符&#xff08;File Descriptor, FD&#xff09;&#xff0c;以便高效地处理多个 I/O 事件。在 UNIX/Linux 和 BSD 系统中&#xff0c;select、poll、epoll、kqueue 都是实现 I/O 多路复用的系统调用。它们各有特点&#xff0…

el-input设置type=‘number‘和v-model.number的区别

el-input设置typenumber’与设置.number修饰符的区别 1. 设置type‘number’ 使用el-input时想收集数字类型的数据&#xff0c;我们首先会想到typenumber&#xff0c;设置完type为number时会限制我们输入的内容只能为数字&#xff0c;不能为字符/汉字等非数字类型的数值&…

性能诊断的方法(五):架构和业务诊断

关于性能诊断的方法&#xff0c;我们可以按照“问题现象—直接原因—问题根源”这样一个思路去归纳。我们先从问题的现象去入手&#xff0c;包括时间的分析、资源的分析和异常信息的分析。接下来再去分析产生问题现象的直接原因是什么&#xff0c;这里我们归纳了自上而下的资源…

外观模式详解:如何为复杂系统构建简洁的接口

&#x1f3af; 设计模式专栏&#xff0c;持续更新中 欢迎订阅&#xff1a;JAVA实现设计模式 &#x1f6e0;️ 希望小伙伴们一键三连&#xff0c;有问题私信都会回复&#xff0c;或者在评论区直接发言 外观模式 外观模式&#xff08;Facade Pattern&#xff09;为子系统中的一组…

linux系统安装miniconda3

一、下载minconda3 下载地址&#xff1a;https://docs.conda.io/en/latest/miniconda.html 一般国内访问比较困难&#xff0c;可到清华软件镜像站 Index of /anaconda/miniconda/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 需要特别注意自己的下载版本和自己的…

初识爬虫2

requests学习&#xff1a; 小技巧&#xff0c;如果你用的也是pycharm&#xff0c;对于控制台输出页面因为数据很长一行&#xff0c;不方便进行查看&#xff0c; 可以让它自动换行&#xff1a; 1.requests文档阅读学习链接&#xff1a;快速上手 — Requests 2.18.1 文档 需掌…

【运维监控】Prometheus+grafana监控zookeeper运行情况

运维监控系列文章入口&#xff1a;【运维监控】系列文章汇总索引 文章目录 一、prometheus二、grafana三、prometheus集成grafana监控zookeeper1、修改zookeeper配置2、修改prometheus配置3、导入grafana模板4、验证 本示例通过zookeeper自带的监控信息暴露出来&#xff0c;然后…

基于imx6ull平台opencv的图像采集和显示屏LCD显示功能(带Qt界面)

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 验证功能一、概述 本文档是针对imx6ull平台opencv的图像采集和显示屏LCD显示功能,创建Qt工程,在工程里面通过点击按钮,实现opencv通过摄像头采集视频图像,将采集的视频图像送给显示屏LCD进…