如何通过C++面试:高级问题TOP榜

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何通过C++面试:高级问题TOP榜



应聘C++开发岗位的面试始终是一项挑战。如果基础问题(new和malloc的区别、什么是虚析构函数)你很可能已经掌握,那么高级水平则需要深入理解语言的内部机制。在本文中,我们将解析在Middle和Senior职位的技术面试中必然会涉及的关键主题。我们不仅会列出问题,还会提供带有代码示例的详细解答。



1. 智能指针及其内部实现



问题:"请说明std::unique_ptr和std::shared_ptr有何区别?引用计数的线程安全性是如何实现的?"



这是经典问题。面试官希望看到你不仅理解语法,还理解资源所有权的语义。



  • std::unique_ptr — 独占所有权。不可复制,只能移动。适用于只有一个所有者的资源。
  • std::shared_ptr — 共享所有权。使用引用计数(控制块)。当计数降至零时,资源被销毁。
  • std::weak_ptr — "观察者"。不增加引用计数。用于打破shared_ptr中的循环依赖。


高级细节:shared_ptr中的引用计数是线程安全的(使用原子操作),但这并不使被管理的对象本身变得线程安全。此外,存在两个计数器:强引用计数和弱引用计数。只要存在至少一个弱引用,控制块就不会被删除,即使对象已被销毁。



#include <memory>#include <iostream>

class Resource {public: Resource() { std::cout << "Resource acquired"; } ~Resource() { std::cout << "Resource destroyed"; } void doWork() { std::cout << "Working..."; }};

int main() { std::unique_ptr<Resource> uptr = std::make_unique<Resource>(); uptr->doWork(); // std::unique_ptr<Resource> uptr2 = uptr; // 编译错误! std::unique_ptr<Resource> uptr2 = std::move(uptr); // 可以

std::shared_ptr<Resource> sptr1 = std::make_shared<Resource>(); std::shared_ptr<Resource> sptr2 = sptr1; // 引用计数 = 2 sptr1.reset(); // 引用计数 = 1 sptr2.reset(); // 引用计数 = 0,对象被销毁 return 0;}


2. 虚函数表(vtable)与动态绑定机制



问题:"虚函数在内存层面是如何工作的?vtable存储在哪里?"



这个问题不仅考察对多态的理解,还考察对C++内存布局的认识。



  • 对于每个至少有一个虚函数的类,编译器会创建一个静态表(vtable)。它包含指向虚函数的指针。
  • 该类的每个对象都包含一个隐藏指针__vptr,指向其所属类的vtable。
  • 当通过指针或引用调用虚函数时,编译器生成的代码会通过__vptr进入vtable,根据偏移量找到对应的函数并调用它。
  • vtable存储在静态内存中(如同全局变量),而不是栈或堆中。


高级细节:多重继承带来的复杂性。在这种情况下,一个对象可能有多个__vptr,并且需要thunk函数(用于调整this指针)。这也是为什么C++中的多重继承被认为危险且效率较低的原因之一。



#include <iostream>

class Base {public: virtual void foo() { std::cout << "Base::foo"; } virtual ~Base() = def

博客

书籍推荐