影石 音视频开发-C++ 一面

1. 自我介绍

2. 写一个高性能模块,需要用链表时,会优先考虑 std::list

答案:不一定。很多人看到“频繁插入删除”就先想到 std::list,但高性能场景下不能只看时间复杂度,还得看缓存局部性、内存分配次数、节点额外开销、遍历成本。std::list 的确能做到已知位置 O(1) 插入删除,但它不是连续内存,每个节点单独分配,cache 命中率通常比较差,实际性能未必比 vectordeque 好。如果模块里遍历远多于插删,或者数据量大、对 cache 敏感,往往连续存储更占优势。如果确实要频繁中间插删,又担心节点分配成本,工程里还可能结合对象池、侵入式链表或者 boost::intrusive 一类方案。所以这题本质不是“链表快不快”,而是选容器要结合访问模式和硬件友好性来看。

3. 如何避免内存泄漏

答案:核心思路不是“记得 delete”,而是让资源生命周期可控。比较稳的方式一般有三种:第一是用 RAII,把资源获取和释放绑到对象生命周期上;第二是优先使用标准容器和智能指针,减少裸指针直接管理资源;第三是明确所有权边界,谁申请谁释放,或者由唯一拥有者负责释放。另外在工程里还要结合工具去兜底,比如 ASan、Valgrind、Visual Leak Detector、自定义内存统计,这样不仅能预防,还能尽快发现问题。

4. newdelete 的规范使用

答案:newdelete 必须成对出现,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_guardunique_ptrfstream,本质上都是 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++ 常考面试题总结 文章被收录于专栏

本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.

全部评论

相关推荐

05-04 08:23
东南大学 C++
一、基本情况与项目背景1.请做一个简单自我介绍。2.详细介绍一下你在字节做的端智能&nbsp;SDK&nbsp;/&nbsp;特征平台项目。3.端上的原始数据流主要包含哪些内容?4.这些数据是在端上落库,还是会上报云端?两条链路分别做什么?5.业务方如何注册、消费自定义特征?二、设备特征缓存优化6.设备特征缓存优化的背景是什么?原来性能瓶颈在哪里?7.为什么设备特征可以牺牲一部分时效性来换性能?8.为什么从统一&nbsp;TTL&nbsp;改成&nbsp;2&nbsp;秒&nbsp;/&nbsp;10&nbsp;秒&nbsp;/&nbsp;90&nbsp;秒分层&nbsp;TTL?9.不同&nbsp;TTL&nbsp;档位分别适合哪些设备特征?10.你们是如何通过打点、实验和&nbsp;A/B&nbsp;验证优化效果的?三、C++&nbsp;智能指针11.你对&nbsp;C++&nbsp;智能指针的理解是什么?12.unique_ptr、shared_ptr、weak_ptr&nbsp;分别适合什么场景?13.shared_ptr&nbsp;的引用计数机制是什么?14.weak_ptr&nbsp;如何解决&nbsp;shared_ptr&nbsp;的循环引用问题?四、特征&nbsp;SQL&nbsp;复用优化15.端上&nbsp;SDK&nbsp;为什么会涉及&nbsp;SQL&nbsp;复用优化?16.端上本地数据库里存的是什么,业务方为什么会查它?17.特征&nbsp;SQL&nbsp;查询的性能瓶颈是什么?18.为什么这些&nbsp;SQL&nbsp;可以模板化、签名化和合并?19.为什么第一版&nbsp;UNION&nbsp;ALL&nbsp;优化效果不理想?20.后续“提取时间戳&nbsp;+&nbsp;最小时间戳查询&nbsp;+&nbsp;应用层分发”的方案是怎么做的?21.SQL&nbsp;优化最终在单模块和全链路上分别带来了多少收益?五、直播端智能&nbsp;/&nbsp;ABR&nbsp;开放题22.你了解&nbsp;ABR&nbsp;吗?23.如果要判断用户是“画质敏感型”还是“流畅度敏感型”,你会在端上采集哪些特征?24.你会如何结合设备信息、网络状态、历史行为来设计直播画质&nbsp;/&nbsp;流畅度策略?25.端智能场景里,你是否接触过模型推理链路?六、AI&nbsp;投资分析系统&nbsp;/&nbsp;Multi-Agent26.介绍一下你的多&nbsp;Agent&nbsp;投资分析系统。27.主控&nbsp;Agent、数据&nbsp;Agent、新闻&nbsp;Agent、知识库&nbsp;Agent、分析&nbsp;Agent&nbsp;分别负责什么?28.多&nbsp;Agent&nbsp;之间的数据和上下文是怎么流转的?29.相比单&nbsp;Agent,多&nbsp;Agent&nbsp;架构在上下文管理、幻觉控制和问题排查上有什么优势?30.多&nbsp;Agent&nbsp;架构会带来哪些复杂度和维护成本?31.真实金融行情数据是如何通过&nbsp;API&nbsp;接入系统的?七、Skill&nbsp;/&nbsp;智能日志分析开放题32.你有没有自己写过&nbsp;skill?平时如何使用&nbsp;skill?33.如果要做一个直播播放日志智能分析工具,你会设计成&nbsp;Agent&nbsp;还是&nbsp;Skill?为什么?34.如果有历史文档和代码库说明日志含义,你会如何构建知识库或&nbsp;RAG?35.用户反馈某个视频播放卡顿时,如何定位、筛选并分析对应播放日志?36.日志分析系统里,工具调用、RAG、意图识别、日志筛选、错误码解释分别怎么设计?37.你会选择&nbsp;ReAct、Plan-and-Execute,还是其他框架来实现这个日志分析系统?八、计算机网络&nbsp;/&nbsp;拥塞控制38.你了解拥塞控制吗?它主要解决什么问题?39.拥塞窗口是如何变化的?40.慢启动、拥塞避免、丢包后的窗口调整分别是怎么回事?九、C++&nbsp;基础&nbsp;/&nbsp;多态41.说一下&nbsp;C++&nbsp;的多态特性。42.静态多态和动态多态分别是什么?43.动态多态如何通过继承、虚函数、虚函数表实现?十、Git&nbsp;基础44.你实习开发中常用哪些&nbsp;Git&nbsp;指令?45.你平时如何创建分支、提交代码、推送代码、拉取更新?46.遇到&nbsp;Git&nbsp;冲突一般怎么处理?十一、算法题:两个有序数组中位数47.用&nbsp;C++&nbsp;实现两个有序数组取中位数。48.先讲一下你的解题思路。49.暴力合并排序方案有什么可以优化的地方?50.既然两个数组本身有序,能否用双指针合并,避免再次&nbsp;sort?51.有没有更高阶的二分解法?十二、实习时间与岗位匹配52.你本科期间是怎么安排时间去北京字节实习的?53.如果来小红书实习,最早什么时候可以到岗?54.你更倾向上海还是北京&nbsp;base?55.你对“产品工程师”这个岗位定位的理解是什么?56.你对直播&nbsp;SDK&nbsp;/&nbsp;播放器&nbsp;SDK&nbsp;/&nbsp;端智能策略方向是否感兴趣?
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务