# 【NO.597】记录一次腾讯c/c++ linux后台开发岗面试经历（面试题含答案）

腾讯c/c++ linux后台开发社招面试流程虽然因人而异，但就个人感受而言，腾讯的面试从考察内容方面来讲，还是有一定的共通性，这一点，可以从网上众多的面经可以看出。

腾讯的面试的流程持续一个多月

第一轮和第二轮电话面试，技术面；

第三轮和第四轮现场笔试+面试，技术面；

第六轮HR面；

最后offer call；

**第一面**

时间晚八点半，电话面，开始项目介绍，技术难点、实现细节。大概说了20分钟左右，可能是项目架构比较复杂，口述不是特别形象，又聊了10分钟，貌似双方谁也没说服谁。开始聊计算机网络、操作系统。内容包括TCP拥塞控制算法、TCP和UDP区别、进程和线程区别等等。都是常规的题目。这一块已经很好的复习过。没问题。时间过去50分钟，面试官总结网络协议这一块不错，原理和项目实战比较强，会有下一面。

**第二面**

距离一面隔了六天。电话面，大概20分钟左右。内容如下，不分先后：

Q1. 构造函数可以是虚函数吗？

A：不可以。原因有两点：

构造对象的时候，必须知道对象的实际类型。而虚函数行为是在运行期间确定实际类型的，在构造对象的时，对象还没有构造成功，编译器无法知道对象的实际类型是该类本身还是其派生类。

虚函数的运行依赖于虚函数指针，而虚函数指针在构造函数中进程初始化，让它指向正确的虚函数表，而在对象构造期间，虚函数指针还未构造完成。

Q2. 网络字节序是大端序还是小端序？

A：大端序。

Q3. Linux中如何创建进程以及创建进程后如何区分子进程？

A：使用fork()调用创建子进程，fork()调用返回两个值，大于0的表示父进程，等于0的表示子进程。

Q4. fork创建的子进程继承了父进程哪些内容

A：子进程继承了父进程的地址空间，打开的文件描述符等。

Q5. fork创建的子进程继承了父进程打开的文件描述符，如何让这种继承不发生

A：可以在打开文件的时候，设置FD_CLOSEXEC标志位，如果文件描述符中这个标志位置位，那么调用exec时会自动关闭对应的文件。

Q6. c++虚函数原理

A：虚函数是依赖于虚函数指针实现，每个拥有虚函数的类都有一个虚表，类的对象存在一个虚函数指针，指向实际类型的虚表。虚函数运行的时候，会根据虚函数指针找到正确的虚表，从而执行正确的虚函数。

Q7. c++多态的实现

A：多态分为两种，一种是运行时的多态，一种是编译时的多态。前者称为动态绑定，后者称为静态绑定。动态绑定时由虚函数来实现，静态绑定是由函数重载来实现。

Q8. c++ vector和list的区别？

A：vector是动态数组，会动态进行分配内存，进行扩容操作。list是双向链表。

Q9. 访问vector的迭代器的时候可以删减元素吗？list呢

A：任何对vector的修改都将导致vector的迭代器失效。list因为是双向链表，所以不会失效。

Q10. c++ vector的底层实现原理

A：vector底层是基于动态数组实现。

Q11. c++ map的底层实现

A：map的底层实现是基于红黑树的。

Q12. 红黑树的特点以及常见的二叉平衡树

A：红黑树性能比较高，插入删除时间复杂度保持在logn。和AVL相比，要求不是那么严格，它只要求到叶节点的最长路径不超过最短路径的两倍。相比之下，AVL要求左右子树相差高度不超过一，简单的插入或者删除都会导致树的不平衡需要旋转操作。

(我只说这么多，后来的同学建议说下红黑树的五个特点)

Q13. c++空类的sizeof大小

A：c++空类的大小为1，如果含有虚函数的话，大小为指针的大小。32位系统指针大小是4。c++要求即使是空类，对象也要有存储空间。含有虚函数的空类则是因为对象由虚函数指针。

Q14. 快速排序的时间复杂度

A：快速排序平均时间复杂度位nlogn，最差O(n^2)

Q15. nLogn是排序最好的时间复杂度吗？

A：不是，还有O(n)的算法，比如说基数排序。

Q16. 基数排序的原理以及应用

A：基数排序根据一个数的高低位进行排序。应用不知道，缺点是对负数的处理不太好。

Q17. 介绍负载均衡的应用

A：不知道。

Q18. http协议有用过吗？

A：这个没用过。

Q19. protobuf协议

A：我们公司之前使用的是json协议，没有用过protobuf协议。

Q20. 数据库

A：没用过。

Q21. redis

A：这个是自己学习使用的，生产环境没用过(这里说了下，我用它干嘛的，使用python的flask web框架基于redis的list结构开发一个网络聊天程序)

Q22. 解释线程安全和可重入函数

