网易互娱-游戏研发-C++ 一面

1. emplace_back 和 push_back 之间的区别是什么?

push_back 接受一个已经构造好的对象。如果传入的是构造函数的参数,它会先调用构造函数生成一个临时对象,然后再通过拷贝构造或移动构造将该对象放入容器,最后销毁临时对象。emplace_back 利用 C++11 的完美转发(Perfect Forwarding)和可变参数模板,直接在容器的底层内存空间中原地构造对象,省去了创建和销毁临时对象的步骤。

2. emplace_back 是否比 push_back 更高效?

不一定总是更高效。当传入的是构造函数的参数时,emplace_back 省去了临时对象的拷贝/移动,确实更高效。当传入的是已经存在的局部对象时,两者的底层行为完全一致,都会调用移动构造函数或拷贝构造函数,性能没有差异。此外,滥用 emplace_back 可能会因为隐式类型转换而绕过显式的构造函数声明。

3. make_shared 的底层原理是什么?

传统的 std::shared_ptr<T>(new T()) 需要进行两次内存分配:一次是为对象 T 分配堆内存,另一次是为智能指针的控制块(用于存放引用计数等信息)分配内存。std::make_shared<T>() 的底层原理是:只进行一次内存分配,分配一块足够大的连续内存,将对象 T 和控制块放在一起原地构造。这样提升了内存分配效率,避免了内存碎片,并在抛出异常时更加安全。

4. shared_ptr 有什么致命缺陷?如何解决?

致命缺陷是循环引用(Circular Reference),会导致两者的引用计数永远降不到 0,发生内存泄漏。解决办法是使用 std::weak_ptr。weak_ptr 不会增加控制块的强引用计数,如果需要访问对象,可以通过 lock() 提升为临时的 shared_ptr。

#include <memory>

struct Node {
    std::weak_ptr<Node> next; // 使用 weak_ptr 打破循环
    ~Node() {}
};

void test() {
    auto a = std::make_shared<Node>();
    auto b = std::make_shared<Node>();
    a->next = b;
    b->next = a;
} // 正常析构,不泄漏

5. 平时项目里的 C++ 主要是用到哪个版本?

主要使用 C++11 和 C++14。重点使用了 C++11 的智能指针(管理内存)、右值引用(优化移动语义)、并发库(多线程同步)以及 auto 类型推导;使用 C++14 的泛型 Lambda 与 std::make_unique 提升安全性与开发效率。

6. std::move 会真实地“移动”内存吗?它的底层做了什么?

不会。std::move 在运行时不产生任何汇编代码,不移动任何内存。它的底层逻辑仅仅是一个编译期的强制类型转换,将左值无条件转化为右值引用。真正的移动操作是由对象的移动构造函数或移动赋值运算符完成的。

// std::move 底层核心等价于:
template<typename T>
typename std::remove_reference<T>::type&& move(T&& arg) noexcept {
    return static_cast<typename std::remove_reference<T>::type&&>(arg);
}

7. 解释一段 C++20 的代码思想

面试题通常会给出如下代码段,要求解释:

#include <iostream>
#include <ranges>
#include <vector>

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5, 6};
    auto result = nums | std::views::filter([](int n){ return n % 2 == 0; })
                       | std::views::transform([](int n){ return n * n; });
    for (int n : result) std::cout << n << " ";
}

这段代码使用了 C++20 的 Ranges 库。它利用管道符 | 将多个操作串联起来,体现了函数式编程思想。核心机制是延迟计算(Lazy Evaluation):filter 和 transform 不会立即生成中间容器,而是在最终遍历 result 时才求值,极大减少了内存开销并提升了代码可读性。

8. TCP 三次握手为什么不

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++ 常考面试题总结 文章被收录于专栏

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

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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