
腾讯2014年校招研发工程师笔试卷A在我手头这份备考资料合集里算得上元老级的存在。很多准备校招的同学第一次看到它第一反应是这么老还有参考价值吗但凡是认真刷完的人基本都会改变这个看法。原因很简单大厂研发岗笔试的核心考点从十年前到现在就没怎么变过数据结构、操作系统、计算机网络、C/C基本功依然是那几座大山。这份卷子适合谁如果你是正在准备互联网大厂校招的应届生想找一份能打的真题来摸底如果你是从业两三年的工程师想看看自己基本功有没有退化甚至是你刚带团队、需要给新人出笔试题的负责人都可以把这份卷子当成一个起点它帮你把研发工程师应该会什么这件事画得非常清晰。接下来说说我这次重新翻它的感受。最早拿到这份卷子是帮一个准备校招的学弟做模拟评估当时心里想的是这份卷子考得真够扎实。后来自己带团队、给新人出笔试题绕了一大圈发现考来考去的核心还是这份卷子里那些东西。这篇文章不打算逐题报答案而是把这份卷子背后的考察逻辑、核心知识点以及我踩过的坑和同行交流得出的经验系统拆给你看。1. 试卷整体设计与考察逻辑1.1 题型分布与分值结构腾讯2014年校招研发工程师笔试卷A整体时长大约是90到120分钟题量不小。从当时参加考试的同学反馈来看卷面大概是这个构成单选题十来道多选题五六道填空题若干后面还有两三道简答题或编程题个别方向还会有附加的开放设计题。这个结构放到今天依然经典因为它能在有限的时间内快速把一个人的基础广度、代码功底和思维深度摸个大概。我辅导学生做模拟时统计下来发现一个规律数据结构和算法类的题目占比通常在30%到40%之间操作系统和计算机网络加起来还有25%左右C/C语言特性大约占20%剩下的是智力题和扩展题。这个比例不是巧合它反映了大厂对研发工程师的能力预期你会写代码但不能只会写代码你得知道代码跑在什么环境里底层发生了什么。有个学生考完出来凭记忆给我复述过一张题目构成表我在这里整理一下选择题里有两道纯C语法题、两道操作系统、一道网络、两道数据结构、一道智力题多选题里有一道是下列哪些排序算法是稳定的填空里有一道是写出TCP三次握手的标志位变化。虽然原题和这个可能有出入但考察轮廓基本就这样。为什么我要强调弄清楚分值分布因为很多人拿到卷子就从头做到尾这是最忌讳的。你至少要花两分钟扫一遍全卷在心里标记出哪些题目是送分题、哪些是硬骨头然后决定先啃哪块。我后面第六节会专门讲做题顺序这里先记住一句话分值越高的板块越值得你优先保证正确率。1.2 为什么这份卷子值得反复研究2014年的大厂笔试可以说是校招标准化筛选的一个分水岭。再往前几年很多公司笔试就是随便出几道题靠面试官主观判断从腾讯这一批开始卷子的结构、难度曲线、考点分布都趋于成熟后来很多公司的笔试都参考过这个模板。所以你研究这份卷子本质上是在研究整个互联网行业沉淀下来的一套研发基本功的通用测试标准。另外有一个很多人忽略的点这份卷子里的不少题其实是带陷阱的。它不是考你会不会背概念而是考你概念背后的理解是否透彻。比如C部分的宏定义、内存对齐网络部分的TCP握手细节如果你只是背了三次握手四次挥手六个字答题时大概率会掉进坑里。这种出题思路到现在还是主流所以反复研究老卷子能培养你对题目陷阱的敏感度。我带校招生最明显的一个感受是刷过这类老牌卷子的同学在笔试环节的通过率明显高于只看面经的同学。原因不在于题目重复而在于刷题过程中形成的题感那种看到考察点就条件反射的感觉是面经给不了你的。这份卷子就是训练题感的好材料。2. 数据结构与算法笔试的绝对核心2.1 链表与指针操作的经典考法无论哪个年份的腾讯笔试题链表都是必考内容。2014年这份卷子里链表题以手写单链表反转最为典型形式上可能是让你补全代码也可能是让你直接写出完整函数。别小看这道题它同时考察了三件事你的指针基本功、你的边界条件意识、你写代码的稳定性。我当时让学生写这道题时发现一个很有意思的现象很多同学在纸上写代码时逻辑没问题但一上机就出错原因往往是忽略了空链表和单节点的处理。正确的做法是先定义好思路用三个指针prev、cur、next从头开始一个一个把方向反过来。我自己更推荐的写法是struct ListNode* reverseList(struct ListNode* head) { struct ListNode *prev NULL; struct ListNode *cur head; while (cur ! NULL) { struct ListNode *next cur-next; cur-next prev; prev cur; cur next; } return prev; }这道题里面有个细节值得多说一句为什么要先把next保存下来因为一旦执行cur-next prev原来的后继就丢了如果不提前保存链表就断了。这个防止断链的思维在很多链表场景题里都会用到比如判断链表是否有环、找链表中点、删除倒数第K个节点本质上都是这套东西。顺便说下判断链表是否有环的经典解法是快慢指针一个走一步、一个走两步如果相遇说明有环。这道题在卷子里经常以选择题出现问如何判断链表有环我会建议你养成画图的习惯。快慢指针相遇的推导过程如果自己推过一遍比死记结论要牢靠得多。2.2 排序与查找的时间复杂度陷阱排序问题是选择题的重灾区尤其是各种排序算法的时间复杂度、稳定性、适用场景。2014年卷子里必有一两道这种题。很多人栽在稳定性这个概念上其实稳定性的意思是如果两个元素值相同排序后它们的相对顺序会不会改变。冒泡、插入、归并是稳定的堆排、快排、选择排序不稳定这个表建议你直接背下来但更重要的是理解为什么。我整理了一个表你在复习的时候可以对着看排序算法平均时间复杂度空间复杂度稳定性冒泡排序O(n²)O(1)稳定插入排序O(n²)O(1)稳定选择排序O(n²)O(1)不稳定快速排序O(nlogn)O(logn)不稳定归并排序O(nlogn)O(n)稳定堆排序O(nlogn)O(1)不稳定举个典型的选择题给出一串数字在排序过程中的中间状态问这可能是哪种排序算法的某一趟结果。这种题考察的是你不仅知道算法原理还得能识别算法的执行过程。我建议你复习时把快速排序的partition过程在纸上手推三五遍把归并排序的合并过程也画两遍这些动作看起来费时间但对考试帮助极大。排序之外查找也是必考。二分查找在2014年那会儿就已经是送分题了但送分不代表你不会出错。二分查找最大的坑是边界条件用left right还是left rightmid是取(leftright)/2还是(leftright1)/2这些细节决定了你的代码会不会死循环。我的习惯是统一用left rightmid取left (right - left) / 2这样可以避免leftright溢出笔试时写死一套最熟悉的别临时换写法。2.3 递归与动态规划的入门级题目递归和动态规划在2014年笔试里属于拉开差距的题目但拉开差距的不是题目本身有多难而是你有没有掌握分析框架。卷子里常见的递归题一个是斐波那契数列一个是爬楼梯。很多人一看到递归就直接写递归int fib(int n) { if (n 1) return n; return fib(n - 1) fib(n - 2); }代码是没错但如果你答完就结束了分数会被扣不少。为什么因为这是个经典陷阱这种写法的时间复杂度是O(2^n)n稍微大一点就爆炸了而且递归调用栈会非常深。笔试题如果你能进一步写出迭代版本或者用带备忘录的递归把复杂度降到O(n)就证明你真的理解了问题本质而不是背了个模板。这就是一道题看出水平的地方。爬楼梯的题也很经典一次可以上1级或2级台阶n级台阶有多少种走法这个题本质上就是斐波那契数列f(n)f(n-1)f(n-2)。很多人不理解为什么我用一个例子解释最后一步要么跨1级要么跨2级所以到第n级的走法数等于到第n-1级的走法数加上到第n-2级的走法数。这个逻辑理清楚状态转移方程就出来了。动态规划的入门题卷子里大概率会有某个二维网格从左上角走到右下角有多少种走法之类的变体套路是先定义dp[i][j]的含义再写状态转移方程最后确定初值。很多人死在第一步dp含义定义错了后面全完。我的建议是笔试前十来天把常见的DP类型过一遍斐波那契类、路径类、背包类、子序列类每种类型做三道题建立起看到题先想dp的条件反射。3. 操作系统与计算机网络基础中的基础3.1 进程线程与内存管理的常见考题操作系统部分的题目腾讯2014年这份卷子重点考察了进程与线程的区别、进程间通信方式、虚拟内存和页面置换算法。这些内容看似是理论其实和实际开发关系非常密切。比如选择题经常这么出下列关于进程和线程的说法错误的是哪一个选项里会混着各种半对半错的表述如果你只是背了进程是资源分配的最小单位线程是CPU调度的最小单位只靠这一句是不够的你还得知道同一个进程里的线程共享什么、不共享什么。进程间通信的方式也是个热门考点管道、消息队列、共享内存、信号量、套接字。这里我提醒一句很多人把信号量和信号搞混信号量是同步工具信号是异步通知机制卷子特别喜欢在这两个概念上设陷阱。答题时看清楚题目问的是同步还是通信再动笔。内存管理部分LRU最近最少使用页面置换算法几乎是必考而且常常不满足于考概念会给你一个访问序列让你模拟LRU的淘汰过程数一下缺页次数。这种题没有捷径老老实实在纸上画表。举个例子如果内存只有3个页框访问序列是1、2、3、4、1、2、5、1、2、3、4、5模拟LRU时每次缺页都要淘汰最长时间没被访问的页面你在纸上画一个三行多列的表格一列一列填很快就能得出缺页次数。FIFO则简单一些先进先出但会出现Belady异常——增加页框反而缺页次数增多。这个知识点在选择题里也考过复习时多留意一下。平时我建议你把LRU的代码实现也练一下用哈希表加双向链表实现笔试虽然不一定考手写但这段代码能帮你把哈希表查找O(1) 链表删除插入O(1)这个设计思路吃透遇到类似的开放题也知道怎么聊。3.2 TCP/IP与网络编程高频考点网络部分年年都是TCP/IP协议的天下。2014年卷子里三次握手和四次挥手几乎是必考的简答题。如果你现在问我三次握手为什么是三次而不是两次我想最直观的解释是三次握手能让双方都确认自己能发、能收对方能发、能收。两次握手的话客户端知道服务端能收到但服务端不知道客户端能否收到自己的握手应答存在资源浪费和连接错乱的风险。四次挥手为什么要四次则是因为TCP是全双工的每一方的关闭都要独立通知对方。这里有个经典考点TIME_WAIT状态。主动关闭方在收到对方的FIN后会进入TIME_WAIT等2MSL才能彻底关闭原因一是保证最后的ACK能到达二是让旧连接的报文在网络中消失避免干扰新连接。笔试题如果问为什么TIME_WAIT要等2MSL你能从这两个角度回答基本就是满分答案。另外提醒一下HTTP状态码在2014年那会儿就已经是送分选择题了200是成功301是永久重定向302是临时重定向403是禁止访问404是资源不存在500是服务器内部错误502是网关错误。这些最好刻在脑子里因为不光是笔试实际排查线上问题也天天用得到。3.3 死锁与并发控制死锁这块最经典的选择题是问死锁的四个必要条件是什么答案就一句话互斥、持有并等待、不可剥夺、循环等待。但光记住还不行卷子经常进一步问你打破哪个条件可以预防死锁或者银行家算法属于哪种策略。银行家算法的核心思想是在分配资源之前判断系统是否处于安全状态只有安全才分配它是一种避免死锁的策略而不是预防策略这个措辞差异在判断题里很要命。并发控制部分生产者消费者问题在笔试里出现的概率极高形式可能是让你用信号量写伪代码也可能只是选择题问需要几个信号量。我建议你认真写一遍这个经典问题重点理解为什么需要三个信号量mutex初值为1empty初值为Nfull初值为0。生产者先P(empty)再P(mutex)消费者先P(full)再P(mutex)顺序不能颠倒不然可能出现死锁。这个顺序的讲究笔试不一定问但你在答案里写出来是加分项。写完之后再把它类比到现实中就有点像多人合作流水线上游生产太快会堵下游消费太快会空必须设个缓冲区加协调机制。这样理解后无论题目怎么变化核心逻辑都在你脑子里。4. C/C语言细节藏在代码里的坑4.1 sizeof、指针与内存对齐C/C部分2014年腾讯笔试卷A有一个非常经典的选择题套路给出一段代码问你sizeof的结果是多少。这类题表面上考的是sizeof实际上考的是指针、数组和结构体内存对齐。比如char str[] hello; char *p str; // sizeof(str) 6因为包括结尾的\0 // sizeof(p) 432位平台或 864位平台很多人栽在第一个空因为忘记了字符串数组末尾的\0。更隐蔽的是第二空明明p指向的是同一个字符串但sizeof(p)算的是指针本身的大小和字符串长度无关。这个数组名和指针的区别是C语言里最经典的陷阱之一笔试题几乎年年翻新但要义就一句话数组名在大多数表达式中会退化为指针但sizeof单独作用于数组名时算的是整个数组的大小。内存对齐的题也很常见。比如问一个包含char、int、char三个成员的结构体占多少字节很多人算成1416正确答案在32位平台上是12因为int要对齐到4字节边界。我教你一个土办法把结构体想象成一行座位每个成员必须坐在自己倍数编号的座位上排在后面的成员不能抢前面的位置最后整个结构体的大小还得是最大成员对齐数的整数倍。这样推一遍基本不会错。struct Node { char a; // 偏移0 int b; // 偏移4需要填充3字节 char c; // 偏移8 // 整个结构体填充到12因为最大对齐数是412是4的倍数 };4.2 宏定义与const的正确用法宏定义这块腾讯的卷子喜欢考带副作用的宏。最经典的就是#define SQUARE(x) x*x // SQUARE(23) 会被展开成 23*23 11而不是 25正确答案是这种宏展开是纯文本替换不会先计算23。这个例子每次我讲给新人的时候几乎都能看到瞳孔地震的表情。如果你想写一个安全的平方宏得写成#define SQUARE(x) ((x)*(x))每一层括号都不能省。如果你在笔试里遇到这种题建议先展开再计算不要心算。const修饰指针的三种情况也是选择题高发区const int *p指针指向的值不能改、int *const p指针本身不能改、const int *const p两者都不能改。我的记忆方法是从右往左读const修饰的是离它最近的那个成分。C里const和引用经常一起用比如函数参数写成const std::string既能避免拷贝又能防止误改这在写工程代码时是基本素养笔试考到也不意外。还要提醒的是宏定义在C里有个替代品叫inline函数inline既能享受类似宏的展开效率又保留了类型检查能避免宏的副作用。如果笔试问你宏和inline函数的区别别只说一个编译期替换、一个运行时调用重点要说清楚宏不检查类型、容易产生副作用inline则是在编译期展开且保留类型安全。4.3 构造函数、析构函数与虚函数C面向对象部分腾讯的笔试卷子里有一道经典中的经典为什么析构函数要声明为虚函数答案很简单如果通过基类指针删除一个派生类对象而析构函数不是虚的那么只会调用基类的析构函数派生类的资源就泄漏了。这个场景在工程里非常常见比如一个工厂函数返回基类指针实际指向的是派生类对象delete时如果析构函数非虚后果就是内存泄漏。拷贝构造函数也是常考点尤其喜欢考什么时候会调用拷贝构造。我总结下来就几类函数参数按值传递时、函数返回对象时、用一个对象初始化另一个对象时。笔试选择题经常问以下哪次调用会触发拷贝构造你得特别小心赋值和初始化的区别初始化调用拷贝构造赋值调用的是赋值运算符两码事。构造函数为什么不能是虚函数这个稍微难一点但2014年就有这种拓展题。原因是虚函数的调用需要依赖虚函数表指针而虚函数表指针是在构造函数里初始化的构造函数还没执行完时虚表指针不存在或不可靠所以构造函数不能是虚的。能答出虚表指针初始化顺序这个层次在笔试里已经超过大多数人了。5. 主观题与拓展题拉开差距的关键5.1 系统设计题的答题思路2014年腾讯笔试的末尾通常会有一两道开放式的简答题可能是设计一个短网址系统或者设计一个线程池。很多同学看到这种题就慌觉得自己没做过系统设计。但其实校招笔试的主观题考官看重的不是你的方案有多完整而是你有没有一套清晰的思考框架。我常用的框架是这样第一步明确需求说清楚这个系统要解决什么问题、核心功能是什么第二步画一个粗略的架构把请求的流转路径讲清楚第三步选核心数据结构比如短网址系统要用哈希表或者数据库表来存长网址到短网址的映射第四步说清楚并发和扩展性怎么处理。把这个框架写在答题区即使细节不完美分数也不会低。这里我要特别说一个很多人犯的错误在系统设计题里一上来就谈用Redis做缓存用消息队列削峰把一堆技术名词堆上去但连系统的基本流程都没说清楚。校招笔试的出题人看到这种答案第一反应是你可能看过面经但没有真正理解。所以我的建议是名词要克制逻辑要清晰把一个简单的流程讲顺远比堆砌技术栈重要。5.2 智力题的逻辑推导方法智力题在2014年的卷子里占比不大但几乎每一年都会出现一两道而且一旦出现就是整场笔试的心理战信号。常见题型包括一根不均匀的绳子烧完需要一小时怎么用两根绳子测出45分钟有12个球其中1个重量异常用天平最少称几次能找出它。很多人一看就懵但其实这类题是有方法论可循的。通用的解题思路是信息论和倒推法。以12球问题为例每次称重有三种结果左重、右重、平衡三次称重最多能区分3的3次方等于27种情况12个球每个可能偏重或偏轻一共24种情况理论上三次是够的。关键是第一次怎么分把球分成三堆每堆4个先称其中两堆利用结果不断缩小范围。这个思路比记住答案重要得多因为笔试现场的题可能是13个球、14个球变形。另一个更实用的建议是智力题不要卡太久5分钟内没思路就先跳过把时间留给后面的编程题。出题人不会因为你在智力题上空着就一票否决但如果你因为卡在智力题上导致后面的代码题没写完那才是真正的损失。6. 备考策略与实战经验6.1 时间分配与做题顺序我前面提到拿到笔试卷子第一件事是通读全卷这句话值得再说一遍。我把做题顺序总结成一稳、二抢、三攻坚先稳稳拿下有把握的选择填空这部分不要追求快但要追求一次做对然后抢时间做简答题和编程题里你熟悉的部分因为主观题分值高且需要大块时间写最后再回来啃那些看着眼熟但一时想不起的题以及智力题。时间分配上如果总分90分钟我建议选择题和填空题控制在30到35分钟内编程题和简答题留够40分钟最后10到15分钟用来检查补漏。检查的时候优先看编程题的