A：这个是关于多线程访问的吗？可重入函数这个名词听过，但是忘记干啥了，面试官说pass.

(一个可重入函数被称为可重入的，表明该函数被重入之后，不会产生任何不良后果，一个函数被重入，表示这个函数没有执行完成，由于内部原因或外部原因调用，又一次进入该函数执行)

Q23. top的命令cache和buffer区别

A：这个平常没有关注过。(buffer是块设备的读写缓冲区，比如磁盘，cache是文件系统的缓存，常用于文件)

Q24. 常见Linux命令是否用过，比如strace和netstat

A：这个有用过，strace用来跟踪程序的执行，top查看内存，以及tcpdump等进行抓包等等。

Q25. 多个动态库的连接顺序有区别吗，顺序怎么排

A：有顺序的，如果顺序错误的话可能导致编译失败。这里的编译顺序应该是被依赖的库放在后面。(这个我之前工作中遇到这个坑，所以知道。不过当时面试的时候，把顺序忘了)

Q26. 智力题，100本书，两个人轮流拿，每次拿1~5本，你先拿，有没有啥策略可以保证你可以拿到最后一本？

A：这个得承认，智力题不是我的强项，每次遇到的话都要很久才思考明白，当时考虑了大概30秒，想着100本这么多，要不先来10本试试，我一本，他一本，我一本…挣扎了几秒，老实承认，没想到啥好方法。

(此题解法可以是先手拿4本，后续双方每次拿6的倍数，这样可以保证最终可以拿到最后一本)。

**第三面**

现场面，时间下午2点，给了一张试卷，1.5小时完成。如果难度分成5个等级，感觉介于2和3之间。试卷内容保密。总之，考察比较基础也比较全面，C++，操作系统，计算机网络，算法和数据结构。

3点半，两个面试官。对着简历介绍项目，细节，技术难点，架构设计等等。接下来考察软件工程原理。这部分只给出题目。

1、Linux互斥锁里面递归锁和非递归锁的使用方式，返回值。

2、Golang Map是否是线程安全，如何设计一个无锁保护的Map(可能答案是使用CAS)。

3、程序的地址空间分布。

4、介绍Linux内存管理机制、涉及到的算法。

5、设计一个内存池。

6、设计一个定时器

7、解释时间轮

8、Golang里面CGO原理

9、awk和sed是啥。咋用。

10、TCP粘包怎么解决。

11、设计线程池。

12、Golang defer语句调用顺序。

13、TIME_WAIT状态有啥用。

14、画出四次挥手原理图。

15、define和inline区别。

16、定义常量指针和指针常量。

17、accept是在三次握手哪一次。

18、backlog作用。

**第四面**

一篇介绍memcpy的标准库函数的博客，让我优化。当时觉得，标准库里的函数咋优化，能优化标准库自己不就优化了，哪轮到我优化？？？但人家让优化，肯定有优化空间，硬着头皮上。对，就是下面这个函数，看了将近一分钟，咋看都觉得这个函数很完美。觉得一个一个复制已经很好了，还能咋办。问了下，能否给点提示，答曰，不急，慢慢来。又想了一会儿，还是没啥思路，这时候，总监来了一句，“你不觉得一个一个复制有点慢吗”。

到了这时候，还是没啥反应，不过既然嫌弃一个一个慢，那两个两个复制可以么？问了下两个两个复制算不算优化，答曰：算。于是想到使用一个short类型复制。后来总监看我有点思路，就提示我说，从汇编角度来优化，包括寄存器大小等等。

然后，我使用long long类型来复制，即每次8个。手写了实现，然后总监问我，如果地址不对齐咋办？到这一步，当时没想到地址对齐这个问题，没有答上来，后来想了下，即使没对齐，可以先一个一个复制等对齐了再每次复制8个。

当时对齐问题没啥思路就pass了。感觉面试官水平很高，这道问题的水准也很高。关于优化以及编译的问题，事后查了相关资料，这里推荐两本书：《深入理解计算机系统》、《程序员的自我修养—链接、装载与库》。对于优化的原理、编译器原理讲解的非常好。

```text
void *memmove (void *dest, const void *src, size_t len)
{
char *d = dest;
const char *s = src;
if (d < s)
while (len--)
      *d++ = *s++;
else
    {
char *lasts = s + (len-1);
char *lastd = d + (len-1);
while (len--)
        *lastd-- = *lasts--;
    }
return dest;
}
```

继续做题。

N个M长度数组求交集，求最优解并给出时间复杂度和空间复杂度。我给出的方案是归并、去重、全排序。然后问了下为啥用归并排序，于是介绍快排、归并、堆排各自优缺点和使用场景。然后问有没有更好的解法。想了下，给出了优化方案，仍然是归并，去重，然后hash。然后过。

第三题，c++手写单例模式，《剑指offer》第二题。

因为简历上有些会shell开发，然后给出第四题：

