跳到主要内容C++ 核心面试题总结:语法、内存与类机制详解 | 极客日志C++算法
C++ 核心面试题总结:语法、内存与类机制详解
C++ 面试核心考点覆盖语法基础、标准库、内存管理及面向对象特性。重点解析变量生命周期、指针与引用差异、智能指针原理、虚函数机制及堆栈区别。辅以 Git 与 Linux 常用命令,助力开发者系统掌握 C++ 岗位必备技能。
暖阳3 浏览 C++ 核心面试题总结
面试中,基础语法的扎实程度往往决定了后续问题的深度。本文系统梳理了 C++ 岗位常考的知识点,涵盖语法基础、STL 标准库、内存管理、类特性及辅助工具,帮助开发者查漏补缺。
一、C++ 语法基础
🔥 谈谈变量的使用和生命周期,声明和初始化
全局变量在程序的任何地方都能访问,通常在整个程序执行期间有效。局部变量定义在函数或代码块内部,作用域受限。静态变量通过 static 关键字声明,具有特殊的存储属性。
下表总结了各变量类型的差异点,熟练掌握这些属性有助于正确使用变量:
| 变量类型 | 声明方式 | 初始化建议 | 内存存储位置 | 作用域 | 生命周期 |
|---|
| 全局变量 | 函数外部声明 | 声明时初始化 | 常量区(静态存储区) | 整个文件 | 程序结束 |
| 局部变量 | 函数或代码块内 | 声明时初始化 | 栈区 | 函数内部 | 函数调用期间 |
| 静态全局 | 加 static 关键字 | 声明或首次使用前 | 常量区(静态存储区) | 整个文件 | 程序结束 |
| 静态局部 | 加 static 关键字 | 声明或首次使用前 | 常量区(静态存储区) | 函数内部 | 函数调用间持久化 |
示例:
int globalVar = 10;
void func() {
int localVar = 20;
static int staticLocalVar = 30;
}
🔥 谈谈 C++ 的命名空间的作用
命名空间主要用于避免命名冲突,将相关函数、类封装在一起,提高代码的组织性和可读性。使用 前缀或 可访问标准库内容。
std::
using namespace std;
namespace MyNamespace {
int x;
void func();
}
std::cout << "Hello, world!" << std::endl;
using namespace std;
cout << "Hello, world!" << endl;
🔥 #include "" 和 <> 的区别
#include <文件名>:包含标准库头文件,编译器按标准路径顺序搜索。
#include "文件名":包含用户自定义或项目内部头文件,优先在当前目录查找,其次才是标准路径。
🔥 指针是什么?
指针是存储变量地址的特殊数据类型。通过解引用操作符 * 访问指向的变量,使用地址运算符 & 获取变量地址。
🔥 什么是指针数组和数组指针
- 指针数组:元素为指针的数组。常用于动态管理一组指针。
- 数组指针:指向数组首地址的指针。用于处理数组整体或多维数组。
🔥 引用是什么?
引用是变量的别名,使用 & 符号定义。必须在定义时初始化,且一旦绑定不可更改。
int num = 10;
int &ref = num;
应用场景包括函数参数传递,允许在函数内部直接修改原始值。
🔥 指针和引用的区别
- 引用不能为空,指针可以。
- 引用无需解引用,指针需要
*。
- 引用必须初始化,指针可后续赋值。
🔥 什么是函数指针和指针函数以及区别
typedef void (*FuncPtr)(int);
void myFunction(int x) {}
int main() {
FuncPtr ptr = &myFunction;
ptr(10);
return 0;
}
int add(int a, int b) { return a + b; }
int (*getAddFunctionPointer())(int, int) { return &add; }
🔥 什么是常量指针和指针常量以及区别
- 常量指针 (
int* const):指针本身是常量,指向的地址不可变,但对象值可变。
- 指针常量 (
const int*):指向的对象是常量,值不可变,但指针指向可变。
🔥 智能指针的本质是什么以及实现原理
智能指针利用 RAII(资源获取即初始化)模式管理动态内存。本质是封装了指针的对象,通过析构函数自动释放资源,避免泄漏。
std::shared_ptr:共享资源,引用计数减至零时释放。
std::unique_ptr:独占资源,移动语义保证所有权传递。
std::weak_ptr:不增加引用计数,解决循环引用问题。
🔥 weak_ptr 是否有计数方式,在那分配空间?
std::weak_ptr 本身不进行内存分配或引用计数,依赖 std::shared_ptr 管理资源。可通过 lock() 成员函数获取 std::shared_ptr,若对象已过期则返回空指针。
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared;
std::shared_ptr<int> locked = weak.lock();
if (locked) {
std::cout << "Value: " << *locked << std::endl;
}
return 0;
}
🔥 类型强制转换有哪几种?
- 静态转换 (
static_cast)
- 常量转换 (
const_cast)
- 动态转换 (
dynamic_cast)
- 重新解释转换 (
reinterpret_cast)
🔥 函数参数传递时,指针、引用以及值传递有什么区别?
- 值传递:复制实参,函数内操作不影响原始值。
- 引用传递:形参是别名,操作影响原始值。
- 指针传递:形参是地址,解引用后影响原始值。
🔥 进程间的通信方式有那些?
管道、命名管道、消息队列、共享内存、信号量、套接字。
🔥 线程间的通信方式有那些?
🔥 简单谈谈对线程的理解,线程间共享资源时该怎么处理?
线程是操作系统调度的基本单位。共享资源时需注意数据一致性和并发安全,通常采用互斥锁避免数据竞争。
🔥 常用关键字含义及其使用
- static:静态变量(生命周期延续)、静态函数(类级别访问)。
- const:声明常量,防止修改。
- sizeof:计算类型或变量字节大小。
- final:禁止类继承或虚函数重写。
- override:显式指示派生类覆盖基类虚函数。
- virtual:声明虚函数,支持动态绑定。
- volatile:声明易变变量,防止编译器优化。
- explicit:防止构造函数隐式转换。
- inline:建议编译器内联展开函数。
- extern C:解决 C/C++ 混合编译链接问题。
- define vs typedef:宏替换 vs 类型别名。
🔥 const 可以修饰那些内容
变量、指针和引用、函数、类对象或类指针、函数返回值。
🔥 class 和 struct 的区别?有了 class 为啥仍还保留 struct?
class 默认私有 (private),默认私有继承。
struct 默认公有 (public),默认公有继承。
保留 struct 是为了语法灵活性和向后兼容性。
二、标准库
🔥 什么是 STL?
STL(Standard Template Library)提供通用模板类和函数,包含容器、算法、迭代器、函数对象和适配器,提升编程效率。
🔥 数组和 vector 的区别?
- 大小:数组固定,vector 动态可变。
- 内存:数组可在栈或堆,vector 通常在堆。
- 功能:vector 支持动态扩展、插入删除等操作。
🔥 list 和 vector 的主要区别是什么?
- 存储:list 是双向链表,vector 是动态数组。
- 访问:list 不支持随机访问,vector 支持常数时间随机访问。
- 增删:list 在中间增删效率高,vector 适合末尾操作。
🔥 在什么情况下使用 list 而不是 vector?
当需要在容器中间频繁插入删除元素,且不需要随机访问时,list 更合适。
🔥 set 的底层数据结构是什么?
通常使用红黑树或其他自平衡二叉搜索树,确保元素唯一且有序,操作复杂度为 O(log n)。
🔥 set 和 multiset 有什么不同?
set 元素唯一,multiset 允许重复元素。
🔥 map 和 unordered_map 的主要区别是什么?
- 结构:map 用红黑树(有序),unordered_map 用哈希表(无序)。
- 性能:map 查找 O(log n),unordered_map 平均 O(1)。
三、内存
🔥 RAII 是什么?
RAII(Resource Acquisition Is Initialization)核心思想是将资源获取与对象初始化绑定,资源在构造函数中获取,析构函数中释放。
🔥 使用 RAII 的原因以及使用方法?
- 原因:自动管理资源,异常安全,代码简洁。
- 方法:定义资源管理类,在构造函数分配,析构函数释放。
🔥 new 和 malloc 的区别?delete 和 free 的区别?
- new/malloc:
new 是操作符,调用构造函数;malloc 是 C 函数,返回 void*。
- delete/free:
delete 调用析构函数;free 仅释放内存。
int* p = new int(10);
delete p;
int* q = (int*)malloc(sizeof(int));
free(q);
🔥 C++ 的内存框架分布情况
- 栈(Stack):局部变量、函数调用信息。
- 堆(Heap):动态分配内存。
- 静态存储区:静态变量、全局变量。
- 常量区:字符串常量等。
🔥 堆和栈的区别?
| 特性 | 栈 | 堆 |
|---|
| 分配方式 | 自动分配释放 | 手动分配释放 |
| 生命周期 | 函数调用期间 | 程序员控制 |
| 大小 | 较小 | 较大 |
| 速度 | 较快 | 较慢 |
| 用途 | 局部变量 | 动态内存 |
🔥 什么是内存对齐,内存对齐有什么好处?
内存对齐指按特定边界排列数据结构地址。好处是提高访问效率,防止硬件异常。
🔥 什么是内存泄漏?写代码时应该怎么防止内存泄漏。
内存泄漏指分配后未释放。防止方法:使用 RAII、智能指针、内存分析工具(如 Valgrind)、良好的编码习惯(new 对应 delete)。
🔥 说说什么是深拷贝和浅拷贝?
- 浅拷贝:只复制指针值,共享资源,可能导致冲突。
- 深拷贝:创建完整副本,独立资源,保证安全性。
四、类相关
🔥 讲讲 C++ 的三大特性(封装、继承、多态)
- 封装:隐藏实现细节,捆绑数据与操作。
- 继承:子类复用父类属性和行为。
- 多态:同一接口作用于不同对象,表现不同行为。
🔥 多态是怎么实现的?
依赖虚函数和动态绑定。运行时根据对象实际类型决定调用版本,通过虚函数表(vtable)和虚指针(vptr)实现。
🔥 什么是虚函数和纯虚函数?以及区别?
- 虚函数:基类声明
virtual,允许派生类重写。
- 纯虚函数:
= 0,定义接口,使基类成为抽象类。
🔥 虚函数是怎么实现的?虚函数在那个阶段生成?
- 实现:每个含虚函数的类有 vtable,对象有 vptr 指向它。
- 阶段:编译期生成 vtable,实例化时设置 vptr。
🔥 构造函数和析构函数的作用?
- 构造函数:初始化对象状态,无返回值,可重载。
- 析构函数:清理资源,名字前加
~,无返回值,不可重载。
🔥 构造函数和析构函数那个可以被声明为虚函数,为什么?
- 析构函数:可声明为虚函数,确保派生类析构被正确调用,防止泄漏。
- 构造函数:不可虚,此时对象未完全构造,无法设置 vtable。
🔥 构造函数和析构函数那个可以被重载,为什么?
- 构造函数:可重载,提供多种初始化方式。
- 析构函数:不可重载,每个类只能有一个。
🔥 谈谈什么是重载、重写、隐藏?
- 重载:同作用域,同名不同参。
- 重写:派生类覆盖基类虚函数。
- 隐藏:派生类同名函数遮蔽基类函数。
🔥 this 指针,为什么会存在 this 指针?
this 指向当前对象,用于访问成员、区分同名变量、实现链式调用。
五、其他必备
🔥 什么是 git? 以及 git 常用命令
git clone [url]:克隆仓库。
git add [file]:添加文件到暂存区。
git commit -m "message":提交更改。
git status:查看状态。
git diff:查看差异。
git remote add [name] [url]:添加远程。
git fetch/pull/push:拉取/推送。
git log:查看历史。
git reset/revert:重置/撤销。
🔥 什么是 svn? git 和 svn 的区别
SVN 是集中式版本控制系统,所有历史存储在中央服务器。Git 更适合代码协作,SVN 有时用于文档管理。
🔥 Linux 系统下常用的命令会那些,举例?
ls/cd/pwd:目录操作。
cp/mv/rm:文件操作。
cat/vim:查看/编辑。
chmod/chown:权限管理。
ps/top:进程监控。
df -h/du -sh:磁盘空间。
kill:结束进程。
ping/ifconfig/netstat:网络诊断。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online