C++面试速通宝典——15

server/2024/10/9 15:20:38/

254. STL有哪些容器?各自特点?

  1. 序列容器:
    1. vector:动态数组,支持快速随机访问。
    2. list:双向链表,支持快速插入和删除。
    3. deque:双端队列,两端都可以快速插入和删除。
  2. 关联容器:
    1. set:集合,元素唯一且自动排序。
    2. map:键值对集合,键唯一且自动排序。
    3. multiset:集合,元素可以重复,自动排序。
    4. multimap:键值对集合,键可以重复,自动排序。
  3. 无序关联容器:
    1. unordered_set:集合,元素唯一,基于哈希表实现,不排序。
    2. unordered_map:键值对集合,键唯一,基于哈希表实现,不排序。
    3. unordered_multiset:集合,元素可以重复,基于哈希表实现,不排序。
    4. unordered_multimap:键值对集合,键可以重复,基于哈希表实现,不排序。
  4. 适配器容器:
    1. stack:栈,后进先出。
    2. queue:队列,先进先出。
    3. priority_queue:优先队列,元素按优先级出队。

255. vector扩容如何实现?

‌‌‌‌  vector扩容通常通过创建一个更大的新内存空间,然后将原有元素复制或移动到新空间中,之后释放原始内存空间来实现。
‌‌‌‌  扩容的大小通常是当前容量的两倍,以减少频繁扩容的开销。

256. map、set特点,怎么实现的?

‌‌‌‌  map和set的特点是他们存储的元素是自动排序的,map存储键值对,其中键是唯一的,而set只存储键且每个键是唯一的。

‌‌‌‌  他们通过平衡二叉搜索树(通常是红黑树)实现的,这个数据结构可以提供对元素的有序存储,以及在对数时间复杂度内进行元素查找、插入和删除操作。

257. 内联函数

‌‌‌‌  C++内联函数是一种通常用于优化小型、频繁调用的函数的编程技术。通过在函数声明前加inline关键字,编译器在调用处直接展开函数代码,以减少函数调用的开销。但最终是否内联取决于编译器的决定。

258. GDB如何debug,怎么传参?

‌‌‌‌  在GDB中进行调试,首先要启动GDB并加载你要调试的程序,可以使用gdb<your_program>命令。传递参数可以在GDB中使用 set args < arg1>< arg2>… 命令来设置命令行参数。然后,你可以使用像run来运行程序、break设置断点、next单步执行等命令来控制程序的执行并进行调试。

解释
‌‌‌‌  GDB(GNU Debugger)是GNU项目下的一个强大的调试工具,用于调试C、C++、Fortran等多种编程语言的程序。它可以帮助开发者追踪程序的执行流程,查找和修复错误。GDB 提供了多种功能,如设置断点、单步执行、查看变量和内存等。

如何使用 GDB 进行调试?

‌‌‌‌  以下是使用 GDB 进行调试的基本步骤:

1. 编译你的程序

‌‌‌‌  在使用 GDB 调试之前,你需要确保你的程序是用调试信息编译的。通常,你可以通过在编译时加上 -g 选项来包含调试信息。例如,对于一个C++程序 main.cpp

g++ -g -o myprogram main.cpp
2. 启动 GDB

‌‌‌‌  启动 GDB 并加载你的程序:

gdb myprogram
3. 设置断点

‌‌‌‌  断点允许你在程序执行到某一行时暂停。例如,要在 main 函数的第一行设置一个断点,可以在 GDB 提示符下输入:

(gdb) break main

‌‌‌‌  你也可以在特定的行号或函数名处设置断点,例如:

(gdb) break 10  # 在第10行设置断点
(gdb) break MyClass::myFunction  # 在类 MyClass 的 myFunction 方法处设置断点

4. 运行程序

‌‌‌‌  在设置断点后,你可以通过以下命令运行程序:

(gdb) run

‌‌‌‌  如果你的程序需要命令行参数,可以在 run 命令后指定:

(gdb) run arg1 arg2 arg3
5. 单步执行

‌‌‌‌  当程序在断点处暂停时,你可以单步执行代码:

  • step(或 s):进入函数调用
  • next(或 n):执行下一行代码,但不进入函数
  • continue(或 c):继续运行程序,直到下一个断点
