ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

腾讯研发笔试核心考点拆解:从C++内存布局到算法基础

腾讯研发笔试核心考点拆解:从C++内存布局到算法基础 这套题放在今天来看考点依然非常“经典”C对象内存布局、排序算法稳定性、进程线程区别、TCP握手状态、链表操作、动态规划……几乎每个大厂笔试都会换着花样考。但腾讯这套题有个特点它不追求偏题怪题而是把所有研发工程师“应该会”的基础能力浓缩到一张卷子里区分度很高。我刷完第一遍的时候对答案对到怀疑人生很多题看着眼熟一选就错。今天我把这套题涉及的核心考点、解题思路、容易踩的坑以及我从面试官视角反推出来的备考策略一次性拆开聊清楚。1. 这套题到底在考什么题型分布与考察逻辑1.1 整体结构回顾腾讯2016研发工程师笔试题一从题型上看以选择题为主偶尔会有简答或编程题整体分为几大块C/C语言基础、数据结构与算法、操作系统、计算机网络以及少量智力题或逻辑题。很多人拿到卷子第一反应是“怎么都是选择题”但真正做起来才发现选择题往往比编程题更容易暴露知识盲区因为选项里全是精心设计的陷阱。从题目分布来看C/C语言基础占了将近三分之一重点集中在指针、内存管理、构造函数/析构函数、虚函数表、const/static关键字、运算符优先级这些点上。数据结构与算法同样是大头链表反转、二叉树遍历、排序算法比较、哈希冲突处理、动态规划都是高频考点。操作系统部分主要考进程与线程、死锁条件、内存分页、虚拟内存。计算机网络则集中在TCP/UDP、三次握手四次挥手、HTTP状态码、DNS解析过程。这套题给我的第一感觉是覆盖面很广但深度并不夸张。它不像某些竞赛题那样需要奇技淫巧更多是在考察你有没有把计算机基础学扎实。你如果平时写业务代码写得顺手但基础概念模糊这套题能直接把你打回原形。1.2 为什么这些知识点被反复拿出来考我后来跟做校招的同事聊过他说腾讯技术岗笔试的出题逻辑其实很明确基础知识决定你能走多快底层原理决定你能走多远。笔试不指望你写出多惊艳的算法而是想确认三件事你有没有完整的计算机知识体系而不是只会调接口、写CRUD你在写代码的时候是不是真的理解内存里发生了什么、网络请求经过哪些节点你在遇到复杂问题的时候能不能快速定位到合适的数据结构和算法模型。这也是为什么C在腾讯笔试里占比这么高。虽然现在很多业务用Go、Java但C能考察到的东西太丰富了指针让你理解内存本质虚函数让你理解运行时多态内存管理让你理解栈和堆的区别。把这些基础打牢换任何语言都能很快上手。还有一个容易被忽略的点这些题目也在间接考察你的取舍能力。排序算法考稳定性、哈希考冲突解决、进程线程考并发模型本质上都是让你在多个方案之间做选择。笔试题目把选择空间压缩到选项里但背后考察的决策逻辑和实际工作中的技术选型是相通的。2. 核心知识点拆解那些容易被忽略的细节2.1 C/C语言基础指针、内存与关键字这套题里关于C/C的部分给我留下最深印象的是几道围绕指针和内存展开的题。比如 sizeof 和 strlen 的区别、指针数组和数组指针的区别、二维数组作为函数参数时的退化问题。很多非科班出身的同学会在这些地方丢分因为平时写代码很少直接操纵内存地址。举个例子面试题里经常出现类似这样的代码char *p hello; char arr[] hello; printf(%d %d\n, sizeof(p), sizeof(arr));这里 sizeof(p) 在64位系统下结果是8指针大小而 sizeof(arr) 结果是6包含结尾的\0。但如果你不熟悉指针和数组的本质区别很容易被这个结果绕晕。指针保存的是地址数组是一段连续内存的名字这两个概念在笔试里被翻来覆去地考。还有一个高频考点是虚函数和虚函数表。腾讯特别喜欢考“含有虚函数的类其对象内存布局是什么样”这类题。理解的关键在于类中只要有虚函数对象头就会有一个虚函数表指针vptr指向该类维护的一张虚函数表vtable虚函数表里按声明顺序存放每个虚函数的地址继承时派生类会覆盖虚函数表中对应项的地址。笔试常考“sizeof(类)”的大小计算题。比如一个类只有两个int成员和一个虚函数在64位机器上sizeof结果往往是16而不是12因为内存对齐会让int占8字节再叠加vptr的8字节。这种题看似是计算实际考的是你对对象内存模型的理解。我建议刷题时遇到这类题一定要画内存布局图把成员变量、vptr、对齐字节都标出来思路立刻清晰。2.2 数据结构与算法从链表到动态规划数据结构部分腾讯这套题明显偏爱链表和二叉树。链表反转出现过不止一次而且经常变着花样出反转整个链表、反转区间内的节点、判断链表是否有环。核心思路就是指针操作但考场上容易因为边界条件写错。我复习时候整理了一个通用模板以反转单链表为例struct ListNode { int val; ListNode* next; }; ListNode* reverseList(ListNode* head) { ListNode* prev nullptr; ListNode* cur head; while (cur) { ListNode* next cur-next; cur-next prev; prev cur; cur next; } return prev; }这个模板的关键就是记住三句话先保存下一个节点再改当前节点的 next 指向前一个最后整体后移。看起来简单但很多人在手写代码时会忘了第一步导致链表断掉。笔试不一定会要求你直接写代码但选择题里会考“执行某次操作后节点指针指向哪里”这一类问题本质上还是考你有没有真正理解指针变化的每一步。二叉树部分常见的考点是遍历序列推导。比如已知前序遍历和中序遍历求后序遍历。这类题的解法其实很固定前序遍历的第一个节点一定是根节点然后在中序遍历里找到根节点就能把左右子树划分出来递归处理。我在刷题时给自己总结了一句口诀“前序找根中序分界递归切分”。记住这个思路不管是求后序还是求层序都能应对。动态规划也是必考项。腾讯喜欢出经典背包、最长公共子序列、爬楼梯这类题目。选择题里一般不会让你完整写状态转移方程但会考“dp数组某个位置的值是多少”或者“状态转移方程应该是哪个选项”。这种题丢分的原因通常是做题太少状态定义不熟练。以爬楼梯为例状态转移方程其实非常直观dp[i] dp[i-1] dp[i-2]因为到达第i阶只能从第i-1阶或第i-2阶迈上来。但考场上题目稍微包装一下比如加上“不能连续走两步”这种限制很多人就懵了。我的建议是刷动态规划题不要追求数量而是把常见几种模型线性DP、区间DP、背包、LIS/LCS的状态定义和转移逻辑彻底搞懂。2.3 操作系统与网络基础原理比记忆更重要操作系统和计算机网络在这套题里占的比重虽然没有C大但绝对是拉分项。操作系统爱考的点包括进程与线程的区别、死锁的四个必要条件、虚拟内存与分页、进程间通信方式。这些内容只看书不刷题很容易产生“我懂了”的错觉真到做题时才发现掌握得不够扎实。举一个经典的例子进程和线程的区别。很多同学能背出“进程是资源分配的最小单位线程是CPU调度的最小单位”但一旦考到“多线程共享哪些资源、独占哪些资源”就开始含糊。线程共享进程的地址空间、全局变量、文件描述符、信号处理器但每个线程有自己的栈、寄存器和程序计数器。这个点反复出现在校招笔试里腾讯也不例外。网络部分TCP三次握手是雷打不动的考点。选择题通常考“第三次握手发送的报文段确认号是多少”或“握手过程中各端状态如何变化”。还有可能结合SYN Flood攻击来考问你为什么需要第三次握手。理解三次握手的核心在于确认双方收发能力都正常同时防止旧连接请求的残留。SYN Flood就是利用不完整的握手过程来发起攻击如果服务端收到大量SYN请求后为每个请求分配资源并等待ACK就会导致资源耗尽。我还记得这套题里有关于TCP和UDP区别的选择题题目本身不难但选项很刁钻。比如“UDP是否可靠”“TCP是否面向字节流”“UDP是否有拥塞控制”。这些都是送分题但如果不仔细看选项很容易被类似的表述迷惑。复习的时候最好把TCP的可靠传输机制确认、重传、流量控制、拥塞控制和UDP的特点整理成一张对比表考前过一遍基本不会丢分。3. 经典题型实操拆解从读题到写出答案3.1 细节题运算符优先级与类型转换腾讯笔试里有一类题看起来简单但正确率往往很低就是运算符优先级和隐式类型转换。这类题考察的不是会不会编程而是有没有真正记住语言的底层规则。举一个高频例子int a 5; int b (a) (a);问 a 和 b 的值分别是多少。这个问题在不同编译器下可能有不同结果C标准里这种“在同一表达式中多次修改同一变量”的行为是未定义的但很多笔试选择题会忽略这一点给一个“标准答案”。实际刷题时遇到这种题最好的策略是记住常见优先级规律但对于未定义行为的代码要能识别出题目本身不严谨。运算符优先级有个流传很广的口诀“单目 算术 移位 关系 位 逻辑 赋值 逗号”。但光背口诀不够更重要的是做题时养成加括号的习惯。我在笔试时遇到不确定的表达式会先在草稿纸上把优先级高的部分先算出来再逐步代入避免凭感觉直接选答案。隐式类型转换也是高频考点尤其是整型提升和算术转换。比如unsigned int a 1; int b -1; if (a b) { printf(a b\n); } else { printf(a b\n); }这段代码输出什么答案是 a b。原因是在比较时int 会被隐式转换为 unsigned int-1 变成了 0xFFFFFFFF也就是 4294967295所以 a b 不成立输出 a b。很多人在这个基础题上翻车不是不会而是没意识到类型转换的时机。遇到这种题先看两边的类型是否一致如果不一致一定要先转换再比较。3.2 算法题从递推公式到边界条件笔试里如果出现简答或编程题动态规划和字符串处理是主流方向。腾讯2016这套题我记得有一道比较有代表性的字符串相关问题核心是求最长公共子串或最长公共子序列。很多人在拿到这类题后第一反应是“这题我见过”但真下手写的时候往往卡在dp数组的初始化上。最长公共子序列的状态转移方程是这样的if (s1[i] s2[j]) { dp[i][j] dp[i-1][j-1] 1; } else { dp[i][j] max(dp[i-1][j], dp[i][j-1]); }这里有个细节特别容易出错dp数组的下标是从1开始还是从0开始。如果直接从0开始那么处理i0或j0时会出现越界。最简单的做法是让dp数组多开一行一列把dp[0][j]和dp[i][0]全部初始化为0这样递推时就不需要额外判断边界。这个技巧在刷题时省了很多时间我在笔试里也是这样处理的。边界条件不仅出现在DP里也出现在二叉树、链表的题目里。比如求二叉树深度时递归出口是“节点为空则返回0”很多同学会写成返回1导致结果偏大。这些小错误在选择题里不会直接暴露但如果考场上让你写代码边界条件就是最容易被扣分的地方。我给自己定的规矩是任何递归函数先写终止条件任何循环先考虑边界索引养成肌肉记忆。3.3 排序算法稳定性和复杂度对比排序算法是腾讯笔试的常客尤其喜欢考“哪些排序算法是稳定的”“最坏时间复杂度是O(n²)的排序有哪些”“堆排序为什么不稳定”这类对比型问题。这里给一张我当年整理的速查表建议直接背下来算法平均时间复杂度最坏时间复杂度空间复杂度稳定性冒泡排序O(n²)O(n²)O(1)稳定选择排序O(n²)O(n²)O(1)不稳定插入排序O(n²)O(n²)O(1)稳定希尔排序O(n^1.3)O(n²)O(1)不稳定归并排序O(n log n)O(n log n)O(n)稳定快速排序O(n log n)O(n²)O(log n)不稳定堆排序O(n log n)O(n log n)O(1)不稳定稳定性这个概念字面意思就是“相等元素的相对顺序在排序后保持不变”。为什么有的场景必须用稳定排序典型场景是成绩排名按总分排完还要保持相同分数下按学号的原始顺序。理解了应用场景就不容易记混。还有一个常见的变体题如果要求“在O(n)时间内把0和1分开”或者“把负数放左边、正数放右边”这其实是快速排序中 partition 操作的应用。很多选择题不会直接问快速排序怎么写而是问“一趟快排之后某个元素的位置会在哪里”本质是在考察 partition 后的结果。我建议把快排的单趟过程亲手模拟一遍比背十遍代码都管用。4. 备考经验与踩坑指南4.1 刷题顺序先基础后综合我在准备这类笔试时走过一段弯路一开始直接刷整套卷子结果错得一塌糊涂对完答案发现很多题不是不会而是基础知识有漏洞。后来我调整了策略先把每个科目的高频考点过一遍再针对薄弱点刷专项题最后才做整套模拟题。具体来说我会把时间分成三个阶段第一阶段基础巩固梳理C语法要点尤其是内存管理和面向对象部分把常见数据结构从头实现一遍包括链表、栈、队列、二叉树操作系统和网络只看高频考点不追求面面俱到。第二阶段专项突破针对每个高频考点刷题比如连续刷20道数组指针题、20道二叉树遍历题、20道动态规划题。刷完后总结出题套路和常见陷阱形成自己的错题本。第三阶段成套模拟严格按照考试时间做整套题做完不仅看正确率还要复盘每道错题背后的知识点漏洞。对于时间比较紧的同学我的建议是优先搞定C基础、经典排序算法、链表和二叉树这几个板块出题概率高回报比也最大。4.2 错题本的正确打开方式说到错题本我曾踩过一个坑把错题抄一遍、答案写上去然后就再也没有翻过。这种错题本除了感动自己没有任何用处。正确的做法是错题本上不写详细解析只写“题目考点 错误原因 正确结论”隔几天遮住答案重新做一遍直到连续两次做对为止。举个例子如果我在“int与unsigned int比较”这类题上栽了跟头我会在错题本上记下考点隐式类型转换规则错误原因忽略整型提升正确结论有符号与无符号比较时有符号数会转为无符号数这样做的意义在于把一道错题抽象成一个知识卡片而不是机械地记住某道题的答案。大厂笔试的题目几乎不会原封不动地重复但考点就那么些抽象成卡片后遇到变体题也能一眼识别出本质。4.3 考场上最容易犯的错误把我自己和其他同学的经验汇总一下考场上常见的丢分点有这几类审题不仔细选项没看完就选。腾讯的选项经常有“A和B都正确”“以上说法都不对”这种组合型选项只看前两个选项很容易选错。在计算题上死磕浪费时间。有些选择题看似要算很多步其实可以用排除法快速定位正确答案先把明显错误的选项排除再在剩下的选项里精算。遇到不会的题乱蒙但忽略了“少得分策略”。如果笔试有倒扣分规则不会的题宁可不选也不要瞎蒙如果没有倒扣分可以凭常识猜一个但不要因此影响后面的答题节奏。我个人的习惯是整套卷子先做一遍遇到卡壳的题先标记不在当场纠结。等第一遍做完再回头处理标记的题目。这样能保证会做的题都拿到分不会因为某一题耗时太久而导致后面会做的题没时间。4.4 长期备考的额外建议如果你准备时间还比较充裕我强烈建议你不要只刷题而是把《C Primer》中关于内存、对象、模板的部分精读一遍把《深入理解计算机系统》中关于链接、虚拟内存、异常控制流的部分扫一遍。这些书虽然厚但读完再看笔试题很多题不用猜就能直接推理出答案。再一个建议就是多写代码。笔试里有些知识点单看解析觉得懂了一旦让你动手实现就会露馅。比如让你实现一个String类包含构造、析构、拷贝构造、赋值运算符这道经典面试题能暴露出很多问题析构函数有没有加virtual、拷贝构造有没有深拷贝、赋值运算符有没有处理自赋值。笔试可能不直接考这么完整的代码题但里面涉及的每一个点都可能在选择题里出现。5. 从这套题反推面试准备方向5.1 为什么笔试后紧接着是问“项目亮点”笔试只是第一关腾讯的面试往往会在项目经历上深挖。笔试基础题做得好说明你有扎实的底子但面试官更关心的是你能不能把基础能力应用到实际项目中。所以我在准备笔试的同时也在复习自己的项目重点想清楚几个问题项目里最有技术含量的模块是哪个它解决了什么实际问题用到了哪些数据结构、算法或者设计模式为什么这么选如果数据量扩大十倍你的方案还成立吗瓶颈在哪里刷题和项目复盘并不是割裂的。比如你在项目里处理过大量日志数据那就可以把哈希、排序、多线程这些知识点串联起来讲比单纯背概念有说服力得多。5.2 笔试是敲门砖不是终点说到最后我想提醒一点不要因为一套笔试题做得不好就否定自己。这套题覆盖面广但每一道题背后都是可以在几个月内通过系统复习补起来的。反过来如果笔试做得顺手也别飘因为真正的战场是面试笔试只是告诉面试官“你可以来聊聊”。我当年刷完这套题之后最大的感受是基础不牢地动山摇。很多业务代码写久了人会变得“会用但不懂”看答案觉得简单自己选就错。只有把那些底层原理真正吃透做题才不是靠猜而是靠推理。这也是我后来每次带校招生都让他们先刷这类经典笔试的原因——它像一面镜子清清楚楚照出你的知识短板在哪里。
返回列表