先说个比较实在的结论:58同城2020校园招聘的后端笔试,考的不只是你会不会写代码,更多是看你有没有一个完整、扎实的后端知识体系。我在当年秋招时做过这张卷子,整体感受是:题目难度不算变态,但覆盖面很广,时间紧、题量大,稍不注意就会在选择题上卡太久,导致后面的编程题和设计题没时间做。今天就把这张卷子的拆解思路、常见考点、答题策略,以及我后来复盘整理出的后端学习路线,一次性说清楚。
这里要提前说明一下:具体的原题细节现在已经不好逐字复现,但后端笔试题的出题逻辑和考察范围是有迹可循的。我下面会按照当年秋招最常见的题型和知识点来展开,尽量还原那张卷子带给人的真实压力,也帮后来的同学知道该往哪些方向用力。
1. 先从58同城的业务底色看后端笔试的出题倾向
很多同学拿到笔试题就开始埋头刷题,却忽略了一个很重要的问题:出题人到底想要什么样的人。58同城做的是分类信息平台,业务覆盖招聘、房产、二手交易、本地生活服务这些场景,后端要面对的是海量信息流、地理位置相关的检索、用户发布和内容的审核管理、高并发的访问压力,以及复杂的多业务线数据隔离问题。明白了这一点,就能理解为什么笔试里会反复出现某些知识点。
1.1 分类信息平台对后端工程师的能力画像
58同城这类平台的特点,是“信息发布—信息检索—信息消费”这条链路非常长。用户要发帖,后端要处理图片/文本内容的存储和审核;用户要搜索,后端要面对关键词匹配、类目筛选、地域过滤、排序策略。这些业务场景决定了后端笔试会重点考察几个方向:
- 数据库设计能力:比如给你一个“二手商品发布”的场景,让你设计表结构,考察字段设计、索引设计、分库分表思路。
- 缓存与性能优化:比如信息流首页如何做缓存、热点数据怎么处理、缓存穿透怎么防。
- 消息队列和异步处理:用户发布内容后要触发审核、通知、索引更新,怎么用异步解耦。
- 搜索引擎相关基础:虽然大部分校招笔试不会直接考Elasticsearch原理,但会考倒排索引、分词、相关性排序的基本概念。
- Linux和网络基础:分类信息网站流量大,线上问题排查、网络协议理解是必备技能。
所以你在复习时,如果只是埋头刷LeetCode,不把数据库、缓存、消息队列这些后端常识补起来,很可能在选择题和简答题上吃亏。
1.2 2020届这个时间节点特别爱考的技术栈
2020年前后端招人,已经明显进入“微服务+容器化”普及的阶段。Spring Cloud、Dubbo、Redis、Kafka/RabbitMQ、MySQL、MyBatis/MyBatis-Plus、Nginx、Docker这些名词在校招笔试里出现频率很高。
我当时做58同城这张卷子时,印象很深的是选择题部分并不只是考孤立的语法题,而是喜欢给一段代码片段,问运行结果、问有没有线程安全问题、问GC行为、问数据库索引是否命中。这种题如果只是背过概念,没有真正动手调试过,很容易选错。比如:
public class Test { public static void main(String[] args) { Integer a = 127; Integer b = 127; Integer c = 128; Integer d = 128; System.out.println(a == b); System.out.println(c == d); } }输出是什么?答案是true和false,原因在于Integer的缓存范围是-128到127。这类题目就是典型的“背过就会,没背过就错”的选择题,但放到一张卷子里,考察的其实是Java基本功扎不扎实。
另一个当时很常见的问法是Spring的循环依赖问题:两个Bean互相依赖时,Spring为什么能解决?解决的前提是什么?如果让你用三级缓存的原理解释,你能说清楚吗?这些知识点不光是笔试会考,面试更是必问。
2. 笔试里的三大题型拆解:选择、编程、场景设计
58同城2020校招后端笔试的题型基本可以分成三块:选择题/填空题、编程题、场景设计或简答题。每块的备考策略完全不一样,下面逐个拆。
2.1 选择题/填空题:计算机基础一个都不能少
选择题部分覆盖的范围非常广,基本是把计算机基础课全部扫了一遍。我当时遇到的考点大概有这些:
- 计算机网络:TCP三次握手和四次挥手、HTTP和HTTPS的差异、HTTP状态码含义、TCP和UDP的区别、DNS解析过程、Cookie和Session的区别。
- 操作系统:进程和线程的区别、死锁的四个必要条件、虚拟内存和分页、进程调度算法、用户态和内核态切换。
- 数据库:事务的ACID特性、隔离级别、索引的数据结构(B+树为什么适合做索引)、最左前缀原则、慢查询优化、MVCC机制。
- 数据结构与算法:数组和链表的区别、栈和队列的应用场景、二叉树遍历、哈希冲突的解决办法、排序算法的稳定性和时间复杂度。
- Java基础:面向对象三大特性、String/StringBuilder/StringBuffer区别、HashMap的底层原理(JDK 7和JDK 8的区别)、ArrayList和LinkedList的区别、异常体系、反射、泛型。
这里很多知识点看似基础,但出题方式很灵活。比如不会直接问你“HashMap为什么线程不安全”,而是给你一个并发put的场景,让你判断结果是怎样的。这类题目的陷阱在于:你光知道结论还不够,还得知道结论是怎么推导出来的。
我的建议是,选择题复习一定要配合刷题输入。八股文可以背,但不要死记结论,要把每一个知识点背后的原理链路搞清楚。比如问到“为什么使用B+树而不是红黑树做数据库索引”,不能只回答“因为B+树矮胖、红黑树高”,还要说清楚磁盘I/O和树高的关系:B+树的非叶子节点不存数据,一个节点能存放更多键值,树的高度更低,磁盘I/O次数更少。
2.2 编程题:数据结构与算法是拉开差距的关键
编程题部分,考的核心就是数据结构和算法。58同城2020年校招后端笔试的编程题大概有两道,难度接近LeetCode的Medium,偶尔会有一道偏Easy的送分题,也会有一道偏难的。
常见的出题方向包括:
- 字符串处理:比如找最长回文子串、字符串匹配、括号匹配。
- 数组和链表操作:比如合并两个有序数组、链表反转、删除倒数第N个节点。
- 二叉树相关:比如二叉树层序遍历、最近公共祖先、路径求和。
- 动态规划:比如爬楼梯、最长递增子序列、背包问题。
- 栈和队列:比如用两个栈实现队列、滑动窗口最大值。
- 排序算法应用:比如寻找第K大元素,要求时间复杂度O(n)。
编程题的难度不在于会不会做,而在于你能否在有限时间内写出严谨、可运行的代码。很多同学平时刷题用的是IDE,有自动补全和语法检查,笔试环境通常是一个在线编辑器,有的甚至没有代码补全。这就意味着你必须对常用API非常熟悉,比如Java里HashMap、List、StringBuilder、Arrays.sort的使用方法。
我记得当时编程题里有一道和“区间合并”有关的题:给定一堆区间,把有重叠的区间合并。这个题本身不难,但需要处理边界情况,比如区间完全包含、区间相邻但不重叠、输入为空。如果没考虑周全,很容易通过部分测试用例但又拿不到满分。
这里分享一个编程题的答题技巧:不要急着写代码,先在草稿纸上理清思路,把边界条件列出来,再动手。在线笔试题的评测通常按通过用例数给分,与其纠结最优解,不如先写一个正确但复杂度一般的解法,保证基础分拿到,再考虑优化。
2.3 场景设计题:贴近分类信息业务的实际问题
这类题是58同城笔试里比较有区分度的部分,也是很多同学容易忽略的。场景设计题不会直接考八股,而是给一个业务背景,让你设计方案或写SQL。
一个典型的场景可能是:
某个同城信息平台有一个“帖子搜索”功能,用户输入关键词可以搜索标题和内容,搜索结果需要按发布时间倒序。随着数据量增长,搜索响应变慢,请设计一个优化方案。
这个题目考察的内容包括:数据库索引设计、全文检索方案(引入Elasticsearch)、缓存策略、数据库分库分表、搜索引擎和数据库之间的数据同步方案。你不会做完整的方案没关系,关键是体现出你有系统设计的思维:从单机到集群、从同步到异步、从MySQL到引入搜索引擎,每一步是什么原因。
另一个常见场景题是“帖子浏览量的统计”。用户每次打开帖子详情页,浏览量加1,高峰期会有大量并发更新同一个count字段,怎么设计?
答题思路可以从几个方向展开:
- 用Redis的Incr做计数,异步定期刷回数据库。
- 在应用层合并请求,减少数据库写压力。
- 对热点帖子做本地缓存。
- 用消息队列削峰,异步消费计数消息。
这个题的考点是缓存、异步、削峰填谷,本质上是一个高并发写场景。如果你只看过概念、没有做过相关项目,可能只能答出“用Redis”,但答不出“Redis里怎么存、什么时候刷回MySQL、Redis丢了怎么办”这些细节。
场景设计题最能拉开差距,因为八股文大家都会背,但能不能把知识应用到具体业务里,只有这类题能看出来。刷题和背八股解决不了场景题,需要你是真正理解每个技术的适用边界。
3. Java和Spring考点分析:最容易翻车的几个知识点
如果给58同城后端笔试的考点做个排序,Java和Spring相关的内容占了很大的比重,而且也是很多人容易丢分的地方。这里专门展开讲一下我在准备和考试过程中踩过的坑。
3.1 JVM内存结构、垃圾回收、类加载
JVM相关题目几乎年年必考。考察方式一般是:
- 画出JVM内存结构,说明哪些线程共享、哪些线程私有。
- 讲述类加载过程:加载、验证、准备、解析、初始化。
- 描述垃圾回收算法:标记清除、标记复制、标记整理。
- 说出常见的垃圾回收器:Serial、Parallel、CMS、G1,各自的适用场景。
- 分析一段代码会创建多少个对象、对象在哪个区域分配。
很多人能背出JVM内存结构有哪几块,但问到“哪个区域会抛出OutOfMemoryError”就卡住了。比如栈溢出对应的StackOverflowError,堆内存不够对应OutOfMemoryError,方法区或元空间不够也可能是OOM。这些细节非常琐碎,但笔试就爱考。
我记得有一道题是这样的:
public class GCTest { private static final int _1MB = 1024 * 1024; public static void main(String[] args) { byte[] array1 = new byte[2 * _1MB]; byte[] array2 = new byte[2 * _1MB]; byte[] array3 = new byte[2 * _1MB]; byte[] array4 = new byte[4 * _1MB]; } }如果在JVM参数里设置了-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8,问哪些对象会进入老年代、何时会触发Minor GC。这个题光靠背是答不准的,你得理解新生代Eden区和Survivor区的比例,理解大对象直接进入老年代的规则。
复习建议:JVM不要死记硬背,一定要动手跑一遍。装一个JDK,自己写代码触发StackOverflowError、OutOfMemoryError,用JConsole或者VisualVM观察堆内存变化,用jstat和jmap看GC日志。只要动手做过一次,对这些概念的理解会深刻很多。
3.2 Spring/IoC/AOP与Spring Boot
2020年的笔试,Spring Boot已经很普及,但Spring的核心思想依然是考察重点。常见问题包括:
- 什么是IoC?什么是DI?为什么用IoC能降低耦合?
- Spring Bean的生命周期有哪些步骤?
- Bean的作用域有哪几种?
- Spring怎么解决循环依赖?
- AOP的实现原理是什么?JDK动态代理和CGLIB代理的区别?
- Spring Boot的自动配置原理是什么?
笔试的选择题有时候会直接给一段配置或代码,问你运行结果。比如:
@Service public class OrderService { @Autowired private UserService userService; }如果UserService和OrderService互相注入,启动时会不会报错?会报什么错?为什么?这种题考的就是循环依赖的处理逻辑,如果你不了解Spring的三级缓存机制,看到“循环依赖”就慌了。
这里也给一个理解循环依赖的思路:Spring创建Bean的过程可以简单理解成三步——实例化、属性填充、初始化。循环依赖问题出在第二步:A创建时需要注入B,B创建时需要注入A,双方都在等待对方完成。Spring的解决办法是先暴露A的早期引用,让B能先拿到一个“还没完全初始化好的A”来填充属性。这背后的核心就是三级缓存。
如果你能把这个过程讲清楚,不管笔试还是面试都有很大优势。不要只记结论,要在自己的项目里实际造一个循环依赖出来,看看Spring启动日志怎么提示,印象才会深。
3.3 并发编程:从线程安全到线程池参数
并发编程是后端笔试中比较硬核的部分,也是实际工作中天天要面对的问题。考点集中在:
- synchronized和ReentrantLock的区别。
- volatile关键字的作用,为什么不能保证原子性。
- ThreadLocal的原理和使用注意事项。
- ConcurrentHashMap的实现原理,JDK 7和JDK 8的区别。
- 线程池的核心参数,ThreadPoolExecutor的拒绝策略。
- 什么是CAS、什么是ABA问题。
- 死锁的排查和预防。
线程池参数这个问题,我在很多同学的简历上看到过,但能答全的人不多。核心参数有七个:核心线程数、最大线程数、空闲线程存活时间、时间单位、任务队列、线程工厂、拒绝策略。笔试常考的是:核心线程数怎么设置?任务队列满了之后会发生什么?拒绝策略有哪几种?
我的理解是:核心线程数不是拍脑袋定的,要分场景。CPU密集型任务,核心线程数一般设置为CPU核数+1;IO密集型任务,可以设置成CPU核数*2左右,或者用公式CPU核心数 / (1 - 阻塞系数)。但这些只是经验值,笔试里只要你把逻辑讲清楚,不一定非要算出一个绝对正确的数。
并发编程的复习不能只看理论。我建议自己用代码验证:写一个多线程累加的例子,看volatile为什么不能保证原子性;分别用synchronized、ReentrantLock、AtomicInteger实现计数器,对比性能;模拟一个线程池队列满的场景,观察拒绝策略的执行效果。只有真正跑出问题,才会对并发有敬畏。
4. 实战应对策略:从答题顺序到代码规范
考试不只是考知识,也考策略。我在做过大量笔试之后,总结了一套比较实用的做题节奏,这里分享给你。
4.1 先易后难还是先分后总:我的实战节奏
我的习惯是拿到卷子先用两分钟把所有题目浏览一遍,分清哪些是送分题、哪些是中等题、哪些是难题。先把送分题拿下,再做中等题,最后腾出剩余时间去抠难题。永远不要在选择题上死磕一道题超过3分钟。
后端笔试题量大,很多同学最后编程题做不完,不是因为不会,而是因为前面浪费了太多时间。我会给自己定一个时间预算:选择题和填空题尽量控制在25分钟内,编程题每题留20-30分钟,场景设计题留15分钟。如果选择题遇到完全没思路的,果断先选一个最可能的答案并标记,等所有题做完再回头思考。
还有一个很重要的点:在线笔试系统一般允许你在本地IDE写代码,但最终要粘贴到网页上。建议编程题直接在本地IDE里写,写完复制过去,这样可以借助本地环境的编译调试能力。如果你在网页编辑器上直接写,语法错误靠肉眼找会非常费时间。
4.2 算法题写不出最优解时,如何稳拿分
遇到算法题没有思路,最忌讳的是直接放弃。即使写不出最优解,也要尽量写暴力解法拿部分分。部分在线笔试平台是按通过的测试用例比例给分的,一个暴力解法如果能通过60%的用例,也比交白卷强很多。
具体操作上,我一般按这个优先级推进:
- 先做复杂度的估算,判断暴力解法会不会超时。
- 超时也要写,先保证输入输出逻辑正确,拿到基础分。
- 再看看数据范围,如果
n很小,暴力解法完全可行。 - 如果时间允许,再想优化,比如用双指针代替双重循环、用哈希表减少查找时间、用前缀和减少重复计算。
编程题还有一个容易忽略的细节:输入输出格式。很多同学算法思路正确,但读入的时候用了Scanner的nextInt()而没有处理换行,或者输出格式多了个空格,导致答案判错。考试前一定要熟悉目标笔试平台对输入输出的要求,尤其要会处理多行输入和不定长输入。
4.3 用编辑器做题时容易被忽视的细节
笔试环境一般不会像本地IDE那么智能,有些平台甚至不能粘贴、不能切屏。我建议考前就适应在纯网页编辑器中写代码的感觉。
几个常见的坑:
- Java类名不能带
public以外的类修饰符,有些平台要求主类名是Main,但有时候又无所谓。建议提前看考试说明。 - 不要用
package语句,在线判题不接受。 - 注意不要引入编译用不到的依赖,有些平台的JDK版本旧,不支持的API用了会直接编译失败。
- 代码里的注释不要写太多,不是加分项,反而容易因为特殊字符出现问题。
- 如果题目要求输出到标准输出,就用
System.out.println,不要自己拼接文件路径。
除了这些,还有一个心态层面的建议:笔试页面一般有倒计时,看到时间只剩5分钟但还有题没做完时,很容易慌。我自己的做法是把必拿分保住,即使最后的题只写了个思路也要把答案填上去。有些平台会对文字性答案给分,能写思路就写思路,不要留空。
5. 复盘之后我重新梳理的后端知识体系
考完试之后,我专门花了一周时间复盘,把这次笔试暴露出来的知识薄弱点整理成了一份清单。后来秋招面试的时候,这份清单帮了我很大的忙。这部分是我觉得整篇内容里最有长期价值的东西。
5.1 基础层:计算机基础是决定上限的底盘
后端开发越往上走,越会发现计算机基础的重要性。操作系统、计算机网络、数据库原理,这三门课不是笔试之前突击一下就能真正掌握的,需要长期积累。
比如这次58同城笔试里对网络协议的考察,不只是背状态码,而是会给出一个实际访问慢的场景,让你分析可能的原因。你如果不懂TCP拥塞控制、不懂HTTP keep-alive、不懂DNS缓存,很难定位问题。
操作系统相关的题目也是类似。考过进程调度、内存分页、文件系统的理解,这些知识在实际工作中体现在线程池参数设计、内存优化、排查CPU飙升问题上。没有操作系统的基础,很多线上问题你只能靠经验瞎猜,而有基础的人能做到看到现象就知道原因大概在哪里。
数据库原理更是后端的核心。事务隔离级别、索引失效场景、SQL优化,这些不是面试题里的“标准答案”,而是你设计表结构、写SQL、排查慢查询时真正要用的东西。
5.2 应用层:从Spring到微服务再到中间件
应用层技术栈是后端笔试的重头戏,但从笔试之后的长远角度看,它也是你进入公司后立刻要用的东西。
Java后端的技术栈至少应该覆盖:
- Spring框架核心:IoC、AOP、Spring MVC的请求处理流程。
- Spring Boot:自动配置原理、启动流程、常用的Starters。
- ORM框架:MyBatis和MyBatis-Plus,了解LazyLoading、一级缓存、二级缓存。
- 数据库:MySQL的使用和优化,索引、事务、锁、日志。
- 缓存:Redis的数据类型、持久化、过期策略、分布式锁、缓存一致性。
- 消息队列:至少掌握一个,了解消息丢失、重复消费、顺序消息的解决方案。
- 微服务相关:服务注册与发现、负载均衡、配置中心、网关、熔断降级。
这些知识点之间不是孤立的。比如你学了Redis,要能回答“缓存和数据库的一致性问题怎么解决”对应的场景;你学了消息队列,要能回答“头条信息流系统怎么保证延迟很低”这种业务题。
5.3 实战层:用项目把知识真正串起来
只刷八股和只刷算法题,都不足以支撑你通过后端笔试和面试。真正让你和其他候选人拉开差距的,是你有没有亲手做过完整的后端项目。
我当时准备秋招时,做了一个带用户认证、发帖、评论、点赞、私信功能的社区类后端项目。技术栈就是Spring Boot + MyBatis + MySQL + Redis + Kafka。项目不算复杂,但做完之后很多笔试和面试的知识点都有了落地的印象。
比如在项目里实现用户登录时,我用Redis存Session,顺手就理解了分布式Session和单机Session的区别;给帖子设计热榜时,用到了Redis的ZSet存储分数;点赞功能用到了Redis的Set去重;关注用户后发私信时,用到了Kafka做异步解耦。
这些经历在笔试场景题里特别有帮助。比如考试时遇到“如何实现一个关注通知功能”,我脑海里已经有完整的方案轮廓,而不是靠临场编。
我的建议是:项目不需要多,一到两个完整的、有深度的项目就够。关键是每个技术组件都要搞清楚“为什么选择它,而不是另一个”。
6. 给后来人的备考安排和资源建议
这部分是写给还没参加校招的同学的。如果你看到这篇文章时已经不是2020届了,也不用灰心,这些备考思路照样适用,因为后端笔试的底层逻辑变化不大。
6.1 从大三下学期到秋招的备考节奏
秋招的战线拉得很长,每年7、8月就开始提前批,9、10月是正式批。如果你是大三下学期开始准备,时间相对充裕,可以按下面这个节奏推进:
- 3月到5月:把计算机网络、操作系统、数据库原理三门核心课过一遍,结合教材和网课,尽量做到理解而不是死记。
- 5月到7月:系统刷一遍Java基础和Spring,动手做一个小项目,同时开始刷LeetCode,按Tag分类刷。
- 7月到8月:提前批开始,做真题、做模拟卷,补充中间件相关知识,复盘每场笔试的错题。
- 8月到10月:正式批高峰期,稳定输出,保持刷题手感,每次笔试后及时复盘。
重点提醒一下:不要把所有的前期时间都花在算法上,后端笔试不是只有算法。数据库、网络、操作系统、Java并发、JVM、Spring,每样都要投入时间。我见过很多同学算法刷得很好,但一到选择题就大量丢分,非常可惜。
刷题的时候,LeetCode建议按专题刷,不要随机刷。把数组、链表、哈希表、字符串、双指针、栈与队列、二叉树、回溯、动态规划、贪心、二分查找这些专题各刷20道左右,基本能覆盖大部分笔试算法题。
6.2 我实际用过的复习资料
资料不是越多越好,关键是吃透。我当年用过的、真正觉得有帮助的,这里列一个精简清单:
- 《Java核心技术卷Ⅰ》:Java基础查漏补缺必读。
- 《深入理解Java虚拟机(第3版)》:JVM部分看这一本就够了。
- 《计算机网络:自顶向下方法》:网络基础首推,配合抓包工具理解更佳。
- 《数据库系统概念》:数据库理论部分,配合实际SQL练习。
- 《MySQL技术内幕:InnoDB存储引擎》:MySQL底层原理。
- 《Redis设计与实现》:Redis数据结构、持久化、集群原理讲得透彻。
- 《Java并发编程的艺术》:并发部分重点看。
- LeetCode高频题单:可以按Top 100列表刷,也可以按Tag刷。
- 牛客网历年笔试真题:这个一定要刷,能帮助熟悉不同公司出题风格。
除了这些书,我觉得最有价值的复习方式是:每学完一个知识点,就尝试用自己的话写成一篇几百字的笔记,并且在本地写一段代码验证。比如学了ThreadLocal之后,自己写一个ThreadLocal的使用案例,再分析它的内存泄漏问题。这种主动输出的方式,比单纯看书记得牢得多。
6.3 笔试翻车不等于全盘皆输
最后想聊聊心态。校招笔试的结果有时候很玄学,跟那套题适不适合你发挥有很大关系。我自己也经历过拿到一套题,感觉每个知识点都见过、但每个选项都不确定的情况。这种时候不用否定自己,说明复习方向可能有些偏移,把错题整理好,下一套卷子就会有明显进步。
记住一个事实:笔试只是整个校招流程里的第一环,后面还有面试、手撕代码、HR面。笔试成绩一般不会单独决定生死,很多公司只要笔试通过线以上,后续还是看面试表现。所以就算今天这套题做得稀烂,也不代表你不行,只代表你还有知识盲区需要补齐。
我的习惯是每场笔试后做一个简单的错题复盘,记录三件事:哪些题是因为知识盲区错、哪些题是因为时间不够没做、哪些题是粗心大意丢分。这个复盘看起来简单,但对后续备考方向的调整非常有帮助。拿58同城2020这张卷子来说,我复盘后最大的收获就是:场景设计题不能靠背,必须真的理解技术组件之间的配合关系,如果你的知识体系里每个组件都是独立的知识岛,遇到综合性问题就会明显吃力。
希望这篇拆解能帮你少走一些弯路。后端这条路很长,笔试只是起点,保持扎实、持续积累,机会总会来的。