影石 音视频开发-C++ 一面
1. 自我介绍
2. 写一个高性能模块,需要用链表时,会优先考虑 std::list 吗
答案:不一定。很多人看到“频繁插入删除”就先想到 std::list,但高性能场景下不能只看时间复杂度,还得看缓存局部性、内存分配次数、节点额外开销、遍历成本。std::list 的确能做到已知位置 O(1) 插入删除,但它不是连续内存,每个节点单独分配,cache 命中率通常比较差,实际性能未必比 vector 或 deque 好。如果模块里遍历远多于插删,或者数据量大、对 cache 敏感,往往连续存储更占优势。如果确实要频繁中间插删,又担心节点分配成本,工程里还可能结合对象池、侵入式链表或者 boost::intrusive 一类方案。所以这题本质不是“链表快不快”,而是选容器要结合访问模式和硬件友好性来看。
3. 如何避免内存泄漏
答案:核心思路不是“记得 delete”,而是让资源生命周期可控。比较稳的方式一般有三种:第一是用 RAII,把资源获取和释放绑到对象生命周期上;第二是优先使用标准容器和智能指针,减少裸指针直接管理资源;第三是明确所有权边界,谁申请谁释放,或者由唯一拥有者负责释放。另外在工程里还要结合工具去兜底,比如 ASan、Valgrind、Visual Leak Detector、自定义内存统计,这样不仅能预防,还能尽快发现问题。
4. new 和 delete 的规范使用
答案:new 和 delete 必须成对出现,new[] 和 delete[] 也必须成对出现,不能混用。new 做了两件事,一是分配内存,二是调用构造函数;delete 也是两步,先调用析构函数,再释放内存。如果对象是通过基类指针释放,而且类存在继承层次,那基类析构函数通常要是虚函数。工程里更推荐“少直接用 new/delete”,尽量交给容器、智能指针和工厂函数管理,否则资源路径一复杂,很容易漏掉释放点。
代码:
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "ctor\n"; }
~A() { cout << "dtor\n"; }
};
int main() {
A* p1 = new A;
delete p1;
A* p2 = new A[3];
delete[] p2;
return 0;
}
5. RAII 思想怎么理解
答案:RAII 可以理解成“资源获取即初始化”,对象构造时拿到资源,对象析构时自动释放资源。它的价值在于把资源管理从“依赖人记得释放”变成“依赖语言对象生命周期自动释放”。这样即使函数中途 return,或者抛异常,也能保证资源被正确清理。RAII 不只是管理内存,还适用于文件句柄、锁、socket、数据库连接这些资源。像 lock_guard、unique_ptr、fstream,本质上都是 RAII 的体现。
代码:
#include <iostream>
#include <mutex>
using namespace std;
mutex mtx;
void func() {
lock_guard<mutex> lock(mtx);
cout << "critical section\n";
}
6. 如果让你手写一个智能指针,最核心要考虑什么
答案:这题如果从文件管理切到内存释放,本质没变,考的还是资源托管设计。最核心要考虑的是所有权模型、析构时机、拷贝语义、移动语义和异常安全。如果是独占型智能指针,那要禁止拷贝、支持移动;如果是共享型智能指针,就要维护引用计数,还要考虑线程安全和循环引用问题。另外删除器也很关键,因为对象不一定总是 delete,有时候可能是 delete[]、fclose 或者自定义释放逻辑。真正写的时候,很多细节都在“边界条件”上,比如自赋值、空指针、控制块释放时机、对象和控制块是否分离。
代码:
#include <iostream>
using namespace std;
template <typename T>
class UniquePtr {
public:
explicit UniquePtr(T* p = nullptr) : ptr_(p) {}
~UniquePtr() { delete ptr_; }
UniquePtr(const UniquePtr&) = delete;
UniquePtr& operator=(const UniquePtr&) = delete;
UniquePtr(UniquePtr&& other) noexcept : ptr_(other.ptr_) {
other.ptr_ = nullptr;
}
UniquePtr& operator=(UniquePtr&& other) noexcept {
if (this != &other) {
delete ptr_;
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
return *this;
}
T* operato
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.