腾讯 PC客⼾端-C++ ⼀⾯

1. 自我介绍

2. C++ 中的智能指针都有哪些,分别解决什么问题

答案:常见的智能指针主要是 unique_ptrshared_ptrweak_ptr,另外还有早期遗留的 auto_ptr,但它已经被废弃。unique_ptr 表示独占所有权,同一时刻只有一个指针拥有对象,不能拷贝只能移动,开销小,最适合所有权明确的场景。shared_ptr 表示共享所有权,多个对象都可以持有同一资源,底层通常有引用计数和控制块,适合多个模块共同管理一个对象的场景。weak_ptr 不拥有对象,只是观察者,通常用来打破 shared_ptr 循环引用,或者在不延长对象生命周期的前提下探测对象是否还活着。工程里不是“智能指针越多越好”,而是先明确所有权。如果生命周期天然受作用域控制,栈对象往往更简单;如果资源归属唯一,优先 unique_ptr;只有真正需要共享时才考虑 shared_ptr

代码:

#include <iostream>
#include <memory>
using namespace std;

struct Node {
    int val;
    Node(int x) : val(x) { cout << "ctor\n"; }
    ~Node() { cout << "dtor\n"; }
};

int main() {
    unique_ptr<Node> p1 = make_unique<Node>(1);
    shared_ptr<Node> p2 = make_shared<Node>(2);
    weak_ptr<Node> p3 = p2;
    return 0;
}

3. shared_ptr 为什么会有额外开销,循环引用怎么解决

答案:shared_ptr 的额外开销主要来自两个地方,一个是控制块,里面通常存引用计数、弱引用计数、删除器等信息;另一个是引用计数的修改在多线程场景下往往涉及原子操作。所以它的价值不在于快,而在于共享所有权时能减少手动生命周期管理错误。循环引用最典型的场景是双向关系,比如 A 持有 B,B 又持有 A,如果双方都用 shared_ptr,引用计数永远不会归零,内存就泄漏了。常见做法是一边保留 shared_ptr,另一边改成 weak_ptr,这样既能访问,又不会把生命周期锁死。

代码:

#include <memory>
using namespace std;

struct B;
struct A {
    shared_ptr<B> b;
};

struct B {
    weak_ptr<A> a;   // 这里不能再用 shared_ptr
};

int main() {
    auto pa = make_shared<A>();
    auto pb = make_shared<B>();
    pa->b = pb;
    pb->a = pa;
    return 0;
}

4. 为什么要做内存对齐

答案:内存对齐主要是为了让 CPU 更高效地访问数据。很多硬件架构更适合按自然边界访问,比如 4 字节整数按 4 字节对齐、8 字节类型按 8 字节对齐。如果对象地址不对齐,轻则访问变慢,重则某些平台直接触发硬件异常。编译器做对齐还有一个重要原因是简化访存逻辑和提高总线利用率。对齐后,CPU 往往能在更少的访存次数里取到完整数据。从 C++ 对象布局看,对齐还会引入 padding,所以成员顺序会影响结构体大小。工程里如果对象数量很大,成员顺序优化有时能明显减少内存占用。

代码:

#include <iostream>
using namespace std;

struct A {
    char c;
    int i;
    short s;
};

struct B {
    int i;
    short s;
    char c;
};

int main() {
    cout << sizeof(A) << endl;
    cout << sizeof(B) << endl;
    return 0;
}

5. malloc、calloc、realloc 有什么区别

答案:malloc 负责申请指定字节数的原始内存,申请成功后内容未初始化。calloc 申请的是若干个同样大小的对象,总大小等于两者乘积,而且会把整块内存置零。realloc 用来调整一块已经分配内存的大小,可能原地扩容,也可能重新申请一块更大的内存并把原数据拷过去。它们都只是 C 语言层面的内存管理接口,不会调用构造函数和析构函数,所以管理 C++ 对象时通常不如 new/delete 或 RAII 安全。

代码:

#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;

int main() {
    int* a = (int*)malloc(5 * sizeof(int));
    int* b = (int*)calloc(5, sizeof(int));
    a = (int*)realloc(a, 10 * sizeof(int));

    free(a);
    free(b);
    return 0;
}

6. new/de

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

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

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

全部评论
米哈游感兴趣的可看主页帖子 可看简历 春招进度巨快!!!!!
点赞 回复 分享
发布于 03-28 13:23 上海

相关推荐

