C++面试题
什么是c++?请简述它的优点和缺点
c++是一种面向对象的编程语言,实现了继承、抽象、多态和封装等概念。**优点:**能够开发复杂的应用程序,提供了极大地灵活性,让开发者能够控制资源的使用和可用性,从而最大限度的提高性能。**缺点:**由于C++太过自由,导致指针对内存操作时可能造成内存溢出、野指针等问题,从而造成程序奔溃。可以使用智能指针解决相应问题。
C++编译与执行的四个阶段
- 预处理:根据文件中的预处理指令来修改源文件的内容
- 编译:编译成汇编代码
- 汇编:把汇编代码翻译成目标机器指令
- 链接:链接目标代码生成可执行程序
C++11有哪些新特性?(招聘时明确要求会c++11的会问)
c++11中引入了新功能:
- auto让我们能够定义这样的变量,将它的类型交给编译器去推断,这样简化了变量的生命,同时不影响类型安全。
- 基于范围的for循环:遍历数组可以像python一样简单。
- **Lambda表达式:**他是一个没有名称的函数,可以编写紧凑的函数对象,而无需提供冗长的类定义,从而极大地减少了代码。
什么是名字空间(namespace)?
名字空间是给代码指定的名称,有助于降低命名冲突的风险。通过std::cout,可以调用该名字空间的独一无二的函数。
什么是变量?什么是常量?什么是常量表达式?
变量:变量就是向编译器指出了变量可存储的数据的性质,编译器将为变量预留必要的空间。
常量:常量的定义基本和变量相同,只是在类型前增加const关键字,这样可以防止之后对其值做修改,如果只是一个固定的值建议使用const关键字。
常量表达式:通过关键字constexpr使用常量表达式,它看起来像函数,但是编译器在编译的时候就会计算函数的值。
有哪些关键字不可作为变量名使用?
c++的关键字有很多:比如auto、if、else、new this、true、false、NULL、void、int、long等都不可以作为变量名来使用。
什么是指针?什么是引用?什么是解引用?(重点)
指针:指针是存储内存地址的变量。声明指针变量时可以使用变量类型在后面加上*变量名 = 值即可,声明指针时务必初始化指针。
引用:引用是变量的别名。声明引用时,需要将其初始化为一个变量,所以引用时另一种访问相应变量存储的数据的方式。
int original = 30;
int& ref1 = original;
cout << "original=" << original << endl;
cout << "ref1=" << ref1 << endl;
cout << "&ref1" << &ref1 << endl;
---------------------------------------------
original = 30;
ref1 = 30;
&ref1 = 0099F764(结果不固定)
解引用:通过指针,找到对应的内存和内存中的数据。我们可以通过解引用访问或修改指针指向的内存内容。
为什么需要使用动态内存分配(或什么是动态内存分配)(重点)
声明一个数组时会出现两个问题:
- 该数组限制了程序的容量,将无法存储超过该数组的上限;
- 如果该数组只存储一个数字,却为该数组分配几百个内存地址空间,这将降低系统的性能。使用new来动态的分配地址,使用new后一定要使用delete释放内存,如果不释放将会继续占用内存空间,容易导致内存泄漏。
什么是构造函数?什么是析构函数(重点)
构造函数:是一种特殊的函数,它与类同名但不返回任何值。构造函数总是在创建对象时被调用,让构造函数成为将类成员变量初始化为选定值的理想场所。
析构函数:与构造函数一样,析构函数也是一种特殊的函数。构造函数在实例化对象时被调用,而析构函数在对象销毁时自动被调用。
C++默认有哪些空构造函数?
默认构造函数、析构函数、复制构造函数、赋值函数
什么是this指针?
在类中,关键字this包含当前对象的地址,也就是其值为&object。挡在类成员方法中调用其他成员方法时,编译器将隐式传递this指针。
什么是继承?什么是派生?什么是多态?(重点)
继承:当创建一个类时,不需要重新编写新的数据成员和成员函数,只需要指定新建的类继承中一个已有的类成员即可。
派生:一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。
多态:多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
c++的类型转换有哪些?它们各自的作用是什么?
- static_cast:用于在相关类型的指针之间进行转换,也可以显示地执行标准数据类型的类型转换。但是如果转换错误编译器不会在运行时检查,需要注意。
- dynamic_cast:动态类型转换在运行阶段执行类型转换,可检查转换类型时的操作结果,以判断类型转换是否成功。
- reinterpret_cast:它让程序员能够将一种对象类型转换为另一种,不管它们是否相关。不建议使用。
- const_cast:可以关闭对象的访问修饰符const,除非万不得已不要使用它来修改const对象,这样可能导致不可预料的行为。
应该避免使用类型转换。
简单介绍STL(非常重点)
- STL为C++的标准模板库,能够提高程序的开发效率和复用性。
- STL包含容器、迭代器、算法、仿函数、适配器、控件配置器等6大组件。
- 容器:容器分为顺序容器和关联容器。
- 顺序容器有:std::vector(在最后插入数据,可以想象成一个书架)、std::deque(与vector类似,但是允许在开头插入或删除元素)、std::list(可视作链条,可在任意位置插入或删除元素)、std::forward_list(类似list,但是是单向的,只能沿一个方向遍历。)
- 关联容器有:std::set(存储各不相同的值,在插入时进行排序;容器的复杂度为对数。),std::unordered_set(存储各不相同的值,在插入时进行排序,容器复杂度为常数。),std::map(存储键值对,并根据唯一的键排序,复杂度为对数)
- STL算法:通过算法函数对容器执行一些最常见的操作
- std::find:在集合中查找值。
- std::find_if:根据用户指定的谓词在集合中查找值。
- std::rerverse:翻转集合中元素的排列顺序。
- std::remove_if:根据用户指定的谓词在集合中删除值。
- std::tranform:使用用户定义的变换函数对容器中的元素进行变换。
- STL字符串类:
- std::string:基于char的std::basic_string具体化,用于操作简单字符串。
- std::wstring:用于操作宽字符串,通常用于存储支持各种语言中符号的Unicode字符。
如果选择正确的容器?(重要)
参考下面的图片(来自21天学会c++)
关于STL标准模板库的问题有点多,可以参考下面的图片(图片来源21天学会C++)
线程与进程的区别(重点)
- 进程是资源(内存、打开的文件)分配的单位,线程是CPU调度的单位;
- 进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈
什么是线程不安全?如何解决?
在随机调度下,线程执行有多种可能,其中可能有代码会导致程序出bug就称为线程不安全。
解决方法:使用互斥锁、条件锁、读写锁等解决该类问题。
什么是死锁?
死锁是指两个以上的进程(线程)在运行过程中因争夺资源而造成的一些进程(线程)都将无法向前推进。
什么是智能指针?有哪些智能指针它们的作用分别是什么?
智能指针能够及时、妥善地销毁动态分配的数据,并实现了明确的对象生命周期。
- unique_ptr:独占式指针,同一时刻只能有一个指针指向同一个对象
- shared_ptr:共享式指针,同一时刻可以有多个指针指向同一个对象
- weak_ptr:用来解决shared_ptr相互引用导致的死锁问题
lambda有哪几种捕获方式
捕获形式 | 说明 |
[] | 不捕获任何外部变量 |
[变量名,…] | 捕获指定的多个外部变量,用逗号分割 |
[this] | 以值的形式捕获this指针 |
[=] | 以值的形式捕获所有外部变量 |
[&] | 以引用形式捕获所有外部变量 |
[=,&x] | 变量x以引用方式捕获,其余变量以传值形式捕获 |
[&,x] | 变量x以值方式捕获,其余变量以引用形式捕获 |
重载、重写、重定义的区别?
- overload(重载),将语义相近的几个函数用同一个名字表示,但是参数列表(参数的类型,个数,顺序不同)不同,这就是函数重载,返回值类型可以不同 特征:相同范围(同一个类中)、函数名字相同、参数不同、virtual关键字可有可无。
- override(重写),派生类覆盖基类的虚函数,实现接口的重用,返回值类型必须相同 特征:不同范围(基类和派生类)、函数名字相同、参数相同、基类中必须有virtual关键字(必须是虚函数)。
- overwrite(隐藏重定义),派生类屏蔽了其同名的基类函数,返回值类型可以不同 特征:不同范围(基类和派生类)、函数名字相同、参数不同或者参数相同且无virtual关键字。
什么是左值和右值?
可以取地址的,有名字的,非临时的就是左值。不能取地址的,没有名字的,临时的,通常生命周期就在某个表达式之内的就是右值(仅为简单概述,可能并不准确)
Qt面试题整理
Qt有什么优缺点?
:+1:优点:
- 跨平台,几乎支持所有平台;
- 接口简单,文档详细;
- 开发效率高;
:no_good:缺点: Qt 作为一个软件平台,比较庞大、臃肿。
Qt的核心机制是什么?(重点)
面试中提到的什么是MOC也就是元对象编译系统(Meta object compiler) 元对象系统Qt的元对象系统提供了用于内部对象通讯的信号与槽机制,运行时类型信息,以及动态属性系统。
什么是信号和机制?如何使用信号和实现对象间通信?(非常重点)
:warning:信号和槽是Qt框架中用于对象间通信的机制。信号是一种特殊类型的函数,用于发出通知对象已经发生了某个事件。当一个信号触发时,与之相连接的槽函数将被自动调用。这样可以实现对象间的解耦和灵活的事件处理流程。使用信号和机制可以在一个对象内部或之间实现异步编程,也可以帮助开发者解耦不同组件、模块的代码,提高系统的可维护性和扩展性。
如何自定义信号或自定义槽函数?(非常重点)
- 自定义信号:关键字signals在QObject类中声明自定义信号。如果没有QObject类将无法使用信号和槽,关键字signals不允许加入任何权限修饰符,默认是public;
- 自定义槽:使用关键字slots来自定义槽函数,可以使用private来进行修饰。
Qt有哪些常用模块和常用组件?列举几个即可
**常用的模块有:**Qt core 、Qt GUI、Qt Network、Qt QML等。**常用的组件有:**QPushButton、QLineEdit、QLabel、QCheckBox等。
什么是Qt的模型视图结构或模型视图有什么好处(重点)
模型/视图结构是进行数据存储和界面展示的一种编程结构。在这种结构里,模型存储数据,界面上的视图组件显示模型中的数据,在视图组件里修改的数据会被自动保存到模型里。模型/视图结构将数据存储和界面展示分离,分别用不同的类实现。
Qt中常用的事件处理有哪些?
鼠标事件(QmouseEvent)、键盘事件(QKeyEvent)、定时器事件(QTimer)、绘图事件(QPainter)等。
Qt文件系统操作和读写
• 打开文件:使用函数 open()以不同模式打开文件,如只读、只写、可读可写等模式。 • 读数据:QFile 有多个接口函数可读取文件内容,如read()、readAll()等。 • 写数据:QFile 有多个接口函数可以向文件写入数据,如write()、writeData()等。 • 关闭文件,文件使用结束后还必须用函数 close()关闭文件。
如何使用Qt连接数据库和操作数据库?(重点)
在pro文件引入sql模块,连接数据库使用QSQLdatabase。然后使用QSQLquery类加以使用sql语句来操作数据库。
Qt的绘图
- Qt的二维绘图基本功能是使用QPainter 在绘图设备上绘图,绘图设备包括QWidget、QPixmap、QPrinter 等。QWidget是最常见的绘图设备,所有的界面组件都是从QWidget 继承而来的,界面组件的显示效果实际上是QPainter 在QWidget 上实现的。QPainter 可以在QWidget 上绘制出自定义的组件形状和实现特定的显示效果,这也是设计自定义界面组件的基础。
- Qt还提供了图形/视图架构。通过使用QGraphicsView、QGraphicsScene和各种QGraphicsItem 类,我们可以在一个场景中绘制大量的图形项,且每个图形项是可选择、可交互操作的。
Qt中如何自定义控件(重点)
有两种方法可以使用自定义界面组件,一种方法是提升法,将一个QGraphicsView组件提升为自定义的QTGraphicsView 类。另一种方法是为Qt Designer设计自定义Widget插件,将其直接安装到Qt Designer的组件面板里,其使用方法如同Qt自带的界面设计组件。
Qt多线程的创建方法?(非常重点)
- 子进程继承QThread,然后重写run()函数来执行子进程;
- 在pro文件中添加QtConcurrent,在任务类中重写run()函数执行进程;
- 使用线程池,QRunnable和QThreadPool,任务类继承QRunnable,需要使用信号槽可多重继承QObject,重写run函数,使用start来启动线程池。
Qt的线程同步和线程安全(非常重点:90%会问到)
为什么需要线程同步:使用线程的目的是允许代码并行运行,但是有时线程必须停止并等待其他线程。例如,如果两个线程试图同时写入相同的变量,结果是不确定的,所以需要同步线程。
Qt中的 QMutex、QReadWriteLock、QSemaphore和QWaitCondition 类提供了同步线程的方法。
- QMutex提供了一个互斥锁(互斥量),在任何时间至多有一个线程可以获得mutex。如果一个线程尝试获得mutex,而此时mutex已经被锁住了 ,这个线程将会睡眠,直到现在获得mutex的线程对mutex进行解锁为止。互斥锁经常用于对共享数据(例如,可以同时被多个线程访问的数据)的访问进行保护。
- QReadWriteLock即读写锁,与QMutex很相似,只不过它将对共享数据的访问区分为“读”访问和“写”访问,允许多个线程同时对数据进行“读”访问。
- QSemaphore即信号量,用来保护一定数量的相同的资源,而互斥锁mutex只能保护一个资源。
- QWaitCondition即条件变量,允许一个线程在一些条件满足时唤醒其他的线程。一个或者多个线程可以被阻塞来等待一个QWaitCondition来设置一个用于wakeOne()或者wakeAll()的条件。
请描述Qt中的网络编程支持,包括使用Qt实现网络通信的方法和相关类。(重点)
QtNetwork模块提供了用于编写TCP/IP网络应用程序的各种类,如用于TCP通信的QTcpSocket和QTcpServer,用于UDP通信的QUdpSocket,还有用于网络承载管理的类,以及基于SSL协议的用于网络安全通信的类。
简述以下Qt串口,以及常用的方法(上位机/嵌入式重点)
Qt Serial Port模块提供了访问串口的基本功能,包括串口通信参数配置和数据读写,使用Qt Serial Port模块就可以很方便地编写具有串口通信功能的上位机程序。
常用方法:
QList<QSerialPortInfo> QSerialPortInfo::availablePorts() //获取系统中的串口列表
QList<qint32> QSerialPortInfo::standardBaudRates() //获取系统支持的串口通信波特率列表
什么是QtCharts?
Qt Charts是一个二维图表模块,可用于绘制各种常见的二维图表,如折线图、柱状图、饼图、散点图、极坐标图等。使用时需要在pro文件中添加charts模块。
QSS样式表常用样式有哪些?(常问)
常用的样式设置有:color:设置前景色(如文字),background-color:设置背景色,boder:设置边框,font-size:设置字体大小,QSS样式表和css使用相似,使用时可以参考css样式表的使用。
了解QML吗?它和QWidget有什么区别?
QML是一种描述性的脚本编程语言,语法格式类似css,支持各种图形特效,以及状态机等。QML和Qwidget区别是QWidget主要应用在军工、安防、航天领域,qml主要集中在汽车仪表、车机等领域(比较适用于嵌入式领域)。
标签:std,面试题,Qt,函数,C++,线程,使用,指针 From: https://blog.51cto.com/u_16311206/9180433