给定一个日志文件，每行包括日期，IP地址，错误码。然后让我使用shell搜索指定日期，指定IP，指定错误的日志出现次数。简单题，grep -rns “date + IP + error” | wc -l

看我的答案之后，在这个题目加了下扩展，除了前述三个内容，还有第四列content，每一行都不一样。马上给了答案：

awk -F"|" “print112 $3” | grep -rns “date + IP + error” | wc -l

应该是考察我awk的使用。这里提醒各位同学，自称会shell开发一定要掌握awk和sed的使用。基本上，面试官看到自称会shell必考。

整个面试流程持续四个小时

**第五面**

距离三面和四面隔了7天，期间没有任何消息，以为凉了。结果来了电话，约复试。

复试的内容没有特殊之处，依旧是基础。内容如下：

1、介绍前公司产品的功能、市场竞争力、自己负责的部分、产品的软件架构

简要介绍下前公司的产品、功能、市场竞争力，虽然咱是搞技术的，但是关于产品市场的事情，平常工作中还是多多少少有所关注。此外，就是介绍产品的软件架构图，以及自己负责的模块等等。很多同学遇到类似的问题，会说，自己只负责一个部分，不知道产品的整体架构。这样回答，往往给人的感觉就是很水，搞技术的，不会可以，但是不会可以学啊，虽然，整体架构没涉及过，但是，没吃过猪肉不能没见过猪跑。做了那么久，产品啥架构还不了解，这就有点说不过去了。所以，建议各位同学平常工作过程中，有空的话也从整体的角度思考下产品，万一哪天需要自己搞呢。

2、路由NAT如何实现

这一块没有接触过。画了一个映射图，大概描述了一下。

3、考察结构体字节对齐问题

4、概率题，两个红球一个白球，三个盒子。问第二个盒子至少一个红球的概率

考察概率论。刚开始拿到题，以为需要算法。想了一会儿没啥好方法，略显尴尬的说，使用枚举吧。所谓暴力法。画了一个多叉树的图，一目了然。事后想来，枚举才是最简单的方法。

5、编程题，字符串去空格

6、进程、线程区别。为什么有了多线程还是用多进程

基本的操作系统原理题。后面的问题只说了进程地址空间有限，不能创建任意多的线程。回来想了下，更好的回答应该是，进程是一个程序实体，多个程序需要多个进程。此外，进程地址空间相互隔离，安全。

7、平时如何定位问题，core dump怎么产生的

通常线上问题先复现、再定位。core dump怎么产生不知道。后来查了下，当程序有未处理的信号时，内核会自动生成core dump。能否生成core dump还有ulimit -c的限制。

8、构造函数调用虚函数可不可以

不可以。说了下虚函数的作用以及构造函数的调用顺序。后面又问，如果调用会出现啥情况。因为不确定所以说不知道。回来测试了下，是调用被调对象的自己的版本。

9、算法题：给定电话号码加区号，如何快速查找对应地区

区号占4位。给了长度10000的数组做hash，O(1)。问有没有办法提高空间利用率，没想到。想到的同学告诉我。然后给了红黑树存储，时间复杂度O(logN)太高。

10、常用的IDE

C语言使用source insight，Golang使用liteide。

11、线程调度问题

这里解释了下两种调度类以及它们的调度策略，然后是底层的实现原理，后来问调度过程的具体步骤，我记得内核的调度函数是schedule()，具体的操作没有分析过，这里只说了大概，保存寄存器、上下文，然后加载被调进程的上下文、寄存器等等。

12、不同编译器编译的库能否混用

没用过，不知道。后来查了下，不同版本的编译器编译出来库不能混用，不过网上的回答也没有解释清楚。觉得可能在问extern "C"问题。

13、离职原因，离职这么久都干嘛去了

14、阅读源码有啥好处？对以前的项目有没有啥改进之处？

15、有什么问题想问的

问了下直播业务涉及的终端以及后台开发过程中使用到哪些中间件技术。然后，问了下腾讯的服务器内核啥样子，回答说是定制的T-Linux内核。

整体感觉面试愉快，面试官也在考察知识深度，不会的也没关系。

**第六面**

距离复试三天时间，中午电话。

1、为什么学些德语

2、第一份工作学习到啥

3、对腾讯怎么看

4、期望薪资以及依据

5、当前薪资、福利

6、以前是通信的，对互联网怎么看

7、部门业务量很多，可能需要加班，你怎么看

8、有什么问题想问的

两天后，给了offer。腾讯的面试流程大体这样，技术面考察的都是基础，要有深度，不能停留在表面。自己前前后后准备了四个月，从第一次的惨败到后期的从容面对，一步步走下来，收获满满，最终得到想要的结果

![img](https://pic1.zhimg.com/80/v2-0f141f494f299642d870fdb807eb5840_720w.webp)

原文地址：https://zhuanlan.zhihu.com/p/474215143

作者：CPP后端技术