1.自我介绍2.第一部分:项目深挖3.问题&nbsp;1:请简单介绍一下你用&nbsp;C++&nbsp;实现&nbsp;RAG&nbsp;系统的流程,分块、向量化、存储、检索这几个环节分别是怎么做的?是自己手写还是调用第三方库?4.问题&nbsp;2:项目依赖的第三方库是如何管理的?5.问题&nbsp;3:依赖库有更新时,你是如何维护的?6.问题&nbsp;4:项目中遇到了哪些性能瓶颈或现实问题?7.问题&nbsp;5:性能优化前后的数据对比是怎样的?精度是如何衡量的?8.问题&nbsp;6:SQLite&nbsp;的写操作可以是多线程的吗?如果需要并发写入怎么处理?9.第二部分:C++&nbsp;语言基础10.问题&nbsp;7:C++&nbsp;中的&nbsp;inline&nbsp;关键字有什么作用?有什么缺点?是否可以用于虚函数11.问题&nbsp;8:在头文件里定义一个全局静态变量,它存在进程地址空间的哪里?如果被多个源文件包含会怎样?12.第三部分:数据结构与数据库13.问题&nbsp;9:常用的数据结构有哪些?在你的项目中用到了哪些?14.问题&nbsp;10:数据库索引一般用什么数据结构?B&nbsp;树和&nbsp;B&nbsp;加树有什么区别?15.第四部分:网络与安全16.问题&nbsp;11:HTTPS&nbsp;相比&nbsp;HTTP&nbsp;多了什么?它是如何确保连接安全的?17.反问。面试官在问第一个问题的时候,看起来表情都不是很耐烦,我就知道肯定挂了,不过不管怎么样,也算积累面试经验了。
查看12道真题和解析
点赞 评论 收藏
分享
04-29 12:34
已编辑
河海大学 C++
投完简历,做了测评,AI&nbsp;面试都还没做。没想到星期一&nbsp;4&nbsp;点投完论文,早上十点多组会的时候就给我发腾讯客户端一面。C++&nbsp;八股左值和右值区别。突然问这么简单的一下有点懵,然后大概答了一下左值、将亡值、纯右值,然后强调了一下左值的所有权,转移时用&nbsp;move。TCP&nbsp;三次握手和四次挥手,简单说了下三次握手和四次挥手流程,提了一下捎带机制和挥手的时候发送剩余数据。智能指针。提了一下&nbsp;shared_ptr,强调了应该优先用在所有权明确时优先&nbsp;unique_ptr,顺带提到了&nbsp;shared_ptr&nbsp;存在的循环引用问题。追问怎么解决循环引用,回答&nbsp;weak_ptr&nbsp;以及shared_ptr&nbsp;引用某个对象时所有权意味着主从关系,若&nbsp;A、B&nbsp;相互引用,造成析构时引用计数无法正确归零。然后解释&nbsp;weak_ptr&nbsp;是弱化的所有权,一方面起到观察作用,另一方面是引用控制块由于是智能指针共享的,其中的弱引用计数也起到了&nbsp;RAII&nbsp;的作用,可以让引用计数块正确析构。虚表是什么。有&nbsp;virtual&nbsp;函数的类就是虚类,类中除了自己定义的成员还有一个虚表指针指向虚表,表里面有虚函数入口地址和&nbsp;RTTI&nbsp;信息,RTTI&nbsp;信息用于&nbsp;dynamic_cast&nbsp;的时候判断类型。追问虚类内存布局,举了个例子,对于一个没有成员的类,大小&nbsp;1&nbsp;字节(约定是这样),若其中包含了虚函数(特别提了一下成员函数不占用类的空间,全局一份),就会在类成员的基础上加上一个虚表指针,这时候类的大小是&nbsp;8&nbsp;字节(64&nbsp;位),也就是一个指针的大小。还好之前有看过&nbsp;LLVM&nbsp;的&nbsp;IR,对这个比较熟。知道哈希吗,怎么实现。通过一个哈希函数将一个大的集合映射到一个小的集合,实现&nbsp;K-V&nbsp;的存储,由于是大集合映射到小集合,所以存在哈希冲突。一般有线性探测、拉链、再次哈希的方案。STL&nbsp;里哈希表是用的拉链&nbsp;+&nbsp;红黑树。追问红黑树。答曰红黑树是&nbsp;AVL&nbsp;的改进版本,AVL&nbsp;要求左右子树高度差最大为&nbsp;1,红黑树放宽了这个限制。由于怕拷打红黑树的操作,遂补充一句红黑树的插入删除时间太久没接触有点记不清了。进程和线程区别。进程是操作系统资源调度的单位,堆、文件句柄(描述符)等资源都托管在进程中,线程是操作系统调度的最小单位,本质是一个在&nbsp;CPU&nbsp;核心上运行的函数。由于这个问题过于简单,怕没有亮点,遂延伸到&nbsp;Windows&nbsp;的进线程模型是比较标准的,而&nbsp;Linux&nbsp;实际上并没有真正意义上的进线程,只有任务(task_struct),任务从行为上类似于线程,task_struct&nbsp;中有&nbsp;thread_struct&nbsp;在上下文切换时存储&nbsp;CPU&nbsp;的通用寄存器值、段寄存器值等,此外还有一些额外的信息标识进线程组来贴合进线程的概念。然后又延伸到&nbsp;Linux&nbsp;fork,fork&nbsp;时仅&nbsp;fork&nbsp;一个&nbsp;task,实际上并没有&nbsp;fork&nbsp;进程的所有线程,若在&nbsp;fork&nbsp;时其他&nbsp;task&nbsp;调用&nbsp;malloc&nbsp;等内部申请锁的函数会导致&nbsp;fork&nbsp;后的&nbsp;task&nbsp;死锁,因为其他的&nbsp;task&nbsp;已经不存在的,还提了一下&nbsp;chrome&nbsp;源码中的一些关于&nbsp;fork&nbsp;的注意事项。滔滔不绝讲了半天面试官说不要延伸太多。什么是线程同步。懵逼二度,不知道从哪里说起。和面试官确认了一下讲了数据竞争问题,mutex&nbsp;是阻塞原语可以实现互斥访问,条件变量是同步原语,可以在某个条件不满足的时候阻塞,等到条件满足时由其他线程唤醒,比如生产者消费者问题。还提到了原子变量和内存屏障也能部分地实现同步,由于之前面试官说不要延伸,遂打住。项目相关:有一个操作系统内核实现(没问)还有一个几十个&nbsp;stars&nbsp;的游戏工具项目,主要是用在游戏里自动刷任务的,讲了一下项目架构。C++&nbsp;实现的控制器里面塞了个自己部署的深度学习模型做推理,判定状态后实时交给&nbsp;Lua&nbsp;执行器执行,Lua&nbsp;执行器里封装了&nbsp;Logitech&nbsp;G&nbsp;Hub&nbsp;API,由于标准库仅支持&nbsp;string、math、table,缺少协程,遂用了一点&nbsp;tricks&nbsp;实现了简易协程用来在命令变更时切换任务。为了让用户使用方便还做了个前端。Skills&nbsp;了解过吗。不了解,但知道&nbsp;Agent,做过一些相关的横向、纵向研究,然后谈了一下&nbsp;AI&nbsp;Agent&nbsp;构建的一些流程。面试官说可以了解一下&nbsp;Skills。算法。面试官挑了半天,给了一道&nbsp;Leetcode&nbsp;hard&nbsp;的并查集&nbsp;Redundant&nbsp;Connection&nbsp;II,人直接炸了。撕了半天,面试官又给了一道(没看)说能做出来一个就行。由于第一道已经写了一点,遂继续尝试。写了半天,运行之后发现结果不对,感觉寄了。面试官说思路是对的,就直接让我过了(人也太好了)。反问。问客户端做什么,说是&nbsp;QQ。正好了解过,就问&nbsp;QQ&nbsp;NT&nbsp;这个架构是怎么做跨平台的,几年前&nbsp;Linux&nbsp;根本没有&nbsp;QQ&nbsp;用,现在除了&nbsp;Wayland&nbsp;下面有点小问题,X11&nbsp;基本体验上和&nbsp;Windows&nbsp;没区别。答曰&nbsp;Electron.js&nbsp;加上底层封装库。问底层封装是不是做成动态链接库给上层调用,答曰是,我附和说跟&nbsp;vscode&nbsp;有点像。日常实习,接不接受&nbsp;base&nbsp;深圳。之前投一堆简历都没啥动静,这会压根不挑了。---分割线---二面:问了我做的那个游戏工具项目,然后纯聊天,最后给了个链表去重。三面:让我讲了做的游戏工具项目,讲了二十多分钟,最后给了个&nbsp;AI&nbsp;Coding。目前流程到&nbsp;HR&nbsp;面,感觉快看到曙光了。
钦某:能看出来大佬很强
查看19道真题和解析
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

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