从腾讯后台开发练习卷看笔试高频考点与备考策略

📅 发布时间:2026/8/30 21:21:05
从腾讯后台开发练习卷看笔试高频考点与备考策略 看到“腾讯2015春招后台开发练习卷”这个标题我第一反应是有些怀念。那会儿校招笔试大多还是纸质试卷加限时答题风格和现在在线OJ完全不一样C、操作系统、网络、数据库四座大山压下来能两个小时内从容做完的人真不多。但回过头看这套练习卷其实是一份很完整的后台开发知识地图——它考的不是你会不会背题而是你有没有具备一个后台开发工程师的基本素养。这篇文章我想拿这套练习卷当引子把后台开发笔试背后的考察逻辑、高频考点、答题策略和复习方法一条条拆开讲清楚。适合正在准备校招和社招的候选人也适合刚进入后台开发方向、想系统梳理基础知识的同学。不管你是哪一类看完应该都能找到一条自己可以照着做的复习路径。1. 这套练习卷到底在考什么1.1 五年过去后台开发的考察基本盘没有变单看年份2015年距离现在已经不近了技术栈变化非常大。云原生、容器化这些概念当时还不像今天这么普及很多团队还在用虚拟机部署服务微服务也没有成为默认选项。但有意思的是后台开发的底层考察点几乎没怎么变操作系统怎么管理进程和内存、网络协议栈怎么传输数据、数据结构怎么设计才能更快、数据库怎么建索引才不拖慢接口这些知识依然是今天面试的高频区。我最近几年面试候选人还是会反复问进程和线程的区别、TCP为什么需要TIME_WAIT、哈希冲突怎么解决这些问题和2015年练习卷上的题目没有本质区别。所以拿到旧练习卷不要觉得题老就不重视。恰恰相反经典题才是后台开发面试的压舱石题目越老越说明它是被验证过的核心考点值得多花时间吃透。1.2 反推能力模型笔试背后的岗位画像一份练习卷最有价值的不是给你答案而是帮你反推公司对后台开发岗的期望画像。我翻过不少校招后台开发卷题型结构通常比较固定选择题或填空题覆盖语言基础、操作系统、网络、数据库等多个知识域简答题或问答题考察对某个机制的原理解释比如死锁产生条件、HTTP和HTTPS的区别编程题重点考察算法和数据结构的落地能力要求手写可运行的代码开放式设计题比如设计一个短链接服务、一个排行榜或一个秒杀系统。这种分布本身就在传递一个信息后台开发不是单纯的“API调用工程师”而是需要理解计算机系统运作原理、能在复杂工程场景中做方案设计的技术角色。笔试不是在考你背了多少知识点而是在考你能否证明自己理解了这个系统。能力维度代表考点考察目的语言功底虚函数、内存布局、智能指针是否写过真正偏底层的代码系统原理进程线程、并发控制、虚拟内存是否理解程序运行的环境网络基础TCP状态、HTTP流程是否了解服务调用的底层链路数据结构链表、树、哈希表、堆是否具备基本算法能力工程素养数据库索引、Linux排查是否具备实际开发和排错能力把这五列当成能力地图你会发现平时复习很容易覆盖前面的语言和算法但工程素养这块经常被忽略。而练习卷里恰恰是那些看似零散的工程题最能拉开差距。2. 高频考点逐个拆解2.1 C与内存虚函数、智能指针一个都不能少2015年C11已经普及了后台开发用C的团队非常多所以练习卷里C相关题目占比通常不低。虚函数是出现频率极高的考点我见过很多种问法虚函数表是什么构造函数能不能是虚函数为什么析构函数建议声明为虚函数这些问题表面在考语法实际在考你有没有理解C对象模型。简单展开讲一下。一个类只要包含虚函数编译器就会给这个类生成一张虚函数表vtable每个对象的内存头部会有一个指针vptr指向这张表。调用虚函数时不会像普通函数那样直接跳转到固定地址而是先通过vptr找到虚函数表再从表中取出真正的函数地址。如果析构函数不是虚的当用基类指针delete派生类对象时编译器只会调用基类的析构派生类中申请的资源就可能泄漏。这就是“析构函数建议声明为虚函数”这个结论的底层逻辑。还常考智能指针。shared_ptr底层的核心机制是引用计数引用计数归零时自动释放内存但循环引用会出现严重问题两个对象互相持有shared_ptr各自引用计数都无法降到零内存就泄漏了。于是就有了weak_ptr来打破循环。练习卷如果考到内存管理通常会给一段代码让你分析是否有泄漏或者让你对比unique_ptr、shared_ptr、weak_ptr的适用场景。我建议复习的时候把对象的生命周期图画出来真正理解“所有权”这个概念比死背接口文档有用得多。2.2 操作系统进程线程、死锁和虚拟内存操作系统是后台开发笔试的另一个大头也是最容易出大题的模块。进程和线程的区别是必问的回答时不要只背“进程有独立地址空间线程共享地址空间”最好能进一步解释清楚为什么线程切换比进程切换轻量因为同一进程内的线程切换不需要切换地址空间和页表所以开销更小。如果再想加分可以提一下协程用户态调度连内核态都不需要进切换成本比线程更低。进程间通信也是个常考点。管道、消息队列、共享内存、信号量、socket这些机制各自的适用场景和性能差异要能分清。共享内存最快因为它不需要内核做数据拷贝但需要自己处理同步消息队列和管道则经过内核缓冲区适合小数据量传递编码简单但性能相对低。面试官听到你能结合场景选方案会比背定义印象深很多。死锁几乎是每一套练习卷都会有的题。四个必要条件互斥、持有并等待、不可剥夺、循环等待。应对策略就是破坏其中一个条件。答辩的时候最好带一个实际例子比如两个线程各自持有一把锁同时试图获取对方的锁这时候就形成了循环等待。这种代码你们平时写并发程序时可能碰到过能讲出来说明你是真写过不是只背了概念。虚拟内存和分页也很重要。为什么要引入虚拟内存因为它让每个进程拥有独立的地址空间内存之间互相隔离同时允许程序使用比物理内存更大的地址空间。这里可以打一个比方物理内存像一间合租房同时住着好几个进程虚拟内存相当于每个人脑子里都觉得自己住的是独栋别墅谁也看不见谁系统在这些“错觉”背后做地址翻译。理解了这一层再把缺页中断、页表、多级页表串起来答这类题会比较完整层次感也出来了。2.3 网络三次握手、TIME_WAIT和HTTP一个都跑不掉后台开发必须有扎实的网络基础这套练习卷里网络题如果丢分基本就与大厂Offer无缘了。TCP三次握手为什么不是两次最核心的原因是防止旧的连接请求突然到达导致服务器错误地建立连接。想象一个场景客户端第一个SYN在网络中滞留了客户端因为没有收到确认而超时重发发出了第二个SYN如果只有两次握手服务器收到滞留的旧SYN后就会建立连接而客户端已经不想连了资源白白浪费。三次握手可以让客户端确认自己发出的SYN是否有效避免这种历史连接错误建立。TCP的TIME_WAIT状态也常被拿出来问特别是“为什么在服务器上看到大量TIME_WAIT”。TIME_WAIT有两个作用一是让被延迟的报文段在网络中自然消失避免影响后续新连接二是等待足够时间确保对端收到最后一个ACK。服务器上TIME_WAIT多通常意味着主动关闭连接的一方是你的服务这时候可以通过开启keep-alive减少频繁建连、调优TIME_WAIT复用参数等方式优化。既有理论又有工程实践这种题目在练习卷里出现率极高。HTTP部分当年主流还是HTTP/1.1至少要清楚keep-alive的作用、GET和POST的区别、常见状态码含义200、301、302、403、404、500、502。现在面试如果再能补上HTTP/2的多路复用、HTTP/3基于QUIC会在考官眼里非常加分但核心还是把TCP和HTTP的关系说清楚。我碰到过很多候选人能背状态码但一问“浏览器输入URL后发生了什么”就卡住了。这道综合题其实可以串起DNS解析、TCP连接、HTTP请求、服务端处理、响应返回全链路后台开发练这套题非常有价值。2.4 数据结构和算法模板不背套路要懂练习卷里的编程题通常不会特别难重点在基本功和边界处理。链表反转、快排、二分查找、二叉树遍历是最高频的几道题我建议这些题目都要能手写而且不能有语法错误。面试官特别爱考链表为空、只有一个节点、节点个数为奇数这些边界条件很多人在这些地方翻车。排序算法要会自己分析复杂度。快排平均时间复杂度是O(nlogn)最坏是O(n^2)为什么最坏情况发生在基准选得不好时因为每次分区都极度不均衡递归深度接近n。理解了这一点你就能解释为什么工程中常用随机选基准或者三数取中法。Top K问题也是后台开发笔试常客比如求海量数据里最大的K个数。常规解法是维护一个大小为K的小顶堆堆里存当前最大的K个数新数据如果比堆顶大就替换堆顶并调整堆复杂度是O(nlogK)。这道题背后其实在考察堆这个数据结构也涉及海量数据的处理思路。答完之后最好补一句如果数据太大不能一次性加载进内存可以对数据分片每片内先求局部Top K最后再合并。这一下就从“会做题”升级为“会做工程”。3. 数据库与Linux笔试里最容易被低估的两块3.1 数据库索引、事务、SQL优化都要答出“为什么”练习卷如果包含数据库题最经典的话题永远是索引原理。为什么MySQL InnoDB用B树而不是哈希表或者二叉树这个问题要答得有层次哈希表适合等值查询但不适合范围查询无法支持order by、like前缀匹配这些场景二叉树的问题是数据量大时树高度太高每次树节点访问都是一次磁盘IO高度越高IO次数越多B树所有数据都存储在叶子节点叶子节点用链表串联天然支持范围扫描同时每个节点可以存大量键值树高度通常只有三四层磁盘IO次数被压到很低。这样回答考官听到的就不只是一个结论而是一条完整的推理链。事务ACID也是高频题。四个特性分别靠什么实现要清楚原子性靠undo log回滚持久性靠redo log落盘隔离性靠锁和MVCC一致性是所有这些机制共同保证的最终结果。隔离级别从读未提交到串行化分别解决脏读、不可重复读、幻读的问题。这里最容易被追问“MVCC怎么实现”核心就三件事版本链、ReadView、隐藏字段。能把这个讲清楚说明你对InnoDB内部机制有真实理解。我记得当年练习卷里还有一道SQL优化题给出一条慢SQL问你如何排查。标准思路是先用EXPLAIN看执行计划检查有没有走索引、有没有回表、有没有filesort再回头审视SQL本身是不是select *取了很多不需要的字段是不是在索引列上做了函数运算导致索引失效是不是多表join顺序不好。比如有一条订单查询select * from orders where user_id 123 and status 1 order by create_time desc limit 10;这条查询可以建一个联合索引(user_id, status, create_time)这样where等值条件可以走索引定位order by字段也可以直接借助索引的有序性避免额外排序。像这种具体例子比空谈“要建索引”有用得多练习卷里如果出现这类题拿分的关键就是把步骤写完整。3.2 Linux排查思路从笔试延伸到真实故障处理练习卷里Linux命令题不算多可一旦出现就容易丢分因为它不靠纯记忆而靠日常积累。比如问你如何查看一个进程打开了哪些文件答案是lsof -p pid。如何看端口被哪个进程占用netstat -tlnp或者ss -tlnp。如何实时看日志输出tail -f。这些都是后台开发几乎每天要用的命令笔试考它们实际上是在看你是不是真的在Linux环境下干过活。还有一类题目更综合比如“线上CPU突然飙高你怎么排查”这种问题的标准流程是先用top找到CPU占用最高的进程再用top -Hp pid找到进程内部CPU最高的线程然后把线程栈打印出来结合日志定位到具体代码。这个排查链路听起来简单但没有实操过的人很难凭想象写完整。我建议准备后台开发的同学真的找一台测试机器部署一个会死循环的服务自己亲手压一压、抓一抓线程栈走一遍完整流程。体验过之后你写出来的答案会完全不一样那种细节感是背多少遍文档都补不出来的。另外一个容易被忽略的命令题是僵尸进程。什么是僵尸进程子进程结束但父进程没有调用wait回收它的退出状态进程就变成僵尸。简单的处理方式是让父进程退出init进程会收养这些子进程并回收也可以让父进程注册SIGCHLD信号处理在子进程结束时自动wait。这道题如果出现在练习卷简答题里能把僵尸进程产生的原因、排查命令ps查看状态列的Z和处理方式写出来得分基本就稳了。4. 编程题与设计题的答题策略4.1 手写代码先谈思路再动手过程分同样重要很多同学做笔试编程题时有个误区看到题目就急着开写结果写到一半发现边界没处理或者方法选得不对时间全浪费了。我更推荐的节奏是先花一两分钟把思路想清楚在草稿纸上写一下数据流向和复杂度分析然后再动手写代码。阅卷流程虽然以最终代码为准但很多时候你写出来的注释、函数命名、边界处理都会影响整体观感过程分并不只是说说而已。以“反转链表”为例这道题几乎每年都会出现。我的写法是这样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原因很简单把cur-next指向prev之后原来的链表就断了如果不提前保存next下一步就没法继续遍历。能把这一点讲清楚说明你是真的理解指针操作而不是死记硬背。再往深一点递归版怎么写递归版需要注意每次递归返回的都是新的头节点一层层回溯时要把指针反向指回去。两种写法各有优劣建议都练熟。我估计很多人会问笔试时间那么紧哪来时间打草稿我的答案是越紧越要打草稿。编程题最怕的不是慢而是方向错了还在埋头写。花两分钟确定思路至少能保证你写出来的代码基本方向正确这比写了一大半推翻重来划算得多。4.2 设计题秒杀系统、短URL这类题怎么一步步拆后台开发笔试的压轴位置偶尔会出现一道开放性设计题更多时候会出现在面试环节。遇到这种题最怕的是没有框架想到哪说到哪。以短URL服务为例核心需求是把长链接转成短链接用户访问短链接时跳回原地址。我习惯按下面五个维度去拆需求分析要支持短码生成、访问跳转、过期时间、访问统计。容量预估假设每天新增100万条记录一年是多少条QPS大概多高需要多大存储这些数字能帮你判断用单机还是集群。方案选型短码生成是发号器还是对长链接做哈希截断存储用Redis还是MySQL要不要分表关键点设计发号器要保证全局唯一可以用数据库自增也可以用雪花算法跳转用301还是302301利于缓存302利于统计通常我会选302然后用额外机制做缓存。扩展考虑某个短链突然被大量访问怎么办加一层Redis缓存挡在前面可以保护DB。这套框架套到秒杀系统也一样成立瞬时流量怎么削峰请求先打到网关做限流和防刷再进入消息队列异步削峰最后才落到数据库更新库存。库存扣减要防止超卖经典做法是数据库乐观锁update stock set count count - 1 where id ? and count 1影响行数为1才表示扣减成功。设计题的价值不在于你真的设计出一个能上线的生产系统而在于你能不能逻辑清晰地一步步推导。建议平时多看一些架构设计文章自己画数据流向图用上面的框架多练几个题。练多了笔试时看到设计题心里就有底不会抓不住重点。5. 用一份练习卷完成自测与复盘5.1 模拟笔试的完整流程拿到一套练习卷后最不推荐的做法是直接翻答案。一套卷子最好的用法是模拟一场真实笔试给自己定一个两小时的倒计时关掉IDE和编译器手机放远一点用纸笔做题。编程题也尽量用手写或记事本写不要依赖自动补全这样能暴露你在边界条件和语法细节上的真实水平。做完之后不要立刻对答案先把每道题标注清楚哪些是确定的哪些是蒙的哪些完全没思路。标注这个动作很关键因为你平时看答案觉得“都会”的题目闭卷一写才发现很多细节根本不记得。把自己放在考试的状态里才能把“记忆层面的熟悉感”和“理解层面的掌握感”区分开。顺便说一下时间分配。我一般建议选择题和填空题控制在30分钟左右简答题40分钟编程题40分钟剩余时间留给设计题和检查。当然这个分配要因人而异但有一个原则是要遵守的千万不要在一道题上死磕太久卡住超过十分钟就果断跳过。笔试拼的是总分不是单题的完美。5.2 错题复盘把做错的题变成知识网络对完答案之后整理错题是整套练习卷收益最大的一步。我习惯按知识域做统计操作系统错了几道网络错了几道数据库错了几道。如果发现某一类错误率特别高那这就是你当前最需要补的短板。比如你发现只要涉及TCP状态转换的题都错那说明你对TIME_WAIT、CLOSE_WAIT这些状态的理解停留在一知半解需要重新把状态转换图自己画一遍。复盘的时候可以用一张简单的表记录题号知识域错误原因关联知识点同类题计划第8题TCP分不清TIME_WAIT与CLOSE_WAIT四次挥手、主动关闭方做3道状态类题然后每周回头看看这张表把错题遮住答案重新做一遍。如果第二次能在几分钟内做对说明这个知识点吸收得差不多了如果还是卡那就要回到基础概念重新学。复盘不是把答案抄一遍就完了而是要把每一道错题都变成一个知识网络的入口顺着它把相关的知识点全部拉出来过一遍。5.3 横向扩展由一道题引出一类题练习卷是死的但知识点是活的。做完一道题之后我会习惯性地想这道题还有哪些变体比如练习卷考了二分查找那我可以接着做寻找旋转数组最小值、查找峰值元素、在有序矩阵中搜索这些变体考了进程和线程的区别那就顺势复习协程、线程池参数、并发队列甚至自己去写一个有界阻塞队列的demo。这种“以题带面”的复习方式效率很高因为每一道母题都是一条知识链的起点。你不需要刷无穷无尽的题只要把核心母题理解透再通过变体题扩展思路就能应对大多数笔试变化。我自己复习后台开发时有个很土但很管用的方法把做明白的题讲给室友听能讲清楚说明真懂了讲不清的地方就是下一步要补的短板。练习卷毕竟是2015年的内容部分考点放到今天已经有了新变化当年很少涉及的云原生、容器、分布式链路追踪现在已经是后台开发的常见话题。所以用这套卷子做知识体检的同时也要再结合当下的技术热点做补充。把旧卷当成一张体检单再照着体检结果制定新的学习计划这比单纯刷一套旧题有意义得多。后台开发这条路没有捷径但有了清晰的知识地图和正确的复盘方法你走起来会比大多数人少踩很多坑。