小红书技术校招笔试复盘:第二批题型分布与备考策略
2019年秋招季我参加了小红书技术类校园招聘的第二批在线笔试。先说结论第二批不是“没赶上第一批的捡漏”而是一个完全独立、名额充足的正式批次阅卷标准、面试流程和第一批没有任何区别。当时我坐在宿舍里对着赛码网的全屏考试界面两个小时把选择题和编程题过了一遍出考场后立刻把题目和思路记在了备忘录里。这篇复盘就是当时整理的完整版包含题型分布、时间分配、编程题解法框架、在线笔试平台操作避坑以及笔试后怎么把考过的知识点转化成下一轮面试的弹药。适合正在准备技术类校招笔试的同学参考不管你是投后端、算法还是客户端这套准备思路都通用。1. “第二批”意味着什么被低估的投递窗口1.1 校招批次的真实组织逻辑很多同学看到“第二批”三个字第一反应是“第一批没招满吧”“是不是补录”于是投递意愿不高准备也不上心。实际参加过之后我可以说这种理解是错的。互联网公司的校招批次一般这样安排提前批内推批→ 正式批 → 补录批。提前批主要面向内推候选人流程快、免笔试或者笔试简单但岗位HC相对少竞争反而激烈。正式批就是常规的秋招批次动辄分两批三批进行在线笔试目的是把大量候选人分散到不同时间点避免服务器压力过大也方便面试官分批消化简历。你被分到第二批不代表你弱只是投递时间或简历筛选节奏把你排到了这个批次。第二批笔试通常和第一批共用题库或近似题库但题目顺序、具体数据用例会不同。所以如果你是准备参加下一场笔试的同学第一批同学在论坛里放出来的题型回忆含金量非常高至少能帮你圈定考察范围。1.2 技术类岗位考察的是同一套底层能力小红书2019年这批技术类在线笔试覆盖的岗位包括后端开发、前端开发、客户端开发、算法工程师、大数据工程师等。从笔试内容看不同岗位用的是同一套或者高度相似的试卷差异只体现在少数专业题上。这意味着你不需要因为投的是算法岗就疯狂刷机器学习也不要因为投的是前端岗就觉得数据结构不重要。这套试卷的核心就是计算机基础四大件加编程能力数据结构与算法选择题 编程题的重头戏操作系统 计算机网络选择题常规考点数据库与SQL选择题常规考点编程语言与编码能力编程题直接考察换句话说不管你想做哪条技术线笔试阶段拼的就是基本功。招聘方的逻辑很简单你能不能在限定时间内用代码解决一个中等偏上的算法题同时具备基本的计算机系统常识。业务深度是面试阶段才考察的事。1.3 从业务反推考点偏好UGC平台的技术特征如果你对小红书2019年这个时间点的产品形态有了解会知道它是一个典型的UGC内容社区用户发布图文笔记、浏览发现页、搜索感兴趣的内容。这种产品的技术挑战集中在三个方面内容理解、分发匹配、社区治理。对应到笔试里常见的命题思路就是给一堆文本/标签数据要求做统计、去重、排序——背后是字符串处理、哈希表、堆排序给用户行为序列要求预测或计算某种指标——背后是数组操作、动态规划给一组带权重的对象要求做资源分配或排期——背后是贪心算法我不是说笔试会直接考“小红书推荐系统”但题型偏好会明显偏向数据处理和文本处理类场景这和其他电商公司偏订单调度、游戏公司偏战斗数值模拟是不同风格的。备考时多练这类题命中率会高一些。2. 题型分布与时间预算先看清战场再动手2.1 笔试的题型结构在线笔试总时长一般是90到120分钟具体时长会根据题目数量浮动。2019年第二批技术类笔试的常见分布如下题型题量建议用时主要考察点单选题10-15道15-20分钟数据结构、操作系统、网络、语言基础多选题5道左右10-15分钟概念辨析、边界条件、易错知识点编程题2-3道50-70分钟算法设计、编码能力、调试能力这里尤其要提醒多选题。多选题是选择题里扣分最狠的少选、多选、错选都不得分。它考的往往不是“你会不会”而是“你知不知道这个概念的坑在哪里”。备考时每遇到一个多选知识点比如死锁的四个必要条件、TCP和UDP的区别、进程和线程的差异都要把“所有选项而不是正确选项”过一遍。2.2 选择题四大知识域与高频考点根据当时一起笔试的同学复盘选择题的高频考点分布基本是稳定的这里列一份可以直接当复习清单的表格知识域高频考点容易踩坑的点数据结构与算法二叉树遍历、排序算法稳定性、时间/空间复杂度计算快速排序最坏复杂度、堆排序稳定性、图的存储方式操作系统进程与线程、死锁条件、虚拟内存、页面置换死锁四个条件必须同时满足、线程共享什么不共享什么计算机网络TCP三次握手、HTTP状态码、DNS解析过程、Cookie与Session第三次握手能不能携带数据、302和304的区别数据库与LinuxSQL基础查询、索引原理、常用Linux命令索引失效场景、IN和EXISTS的区别、grep/awk/sed场景选择我当时在选择题上栽了一个跟头就是“TCP第三次握手是否可以携带数据”。正确答案是可以第三次握手时客户端已经确认了服务端的接收能力可以发送数据了。这种知识点只看书不上手抓包很难有印象。备考阶段建议搭配抓包工具或者网上现成的TCP状态图把三次握手、四次挥手完整走一遍而不是死记结论。2.3 时间预算策略留出编程题的完整大块时间在线笔试最容易犯的战术错误就是前边的选择题耗时过长导致编程题只剩十几分钟连题都读不完。选择题一道一分编程题一道二十分到三十分性价比完全不同。我自己执行的时间分配方案是拿到试卷先看一遍全部题目心里有数。编程题如果有一道看起来有思路先做它。选择题按“每道不超过1分钟”的节奏推进超过1分钟还拿不准的标记后跳过。不要在一道二分题上耗十分钟。所有选择题做完后花3-5分钟回头处理标记的难题此时如果编程题还没动果断放弃难题直接进入编程题。编程题先做有完整思路的再做半会的最后留5-10分钟检查输出格式和边界条件。这套策略的核心思路是分数最大化不是题目全做完。笔试是筛选机制不是满分比赛你要做的是保证所有会做的题都拿到分。3. 编程题思路复盘三类高频题型与一套通用解法编程题是整场笔试的胜负手也是笔试之后最值得复盘的部分。我根据自己的做题经历和同期同学讨论的结果整理了这类校招在线笔试里出现频率最高的三类算法题。注意我不保证题目内容完全一致但题型框架和解题思路非常典型可以作为备考练手的参考方向。3.1 字符串处理与哈希表数据处理类题目绕不开的组合这类题目的常见场景是给你一堆文本数据、标签或者用户ID要求统计、分组、筛选、去重然后按某种规则输出。听起来简单但实际做题时处处是坑。一道很有代表性的题长这样给定一个英文文本统计每个单词出现的次数按出现次数从高到低排序如果次数相同按字典序升序输出。思路非常直接先用正则表达式或者遍历法把文本切分成单词列表用哈希表Python里的dict统计每个单词的出现次数对字典项排序排序关键字是(-次数, 单词本身)这样次数降序、字典序升序一步到位Python参考实现import re from collections import defaultdict def word_count(text): words re.findall(r[a-zA-Z], text.lower()) counter defaultdict(int) for w in words: counter[w] 1 # 按出现次数降序字典序升序 sorted_items sorted(counter.items(), keylambda x: (-x[1], x[0])) return sorted_items这种题目的真正考点其实不在哈希表本身而在三个细节大小写处理。英文文本要统一转小写否则Hello和hello会被当成两个单词。单词边界。如果手动切分很容易把标点符号带进去——用正则是最稳的方案。排序稳定性与多关键字排序。Python里sorted是稳定排序但更稳妥的做法还是直接用元组作为排序键一次性定义好几个关键字的优先级。我在笔试时犯过的错是忘记了-x[1]这种技巧导致又写了一个复杂比较函数。多关键字排序用元组键是这类题的核心技巧一定记牢。3.2 动态规划识别状态转移比硬背模板更重要动态规划几乎是所有校招笔试编程题的常客。这类题目的特征是求最大值、最小值、方案数、可行性判断并且问题可以被拆分成重叠子问题。一道典型的DP题是这样的给定一个数组求最长连续上升子序列的长度。例如[1, 3, 5, 4, 7]的最长连续上升子序列是[1, 3, 5]长度为3。先别急着写代码先把状态定义想清楚定义dp[i]表示以第i个元素结尾的最长连续上升子序列长度初始状态每个元素单独组成序列长度都是1转移方程如果nums[i] nums[i-1]则dp[i] dp[i-1] 1否则dp[i] 1最终答案是所有dp[i]的最大值Python参考实现def longest_continuous_increasing(nums): if not nums: return 0 n len(nums) dp [1] * n for i in range(1, n): if nums[i] nums[i-1]: dp[i] dp[i-1] 1 return max(dp)这个例子虽然简单但它展示了DP题目的通用思考流程先定义状态再写转移方程再处理边界最后实现。很多同学一看到DP题就条件反射去想“这是背包这是股票买卖”而不是先分析问题的状态结构结果套模板套错白白丢分。值得提醒的是这题还有个优化的观察点因为只要求全局最大值不需要保留整个dp数组用一个变量滚动更新就够了。这类“空间优化”在笔试里是加分项但如果时间紧先用数组版本AC优化不是必须的。3.3 区间与排序组合贪心策略的思考顺序第三类高频题型是区间调度、任务排期类的贪心题目。小红书这类强调内容分发的平台笔试中很容易出现类似这样的题给定一组任务的开始时间和结束时间一个人最多能参加多少个时间不冲突的任务这类题目的标准解法是按结束时间排序然后依次选择最早结束且与已选任务不冲突的任务。关键思路是结束时间越早给后续任务留下的空间越大。Python参考实现tasks.sort(keylambda x: x[1]) # 按结束时间升序排序 count 0 cur_end -1 for start, end in tasks: if start cur_end: count 1 cur_end end print(count)贪心题最容易出问题的地方在于证明贪心策略是对的或者识别什么样的题目可以贪心。面试官在代码评审阶段很可能追问“为什么按结束时间排序是正确答案”。一般可以这样阐述假设最优解第一个选择的任务不是最早结束的我们可以用最早结束的任务替换它且不会影响后续任务的选择区间所以贪心策略至少不比最优解差。笔试时你不需要在代码里写证明但平时练习时每道贪心题都要追问一遍“为什么贪心是对的”。因为如果你没有这个追问过程遇到变式就会懵。3.4 编程题的通用调试顺序不管是哪类题目在提交之前用下面这套顺序过一遍自己的代码能避免至少一半的提交错误空输入如果输入为空你的代码会不会崩溃单元素输入只有一个元素时边界条件是否正确最大值/最小值涉及整数运算时会不会溢出重复元素排序、去重相关的逻辑是否稳定题目给的样例先跑通样例再测自制用例。我在那次笔试里就遇到过一个很尴尬的情况题目样例过了但自己加了一个“单个元素”的用例就暴露了数组越界。这个习惯养成之后笔试通过率会明显提升。4. 在线笔试的隐形扣分点平台操作与输入输出4.1 在线笔试平台是ACM模式不是LeetCode模式2019年小红书这批在线笔试用的是第三方笔试平台常见的有赛码网、牛客网等。这类平台有一个和LeetCode最大的区别所有代码都要自己处理输入输出。LeetCode默认给你一个函数参数已经填好你只需要返回结果。在线笔试平台不是这样的它要求你从标准输入里读取数据然后再用print输出结果。很多平时只刷LeetCode的同学第一次接触这种模式光读取输入就花掉了二十分钟。以Python为例你需要掌握的最基础输入模板import sys # 读一行整数存成整数数组 line sys.stdin.readline().strip() if not line: nums [] else: nums list(map(int, line.split())) # 读多行每行两个整数直到文件末尾 for line in sys.stdin: a, b map(int, line.strip().split()) # 处理这一组数据如果你投的是Java岗对应的就是Scanner的nextInt()和nextLine()用法C则是cin和getline配合使用。强烈建议在笔试前一周把常用的输入读取模板背到滚瓜烂熟不要在考场上现查记忆。4.2 输入输出的三个高频错误根据我自己踩过的坑和同学的血泪教训高频错误基本集中在三类现象原因解决方式本地运行正常提交后0分输出多了提示信息比如print(请输入)标准输出只能有题目要求的内容调试用的打印全部删掉多组输入只处理了第一组平台要求处理到EOF但只写了单次逻辑用while True: try: ... except EOFError: break或for line in sys.stdin字符串数组读取错误输入含空格分隔的字符串不知道怎么按行读取读取一行后用.split()切分注意字符串不需要map(int, ...)我见过最可惜的一个案例是同学把所有题都做对了但每道题都多打印了一句“答案是”最后平台判定格式错误一题都没过。输出格式和答案内容一样重要丢了分真的是全冤。4.3 本地通过但线上0分的排查清单如果本地IDE测试完全正常但提交到平台就是0分按下面的顺序排查检查是否忘记移除调试输出。这是最常见的原因。检查函数入口是否正确。有些平台要求完整的main函数如果代码写成了脚本方式直接执行可能在平台环境里没有入口。检查是否使用了平台禁止的库或方法。极端情况下平台Python版本较老不兼容新语法比如f-string在旧版本3.5下不能用尽量用兼容性好的写法。检查是否有死循环。比如while条件写成了恒真且循环体内没有break会直接超时。检查递归深度。如果题目数据范围比较大递归写法可能爆栈改成迭代写法。我在笔试题里遇到过一次“本地正常提交过不了”最后发现是Python版本不支持math.inf这种写法的老问题。从那之后我的笔试代码一律只用最基础的语法和标准库不追求炫技。4.4 在线笔试环境的实操建议在线笔试还有一个特点不是你在牛客网刷题那样随意。正规校招笔试会有严格的防作弊监控比如需要摄像头、屏幕录制甚至手机副摄像头监控。建议提前半小时做好以下准备找一个安静、光线稳定的房间测试摄像头和麦克风平台一般有模拟测试链接关掉所有弹窗软件避免答题时被系统误判切屏准备好身份证/学生证有些平台考前需要拍照验证把本地IDE调试环境打开并测试一遍有一点容易忽略答题期间不要切屏。有些平台对切屏次数有记录超过一定次数会直接交卷。我当时写代码的时候习惯去浏览器查点东西但考试期间一次都没切过——宁可留到考完再查也别冒着被判作弊的风险。5. 笔试之后如何把一场机试变成面试弹药5.1 考后复盘比分数更重要的是错题很多人笔试结束就松了一口气把题目抛在脑后等面试通知。这个习惯很亏。笔试里暴露出来的知识盲区大概率就是面试官接下来要问你的地方。我在笔试结束后做的第一件事就是用20分钟在备忘录里记下哪道选择题完全不会涉及哪个知识点哪些选择题是蒙对的需要回去补基础编程题每道用了多少时间哪一步卡住了有没有题目读错了或者输出格式错了这份复盘记录成了我后面几天备战面试的核心清单。比如我在选择题里遇到一道关于数据库索引失效的场景题当时拿不准复盘后我花了一个晚上把索引失效的几种场景全部弄明白。结果后来的技术面试里面试官真的问到了类似的问题我直接照复盘后的理解答了出来。笔试和面试是连贯的考察链路笔试不是筛选完成就结束而是提前帮你画出面试重点。5.2 从笔试考点反推面试重点技术类校招面试通常包含两到三轮技术面每一轮都看重不同的能力。笔试复盘能帮你预判面试官会问什么笔试暴露的问题面试可能追问的方向提前准备的内容排序算法时间复杂度不熟手写快排、堆排追问稳定性常见排序的实现、复杂度、稳定性对比TCP三次握手不熟追问“为什么要三次握手”“第三次可以带数据吗”用抓包工具走一遍完整的TCP连接哈希表题写得慢追问哈希冲突、HashMap实现原理Java HashMap的扩容、红黑树、并发问题DP题没做出来现场手写一道DP题并解释状态定义至少过一遍10道经典DP题这种反推不是玄学而是面试官通常会基于简历和笔试记录来出题。笔试记录在招聘系统里会被面试官看到你在笔试中暴露的短板如果不主动补齐面试时很可能被精准打击。5.3 给下一批同学的备考清单结合这次笔试的经验我整理了一份“笔试前一周冲刺清单”你可以直接照着执行LeetCode高频题100道刷完一遍重点练数组、字符串、哈希表、双指针、二叉树、DFS/BFS、动态规划、贪心。在牛客网或者赛码网上完成至少3套校招真题熟悉ACM模式的输入输出模拟考试时间环境。数据结构与算法基础再过一遍栈、队列、链表、树、图、堆、排序、查找、哈希。操作系统和计算机网络各总结一张A4纸把核心概念和面试高频题写在纸上考前反复看。数据库SQL语法上手练习尤其是多表查询、聚合函数、索引机制。准备一个自己的笔试代码模板库包含输入读取模板、常用排序、二叉树遍历框架、并查集模板等。为什么强调“在平台上练习”而不是只在LeetCode上刷因为笔试环境的心理压力和处理输入输出的额外负担必须通过模拟来适应。你刷LeetCode是开卷答题在线笔试是闭卷上战场两者之间的差距要靠完整模拟来弥补。最后分享一个最实用的技巧在我后来参加的多次在线笔试里有一个习惯让我每次都稳定发挥开考后的前5分钟不做任何题目而是把所有题目都快速浏览一遍把编程题的输入输出格式抄在草稿纸上再开始按部就班地做题。这个习惯帮我避免过两次“题目读了一半就去选题结果审错题”的悲剧。如果你正在准备技术类校招笔试记住这句话校招笔试的题目难度不会到竞赛级别它考的就是你有没有把数据结构、算法、操作系统、网络、数据库这五门课的基础打牢同时能不能在ACM模式下快速写出无Bug的代码。你不需要成为算法天才只需要在有限时间内稳定输出。做到这一点第二批、第三批都只是你拿offer路上的一个普通关卡而已。