6. 查看变量和内存

‌‌‌‌  你可以查看变量的值:

(gdb) print variable_name

‌‌‌‌  你也可以查看内存地址:

(gdb) x /nfu address

这里的 n 是单元数,f 是显示格式,u 是单元大小。例如:

(gdb) x /4xb 0xaddress  # 查看地址 0xaddress 处的 4 个字节,以十六进制显示

一个完整的 GDB 调试示例

假设你有一个简单的C++程序 main.cpp

#include <iostream>
using namespace std;void function(int a) {int b = a * 2;cout << "Value of b: " << b << endl;
}int main(int argc, char* argv[]) {int x = 5;function(x);return 0;
}

编译程序

g++ -g -o myprogram main.cpp

启动 GDB

gdb myprogram

设置断点

(gdb) break main

运行程序

(gdb) run

程序在 main 处暂停后,单步执行

(gdb) next  # 执行下一行
(gdb) step  # 进入 function 函数

查看变量

(gdb) print x
(gdb) print b

继续运行程序

(gdb) continue

‌‌‌‌  通过这些步骤,你可以使用 GDB 来有效地调试你的程序,查找并修复错误。

259. 指针的初始化和释放

‌‌‌‌  指针的初始化应该将其设为nullptr(C++11及以后)或NULL,以指示它尚未指向任何对象。当指针分配了动态内存后(例如,使用new),完成使用后应使用delete(对于单个对象)或delete[](对于对象数组)来释放分配的内存,然后把指针重新设置为nullptr避免悬挂指针的问题。

260. 三个进程都需要读写一块内存,如何调度?

‌‌‌‌  为了协调三个进程对同一块内存区域的读写访问,可以使用互斥锁(mutexes)或读写锁(read-write locks)。

  1. 互斥锁确保任一时间只有一个进程可以访问该内存。
  2. 读写锁允许多个读取者同时访问,但写入者单独访问。
    ‌‌‌‌  
    ‌‌‌‌  适当的锁机制需要根据访问模式和性能要求进行选择。

261. vfork了解么?

‌‌‌‌  vfork是一个UNIX系统调用,用于创建一个新的进程,成为子进程,它与创建它的父进程共享相同的内存空间。vfork被设计用来在执行exec系列函数前作为一个临时步骤。它区别于fork,因为他不会复制父进程的地址空间,而是直接使用父进程的地址空间,直到子进程调用exec或exit。这样做的目的是为了提高性能,但缺点是可能导致父子进程之间的同步问题。现代系统上,vfork的行为通常与fork相似,或被clone系统调用所取代。

262. C++程序编译链接过程

  1. 预处理(Preprocessing):预处理器处理源代码文件中的预处理指令,如宏定义、条件编译指令和文件包含指令等,生成预处理后的代码。
  2. 编译(Compilation):编译期间预处理后的代码转换为汇编指令,并进行语法和语义分析,生成相应平台的汇编代码文件。
  3. 汇编(Assembly):汇编器将汇编代码转换为机器代码生成目标文件(通常是.obj或.o文件)。
  4. 链接(Linking):链接器将所有目标文件以及所需的库文件合并解决代码中的外部引用,并生成最终的可执行程序

263. 静态链接和动态链接的区别

静态链接

  1. 所有必要的库代码整合到最终的可执行文件中
  2. 创建大的可执行文件,因为所有的代码都包含其中。
  3. 在程序启动时不需要加载外部库,因为所有的功能都已经内嵌。
  4. 可执行文件不依赖外部的库文件,更易分发。

动态链接

  1. 可执行文件包含指向动态链接库(DLLs或.so文件)的引用,而不是可执行代码。
  2. 生成更小的可执行文件,因为只需要存储库引用。
  3. 在程序运行时,需要额外的步骤来加载所需的动态库。
  4. 可执行文件依赖于外部库文件,因此需要确保相应的库在系统上可用。

264. 拷贝构造函数和移动构造函数的区别

拷贝构造函数

  1. 创建一个类的新对象时,他会从另一个同类型对象(源对象)复制数据。
  2. 它通常执行深拷贝,即分配新的资源,并复制对象的内容。

