前阵子整理电脑里的旧笔记,翻到当年参加网易2020校招笔试 Java 开发工程师(提前批)时的记录,很多细节还挺值得拿出来聊聊。那场笔试给我的感觉是:考察面很宽,算法题不算变态,但 Java 基础和工程细节挖得深,稍不注意就会在选择题里翻车。趁着热词里全是"Java 面试八股文""Java 基础""排序算法"这些关键词,我干脆把这套笔试题型的拆解、考点复盘、还有备考时踩过的坑一次性写完整。不管你是正在准备校招的应届生,还是想系统梳理 Java 知识点的同学,这份内容应该都能帮你省不少时间。
1. 笔试整体情况与考点分布
1.1 网易校招提前批笔试的定位
网易的校招提前批一般安排在每年的七八月,比正式批早一两个月,目的很明确:提前锁定一批基础扎实、工程能力强的候选人。我参加的那场 Java 开发工程师(提前批)笔试,是在牛客网一类的在线测评系统上完成的,全程摄像头监控,题型分选择、编程、问答三大块,考试时间大概是 120 分钟。时间看上去够用,但如果你对某个知识点不够熟,很容易在一道选择题上磨掉好几分钟,最后留给编程题的时间就不太够了。
这场笔试本质上是"基础能力筛选器"。它不会像正式批面试那样深挖项目,但会把 Java 语法、集合框架、JVM、并发、算法、网络、数据库这些基本功拎出来反复考。网易的技术面试向来比较务实,笔试阶段淘汰率很高,所以千万不能抱着"过了就行"的心态去裸考。提前批的笔试成绩往往会和后面的面试挂勾,如果笔试排名靠前,面试官在后续环节也会对你多一分认可。
1.2 题型结构与 Java 考点权重
我回忆了一下,当时这套题大概包含 20 道左右单选题、5 道左右多选题,外加 2 道编程题,个别批次还会有 1 道系统设计或者场景问答题。单选题覆盖面很广,Java 基础、集合、并发、JVM、网络、数据库都会涉及;多选题则更考验概念边界,比如"以下哪些集合是线程安全的"这种题,只要你对 synchronized 的实现细节理解不够准确,很容易多选或者漏选。
这里我整理了一个考点权重表,不是官方数据,而是根据我和一起参加笔试的同学复盘后得出的相对比例,供参考:
| 考点方向 | 大致占比 | 常见出题形式 |
|---|---|---|
| 数据结构与算法 | 30% | 编程题 + 选择题 |
| Java 核心基础 | 20% | 选择题 + 多选题 |
| JVM 与并发编程 | 15% | 选择题 + 多选题 |
| 计算机网络 | 10% | 选择题 |
| 操作系统 | 5% | 选择题 |
| 数据库 | 10% | 选择题 + 问答题 |
| 工程场景与设计 | 10% | 问答题 + 扩展题 |
从这张表能看出来,算法和 Java 基础加起来占了半壁江山,这跟校招生的能力模型是匹配的:你还没进入公司,面试官不清楚你会不会写业务代码,只能先通过算法题确认你的逻辑思维,再通过 Java 基础题确认你的语言功底。
1.3 这场笔试考的是哪些底层能力
很多人以为校招笔试就是刷 LeetCode,其实不完全对。网易的笔试题里,算法题往往不难,但很在意边界条件和代码规范。比如让我印象很深的一道题:手写一个单例模式,要求支持懒加载且线程安全。这道题表面考设计模式,实际考的是 volatile 的可见性和禁止指令重排、synchronized 的锁粒度、以及静态内部类方式的实现原理。你光会背"双重检查锁"没用,还得解释清楚为什么不能只加 volatile 或者只用 synchronized。
除了语言能力,笔试还隐含地考了你的"排查能力"。比如热词里反复出现的 Java 环境变量配置、VSCode 运行 Java 报错乱码、Lombok 报错"you aren't using a compiler supported by lombok"这些问题,虽然笔试不直接考,但如果你连本地环境都搭不明白,在线编程环节就会被编译环境折腾得够呛。我当年有一个同学就是因为 JDK 版本和编译器版本不匹配,编程题本地运行没问题,一提交到在线平台就编译失败,这种教训太伤了。
2. Java 核心考点拆解:从基础到“八股文”
2.1 面向对象、集合框架、泛型与枚举
面向对象是 Java 的地基,笔试里几乎必考。常见的有:接口和抽象类的区别、重载和重写的区别、静态方法和实例方法的区别。这些概念看起来基础,但出题人很喜欢挖细节。比如"接口中的默认方法可以被实现类重写吗",很多人会想当然地说不可以,实际上 Java 8 之后默认方法是完全可以被重写的,而且还有一套复杂的冲突解决规则。再比如"抽象类能不能有构造方法",答案是可以,抽象类的构造方法是在子类实例化时被调用的,用来初始化父类成员变量。
集合框架更是高频考点。ArrayList 和 LinkedList 的区别不用说了,关键是底层原理:ArrayList 扩容时机和扩容倍数、LinkedList 为什么在随机访问时慢。HashMap 的考点最多:数组加链表加红黑树的结构、默认负载因子为什么是 0.75、put 流程、resize 流程、hash 扰动函数、为什么线程不安全。ConcurrentHashMap 也是常客,Java 7 是分段锁,Java 8 是 CAS 加 synchronized 锁头节点,这些要能讲清楚。fail-fast 机制也可以考,比如在遍历 ArrayList 时调用 remove 方法为什么会抛 ConcurrentModificationException。
泛型和枚举在笔试中属于中等难度考点。泛型考擦除机制,比如"List<String> 和 List<Integer> 在运行时是同一个 Class 吗",答案是肯定的。枚举考的是底层实现,Java 枚举本质上是继承自 java.lang.Enum 的普通类,所以枚举可以有构造方法、成员变量、抽象方法。让我印象最深的一道题是"用枚举实现单例为什么是线程安全的",答案不是因为枚举关键字本身有魔法,而是枚举的构造器是被 JVM 保证只实例化一次的。
2.2 JVM、并发与内存问题
JVM 这块的考点比较固定:内存区域划分、对象创建过程、垃圾回收算法、类加载机制、OOM 类型。选择题常见的是"以下哪个区域不会发生 OutOfMemoryError",直接考你哪个区域是不受内存溢出影响的。程序计数器是唯一不会 OOM 的区域,这个知识点能筛掉一批人。
热词里有一条是"java: outofmemoryerror: insufficient memory",这是我在实际项目里踩过的坑。当时用 Java 写了一个批量处理任务,一次性把几百万条数据读进内存,结果 JVM 直接抛 OutOfMemoryError。后来排查发现就是没有分批处理,也没有控制好集合里的引用。这类问题在校招笔试中会以场景题出现,比如"线上系统频繁 Full GC,你如何排查"。标准思路是先用 jps 找到进程,再用 jstat 看 GC 情况,接着用 jmap 导出堆快照,最后用 MAT 或 VisualVM 分析大对象。这些排查思路不能只会背,要真的在本地搭建过一个出问题的 demo。
并发这块,synchronized 和 ReentrantLock 的对比是经典题。volatile 的可见性和禁止指令重排要讲清楚,尤其是"volatile 不能保证原子性"这句话,很多面试官会在选择题里偷换概念。线程池的七个参数、拒绝策略、执行流程也常考,特别是"提交一个任务后,线程池的执行顺序是什么"。我来写一个标准的线程池创建示例,这是笔试手写题里很常见的考查点:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // 核心线程数 5, // 最大线程数 60L, TimeUnit.SECONDS, // 空闲线程存活时间 new ArrayBlockingQueue<>(10), // 任务队列 Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() // 拒绝策略 );需要注意的是,阿里巴巴开发规范不建议使用 Executors 提供的静态方法创建线程池,因为默认的队列可能是无界的,容易导致 OOM。笔试如果问"为什么不用 Executors.newFixedThreadPool",你要能回答出这点。
2.3 Java 8+ 新特性:Lambda、Stream、Optional
热词里有 lambda 函数 Java,还有"java8"。Java 8 的新特性在 2020 年的校招笔试中已经算基础考点,现在更是必问。Lambda 表达式本质上是函数式接口的实例,这个概念要抓住。它会考你"以下哪个接口是函数式接口",Function、Predicate、Consumer、Supplier这几个要能分清楚,Runnable和Callable也属于函数式接口。
Stream 的考点集中在中间操作和终端操作。中间操作是惰性的,只有终端操作执行时才会真正遍历数据。比如filter、map、distinct是中间操作,collect、forEach、reduce是终端操作。笔试中可能会让你写出stream().filter(...).collect(Collectors.toList())的执行结果,或者判断这段代码的时间复杂度。其实 Stream 内部对多次中间操作做了合并优化,所以不要单纯以为每个操作都会产生一次完整遍历。
Optional 的考点是"怎么避免 NullPointerException"。不过我想提醒一句,Java 8 之后虽然有了 Optional,但用不好会写出更难受的代码。比如在字段类型上直接声明Optional<String>就是不推荐的,因为 Optional 本身没有实现序列化接口,而且会让 API 的语义变得更复杂。笔试中更可能考的是orElse和orElseGet的区别:orElse不管是否为空都会执行传入的表达式,orElseGet是只有为空才执行。这是一个经典陷阱。
2.4 异常处理与常见坑
异常在 Java 基础题里的出现频率很高,但很多同学对异常体系的理解只停留在"try-catch-finally"上。笔试爱考的是:Error和Exception的区别、受检异常和非受检异常的区别、finally块中的 return 和 catch 中的 return 谁先执行。如果你在finally里写了 return,它会覆盖 catch 里的返回值,这个行为很容易被忽略。
还有一个高频考点是 try-with-resources 语法。它要求在 try 括号中声明的资源必须实现AutoCloseable接口,并且在 try 块结束后自动关闭资源。这个机制的底层其实是编译器帮你生成了 finally 块和 addSuppressed 逻辑。笔试中可能会问"如果 try 块和 close 方法都抛了异常,最终抛哪个",答案是 close 方法的异常会被抑制,最终抛出 try 块中的异常,同时可以通过getSuppressed()获取被抑制的异常。
我见过很多人在处理异常时直接 catch 住整个 Exception 然后打印堆栈,这种做法在笔试中不算最优解。面试官想看的是你能区分哪些异常需要向上抛出,哪些需要降级处理。比如在批量任务里,某一条数据解析失败,你是应该中断整个任务还是把这条数据单独记录下来继续跑?正确做法是记录错误后继续处理其他数据,这样才能保证系统的可用性和数据完整性。
3. 算法与编程题实战:手写代码是重头戏
3.1 排序算法高频考点:冒泡排序与快速排序
编程题里排序算法几乎是必考的,尤其是冒泡排序和快速排序。热词里也出现了"冒泡排序java""快速排序java实现",说明大家搜索这些题目的频率很高。冒泡排序虽然时间复杂度是 O(n²),但它作为一种经典排序,经常被用来考察基本的数组操作和循环逻辑。很多同学能背出代码,但一被问到"第几轮排序后数组是什么状态"就懵了,所以理解每一轮冒泡的效果非常重要。
我贴一个标准冒泡排序实现:
public static void bubbleSort(int[] arr) { if (arr == null || arr.length <= 1) { return; } int n = arr.length; for (int i = 0; i < n - 1; i++) { // 用一个标志位做优化,如果某一轮没有发生交换,说明已经有序 boolean swapped = false; for (int j = 0; j < n - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; swapped = true; } } if (!swapped) { break; } } }快速排序是笔试编程题的常客,但很多人会卡在 partition 部分的边界条件上。我建议大家不要死记模板,而是先理解它的核心:每轮选一个基准值,通过 partition 把小于基准值的放左边,大于基准值的放右边,然后递归处理左右两边。最经典的写法是挖坑法,取第一个元素为基准值,从右往左找小于基准值的元素填坑,再从左往右找大于基准值的元素填坑。这个过程中要特别注意数组下标不能越界,循环里要时刻判断left < right。
快速排序的平均时间复杂度是 O(n log n),但最坏情况下会退化到 O(n²),比如数组本身已经有序且每次都选最左边的元素作为基准。笔试如果问"如何避免最坏情况",你可以回答随机选择基准值或者三数取中法。我建议在练习时把这两种 partition 方式都写一遍:Hoare 版和 Lomuto 版,因为面试官可能会让你手撕一个快排,然后追问 partition 返回的下标含义。
3.2 字符串、数组、链表常见题型思路
除了排序,编程题还会考字符串处理、数组操作、链表反转这些基本功。字符串题里常见的有:判断回文串、最长公共前缀、字符串中第一个不重复的字符、括号匹配。这些题看似简单,但要注意 Unicode 字符的处理,比如 emoji 是代理对,不能简单按 char 遍历。数组题高频的有:两数之和、三数之和、合并两个有序数组、找数组中的重复元素。
链表题在笔试题里可能会以"手写链表反转"出现,循环方式和递归方式都要会。循环方式用三个指针 pre、cur、next 互相配合,递归方式要理解"把下一个节点反转后指向当前节点"这一层关系。如果你在笔试现场遇到了链表题,但数据输入是用数组模拟的,也别慌,把下标当作指针来处理就行。
这里我给出一个比较实用的笔试实战策略:拿到题目先用注释写出思路,再动笔写代码,这样如果中间卡住,编译器或者阅卷人也能看到你的思路。同时要先把边界条件写清楚:数组为空、只有一个元素、元素重复、数值溢出、负数参与运算等情况都要在代码中处理掉。很多同学的提交只是没通过极端用例,不是算法本身错了,而是边界没考虑。
3.3 笔试中的时间复杂度和边界条件
笔试编程题的判题系统对时间复杂度很敏感,如果数据范围是10^5而你写了一个 O(n²) 的算法,大概率会超时。所以拿到题先看数据规模:如果 n 小于 100,O(n²) 可以接受;如果 n 到 10^5 级别,就要考虑 O(n log n) 甚至 O(n) 的解法。热词里提到的 Top K 问题、堆排序、快速选择、二分查找,都属于这个范畴。
边界条件是笔试中最大的失分点。我举一个例子:实现一个函数,把字符串转换成整数。这题看起来简单,但需要考虑空字符串、正负号、前导空格、溢出、非法字符。LeetCode 上的剑指 Offer 67 题就是这个考点。另一个例子是二分查找,很多人写的时候没有处理left + right溢出,或者没有想清楚 while 循环是left < right还是left <= right。这些细节都是阅卷时会重点看的。
边界条件写得好不好,反映的是一个人对异常输入的敏感度。笔试中,哪怕代码风格一般,只要边界判断完整,通过率就会高很多。我个人的习惯是每写完一个函数,都花 10 秒钟在脑子里跑三个用例:空输入、单元素输入、全同一元素的输入,这样能拦住大部分隐藏 bug。
4. 数据库、网络与分布式基础
4.1 MySQL 索引与事务
数据库考点里,索引和事务是绝对的高频。索引这块,最常问的是"为什么 MySQL 的 InnoDB 引擎用 B+ 树而不是红黑树或 B 树"。答案要从磁盘 IO 出发:B+ 树的非叶子节点不存储数据,单个磁盘页能容纳更多索引项,树直接变矮,IO 次数减少;同时叶子节点之间通过链表相连,范围查询更高效。这个知识点不能只会背结论,要能画出示意图并讲清楚树高和 IO 次数之间的关系。
事务这块,ACID 的特性要能定义清楚,但更重要的是隔离级别和锁机制。MySQL 默认的隔离级别是 Repeatable Read,InnoDB 通过 MVCC 实现快照读,通过当前读加锁实现写操作。间隙锁和临键锁在 RR 隔离级别下可以解决幻读问题。笔试选择题可能会给你一个并发场景,让你判断在每个隔离级别下会不会出现脏读、不可重复读或幻读。我把这几个级别整理成一张表:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read Uncommitted | 可能 | 可能 | 可能 |
| Read Committed | 不会 | 可能 | 可能 |
| Repeatable Read | 不会 | 不会 | InnoDB 下基本不会 |
| Serializable | 不会 | 不会 | 不会 |
4.2 HTTP 与 TCP:校招笔试题的常客
网络协议在 Java 笔试中占比虽然不算高,但每年都会考。TCP 三次握手和四次挥手是选择题常客,要能说出每次握手时客户端和服务端的状态变化(SYN_SENT、SYN_RCVD、ESTABLISHED、FIN_WAIT_1、CLOSE_WAIT、TIME_WAIT)。尤其是 TIME_WAIT 状态,为什么主动关闭方要进入 TIME_WAIT 并等待 2MSL?一是为了保证最后一个 ACK 能被对方收到,二是为了让旧连接中的报文在网络中自然消失,避免端口复用带来的数据混淆。
另外,HTTP 的考点集中在状态码、GET 与 POST 的区别、HTTP 无状态、HTTPS 的握手流程。状态码至少要知道 200、301、302、400、401、403、404、500、502、503 分别表示什么。HTTPS 则是 TLS 握手过程,校招笔试通常只考到"对称加密和非对称加密如何配合"这个层面。如果你是 Java 方向,还可以顺带提一下 Java 中的 HttpsURLConnection 和 HttpClient 怎么处理证书校验问题,但笔试中一般不会深挖到代码级别。
4.3 分布式场景:缓存、消息队列、接口幂等
网易这种体量的公司,笔试里出现分布式相关场景题太正常了。常见问法有:缓存穿透、缓存击穿、缓存雪崩的区别和解决方案;分布式锁怎么实现;接口怎么做幂等;消息队列怎么保证消息不丢失和不重复消费。这些题没有标准答案,但面试官会看你能不能把方案完整地讲出来,包括边界情况和代价。
分布式锁常见的三种实现:数据库唯一索引、Redis SET NX、ZooKeeper 临时顺序节点。笔试如果让你选型,要能说清楚各自优缺点。Redis 锁需要注意锁过期时间、原子性(高版本用 Lua 脚本)、和 RedLock 是否存在问题。消息队列这块,Kafka 的 at-least-once、exactly-once 语义会被考到,RocketMQ 的事务消息也值得了解。幂等设计最简单的做法是业务单据加唯一索引,或者用状态机判断当前状态能否流转,不要一上来就引入分布式组件。
这里还要提一个热词出现的场景:ES 异步写入 Java。实际业务中,数据写入 MySQL 后,为了检索方便,经常需要异步写入 Elasticsearch。笔试题可能会问"MySQL 和 ES 数据一致性问题怎么解决",答案往往是"先更新 MySQL,再通过消息队列异步写入 ES,消费端做幂等处理"。这个思路既考了本地消息表、事务消息,也考了柔性事务和最终一致性,是很典型的工程设计题。
5. 工程化与真实项目经验:笔试之外的加分项
5.1 Spring Boot 接口设计与安全对接
网易的笔试很少直接考 Spring Boot 注解,但如果你在简历里写了 Spring Boot 项目,进入面试环节后这些就会变成必问项。热词里有一条"java springboot apikey 安全对接",这正好是很多实习项目里会遇到的场景:第三方系统调用你的接口时,你不能什么都不验证就放行,至少要做 ApiKey 和 Secret 签名校验。
一个常见的做法是:调用方使用 ApiKey 标识自己,用 Secret 对请求参数和时间戳做 HMAC 签名,服务端根据 ApiKey 找到对应的 Secret,重新计算签名并比较。为了防重放攻击,还要校验时间戳是否在 5 分钟内。签名算法一般用 HmacSHA256,Java 的Mac类可以直接支持。我建议在校招准备阶段,用 Spring Boot 写一个简单的接口签名 demo,既能加深理解,面试时又能拿得出手,比背一堆概念有用得多。
接口幂等也是项目里的硬需求。比如订单支付回调,网络波动可能导致回调重复推送。设计时可以在接口入口用 Redis SETNX 或者数据库唯一索引做防重,关键的写操作加上 update 条件判断,比如UPDATE order SET status = 'paid' WHERE id = ? AND status = 'unpaid',这样即使重复请求也不会把数据改坏。
5.2 异步写入与 Elasticsearch 场景
热词里的"es异步写入java"其实是一个很具体的业务场景问题。ES 本身不擅长高频实时写入,尤其是大规模的全文检索业务,如果每来一条数据都同步调用 ES 接口,系统压力会很大,而且 ES 写入失败还会拖慢主链路。更合理的方案是:业务数据先落到 MySQL,把需要同步到 ES 的事件丢进消息队列,由消费端异步写入 ES。
这个设计里有几个坑值得注意。第一,消费端要把消息设计成可重试的,否则 ES 临时不可用时消息就丢了;第二,消息体中不要只带一个数据库 ID,然后消费端再查库,如果库里数据已经被修改,就会漏掉中间版本,所以最好带完整的文档内容;第三,要对 ES 写入失败做重试和告警,并保证最终一致性。笔试时间有限,不要求你现场写全代码,但你能想到异步、MQ、幂等、重试这几个关键词,就已经高出很多人了。
另外,近年从热词里看到"Milvus"、"langchain4j"这些关键词,说明 Java 技术栈也在往向量数据库和 LLM 应用的方向走。如果你有精力,可以在项目里尝试用 langchain4j 接一个 Milvus 做向量检索 demo,对校招来说是一个很亮眼的加分项。不过要时刻记住,笔试和面试的核心还是基础,项目只是基础之上的延伸。
5.3 环境配置与常见报错的排查能力
别看环境配置不是笔试内容,但很多同学在线笔试时直接栽在了本地编译环境上。热词里"java环境变量配置""vscode运行java报错乱码""java: 警告: 源发行版 17 需要目标发行版 17""lombok will not work"这些都是真实高频问题。我强烈建议在校招季到来之前,把 JDK、Maven、IDE 全部配好,并确保java -version和javac -version输出的版本一致。
VSCode 运行 Java 报乱码,多半是因为默认编码不是 UTF-8,Windows 下可以把file.encoding设为 UTF-8,或者在settings.json里加一行"java.debug.settings.consoleEncoding": "UTF-8"。源发行版 17 需要目标发行版 17 这个警告,通常是因为 pom.xml 里没有指定统一的 maven.compiler.source 和 target,或者 IDE 的 Java 编译器级别设置和项目 JDK 不一致。Lombok 报错则往往是 IDEA 或 VSCode 里的 annotation processing 没有开启,或者 Lombok 版本和 JDK 版本不兼容。
在线笔试平台通常用的是自己的编译器,很多本地特性不一定支持。我给你的建议是:平时练习时就用标准 JDK 编译,不要依赖 IDE 的辅助功能;写 Java 文件时不要用 package 声明,除非试题明确要求,否则提交到在线平台很容易编译失败。
6. 备考路线与常见问题排查
6.1 三个月备考计划
如果你的目标是网易这种级别的互联网公司,我建议把备考分成三个阶段。第一个月主攻知识和算法基础,把 Java 集合、JVM、并发、数据库、网络过一遍,同时每天刷 2 到 3 道 LeetCode 简单题,保持手感。第二个月强化练习,LeetCode 刷到中等难度,按标签刷题,比如数组、链表、树、动态规划;同时把 Java 核心知识整理成自己的"八股文",不是背别人的,而是用自己的话把每个知识点写成小短文。
第三个月就是冲刺模拟阶段。找牛客网或者公司往年真题做限时训练,模拟真实笔试的紧张感。这个阶段要做三件事:控制做题节奏、总结错题、补齐薄弱环节。我当年就是在这个阶段把 HashMap、ConcurrentHashMap 的原理从头到尾看了三遍,才敢说在选择题里不会翻车。另外,强烈建议抽出一些时间练手写代码,不要在 IDE 里写完贴过去,而是直接在记事本或者在线编辑器里打出来,因为笔试平台没有自动补全和语法提示。
6.2 笔试过程中的答题策略
拿到笔试卷子后,我建议先花 3 分钟通读一遍,了解题目数量和大致难度,再决定答题顺序。编程题如果第一题比较简单,可以先做,确保拿分;如果某道选择题卡住超过 2 分钟,就标记一下先跳过,不要浪费后面的时间。在线笔试一般支持题目切换,但要注意部分平台可能限制跳题,所以提前熟悉牛客网的答题界面很重要。
做编程题时,先读清楚输入输出格式,尤其是多组测试用例的情况,很多同学不是不会算法,而是没搞明白输入格式导致整个程序读了个寂寞。如果题目有时间限制,可以用BufferedReader替代Scanner来提升 IO 效率;如果内存限制比较严格,避免用大数组。代码写完以后,哪怕没有跑测试用例,也可以在脑海里自动演算一遍边界输入,比如空字符串、0、负数、数据量最大值。
6.3 手撕代码的常见失分点
我把这几年看别人刷题以及自己参加笔试时最容易丢分的点整理成了一份速查表,希望对你有用:
| 失分点 | 表现 | 正确做法 |
|---|---|---|
| 没有处理空指针 | 直接对数组或字符串调用方法 | 在入口处判空 |
| 循环边界写错 | for 循环多跑一次或少跑一次 | 用具体小例子代入验证 |
| 没有考虑整数溢出 | 两数相加超过 int 范围 | 提前把值转换为 long 或使用安全写法 |
| 没有考虑重复元素 | 去重或计数时统计错误 | 在草稿纸上列出重复用例 |
| 递归没写终止条件 | 栈溢出或死循环 | 先写 base case 再写递归逻辑 |
| 输入输出不匹配 | 题目要求多行输出却只输出一个 | 仔细读题,按样例格式输出 |
| 没有考虑性能 | 数据量大时 O(n²) 超时 | 先分析复杂度再选算法 |
| 依赖 IDE 补全 | 手写代码时写错方法签名 | 平时多练习手写常用 API |
6.4 复盘记录:一道典型的场景设计题
最后再分享一道当年笔试里让我印象深刻的场景题,题目大意是:设计一个短链接生成系统,要求支持高并发访问,能够统计每个短链接的点击次数。这种题核心在几个点:发号器怎么设计、短链接如何存储、重定向用 301 还是 302、点击次数如何异步统计。发号器可以用 Redis INCR 或者数据库自增 ID 再转 62 进制;存储用 MySQL 或者 Redis 缓存热点链接;点击统计不能同步写数据库,而是放到消息队列里异步更新。
答案的开放性很强,但考官想看的其实就是"你有没有完整系统设计的意识"。我会先在纸上画出链路:用户提交原始 URL,服务生成短码并写入数据库,返回短链接;用户访问短链接,服务端查库找到原始 URL,返回 302 跳转,同时把点击事件写入 MQ;消费端更新 Redis 中的计数,定期刷入 MySQL。这个链路包含了缓存、异步、去重、幂等这些关键词,哪怕细节有瑕疵,整体思路已经能拿到大部分分值。
写在最后
我参加网易 2020 校招提前批那次笔试,最大的体会就是:校招笔试考的不是"你有没有背过这道题",而是"你能不能在一个限时、紧张、没有 IDE 补全的环境里,凭真实功力把一道题写对"。Java 八股文可以帮你应付选择题和面试,但真正决定 offer 的,还是你对每一行代码背后原理的理解,以及面对线上问题时冷静排查的工程习惯。如果你能把本文提到的集合、JVM、并发、算法、数据库、分布式这几个方向踏踏实实过一遍,再配上足够的刷题量,网易的笔试对你来说就不会再是一座山。最后再分享一个小技巧:每次笔试完,不管结果如何,都要尽快把题目回忆出来记录在笔记里,这东西比你刷十套模拟题都值钱。