
2020届秋招那会儿我投了搜狗的后端岗提前批没赶上正式批报的是第二场笔试。搜狗笔试是牛客网系统双机位监控2个小时题量不算小编程题占了很大比重。那场是9月中旬考的考完之后我花了不少时间复盘把题目和考点都整理了一遍。后面陆续又面了几家大厂发现搜狗这场笔试考察的范围和难度在国内互联网校招里属于比较典型的一档很多东西是通用的。这篇把第二场笔试的题型分布、核心考点、编程题思路、复盘心得完整拆一遍给后面准备校招后端岗的朋友做参考。搜狗2020校招后端笔试第二场核心考察方向是数据结构与算法、计算机网络、操作系统、Java基础如果你投的是Java后端以及数据库。整体难度中等偏上区分度主要在两道编程大题上。适合正在准备秋招或者春招补录的后端岗位候选人阅读不管是零基础还是已经刷了一些题这篇文章都会把题目背后的考点逻辑、考场上的时间分配策略讲清楚。1. 笔试整体设计与题型拆解1.1 考试形式与时间分配搜狗校招笔试统一走牛客网在线评测系统后端岗位第二场考试时长120分钟题量大概在20道单选、5道多选、2道编程题每个题型单独计时不是整场统一计时所以时间分配很有讲究。我当时拿到卷子先快速扫了一遍全卷重点关注了两道编程题的难度。这个习惯我建议所有人都养成——先看大题再倒推时间分配而不是从第一道选择题慢慢往后做。因为选择题再难也就一两分钟一道编程题一旦卡住半小时都不一定出得来。我个人的时间分配策略是这样单选题30分钟内搞定遇到特别偏的题先标记跳过不恋战多选题20分钟内完成多选少选都不得分遇到模棱两可的先凭第一印象选完两道编程题预留60-70分钟其中第一道简单题控制在20分钟以内第二道难题至少留40分钟这个时间规划在实战中非常关键。我看到不少同学前60分钟全耗在选择题上最后编程题只剩半小时简单题能做出来难题基本只能交白卷。其实后端笔试的分数构成里编程题占比普遍在40%-60%选择题更像是基础门槛真正拉分的就是最后两道代码题。提示牛客网在线笔试支持本地IDE调试提交前务必在本地把边界情况测一遍再粘贴到评测框里不要直接在网页编辑器里写大段逻辑那样debug效率极低。1.2 考点范围与比例分布搜狗后端笔试的考点分布大致可以分成以下几个模块考察模块大致占比典型题型数据结构与算法30%选择题编程题计算机网络15%选择题、多选题操作系统15%选择题、多选题数据库10%选择题Java基础与JVM15%选择题、多选题Spring与框架10%选择题系统设计5%问答题或选择算法这一块是绝对的重头戏。考到的数据结构覆盖了数组、链表、栈、队列、二叉树、哈希表、堆、图排序算法和动态规划是常客。第二场笔试的编程题一题是典型的动态规划问题另一题是字符串处理加贪心思想这两道题我在后文会详细拆解。计算机网络的考点集中在了TCP三次握手四次挥手、HTTP协议状态码、TCP和UDP的区别、DNS解析过程、HTTP与HTTPS的区别这些经典内容。操作系统主要考察进程和线程的区别、死锁的四个必要条件、进程调度算法、内存管理、虚拟内存、页面置换算法。数据库这块考的偏基础事务的ACID特性、索引的原理B树、数据库的三大范式、SQL语句的编写。值得注意的一个细节是搜狗笔试卷里出现了不少关于并发编程的题目基本集中在Java线程池、synchronized和Lock的区别、volatile关键字、CAS机制这些方向。搜狗很多业务线的后端都是Java技术栈所以Java并发这一块面试官和出题人都非常重视。2. 编程题核心考点与解题思路2.1 第一道编程题经典动态规划第一道编程题原型是一道非常经典的动态规划问题和编辑距离系列高度相似。题目的大致意思是给定两个字符串允许对其中一个字符串进行三种操作分别是插入一个字符、删除一个字符、替换一个字符问最少需要多少次操作可以把两个字符串变成相同的。这道题本质就是LeetCode 72. Edit Distance。考场上我看到这题第一反应就是典型的二维DP。定义dp[i][j]表示字符串A的前i个字符转换成字符串B的前j个字符所需的最小操作次数。状态转移分两种情况如果A[i-1] B[j-1]说明当前字符相同不需要额外操作dp[i][j] dp[i-1][j-1]如果A[i-1] ! B[j-1]则考虑三种操作中代价最小的插入dp[i][j-1] 1删除dp[i-1][j] 1替换dp[i-1][j-1] 1初始化条件是dp[i][0] idp[0][j] j因为把任意字符串变成空串只能通过逐字符删除完成。我当时写了一个两层循环嵌套的版本时间复杂度O(mn)空间复杂度也用了O(mn)的二维数组。这道题如果只是为了应付笔试二维数组的做法已经完全够用了没必要强行优化到一维滚动数组。因为笔试评测的数据量一般不会大到O(m*n)过不了的程度写清楚、写对比写花哨重要得多。public int minDistance(String word1, String word2) { int m word1.length(); int n word2.length(); int[][] dp new int[m 1][n 1]; for (int i 0; i m; i) { dp[i][0] i; } for (int j 0; j n; j) { dp[0][j] j; } for (int i 1; i m; i) { for (int j 1; j n; j) { if (word1.charAt(i - 1) word2.charAt(j - 1)) { dp[i][j] dp[i - 1][j - 1]; } else { dp[i][j] Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) 1; } } } return dp[m][n]; }这题的易错点主要有两个。第一个是charAt的索引容易搞混dp数组的下标i对应的是字符串的前i个字符对应到charAt的时候是i-1这个偏移量问题我见过太多人写错了。第二个是状态转移时三种操作对应的方向容易记错——插入对应的是dp[i][j-1]删除对应的是dp[i-1][j]替换对应的是dp[i-1][j-1]这种方向问题一旦写反小数据可能发现不了错误大数据就挂。踩坑记录我当时第一次提交在初始化dp[0][j]的时候写成了dp[0][i]结果编译器没报错逻辑跑起来全错。这类下标初始化错误看代码很难发现建议初始化阶段就printf或System.out.println把dp数组打出来看一眼确认边界值正确再继续写核心逻辑。2.2 第二道编程题字符串与贪心第二道编程题考察的是字符串处理加贪心思想。题目的基本思路是给定一个字符串要求将字符串按照某种规则切分成若干子串使得每个子串中的字符都满足某种条件比如字符唯一求最大可切分的子串数量或者输出所有切分结果。这类题在LeetCode上有很多变体比较典型的有分割平衡字符串、划分字母区间、无重复字符的最长子串等。搜狗这道题的切入点是贪心——在遍历字符串的过程中尽量在当前区间内分割出最短的合法子串从而使得总子串数最大。我当时用的方案是哈希表加贪心。具体思路用HashMap记录当前窗口内每个字符最后出现的位置遍历字符串维护当前子串的起始位置start和当前遍历位置end每遇到一个字符更新它在哈希表中的最后出现位置如果当前索引等于当前子串内所有字符最后出现位置的最大值说明子串可以切分这个思路实际上就是LeetCode 763划分字母区间的标准解法。不过这题隐藏的一个变化是它要求的是尽可能多的子串那么切分策略会略有不同——不是等到所有字符最后出现位置的最大值才切而是要有更贪婪的切分方式比如每次遇到字符第一次重复就考虑是否切分。我考场上写的是这样一个版本def maxSplit(s): n len(s) last_pos {} for i, ch in enumerate(s): last_pos[ch] i res [] start 0 end 0 for i, ch in enumerate(s): end max(end, last_pos[ch]) if i end: res.append(s[start:i1]) start i 1 return res这道题在笔试里有一些边界情况需要注意。字符串为空时要返回空列表字符串只有一个字符时返回包含这一个字符的列表字符串中所有字符完全相同时结果应该是一个完整的大字符串。这类边界情况在做题时最好单独列出来测试一遍不要把所有希望寄托在测试用例上。注意笔试环境里很多同学习惯于写完代码直接提交然后看评测结果但牛客网的笔试评测通常只能看到部分用例通过情况看不到具体是哪组用例挂了。所以我建议在本地IDE里自己构造边界用例全部跑一遍再提交这比盲目提交等着看错误要节省时间得多。2.3 编程题实战中的代码框架搭建笔试编程题如果想在有限时间内写出高质量代码我建议平时就固定一套自己熟悉的代码框架。比如我在这两道题上使用的就是标准的函数定义边界检查核心逻辑返回值四段式结构这样上了考场不需要思考代码组织问题直接按模板往里面填核心逻辑即可。以编辑距离这道题为例完整的框架应该是public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); String a sc.nextLine(); String b sc.nextLine(); System.out.println(minDistance(a, b)); } public static int minDistance(String word1, String word2) { // 1. 边界检查 if (word1 null || word2 null) return 0; // 2. 初始化 int m word1.length(), n word2.length(); // 3. 核心逻辑 // ... // 4. 返回结果 return dp[m][n]; } }不同公司的笔试系统输入输出方式会有差异有的用Scanner有的用BufferReader有的按行读有的按空格分隔。建议每种IO模式都在平时练习中至少写过一遍免得考试时浪费宝贵时间在调试输入输出上。3. 计算机基础知识考点梳理3.1 计算机网络高频题目搜狗后端笔试卷的计算机网络部分考察的知识点可以说是非常八股的都是计算机专业面试中最常见的那几个问题TCP三次握手和四次挥手的具体流程、HTTP常见状态码的含义、TCP与UDP的区别和应用场景、HTTP与HTTPS的加密原理、DNS的解析过程。三次握手这里有一道选择题我记得很清晰问的是第二次握手时服务器发给客户端的报文段中SYN和ACK的值分别是什么。这题本质就是考TCP报文段标志位如果对TCP头部结构不够熟悉非常容易丢分。三次握手的本质是确认双方收发能力正常并同步初始序列号这个理解比单纯背步骤要重要得多。HTTP状态码那块考到了403、404、500、502、504的区别。这些状态码在真实业务开发中几乎天天遇到但很多同学只记了大概含义没有深究。比如403表示服务器理解请求但拒绝执行504表示网关超时502是网关或代理服务器收到了无效响应这三个特别容易搞混。因为搜狗后端本身做搜索业务对HTTP协议这块的掌握程度要求很高所以笔试里考察的频率也比一般公司高。还有一道题目让我印象很深——TCP建立连接为什么是三次而不是两次。这题如果在选择题里出现答案一般是防止已失效的连接请求报文段突然又传送到服务器端因而产生错误。但如果是简答题形式出现需要从序列号同步、资源浪费、历史重复连接这几个角度来答我在后来的面试中就被追问过这个问题的扩展版本。3.2 操作系统核心考点操作系统部分主要考察进程管理和内存管理两大块。进程管理方面死锁的四个必要条件互斥、占有并等待、不可剥夺、循环等待是必考内容而且经常会出现变体题。比如给你几个进程资源分配的场景问你当前是否处于死锁状态、如何通过破坏某个必要条件来解除死锁。面试官对这种场景题比单纯背概念题更看重因为出题人更容易从真实业务中抽象出来。进程和线程的区别也是一个高频考点。选择题给出的四个选项通常会有一个线程拥有独立的地址空间的干扰项以及一个进程之间通信只能通过IPC的正确选项。要注意的是同进程的多个线程共享该进程的地址空间这是线程和进程最本质的区别之一。另外还需要掌握进程间通信的几种方式管道、消息队列、共享内存、信号量、Socket以及它们的优缺点和适用场景。内存管理方面虚拟内存、分页和分段、页面置换算法FIFO、LRU、OPT、局部性原理是核心考点。有一道多选题问的是下列哪些页面置换算法不会出现Belady异常答案是LRU和OPT。这题考察的不只是算法本身还考察了对算法特性的深入理解。信号量机制那本书上的经典题目也出现了——生产者-消费者问题。这不是简单地背代码而是要求理解wait和signal操作的原子性以及信号量初始值的含义。搜狗这种做搜索和AI产品的公司后端并发场景非常多所以这套经典同步互斥问题是必考范围。3.3 数据库与SQL考察方向数据库题目占比不算太高但考得非常细致。事务的四大特性ACID——原子性、一致性、隔离性、持久性属于送分题但会进一步考察隔离级别的含义和各自解决的问题。比如读未提交、读已提交、可重复读、串行化分别解决了脏读、不可重复读、幻读中的哪些问题这个对应关系一定要背熟。索引这部分考察了B树索引的优点以及聚簇索引和非聚簇索引的区别。有一道题目问的是为什么InnoDB使用B树而不是B树作为索引结构这道题的得分点在于B树的非叶子节点只存索引不存数据同样大小的磁盘页能容纳更多索引项树高更低磁盘IO次数更少而且B树叶子节点有链表指针做范围查询效率极高。SQL编写的题目考了一道两表联查加分组统计。大致的意思是有一张用户表和一张订单表要求统计每个用户的订单总额输出用户ID和总金额按金额降序排序。这个题目本身难度不大但要注意GROUP BY和ORDER BY的执行顺序以及JOIN时需要用LEFT JOIN以保证没有订单的用户也要输出。SQL题还有一个非常容易踩的坑就是SQL关键字的大小写问题。牛客网评测环境有的支持大小写混用有的对大小写有严格要求。我建议统一使用小写关键字配合大写表名和列名或者反过来保持一致避免不必要的报错。4. Java基础与并发编程深度考察4.1 Java集合框架源码级考点搜狗后台主要以Java技术栈为主所以Java部分的笔试题目出得比较深尤其是集合框架不再停留在HashMap和Hashtable有什么区别这种层面而是深入到了源码层面。HashMap是最高频的考察对象。涉及到的考点包括底层数据结构是数组加链表加红黑树链表转红黑树的阈值是8红黑树转链表的阈值是6负载因子默认是0.75初始化容量必须是2的幂。为什么要用2的幂次方作为容量因为计算桶下标用的是hash (length - 1)只有length是2的幂时这个位运算才等价于取模且速度远快于取模运算。还有一道选择题考察了HashMap的扩容机制。当Map中元素个数超过capacity * loadFactor时触发扩容扩容时容量翻倍put操作的流程是先计算key的hash值再通过hash (capacity - 1)找到桶位置如果桶已经存在元素则遍历链表或红黑树判断key是否已存在存在则覆盖value不存在则插入新节点。ConcurrentHashMap也是一个重点。JDK 1.7及以前使用Segment分段锁JDK 1.8之后改为CAS加synchronized锁住桶的头节点。这个变化的核心是锁粒度从分段锁细化为单桶锁并发度更高而且避免了Segment数组的额外内存开销。考场上有一道多选就是考察1.8版本ConcurrentHashMap的锁机制选项有CAS、synchronized、ReentrantLock、volatile等干扰项就是ReentrantLock因为它是1.7版本Segment的加锁方式。ArrayList和LinkedList的对比同样考到了。ArrayList基于动态数组随机访问快插入删除慢如果需要移动元素LinkedList基于双向链表插入删除快已知节点时随机访问慢。还有一个考点是ArrayList的扩容机制默认初始容量10每次扩容为原来容量的1.5倍扩容时调用Arrays.copyOf进行数组复制。4.2 JVM内存模型与垃圾回收JVM这部分考察了运行时数据区、垃圾回收算法、类加载机制三个方向。运行时数据区需要掌握的是程序计数器、虚拟机栈、本地方法栈、堆、方法区这五个部分的作用以及哪些区域是线程共享的、哪些是线程私有的。这个考点几乎是Java后端必考基本每年各大公司的笔试面试都会出现。线程共享的是堆和方法区线程私有的是程序计数器、虚拟机栈和本地方法栈。Java 8之后方法区被元空间取代元空间使用的是本地内存而不是JVM堆内存这也是一个高频考点。垃圾回收这里考察了可达性分析算法、GCRoots包括哪些对象、常见垃圾回收算法标记-清除、标记-复制、标记-整理、新生代和老年代的垃圾回收器选择。选择题里有一道是问哪些对象可以作为GCRoots正确答案包括虚拟机栈中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象还有一个干扰项是运行时常量池中的对象这个是不对的。类加载机制考察了双亲委派模型。题目问的是如果一个类加载器收到了类加载请求它首先会怎么做正确答案是将该请求委派给父类加载器去完成。双亲委派模型的作用是保证Java核心类库的安全防止自定义的java.lang.String覆盖JDK自带的类这个机制在后面的面试中通常还会被深入追问建议一定要理解透彻。JVM相关题目还有一个容易被忽略的考点——内存溢出和内存泄漏的区别。内存溢出是申请内存时没有足够空间内存泄漏是对象不再使用但依然被引用导致无法回收。笔试中出现了一个场景题说某个Java服务长期运行后越来越慢最终抛出OutOfMemoryError问这种问题最可能的原因是什么答案应该是存在内存泄漏导致GC频繁触发最终内存耗尽。4.3 Java并发编程核心机制并发编程这块搜狗笔试考得比其他公司要深这和搜狗搜索业务的高并发场景有关系。核心考点集中在synchronized关键字、Lock接口、volatile关键字、CAS机制、线程池、ThreadLocal这几个方向。synchronized和ReentrantLock的对比是一个经典的考察点。synchronized是Java内置的关键字自动释放锁ReentrantLock需要手动加锁和解锁synchronized是非公平锁ReentrantLock可以指定公平还是非公平synchronized不可中断ReentrantLock支持可中断地获取锁synchronized在JDK 1.6之后引入了偏向锁、轻量级锁、重量级锁的升级机制。有一位同学整理过这个对比表放在牛客网上被转了很多次我建议大家在复习阶段也自己整理一份记忆效果远好于直接背别人的总结。volatile关键字考察了两个核心特性可见性和禁止指令重排序。可见性是通过缓存一致性协议MESI实现的禁止指令重排序是通过内存屏障实现的。volatile不能保证原子性所以经典的i问题使用volatile依然不是线程安全的。这个考点需要重点理解因为我在后续面试中被多次问到。CAS机制Compare And Swap考察了其实现原理和ABA问题。CAS通过比较内存中的值是否等于预期值来决定是否更新整个过程是原子操作。CAS的ABA问题指的是一个值从A变成B再变回ACAS无法感知这个过程解决方案是使用版本号Java中AtomicStampedReference就是基于这个思路设计的。笔试中的一道多选题问的是CAS的缺点正确答案包括ABA问题、只能保证一个共享变量的原子操作、循环时间长CPU开销大这三个都是。线程池相关考了一道应用场景题给定一个任务队列和一组线程池参数问该线程池执行完所有任务后的线程数量是多少以及队列中任务的最大等待数量。计算这类题目的前提是理解ThreadPoolExecutor的七大参数即核心线程数、最大线程数、空闲线程存活时间、时间单位、工作队列、线程工厂、拒绝策略。有一个细节容易出错——提交任务时如果当前线程数小于核心线程数即使存在空闲线程也会创建新线程来执行任务而不是复用已有线程。这个规则需要特别注意很多资料里都没有讲透。5. Spring框架与系统设计考察5.1 Spring核心知识点框架部分的考察主要集中在Spring和Spring Boot。搜狗作为一家业务成熟的公司后端技术栈以Spring为主所以笔试里涉及Spring的题目不算少。Spring的IOC控制反转和AOP面向切面编程是最高频考点。IOC的核心思想是把对象的创建和管理交给Spring容器而不是在代码中手动new对象这样做的目的是降低类与类之间的耦合度。Bean的生命周期是Spring部分的重中之重从实例化、属性赋值、初始化、使用到销毁每个阶段都有对应的扩展接口BeanPostProcessor、InitializingBean、DisposableBean等。笔试中有一道选择题把Bean的生命周期打乱要求按正确顺序排列这题如果对Spring源码不够熟悉很容易出错。AOP考察了动态代理的两种实现方式JDK动态代理和CGLIB代理。JDK动态代理要求目标类实现接口通过Proxy类和InvocationHandler生成代理对象CGLIB代理通过继承目标类生成子类来代理不需要目标类实现接口。Spring Boot 2.x之后默认使用CGLIB代理这是一个容易忽略的新变化。Spring Boot的自动配置原理也考到了。自动配置是通过EnableAutoConfiguration注解引入的Spring Boot启动时会扫描META-INF/spring.factories文件中配置的自动配置类然后根据条件注解ConditionalOnClass、ConditionalOnMissingBean等决定是否生效。这个机制的底层逻辑贯穿了Spring Boot所有默认配置理解了它就理解了为什么引入一个starter依赖之后绝大多数配置都不需要手动写了。5.2 Redis缓存与消息队列虽然Redis和消息队列不一定以独立题目形式大量出现但搜狗第二场笔试卷里确实涉及了几个相关考点。Redis方面考了缓存穿透、缓存击穿、缓存雪崩的区别和对应的解决方案。缓存穿透是指查询一个不存在的数据由于缓存和数据库中都没有所以请求直接打到数据库上解决方案是布隆过滤器拦截或缓存空值缓存击穿是指一个热点key过期瞬间有大量请求打到数据库解决方案是互斥锁或设置逻辑过期时间缓存雪崩是指大量key同时过期导致数据库压力激增解决方案是给过期时间加随机值。还有一题问的是Redis持久化机制RDB和AOF的区别。RDB是定期快照恢复速度快但可能丢失最后一次快照后的数据AOF是追加日志数据完整性更高但文件体积大、恢复速度慢。在实际生产环境中通常两者结合使用。消息队列虽然出现频率较低但考了一道基础题问的是消息队列的作用。正确答案是异步处理、流量削峰、应用解耦。这几个作用需要理解透彻因为在后续面试中经常会被要求结合项目经历来谈。5.3 系统设计题的答题框架搜狗笔试的最后一类题型是系统设计题占比虽然只有5%左右但如果遇到了答题框架和思路直接决定了这部分的得分情况。系统设计题的主要形式是给一个业务场景要求画出架构图、设计数据表、或者说明关键的实现方案。搜狗第二场笔试的设计题我记得是给了一个类似短链接生成的场景要求设计一套完整方案包括数据库表结构设计、URL转短链的算法选型、短链跳转时的高并发处理策略。这类设计题答题时不需要写非常详细的代码但需要清晰地表达出架构层次和核心设计选择。我的答题框架是需求分析明确系统的核心功能和非核心功能明确流量规模和数据规模数据库设计给出核心数据表结构包含字段名、类型、索引设计说明为什么这样设计核心算法比如短链接生成算法用的是哈希取模还是Base62编码哈希冲突怎么解决高并发策略缓存怎么用、限流怎么做、是否需要引入消息队列扩展性考虑将来流量增加后如何水平扩展短链接场景的核心问题是全局唯一ID的生成方案常用的有雪花算法Snowflake和数据库自增ID加号段缓存。雪花算法生成的64位整数最高位是符号位接下来41位是毫秒时间戳然后是5位数据中心ID、5位工作节点ID最后12位是同一毫秒内的序列号。这套方案在分布式环境下能保证全局有序且唯一是后端面试中非常高频的设计方案。数据表设计这块核心表至少需要id、短码、原始URL、创建时间、过期时间、点击量这几个字段同时在短码字段上建立唯一索引。查询时通过短码从缓存中查找如果缓存没有命中则回源数据库查询成功后再回填缓存。6. 笔试实战经验与复盘总结6.1 考场时间管理与做题顺序考后复盘的时候我在牛客网上看到了不少参加同一场笔试的同学发的帖子发现大家最大的问题不是知识点不会而是时间不够用。搜狗第二场笔试的题量在2小时内完成确实有点紧凑尤其是选择题里有一些比较偏的八股题目很容易让人在做题中迷失方向把时间浪费在一两道低分值题目上。我自己形成的做题顺序是先做编程题再做选择题。这个策略和大多数人的习惯相反但实测下来效率更高。原因很简单编程题分值高而且越到考试后期大脑越疲劳写代码的逻辑能力会下降。趁头脑清醒先把两道编程题搞定后面就算选择题做得慢一点心态也不容易崩。编程题的做题顺序也有讲究先做简单题再做难题这个没什么争议。但有一类同学容易在简单题上过度自信代码写完了不检查就直接提交结果因为边界条件少处理了一个分支而挂掉。我建议简单题提交前至少留3分钟检查一下输入范围和空值异常。6.2 高频易错点汇总基于这次笔试和后续多场校招笔试的复盘我把高频易错点整理成了表格方便大家复习时对照自检模块高频易错点正确的理解计算机网络四次挥手中TIME_WAIT状态出现在哪一端主动关闭连接的一方操作系统进程中线程共享哪些资源共享地址空间、文件描述符、信号处理器不共享栈和寄存器数据库不可重复读和幻读的区别不可重复读是同一记录值变化幻读是记录数量变化Java集合HashMap的负载因子意义超过容量*负载因子即触发扩容默认0.75Java并发volatile能否保证原子性不能只保证可见性和有序性JVMJava 8中方法区的变化被元空间取代使用本地内存不再使用JVM堆内存SpringBean默认作用域默认是单例singleton不是原型prototype网络编程粘包和拆包的本质原因TCP是面向字节流的没有消息边界这八个易错点几乎覆盖了国内大厂后端笔试的高频陷阱。我在面试了几个同学之后发现很多人对这些概念能说出来一个大概但一落到具体的判断题或选择题上就会犹豫根本原因是对概念的边界理解不够清晰。6.3 考后复盘的正确姿势笔试结束后不要急着对答案或者刷下一家的题库花30-60分钟时间做一次系统复盘效果远好于盲目刷题。复盘的重点不是记录这道题选什么而是搞清楚为什么我之前没做对。我的复盘方法分三步第一步把每道错题的知识点归类到对应的模块中建立一张知识点-错误原因映射表。比如有一道操作系统题做错了原因是进程调度算法掌握不清那就记录到操作系统-调度算法这一项下。第二步针对每个薄弱知识点找3-5道同类题目集中练习直到不再犯错。这个环节的目的是把知道概念变成能做对题两者之间存在很大差距。第三步把错题和对应的知识点总结成一份自己的错题集放在笔记系统里秋招期间每周翻一遍。我发现很多同学在复习时只看重点知识清单完全不看错题集这是不对的。错题集是高度个性化的复习资料它精确标注了每个候选人自己的知识盲区。提示笔试结束后牛客网通常会有整卷的答案解析建议认真看一遍尤其是做错的选择题。有些解析看了一遍仍然不懂的说明对应的基础知识存在系统性欠缺需要回到教材或课程中重新学习而不是只背下这一道题的答案。6.4 从笔试到面试的能力迁移通过这场笔试之后接下来的面试环节会更加注重对知识的深度理解和项目经验的考察。笔试中对知识点的掌握程度是面试的基础但面试还会进一步追问为什么和在项目中怎么用这类开放性问题。以Redis为例笔试只要求你选出缓存穿透的解决方案但面试可能会问你你在实际项目中遇到过缓存穿透吗你是如何监控和处理的这时候如果只是背了布隆过滤器这个名词回答就会非常干瘪。建议在准备面试时把笔试中掌握的知识点按照是什么-为什么-怎么用-踩过什么坑的逻辑重新梳理一遍形成自己的知识体系。现场编程环节也是面试中的重头戏面试官通常会出比笔试略简单但更偏实际业务的题目。比如给定一个日志文件统计每个接口的请求量排名这类题目在笔试中可能不会出现但在面试中非常常见。面试官重点考察的是编码规范、边界条件处理、时间空间复杂度分析、以及和面试官沟通解题思路的能力。笔试可以闷头写代码面试一定要边写边讲把你每一步的思路清楚地表达出来这才是面试环节获得高分的关键。另外想提醒一点笔试和面试是连续的不要因为笔试发挥不错就放松了后续准备。我见过一些同学笔试过了但因为在等待面试期间过于松懈导致面试基础八股回答得磕磕绊绊最终遗憾止步。保持笔试时的复习节奏持续刷题和复盘是拿到offer的最稳路径。