移动构造函数

  1. 也是创建新对象,但他从临时对象(rvalue,通常是将要销毁的对象)“移动资源”。
  2. 他执行浅拷贝,直接接管源对象的资源指针,并将源对象留在可销毁、但有效状态,这样就避免了资源的额外复制,提高了效率。

265. 浅拷贝和move有区别么?

有。

浅拷贝
‌‌‌‌  复制对象的指针或引用,新旧对象共享相同的底层数据资源

移动操作(move)

  1. 将资源从一个对象转移到另一个对象,原对象资源被置为null或有效但未定义状态,不再拥有资源。
  2. 只有移动构造函数或移动赋值操作符才参与移动操作。

266. 空类的大小

‌‌‌‌  空类的大小为1字节。

267. 类的继承方式有哪几种?区别是啥?

C++中类的继承方式有三种:

  1. 公有继承(public):基类的公有成员和保护成员继承后在派生类中保持原有状态,基类的私有成员不能直接访问。
  2. 保护继承(protected):基类的公有成员和保护成员继承后在派生类中变为保护成员。
  3. 私有继承(private):基类的公有成员和保护成员继承后在派生类中变为私有成员。

http://www.ppmy.cn/server/129332.html

相关文章

如何获取网页内嵌入的视频?

如何获取网页内嵌入的视频&#xff1f; 有时插件无法识别的视频资源&#xff0c;可以通过手动使用浏览器的开发者工具来抓取。你可以按照以下步骤操作&#xff1a; 步骤&#xff1a; 打开网页并按 F12&#xff1a;在视频页面按下 F12 或右键点击网页并选择“检查”或“Inspe…

Spring Boot教学资源库:开发者的成长之路

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

LeetCode讲解篇之1043. 分隔数组以得到最大和

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 对于这题我们这么考虑&#xff0c;我们选择以数字的第i个元素做为分隔子数组的右边界&#xff0c;我们需要计算当前分隔子数组的长度为多少时能让数组[0, i]进行分隔数组的和最大 我们用数组f表示[0, i)区间内的…

诺贝尔物理学奖新篇章:AI之父的非凡成就与物理学的不解之缘!

2024 年 10 月 8 日北京时间 17 时 45 分许&#xff0c;约翰J.霍普菲尔德 (John J. Hopfield) 和杰弗里E.欣顿&#xff08;Geoffrey E. Hinton&#xff09;因奠定借助统计物理学思想训练人工神经网络的基础&#xff0c;获得 2024 年诺贝尔物理学奖。辛顿在接受电话采访时表示&a…

Java报错输出的信息究竟是什么?

Java报错输出的信息究竟是什么&#xff1f; 本篇会带大家了解一下java运行时报错输出的信息内容&#xff0c;简单学习一下虚拟机内存中Java虚拟机栈的工作方式以及栈帧中所存储的信息内容 异常信息 当你的程序运行报错时&#xff0c;你是否会好奇打印出来的那一大坨红色的究竟…

如何在银河麒麟服务器中获取关键日志信息

如何在银河麒麟服务器中获取关键日志信息 1、获取messages日志2、获取dmesg输出 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在银河麒麟服务器中&#xff0c;获取messages和dmesg日志是排查问题的重要步骤。 1、dmesg命令用于显示或控制…

【重学 MySQL】五十、添加数据

【重学 MySQL】五十、添加数据 使用INSERT INTO语句添加数据基本语法示例插入多行数据注意事项 使用LOAD DATA INFILE语句批量添加数据其他插入数据的方式注意事项 在MySQL中&#xff0c;添加数据是数据库操作中的基本操作之一。 使用INSERT INTO语句添加数据 使用 INSERT IN…

E36.C语言模拟试卷1第一大题选题解析与提示(未完)

点我去下载C语言模拟试卷1的文件 备注:ZIP文件中的参考答案仅仅提供最终结果 目录 第3题 第5题 第7题 第9题 第14题 第16题 第19题 第20题 第22题 第24题 第26题 第27题 第28题 第3题 3.若有说明语句&#xff1a;char c ‘\64’ ; 则变量C包含&#xff1a; …