尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

搜狗2020校招后端笔试第一场全解析:考点覆盖与实战策略

搜狗2020校招后端笔试第一场全解析:考点覆盖与实战策略 搜狗2020校招后端笔试第一场是我在帮几届学弟学妹准备校招时反复拿出来讲的一套题。它不像有些厂的笔试那样剑走偏锋出偏题怪题相反这套题的考点非常典型语言基础、网络协议、操作系统、数据结构和算法再穿插一两道跟搜索引擎业务沾边的设计题。如果你准备的是后端岗位把这套题吃透基本等于把大厂后端笔试的常见题型过了一遍。先说结论搜狗这套后端笔试题的难度在当时的一线互联网公司里不算最变态的但它的覆盖面很全而且带着明显的搜索引擎业务色彩。全文我会按题型结构、选择题考点、编程题推导、开放题思路、备考复盘这条线来讲中间会穿插很多我当时实际踩过的坑和总结出来的答题策略。1. 第一场笔试的全貌题量、时长与考察范围1.1 题型分布与时间压力搜狗2020校招后端笔试第一场从大家考后复盘的情况看整体结构是一套选择题加三道编程题总时长大约120分钟。选择题大概20道左右包含单选和多选覆盖C/C、Java、数据结构、算法、计算机网络、操作系统、数据库和Linux常用命令。分值上选择题和编程题大概各占半壁江山编程题虽然只有三道但每道都是硬骨头直接影响你能不能进面试。时间压力是真实存在的。20道选择题看着不多但不少题目本身有迷惑性比如多选里的“下列说法正确的是”四个选项里可能有两三个都长得像对的如果不控制节奏很容易在前面耗掉四五十分钟。我的建议是选择题平均每题控制在1.5到2分钟以内遇到卡壳的先标记跳过不要在单个题上较劲。先给个大概的参考时间分配表具体可以按自己的强弱项微调题目类型题量建议用时核心策略选择题约20道30-40分钟快准狠犹豫的题先标记编程题第一题1道20-25分钟求稳拿满分为目标编程题第二题1道25-30分钟中等难度写清楚思路编程题第三题1道30-40分钟能拿部分分就部分分检查与提交-10-15分钟检查输入输出边界别留空题1.2 业务背景如何影响出题搜狗做搜索起家后来又做了输入法、AI硬件这些方向但搜索相关的技术栈始终是它的底色。这套后端笔试题里你能明显感觉到出题人对文本处理、海量数据统计、检索和缓存这几个方向的偏爱。具体来说编程题里几乎必然会有一道字符串处理相关的问题比如解析搜索日志、统计词频、找出TopK之类的。这不是巧合而是搜索后端日常工作的高度浓缩。搜索引擎每天要处理海量query怎么在内存里快速统计、怎么在分布式环境下做归并都是后端工程师真正要面对的问题。如果你提前了解这一层背景备考方向就会清晰很多。不要只闷头刷LeetCode上的纯算法题还要刻意练一练带业务场景的题目比如“给一个日志文件统计每个用户的请求次数并排序输出”。这类题在LeetCode上不一定有原题但在搜狗、百度这类搜索公司的笔试里出现频率极高。1.3 笔试平台与提交环境搜狗那几年校招笔试大多在牛客网上进行选择题和编程题在一套试卷里连续作答编程题采用ACM模式也就是需要你自己处理标准输入输出而不是像力扣那样只需要实现一个函数。这个区别非常重要因为很多人平时刷题刷习惯了只写核心函数到了笔试平台上一遇到输入解析就手忙脚乱。我记得当时辅导过的一个学弟第一道编程题逻辑完全写对了但读取一行字符串时没处理行尾换行符导致结果对不上测试样例白白浪费了将近二十分钟排查。这个问题在本地IDE里通常看不出来因为本地输入不会带那些隐藏的换行符。我的经验是笔试前一定要去牛客网上做几套模拟题适应一下它那种“全篇代码自己写main、自己解析”的形式。另一个容易被忽略的点是牛客网的提交是单题分别判分的三道题之间可以任意顺序切换到下一题。如果你在第三题上卡死完全可以先回头把第一题第二题的边界情况再检查一遍把能拿的分拿稳而不是死磕一道题到最后一刻。2. 选择题里的高频考点网络、操作系统与语言基础2.1 C/C与Java语言基础的考察角度搜狗后端的主要技术栈是C和Java所以语言基础选择题也基本围绕这两种语言展开。C这边虚函数、构造与析构顺序、智能指针、内存管理是绝对重点Java那边则是JVM内存区域、垃圾回收、集合类底层实现、并发包这些。举个例子有一类题特别经典给定一个类B继承自类A类A里有一个成员对象C问创建B对象时构造函数的调用顺序。这种题没有任何技巧纯粹看基础扎不扎实。正确的是先构造基类A再构造成员对象C最后执行B自己的构造函数析构顺序完全相反。但很多人会栽在“成员对象的构造顺序取决于声明顺序而不是初始化列表里的顺序”这个细节上。还有Java的HashMap当时Java 8的升级已经把链表转红黑树的阈值、扩容机制这些讲得很细了笔试里也很喜欢考。比如问你“HashMap什么时候会触发树化”“为什么链表转红黑树的阈值是8”这类题本质上是在考察你对底层实现有没有真正读过源码而不是只知道会用。2.2 TCP、HTTP与网络模型经典问法网络协议是后端笔试选择题里性价比最高的一块因为考点非常固定。TCP三次握手、四次挥手、为什么挥手要四次、TIME_WAIT状态的作用、SYN Flood攻击的原理、HTTP状态码的含义、GET和POST的区别、Cookie和Session的关系基本上翻来覆去就这些。搜狗这套题里我记得比较深的是考了一道关于TIME_WAIT的题主动关闭连接的一方在收到对方的FIN后会进入TIME_WAIT状态为什么这个状态要等2MSL而不是直接关闭。正确理解是一方面要确保自己最后发的ACK能被对方收到如果丢了对方会重发FIN另一方面是为了让旧连接上的延迟报文段在网络中消失避免影响相同四元组的新连接。这个点如果只是背答案很容易在多选变体里翻车。这里给个提醒网络题不要只背结论要能自己画一遍时序图、解释清楚每个状态迁移的原因。面试现场画图倒不至于但笔试选择题里多选变体非常多只有理解了原理才能准确判断哪些选项是对的哪些是出题人故意挖坑的。2.3 操作系统、数据库与Linux命令选择题操作系统这边死锁产生的四个必要条件、进程和线程的区别、虚拟内存和页面置换算法、进程调度算法都是高频考点。LRU缓存淘汰策略在选择题里出现的频率尤其高因为它既能考操作系统里的页面置换又能考Redis内存淘汰还能和编程题里的缓存设计联动。数据库的选择题主要集中在索引和事务上。B树为什么适合做数据库索引、什么情况下索引会失效比如对索引列使用函数、隐式类型转换、左模糊查询、事务的ACID特性、四种隔离级别分别解决什么问题这些都属于后端笔试“必考清单”。特别是隔离级别和“脏读、不可重复读、幻读”的对应关系几乎每个厂都考。Linux命令的选择题一般是送分题但也会出一些容易混淆的选项。比如查看进程用ps查看端口占用用netstat或ss查看磁盘用df查看内存用free查看日志用tail和grep组合。不要小看这些命令有时选择题里会故意把netstat和ss搞混或者把df和du的用途互换基础不牢的人很容易凭印象选错。3. 编程题实战三道算法题的完整推导3.1 字符串与模拟题别在小细节上翻车编程题第一道通常是整场考试的热身题难度不大但特别考验细致程度。搜狗这套题里第一道我印象里是给一段搜索日志每行格式类似“用户ID\t搜索词\t时间戳”要求统计每个用户的总搜索次数按次数降序输出次数相同的按用户ID升序。这道题考察的核心就是字符串切分、哈希统计和排序思路三秒钟就能想出来但真正写起来有几个细节很容易踩坑输入行数不固定需要用while循环读取到文件末尾不要假设固定行数。分隔符是制表符\t不是空格如果用split( )去切会得到一堆空串。用户ID可能包含字母和数字排序时按字典序不是按数值序。输出格式要跟题目要求完全一致多一个空格都可能导致判分失败。一个简化版的参考逻辑是这样BufferedReader reader new BufferedReader(new InputStreamReader(System.in)); MapString, Integer countMap new HashMap(); String line; while ((line reader.readLine()) ! null line.length() 0) { String[] parts line.split(\\t); if (parts.length 2) { countMap.put(parts[0], countMap.getOrDefault(parts[0], 0) 1); } } countMap.entrySet().stream() .sorted(Map.Entry.String, IntegercomparingByValue().reversed() .thenComparing(Map.Entry.comparingByKey())) .forEach(e - System.out.println(e.getKey() e.getValue()));注意字符串切分时我在split里写了\\t而不是\t因为Java的split接收的是正则表达式裸的\t会被当成转义字符本身只有写成\\t才能匹配制表符。这种细节在本地IDE里可能因为输入样本恰好没体现出来而被忽略但在判题机的隐藏用例里一测一个错。3.2 TopK与词频统计搜索引擎的常客第二道编程题通常开始上强度了。搜狗这套里有一道是给一篇很长的英文文本要求找出出现频率最高的K个单词如果频率相同按字典序输出。这题本质上就是TopK问题在搜索引擎的后端业务里非常常见比如统计热门搜索词、找出热门新闻关键词都是同一个套路。我当时给学弟学妹讲这道题时强调了一个关键决策为什么要用小顶堆而不是把全部数据排序假设文本里一共有N个不同单词如果全部排序时间复杂度是O(N log N)如果维护一个大小为K的小顶堆每来一个单词就与堆顶比较比堆顶大就替换并调整最终堆里留下的就是最大的K个时间复杂度只有O(N log K)。当N是百万级、K是10的时候这个差距是数量级的。另一个隐藏的细节是如何统计单词。如果对每个单词都调用一次containsKey加put性能其实也够但更优雅的写法是MapString, Integer freq new HashMap(); for (String word : words) { freq.merge(word, 1, Integer::sum); } PriorityQueueMap.EntryString, Integer heap new PriorityQueue( (a, b) - a.getValue().equals(b.getValue()) ? b.getKey().compareTo(a.getKey()) : a.getValue() - b.getValue() ); for (Map.EntryString, Integer entry : freq.entrySet()) { heap.offer(entry); if (heap.size() K) { heap.poll(); } }堆顶是当前K个里频率最小的频率相同时字典序最大的先被淘汰这样最后堆里剩下的就是频率最大、字典序最小的K个。很多人会把比较器的方向写反我的经验是写完比较器之后先用一个只有三五个元素的小例子手动推一遍确认堆顶是符合预期“最该被淘汰”的那个再提交。3.3 动态规划题拉开区分度的关卡第三道编程题一般是动态规划或者带一点算法设计的题。按2020年前后搜狗的出题风格我复盘到的是一道类似于“最小编辑距离”的题给定两个字符串允许插入、删除、替换问最少多少次操作能把第一个串变成第二个串。这道题当年在牛客上讨论热度很高因为DP状态转移很经典但边界处理容易出问题。状态定义是dp[i][j]表示字符串A的前i个字符变成字符串B的前j个字符所需的最小编辑次数。转移方程分两种情况如果A[i-1] B[j-1]那么dp[i][j] dp[i-1][j-1]不需要额外操作。如果不相等取三种操作的最小值再加1替换dp[i-1][j-1] 1删除dp[i-1][j] 1插入dp[i][j-1] 1初始化时dp[i][0] i表示把A的前i个字符全部删掉dp[0][j] j表示空串插入j个字符。这个初始化很多人会漏导致第一行第一列全部是0结果全错。如果只求最优值可以用滚动数组把空间从O(mn)优化到O(n)因为每一行的状态只依赖上一行和当前行。笔试题里空间优化一般不是必须的但写出来会是个加分项。我当时鼓励学弟学妹用滚动数组因为面试官看笔试代码时看到你能主动优化空间印象分会高一些。另外这类DP题的输入是两个字符串要注意字符串里是否包含空格如果用next()读就只会读到空格前的部分导致后续字符全部丢失。正确做法是用nextLine()或按行读取后去掉末尾换行。3.4 笔试现场踩过的坑输入输出、越界与心态编程题部分的坑很多不是算法本身的坑而是工程习惯的坑。我把当时复盘时总结的常见问题列在这里都是真实发生过的事输入读取提速不要用Scanner逐行读大批量数据用BufferedReader加StringTokenizer或者直接split效率差好几倍。有些判题机数据量大Scanner读超时是真的会发生的。数组越界DP题里最容易出现dp[i-1]没判断i是否大于0或者循环从0开始时访问到dp[-1]。我的习惯是循环下标从1开始把下标0的位置留作边界初始化。整数溢出统计词频、计算路径数这类题结果可能超过int范围该用long就早用long不要等溢出了再回头改类型。输出格式题目要求输出以空格分隔还是换行分隔、末尾是否允许有多余空格这些都必须严格照做。判题机是按字符串精确比对不是人眼阅卷。找不到bug时重读一遍题有至少20%的情况代码逻辑没错是你看漏了题目的某个限制条件比如“单词不区分大小写”“只考虑字母字符”等隐含条件。心态上我记得有不少人第一道题因为小细节卡了半小时直接心态崩了后面两道题草草收场。我的建议是如果一道题连续调试超过15分钟还没找到问题先把它放一放去做下一道等整个试卷都过完一遍再回来。大脑切换上下文之后往往一眼就能看出之前忽略的问题。4. 开放性问题搜索引擎场景下的后端设计题4.1 这类题为什么会出现搜狗后端笔试里偶尔会有1到2道简答或设计类题目不需要写出完整代码而是让你用文字描述设计方案。很多人准备笔试时完全不练这类题结果考场上遇到只能随便写两句。其实这类题恰恰是最能体现后端工程师和纯刷题选手差异的地方。搜索引擎公司为什么要考设计题因为后端日常工作里很多问题不是“写一个算法”能解决的而是要综合考虑数据量、并发、缓存、存储、容错。笔试里考察你一下字符串处理或TopK只能看出你代码写得好不好考一道设计题才能看出你有没有做工程的sense。4.2 典型设计题搜索框关键词联想我当时复盘到的一道代表性设计题是请设计一个搜索框的关键词联想服务用户输入“北”时下拉框要能展示“北京”“北京大学”“北京天气”等热门词要求说明数据结构、存储方案和更新策略。这道题的经典解法分两层。第一层是前缀匹配的数据结构用Trie树字典树存所有候选词每个节点记录经过该前缀的热门词TopK列表。这样用户每输入一个字符就能立刻在Trie树上走一步然后返回当前节点预存好的TopK时间几乎只跟K有关跟词典大小无关。第二层是工程方案的取舍。不可能把所有词和频次都存在内存里更不可能实时去数据库里数一遍频次所以要做离线计算加在线召回离线统计过去一段时间的热门搜索词定期构建或更新Trie树及每个前缀的TopK列表推到Redis等缓存中在线服务收到请求时优先查本地缓存查不到再查RedisRedis也没有就退回一个较小的默认词表。我在讲这道题时一定会强调容量估算。比如假设候选词有1亿条每条平均长度20字节加上Trie树的指针开销原始Trie树可能需要几GB到十几GB内存这样的量级单机是能扛住的但要考虑多副本和容灾。答出这一层说明你真的思考过系统的成本问题而不仅仅是在背架构。4.3 另一个方向接口性能优化还有一种开放题风格是给场景让你优化。比如“搜索结果页接口很慢用户普遍反馈卡顿你作为后端工程师会怎么排查和优化”。这种题没有标准答案但有一个很固定的答题框架我习惯称之为“先定位再拆分后优化”。先定位用链路追踪或日志分析找出慢在哪一环。可能是数据库查询慢、可能是下游服务响应慢、可能是代码里有耗时操作甚至可能是网络抖动。没有数据支撑的优化都是瞎猜。再拆分从浏览器发起请求到页面渲染整个链路上有哪些环节。前端发了几个请求、网关有没有做聚合、后端服务有没有串行调用可以改成并行、数据库有没有慢查询和全表扫描、有没有大量重复查询可以加缓存。后优化按照性价比从高到低排列优化手段。加缓存、加索引、改SQL、并行化调用、异步化非核心逻辑、限制单用户QPS、做降级方案。每一层优化都要能验证效果比如对比优化前后的P99耗时。开放性问题的答题要点是结构清晰、步骤完整、可行性高。面试官和判卷人不会期待你设计出一个完美的系统他们想看的是你有没有一套稳定的分析框架能不能把一个大问题拆成小问题逐个击破。5. 从笔试题到后端日常工作复盘后的三点体会5.1 考点其实都在映射真实业务我把搜狗这套笔试题的考点和后端日常工作做了个对应发现重合度非常高。TopK词频统计对应的是热门搜索词挖掘字符串解析对应的是日志清洗最小编辑距离对应的是搜索词纠错关键词联想设计对应的是搜索补全服务。笔试不是在考你偏题怪题而是把你放进一个准后端工程师的角色里看你能不能处理真实工作中会遇到的建模需求。想通这一点备考的思路就不一样了。刷题时多问自己一句“这道题在实际业务里可能出现在哪里”而不是机械地记套路。带着业务视角去刷题效果远比盲目刷题数量要好得多。5.2 针对搜索类公司的备考节奏建议如果你瞄准的是搜狗、百度这类搜索业务为主的公司备考节奏可以这样安排先用两周时间把数据结构与算法的基础模块过一遍重点放在字符串、哈希表、堆、Trie树、并查集、DP这几块然后开始刷往年真题和牛客上的模拟卷每天至少完整做一套严格计时模拟真实笔试环境。选择题丢分多的模块单独拉出来做专项训练比如网络协议题错得多就把TCP/IP那几章重新精读一遍。编程题则坚持“每题两种解法”的原则想出一种解法后别急着写先思考一下有没有更优的数据结构或更省空间的方案再动键盘。考前一周不要再刷新题了。把那段时间整理的错题本拿出来反复看重点看那些“以为会但做错”的题。笔试考场上真正拉开差距的往往不是最难的题而是容易题里的细节你能不能一次做对。5.3 一个实用的错题复盘方法最后分享一个我自己的复盘习惯。每次笔试或者模拟测试结束后我会上网找同场考生的讨论帖和题解然后建一张表格把每道错题的几个关键信息记录下来题目描述、我的错解想法、错在哪里、正解思路、同类题变体。不要只在脑子里过一遍一定要写下来而且要写得足够具体。这张表积累到二三十道题之后你会发现自己的错误类型非常集中。有的人总是栽在数组越界有的人总是在多选里过度纠结有的人喜欢在字符串处理上用错误的切分方式。考前复盘时只盯着这些高频错误点看效率是最高的。我当时靠这个习惯把笔试里的失误率从最开始的一道题错一次降到了后期的基本稳定这也算是我校招季最值得做的一件事。如果你也在准备后端校招建议你也把这个习惯保留下来尤其是多花点时间研究透一套像搜狗这样考点覆盖全面的真题远比盲目刷几十套雷同的卷子更有价值。
返回列表