
聊到美团2017秋招笔试真题-后台开发很多准备校招的同学会先犹豫一下2017年的题放到现在还有参考价值吗我的回答是有而且价值比想象中高得多。题型会变考点会迭代但后台开发这个岗位的核心能力模型这几年其实没有本质变化。我自己当年刷这套真题时走了不少弯路后来参与了几届校招出题和面试再回头看这批题目才真正搞清楚每道题背后到底在考什么。这篇就把当年真题的结构、高频考点、编程题套路、系统设计题的应对方式以及我踩过的坑一并整理出来给正在准备后台开发校招的人一个可复用的参考。1. 真题整体布局题型、分值与出题思路1.1 笔试三个模块决定了你不能只当“算法刷子”美团后台开发的笔试整体时间是120到150分钟形式上分三个大块客观题选择题、编程题、主观题问答题或系统设计题。这个结构本身就是一种信号——它要求你同时具备知识广度、算法功底和工程思维任何单一维度的准备都不够。客观题一般30到45道左右覆盖计算机网络、操作系统、数据库、数据结构、语言基础考察方式非常细很多都是你好像见过但没记牢的选项。编程题通常是2到4道难度从Easy到Medium再到一道Hard梯度排列主要考察数据结构和算法的基本功力。主观题一般1到2道通常以业务场景为背景比如高并发下单、秒杀系统、缓存设计、订单状态机这类考察的是你有没有从需求到架构的完整思考能力。我见过不少同学只刷LeetCode客观题基本靠蒙系统设计题写两行字就交卷最后挂在笔试阶段。原因很简单后台开发不只看你会不会写代码还看你在真实业务约束下能不能做技术选型和架构取舍。所以备考时一定要按真实的试卷结构来分配精力不能偏科。1.2 考点分布数据结构和算法不是全部结合网上的真题回忆和面经复盘我把2017年这套笔试的考点分布估算了一下给出一张大概的权重表后面复习可以按这个比例分配时间考察方向大致占比常见考查形式数据结构与算法30%选择题 编程题计算机网络20%选择题为主操作系统15%选择题为主数据库15%选择题 主观题Java/C 语言基础10%选择题系统设计/场景题10%问答题这个分布其实有明确的行业背景。美团的核心业务是交易和本地生活服务后台系统天天面对高并发请求、热点数据、库存扣减、订单状态流转这类问题。所以笔试题里网络和操作系统占比高是为了筛选出真正理解一个请求从客户端发出到服务端处理完要经过哪些环节的人。数据库考得细是因为几乎所有业务最终都要落到存储层。系统设计题更是直接模拟了后台开发日常要做的技术决策。出题思路其实和面试官选人的逻辑完全一致我不需要你知道所有知识但你必须掌握与业务强相关的那部分核心知识并且能灵活运用。2. 基础考点深度解析那些容易丢分的选择题2.1 计算机网络不止考三次握手网络部分是选择题的绝对大户而且考得比教科书例题细致得多。我记得真题里出现频率最高的几个方向是TCP三次握手和四次挥手的状态变化、TCP与UDP的对比、HTTP状态码语义、HTTPS建立连接过程、TCP拥塞控制机制。先说TCP三次握手的两两状态几乎必考。比如服务端收到SYN后进入SYN_RCVD客户端发送SYN后进入SYN_SENT握手完成后进入ESTABLISHED。这些状态名背下来只是第一步更常考的是细节问题为什么需要三次握手而不是两次最核心的原因是为了防止旧的重复连接请求突然到达服务器导致服务器误以为这是一个新连接从而浪费资源。四次挥手里的TIME_WAIT状态也是高频考点为什么主动关闭方要等2MSL一是为了确保最后一个ACK能到达对方二是为了让本连接产生的所有报文在网络中消失避免影响后续连接。HTTP状态码这块我建议你把容易混淆的几个成组记忆301永久重定向、302临时重定向、307临时重定向保持请求方法不变401未认证、403禁止访问、404资源不存在500服务器内部错误、502网关错误、503服务不可用真题里常见考法是给你一个业务场景让你判断应该返回哪个状态码或者反过来给状态码让你选场景。如果你只记得404就是找不到碰到302和307的区别就会懵。还有一个容易遗漏的点是HTTP和HTTPS的握手流程对比。HTTPS在TCP握手之后还要做TLS握手涉及证书校验、密钥协商选择题可能会问HTTPS建立连接过程中以下哪一步发生在TCP三次握手之后答案就是TLS握手。这块需要把整体流程串起来记单独背知识点很容易漏。2.2 操作系统进程线程和虚拟内存是重点操作系统选择题的高频区域相对固定进程与线程的区别、进程状态切换、进程调度算法、死锁的四个必要条件、虚拟内存与页面置换算法、用户态与内核态的切换。进程状态图几乎是必考我当年就吃过亏只记得就绪、运行、阻塞三种状态结果考到当进程等待I/O完成时进程从运行态进入什么状态正确答案是阻塞态我却选了就绪态。这里有个关键区分就绪态是万事俱备只欠CPU阻塞态是CPU分配给你也执行不了。这两种状态容易混淆一定要结合场景多过几遍。调度算法里多级反馈队列调度算法是选择题常客它结合了先来先服务、时间片轮转和优先级调度的思想核心是短作业优先长作业也不会饿死。考察方式一般是给你几个进程的到达时间和执行时间让你算平均周转时间或者直接问某个算法的特点。这种题属于计算型准备时一定要动手推几遍光看答案是记不住的。死锁四个必要条件互斥、占有且等待、不可剥夺、循环等待属于送分题但考法会绕一下比如以下哪种策略破坏了不可剥夺条件答案是允许进程抢占其他进程持有的资源。预防死锁和避免死锁银行家算法的区别也容易考前者是做前置限制后者是动态检查安全性。虚拟内存部分页面置换算法FIFO、LRU、OPT的出镜率非常高尤其是LRU因为它考察的是你知不知道LRU在工程里是怎么实现的。选择题通常不会让你写代码但会问下列哪种数据结构适合实现LRU缓存答案是哈希表双向链表。这个如果只背页面置换算法的定义是不够的要理解它在JVM、Redis、CPU Cache里的实际应用。2.3 数据库索引、事务、SQL细节数据库在客观题里的占比不算最高但主观题里常常会带一问而且一旦考到就是拉分项。重点三个方向索引底层原理、事务隔离级别、SQL执行顺序。索引为什么用B树而不是B树或哈希表这个问题几乎年年出现。核心回答点有三个B树非叶子节点不存储数据单节点能存放更多索引项树更矮磁盘IO更少B树叶子节点通过双向链表连接范围查询和排序非常高效B树所有数据都在叶子节点查询效率稳定。注意选择题常考的是哪种存储引擎支持事务MyISAM和InnoDB的对比也要一起准备。事务隔离级别是另一个高频点MySQL默认隔离级别是可重复读这一点要记牢。四个隔离级别分别是读未提交、读已提交、可重复读、串行化分别解决脏读、不可重复读、幻读问题。考法经常是在可重复读隔离级别下事务A两次查询结果一致此时事务B插入了一行并提交事务A再次执行相同的范围查询可能发生什么如果只看概念容易答错。SQL执行顺序也值得单独讲一下因为它决定了为什么WHERE里不能用聚合函数、HAVING里才能用。一条标准SQL的执行顺序是FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT。这个顺序优先级很靠前因为后台开发每天都要写SQL如果连这个都搞不清楚后面性能优化就不用谈了。3. 编程题实战从暴力解到满分解3.1 字符串和双指针题是“送分题”还是“送命题”编程题的第一题通常不会太难但恰恰是这种题最容易因为边界条件丢分。以最长无重复子串为例这道题在美团笔试中出现的概率很高最优解是滑动窗口。思路不复杂用两个指针维护一个窗口窗口内部保证没有重复字符右指针不断右扩遇到重复字符时左指针收缩。public int lengthOfLongestSubstring(String s) { SetCharacter set new HashSet(); int left 0, right 0, max 0; while (right s.length()) { char c s.charAt(right); if (!set.contains(c)) { set.add(c); max Math.max(max, right - left 1); right; } else { set.remove(s.charAt(left)); left; } } return max; }这版写法有两个细节值得强调一是set.remove的位置它移除的是窗口左边界的字符但此时右边界的重复字符可能还有残留所以要用while循环而不是if来收缩二是有个更优的优化方案是用HashMap记录每个字符最后出现的位置把收缩过程从逐个移动变成直接跳到重复位置的下一个复杂度依然是O(n)但常数更小。笔试的时候我建议先把滑动窗口这种通用解法写清楚不要再纠结有没有更优解时间有限先保证Accepted再说。但如果题目明确要求时间复杂度O(n)那就要提前考虑用HashMap的方案。3.2 动态规划识别状态定义才是难点动态规划题属于典型的会者不难难者不会真题里常见的DP题包括爬楼梯、最大子序和、零钱兑换、最长上升子序列。这类题其实有固定套路先定义dp数组含义再找状态转移方程最后处理初始化和边界条件。拿最大子序和举例dp[i]表示以第i个元素结尾的连续子数组的最大和那么状态转移方程是dp[i] max(dp[i-1] nums[i], nums[i])。为什么是以第i个元素结尾而不是前i个元素中的最大子序和因为只有以当前元素结尾才能保证连续性才能和后面的元素拼接起来。这个定义是关键中的关键很多人卡在状态定义上后面全乱。优化的时候可以观察到dp[i]只依赖dp[i-1]所以可以把一维数组压缩成两个变量public int maxSubArray(int[] nums) { int maxSoFar nums[0]; int maxEndingHere nums[0]; for (int i 1; i nums.length; i) { maxEndingHere Math.max(nums[i], maxEndingHere nums[i]); maxSoFar Math.max(maxSoFar, maxEndingHere); } return maxSoFar; }这类题平时准备的时候我强烈建议你准备一个DP题单每道题都自己推导一遍状态转移方程不要直接看题解。考试时如果10分钟内推不出来果断先写暴力解不要在一道题上耗太久。3.3 链表题快慢指针几乎必考链表在笔试里的出现频率也相当高原因很简单后台开发里链表的应用场景非常多比如Java里的LinkedList、Netty的队列。而且链表题对指针操作要求高能有效区分只会写代码和理解内存结构的人。高频题有反转链表迭代和递归两种写法、判断链表是否有环快慢指针、找链表中间节点快慢指针的变体、删除倒数第N个节点双指针。这类题的核心技巧就是多画图不要用脑内执行来跟踪指针的变化画出来之后逻辑会清楚很多。public ListNode reverseList(ListNode head) { ListNode prev null; ListNode curr head; while (curr ! null) { ListNode nextTemp curr.next; curr.next prev; prev curr; curr nextTemp; } return prev; }反转链表这段代码里最容易出的bug是忘记保存nextTemp导致链表断掉。笔试卷面看不到运行结果所以这种细节一定要靠平时肌肉记忆。4. 系统设计/场景题后台开发的隐藏重头戏4.1 先看清题目在问什么主观题里最常见的是让你设计一个业务系统常见题目有设计一个秒杀系统、设计一个短链接服务、设计一个订单状态机、设计一个外卖配送调度方案。美团因为是业务驱动的公司这类题目非常贴近线上真实问题。我踩过最大的坑是一上来就画架构图结果画了一堆又不知道怎么落到数据存储和接口设计。后来我总结了一套答题顺序先明确需求边界哪些功能必须做哪些可以延后再画整体架构然后细化到数据模型和核心接口最后说性能优化和容错方案。这套顺序本质上是从业务到技术的推演过程。4.2 秒杀系统的架构要点秒杀系统大概是后台开发笔试里出现频率最高的系统设计题因为它的难点非常集中高并发、热点数据、超卖风险。答题时可以分四层展开第一层是前端和接入层思路是页面静态化把秒杀页面的商品信息提前生成静态HTML配合CDN加速避免所有请求都打到应用服务器。请求到达后端后第一道关卡是接口层限流常用令牌桶算法或滑动窗口算法防止瞬时流量把系统打垮。第二层是服务层核心是削峰。秒杀瞬间的写请求量非常大直接打到数据库必挂所以一般会在应用层和数据库之间加一层消息队列先把请求接住然后异步地去处理订单。这一步想表达的核心是你理解请求可以积压但系统不能挂。第三层是数据层也是踩坑最多的地方。扣减库存时必须防止超卖经典做法是乐观锁update product set stock stock - 1 where id #{id} and stock 0;这条SQL利用了数据库的原子性在更新时判断库存是否大于0如果受影响行数为0说明库存不足扣减失败。为什么要用乐观锁而不是select ... for update因为悲观锁在更新时持有行锁锁等待会严重拖垮吞吐量高并发场景下不可接受。第四层是缓存层热点商品的库存数量可以提前放到Redis里通过Lua脚本原子扣减异步同步回数据库。这里要注意缓存击穿——如果某个热key过期了一瞬间大量请求会穿透到数据库。常见方案是互斥锁重建缓存或者热点数据不设过期时间由后台任务异步更新。答题的时候不需要每层都写得很细但一定要让面试官看到你有从接入到存储的整体思维而且每个关键决策都能说出理由。4.3 短链接服务的完整思考链短链接也是后台开发笔试里的经典题目它看着简单实际考察点非常全面。核心功能有两个长链接转短链接、短链接跳回长链接。设计思路分三步第一步是算法选型。短链接生成通常用哈希算法或自增发号器哈希会考虑碰撞问题自增发号器需要依赖发号器服务两者各有取舍。笔试题答出用Base62编码将自增ID转成6到8位字符串这个方案基本就能拿大部分分。第二步是存储选型。短链接和长链接的映射关系适合放在Redis这类KV存储里因为读多写少且要求低延迟。同时要考虑过期策略避免垃圾链接堆积。第三步是高可用和扩展。跳转本身是302重定向要考虑重定向状态码的选择——301是永久重定向会缓存302是临时重定向每次都会请求短链接服务可以方便统计点击次数和做后续分析所以一般选302。这种题想拿高分重点在于你能把思考过程完整呈现出来而不是只堆名词。5. 备考路线和踩坑复盘5.1 三轮复习法基础、算法、真题看完真题分析很多人的反应是天哪要准备这么多东西。我的建议是别慌分三轮走。第一轮是基础扫盲花两周时间把计算机网络、操作系统、数据库的教科书重点章节过一遍。网络看TCP/IP协议栈和HTTP操作系统看进程管理和内存管理数据库看索引和事务。这一轮不追求记住所有细节目标是形成知识框架。第二轮是算法专项花三到四周按题型刷题数组、字符串、链表、树、动态规划、贪心每类至少刷20道经典题。这个阶段的重点是建立起看到题目能联想到对应解法的直觉。第三轮是真题模拟和系统设计专题花一周时间严格按照考试时间做整套卷子然后针对主观题做专项积累。系统设计没有标准答案你可以把几个经典题目秒杀、短链接、订单系统、消息推送的答题框架提前写好考试时往里面填具体需求。5.2 我当年踩过的坑第一个坑是只刷算法题不重视客观题。自信满满上考场结果发现35道选择题占了将近一半分值做完编程题才发现客观题还没答完。建议平时每周都要给自己做两次40题左右的选择题限时训练找题感。第二个坑是编程题不练输入输出。有些学校的上机课用核心代码模式笔试却要求自己处理输入输出比如多组测试用例、用逗号分隔数组、字符串里包含空格等。第一次碰到这种格式时会因为解析输入浪费大量时间。提前把各种输入输出场景用代码练一遍真的能救你一命。第三个坑是系统设计题没有提前积累。我当年面对秒杀题时脑子里没有限流、削峰、防超卖这几根柱子答得毫无章法。后来才知道这类题的答题框架是可以提前准备好的。哪怕是临时抱佛脚至少在考前把这几个柱子的基本逻辑过一遍考场上也不会慌。5.3 临考时的时间分配技巧最后说一下实战时间管理。拿到试卷后前10分钟不要动笔先通读一遍所有题目明确哪些题是好拿分的哪些题是要放弃的。客观题平均每题控制在1分钟以内超过90秒直接标记跳过最后有时间再回来看。编程题先做最有把握的那道拿到基础分再回头啃难题。主观题至少预留20分钟即使写不出完整方案也要把思路框架和关键组件写出来让阅卷人看到你的思考过程。我个人做了几年后台开发之后回头看2017年这套真题最大的感受是校招笔试筛选的其实不是背了多少知识点而是你面对一个具体问题时能不能拆清楚、说明白、写出来。题库会更新框架会迭代但这种能力不会过时。如果你正在准备后台开发的校招希望这篇复盘能帮你少走点弯路在考场上比当年的我多拿几分。