在准备华为 OD 的技术面试时,C++ 基础概念往往是必问环节。很多候选人容易在这些看似简单的'八股文'上栽跟头,其实它们考察的是对语言底层机制的理解。下面梳理了几个高频问题,希望能帮你理清思路。
变量的声明和定义的区别
理解这两者的关键在于存储空间的分配。声明只是告诉编译器变量的名字和类型,不占用实际内存;而定义会真正分配存储空间并建立实体。一个变量可以被多次声明(比如在多个文件中通过 extern 引用),但只能被定义一次。需要注意的是,如果 extern 修饰的变量带有初始化语句,那它实际上就变成了定义。
内存泄露是什么意思?怎么避免
内存泄漏简单来说就是程序申请了内存却忘了释放,导致这块资源无法回收。随着运行时间增长,可用内存会被逐渐耗尽,轻则性能下降,重则直接崩溃甚至宕机。
避免泄漏的核心思路是尽早释放:
- RAII 机制:利用对象生命周期自动管理资源,析构函数里做清理工作。
- 智能指针:优先使用
std::shared_ptr、std::unique_ptr等 STL 容器替代裸指针。 - 成对出现:如果用
new/delete或malloc/free,务必保证配对调用。 - 置空习惯:
delete后将指针设为nullptr,防止悬空指针误用。
怎么排查内存泄漏,遇到内存泄漏情况,一般怎么解决
排查通常分两步走。首先是观察监控,看进程内存是否持续上涨且不回落。其次在测试环境稳定复现后,结合日志分析或内存检测工具进行定位。常用的工具有 Valgrind、Dr. Memory 以及编译器的 AddressSanitizer。找到泄漏点后,回溯代码逻辑,检查是否有循环引用未断开、异常路径下资源未释放等情况。
define 和 const 的区别
虽然都能定义常量,但处理方式不同。#define 是预处理宏替换,没有类型检查,容易引发副作用;const 是真正的类型安全常量,有作用域限制,调试时更容易追踪。实际开发中建议优先使用 const。
define 和 typedef 的区别
两者都用于别名,但本质不同。typedef 创建的是类型别名,参与类型检查,支持模板;#define 只是文本替换,不参与编译期的类型系统。写复杂类型别名时,typedef 更安全。
宏函数和内联函数的区别
宏函数在预处理阶段展开,没有类型检查,参数求值可能重复;内联函数由编译器处理,有类型检查,执行效率接近宏但更安全。除非为了极致优化且确定无副作用,否则推荐用内联函数。
类和结构体的区别
语法上几乎一样,主要区别在于默认访问权限。class 默认成员是私有的(private),而 struct 默认是公有的(public)。此外,类更倾向于面向对象设计,结构体常用于数据聚合。
结构体和联合体差别
结构体每个成员都有独立的内存空间,总大小是各成员之和(含对齐填充);联合体所有成员共享同一块内存,大小取决于最大成员。联合体适合需要复用内存的场景,比如协议解析。
静态库和动态库区别
静态库在编译链接时就被复制到可执行文件里,体积大但独立性强;动态库在运行时加载,节省空间但依赖系统环境。Linux 下通常是 .a 和 .so,Windows 下是 .lib 和 .dll。
C++ 的编译过程
整个流程分为四步:预处理(展开宏、头文件)、编译(转汇编)、汇编(转机器码)、链接(合并符号、生成可执行文件)。理解这个过程有助于排查链接错误和符号冲突。


