每年校招季,网易的笔试系统一开,Android开发岗的题目就会在牛客和各大技术群里被反复讨论。我帮学弟学妹们做校招辅导时,被问得最多的问题就是:网易这种大厂的Android笔试到底考什么、怎么准备才能不陪跑。说实话,2020年的正式批笔试题目拿到现在看,知识点框架反而更有参考价值——那一年正好是Android 10普及、Kotlin协程开始大规模应用的节点,题目难度和考察方向都很有代表性。这篇文章我就按当年正式批笔试的考察逻辑,把题型构成、核心考点、编程题思路、场景题的答题框架全部拆开讲,顺便把备考过程中最常见的坑也一并指出来。适合正在准备大厂Android校招的应届生,也适合想系统自查Android知识体系有没有漏洞的同学。
1. 笔试整体设计与考察思路
1.1 科目构成与时间分配
网易Android开发工程师的笔试通常是在牛客网这类在线评测平台完成,整体时间大约120分钟,题型基本固定为三个大块:行测逻辑题、专业技术客观题、编程题。行测部分主要是言语理解、数字推理和图形推理,题量在20道左右,建议控制在30分钟以内;专业客观题以单选和多选为主,覆盖Java基础、Android四大组件、网络、操作系统和计网基础,建议45分钟左右;剩下的45分钟留给2到3道编程题。
这里有个非常容易被忽略的点:行测题看似跟技术岗关系不大,但它决定了你能否进入面试池。大厂笔试是机器+人工双重筛选,系统会按总分排名,而行测题往往是拉开总分差距的关键。技术题大家都答得差不多,行测多错5道题,名次可能就差出几千名。
1.2 为什么用这种考察结构
笔试虽然只有两个小时,但大厂想考察的能力维度非常清晰:逻辑敏捷度、知识深度、代码落地能力。
行测题考的是候选人在时间压力下的逻辑反应速度和阅读理解效率。技术团队需要能在复杂业务中快速拆解问题的人,如果一道图形推理就要想三分钟,大概率很难适应快节奏的开发迭代。
专业客观题是知识面的扫描仪。简历上写“熟练掌握Android”的人很多,但能把AMS的工作流程、Handler的消息机制、Binder的通信原理答明白的人很少。笔试题不考API怎么调用,考的是底层的“为什么”——为什么主线程Looper是个死循环但不会卡死应用、为什么HashMap并发扩容会丢数据。这些问题能直接把只会写业务代码的候选人筛掉。
编程题则是代码能力的试金石。在线编程环境下没有IDE的自动补全,没有编译器提示,所有细节都要自己写出来,眼高手低的候选人在这里基本藏不住。
2. 专业技术客观题:高频考点与底层原理
2.1 Java基础与并发:最容易拿分也最容易丢分的板块
Java基础在专业题里的占比通常在30%以上,因为Android上层的大部分问题根源都在Java层。HashMap是绝对的高频考点,尤其是JDK 1.7和1.8的区别、put流程、resize扩容机制、为什么引入红黑树。很多同学能说出“数组+链表+红黑树”,但被问到底层细节就卡住,比如:为什么HashMap容量要求是2的幂次、为什么链表转红黑树的阈值是8。
这里最核心的理解点是:HashMap的put过程本质是“计算哈希 -> 定位桶 -> 插入”,其中计算索引的方法不是取模,而是(n - 1) & hash,因为n是2的幂时这个位运算等价于取模,但性能更高。红黑树的引入是为了解决哈希碰撞严重时链表过长、查询退化成O(n)的问题,阈值定8是因为泊松分布下链表长度达到8的概率已经极低。
并发题目通常考synchronized和volatile的区别、线程池的核心参数、AQS的基本原理。一个典型的笔试选择题是:线程池corePoolSize为2、maximumPoolSize为5、阻塞队列容量为3,提交8个任务时,线程池的处理顺序是什么。答案是:前2个任务直接创建核心线程,第3到第5个任务进入队列,第6和第7个任务创建非核心线程,第8个任务触发拒绝策略。注意触发顺序不是“先填满线程再填队列”,而是“核心线程先执行,队列先容纳,再扩容线程”,这是面试官最喜欢的细节题。
2.2 Android核心组件与机制:笔试的重头戏
四大组件是Android题的绝对主力。Activity生命周期要掌握常规流程(onCreate -> onStart -> onResume,按Home键到onStop但不销毁),还要掌握异常情况:屏幕旋转时Activity会先销毁再重建,onSaveInstanceState保存数据。启动模式常考singleTask和singleInstance的区别,前者会清空栈顶之上的Activity,后者是全局唯一实例,适合来电页面这类场景。
Service部分要区分startService和bindService的生命周期差异,知道startService用startCommand的返回值控制重启策略。BroadcastReceiver要注意不能在里面做耗时操作,而且从Android 8.0开始大部分隐式广播已经不能通过清单文件注册接收。ContentProvider的核心是跨进程数据共享,要理解它底层走的是Binder,所以访问ContentProvider天然是线程安全的——但这个“线程安全”是指数据访问的进程隔离,不意味着数据库操作不用加锁。
Handler机制几乎是必考内容。要能把Looper、MessageQueue、Message三者的关系讲清楚:主线程启动时Looper.loop()进入死循环,不断从MessageQueue取消息;handler.sendMessage()最终通过enqueueMessage把消息插入队列;取到消息后回调dispatchMessage,最终走handleMessage。还有一个经典问题:主线程Looper是死循环,为什么不会卡死应用。回答的关键是:主线程并非一直阻塞在loop里,没有消息时epoll机制会让线程进入休眠,不消耗CPU,而系统每16ms会通过Choreographer往消息队列里投递VSync信号触发UI绘制。
Binder和AIDL也是高频考点。Binder是Android系统里最核心的进程间通信机制,一次完整的Binder调用需要经历:客户端通过代理对象发送数据 -> 驱动层复制数据 -> 服务端执行并返回结果 -> 驱动层再次复制。有人说Binder是Android专属的“唯一一个Android内核里专门为某种业务定制的IPC机制”,这不算准确,但能体现出你理解这个机制的特殊地位。
2.3 网络、存储与系统原理:跨领域的知识拼图
网络题主要考HTTP/HTTPS、TCP/UDP。注意区分:HTTP是应用层协议,TCP是传输层协议。HTTPS比HTTP多了一层TLS/SSL加密,握手过程涉及非对称加密交换密钥、对称加密传输数据、证书验证防中间人攻击。常考的问题是:HTTPS为什么需要证书?因为客户端需要确认自己连接的服务端确实是目标服务器,而不是中间人伪装的。
TCP的三次握手和四次挥手是必背题,但要理解背后的设计思想:三次握手是为了确保双方的收发能力都正常。第一次握手客户端发SYN,服务端收到后知道客户端发送能力正常;第二次握手服务端回SYN+ACK,客户端收到后知道服务端收发都正常;第三次握手客户端回ACK,服务端收到后知道自己发送能力正常、客户端接收能力正常。四次挥手是因为TCP是全双工的,双方需要各自关闭自己的发送通道。
操作系统和存储方向常考的是进程与线程的区别、死锁条件、SQLite事务、APK打包流程。APK打包流程可以总结为:资源编译 -> aidl生成Java文件 -> javac编译 -> dex打包 -> 资源+dex+so打包签名。Android构建过程中的R8代码混淆也是近年笔试的热门点,R8不仅做混淆,还做资源收缩和代码裁剪,能显著减小APK体积。
3. 编程题:从思路到代码的完整闭环
3.1 高频算法题型的解题框架
网易笔试的编程题难度通常对标LeetCode中等题,但有些题目会做场景包装。常见的出题方向有四类:数组/字符串处理,典型解法是双指针、滑动窗口、哈希表;链表操作,涉及反转、合并、找环;二叉树题目,层次遍历和最近公共祖先出现频率高;动态规划,股票买卖、背包问题、编辑距离都可能出现。
在做编程题时,我建议套用四步法:理解题意、设计算法、编码、测试边界。很多同学上来就写代码,写到一半发现题目理解错了,浪费大量时间。理解题意这一步至少花2分钟,确认清楚输入输出格式、题目给的数据范围、有没有特殊限制,数据范围决定算法复杂度:如果n是10^5,O(n^2)必然超时,必须用O(n)或O(nlogn)。
3.2 一个经典手写题:LRU缓存的完整实现
LRU缓存是笔试和面试都绕不开的题目,网易笔试曾直接让手写LRU。考点不只是缓存淘汰逻辑,而是能否设计出O(1)时间复杂度的数据结构。核心思路是HashMap + 双向链表,HashMap提供O(1)查找,双向链表维护访问顺序。
代码实现如下:
import java.util.HashMap; public class LRUCache { private static class Node { int key; int value; Node prev; Node next; Node(int key, int value) { this.key = key; this.value = value; } } private final int capacity; private final HashMap<Integer, Node> map; private final Node head = new Node(-1, -1); private final Node tail = new Node(-1, -1); public LRUCache(int capacity) { this.capacity = capacity; this.map = new HashMap<>(); head.next = tail; tail.prev = head; } public int get(int key) { Node node = map.get(key); if (node == null) return -1; moveToHead(node); return node.value; } public void put(int key, int value) { Node node = map.get(key); if (node != null) { node.value = value; moveToHead(node); return; } if (map.size() == capacity) { Node last = tail.prev; removeNode(last); map.remove(last.key); } Node newNode = new Node(key, value); map.put(key, newNode); addToHead(newNode); } private void addToHead(Node node) { node.next = head.next; node.prev = head; head.next.prev = node; head.next = node; } private void removeNode(Node node) { node.prev.next = node.next; node.next.prev = node.prev; } private void moveToHead(Node node) { removeNode(node); addToHead(node); } }注意几个细节:get操作命中后要把节点移到头部;put操作要先判断key是否存在,存在则更新value并移到头部;容量满时删除尾部节点,同时从map中移除。这里的head和tail是哨兵节点,避免了空指针判断,代码更简洁。为什么用双向链表而不是单向链表?因为删除尾部节点时需要拿到它的前驱节点,单向链表做不到O(1)的删除。
3.3 编程题的考场时间控制与边界处理
大厂笔试编程题不只考会不会做,还考能不能在限时内做对。我见过太多人在第一道题死磕四十分钟,导致后面两道题完全没时间看。正确策略是:先扫一遍所有题目,从最简单的一道开始做,保证起码拿到一题的满分,再回头啃难题。如果卡了15分钟还没有思路,果断跳过,把能拿的分先拿住。
边界条件是最容易丢分的地方。写题时时刻问自己:输入为空怎么办、只有一个元素怎么办、数组长度是奇数怎么办、数值相加会不会溢出。比如题目要求返回int,但中间计算可能超出int范围,就要提前用long接收。另外,在线判题平台的输入读取和输出格式也要提前适应,核心代码模式只需要实现函数,ACM模式需要自己处理多行输入,两种模式在牛客网和赛码都可以模拟练习。
4. 场景设计题与开放问题的答题套路
4.1 设计题的高分回答框架
网易这类大厂的笔试中偶尔会出现一道简答或设计题,分值不高但很能体现候选人的工程思维。常见题目类型包括:设计一个图片加载库、设计一个消息推送SDK、如何优化一个列表的滑动流畅度、如何排查线上OOM。
回答设计题一定不要直接说方案,要按“需求分析 -> 模块划分 -> 技术选型 -> 核心流程 -> 优化点 -> 监控与降级”这个框架来组织答案。以图片加载库为例,先明确核心需求:支持异步加载、内存缓存、磁盘缓存、支持获取过程中取消、能监听生命周期。接着拆模块:请求管理模块、缓存模块、解码模块、显示模块。技术选型上,内存缓存用LruCache、磁盘缓存用DiskLruCache、线程池用固定大小的IO线程池、解码用BitmapFactory配合inSampleSize做采样压缩。核心流程写清楚:加载图片时先查内存缓存,再查磁盘缓存,最后走网络;网络图片下载后先写磁盘再解码显示。优化点包括:预加载、占位图、避免列表滑动时加载错乱。最后一定要提到降级和监控,比如内存缓存命中率上报、OOM兜底方案,这样的答案才是完整的。
4.2 几个典型的Android场景问题与思路示例
场景题的第一类是系统机制类,比如“如何实现一个尽可能不被系统杀死又能及时收到消息的服务”。这道题考察Service的优先级、前台服务原理和系统限制。答案要点:通过startForeground()绑定前台服务,降低被杀概率;onStartCommand返回START_STICKY,让系统杀死后尝试重建;在onTaskRemoved里做逻辑处理。但要注意,现在的Android系统对后台启动和保活的限制越来越严格,回答时强调“合法方案优先、面向业务稳定性设计”,比苦苦追求“永不被杀”更符合大厂对工程素养的期望。
第二类是问题排查类,比如“如果线上App出现OOM,你会怎么排查”。回答框架是:先收集崩溃现场和内存快照,用Bugly或自研平台采集堆栈;再通过hprof文件用Android Studio的Memory Profiler或MAT分析大对象占用,重点看Bitmap数量和当前Activity数量;最后做代码走查,排查静态变量持有Context、Handler未移除回调、数据库游标未关闭这些典型问题。排查OOM的答案没有标准解,关键是每一步都有具体工具和方法支撑,而不是只说“用工具看看”。
第三类是性能优化类,比如“列表滑动掉帧怎么定位”。要答出从现象到根因的完整链路:先通过开发者选项的GPU渲染模式判断是不是主线程卡顿;再用Systrace抓取主线程执行轨迹,看关键函数耗时;如果主线程没查到大耗时,就检查布局层级是否过深、图片解码是否占用主线程、有没有频繁的GC触发;最后用Diff工具对比优化前后的帧耗时。这类题的核心是展示你遇到问题时有系统化的排查手段,而不是拍脑袋试。
5. 备考路线与笔试避坑指南
5.1 分阶段备考路线
准备校招笔试,一个月到两个月是比较合理的周期。我建议按四个阶段来安排。
第一阶段(第1-2周)重刷算法基础。把LeetCode热题100按标签刷一遍,双指针、滑动窗口、二叉树、动态规划、链表五大类必须全覆盖。每天保证3道新题加2道复刷,重点不是数量,是每道题都要自己写出来并跑通,只看题解不手写等于白刷。
第二阶段(第3-4周)集中补基础知识。Java并发和JVM一边看《Java并发编程的艺术》和《深入理解Java虚拟机》的对应章节,一边把Android四大组件的生命周期、启动模式、Handler机制、Binder原理这些核心知识点逐个用思维导图整理出来,每个知识点至少能说出一个低频但常考的细节,比如Activity的onNewIntent什么时候回调、Service的onRebind什么时候触发。
第三阶段(第5-6周)做真题和项目复盘。去牛客网找历年大厂Android笔试题,按真实考试时间模拟2到3次,适应时间分配和打字速度。同时把简历上的项目按“技术难点 -> 解决方案 -> 实现细节 -> 优化效果”四个维度复盘一遍,笔试后的面试大概率会围绕项目深挖。
第四阶段(第7-8周)查漏补缺。把自己手写过的代码翻出来再写一遍,把整理过的知识图谱过一遍,把错题集里的题目重新做一遍。这个阶段拼的不是新增量,而是稳定输出。确保考场上能把自己掌握的内容完整写出来。
5.2 笔试中最常见的三大坑
| 坑 | 典型表现 | 解决思路 |
|---|---|---|
| 只看题解不手写 | 觉得思路懂了,上机写不出完整代码 | 每道题必须独立手写并跑通测试用例 |
| 行测题耗时过长 | 图形推理想5分钟,编程题没时间 | 行测限时30分钟,超时直接蒙一个跳过 |
| 选择题审题不清 | 问“错误的是”选了“正确的” | 圈出关键词,单选题看清楚再下笔 |
还有一个容易被忽视的坑是键盘输入不熟练。在线笔试时没有IDE的自动补全,类名、方法名、import全都要手打,平时习惯了IDE提示的同学很容易在这里翻车。建议考前专门用牛客网的在线编辑器练习几套题,习惯手写import和main函数。
5.3 资料与工具选型建议
工具方面,笔试前需要准备的是Android Studio和JDK。虽然在线笔试用不上,但笔试后的技术面试会通过远程共享屏幕或线下白板让你写代码,提前熟悉Android Studio的常用快捷键和代码重构操作能省不少时间。另外,Android Studio自带的模拟器和Profiler工具建议提前折腾一遍,面试聊性能优化时随口说出命令路径会显得你很专业。
资料方面,算法用LeetCode加牛客网真题就够;Java基础推荐《Java并发编程的艺术》和《深入理解Java虚拟机》;Android基础首选《Android开发艺术探索》,这本书虽然出版时间早,但讲Handler、事件分发、View绘制这些核心知识仍然是最系统的。官方文档和Android开发者网站上的性能优化指南也是必看内容。
提示:2020年网易笔试的核心考点放到今天依然是主流考察方向,但要注意Android的新变化,比如协程在项目中的大量使用、Jetpack Compose逐步替代传统View体系,这些新内容虽然不一定在笔试客观题里出现,但面试环节一定会被问到。
我自己当年准备校招时,最吃亏的地方就是太爱背结论。看到源码解析就划过去,觉得自己“懂了”,结果笔试里一考到Handler消息池的复用机制、HashMap扩容的具体步骤这类细节就答不上来。后来换了个策略,每看到一个知识点,都打开源码或写个小demo自己验证一遍,能画出流程图的画流程图,能手写代码的手写代码。笔试通过率和后续面试的表现都明显上了一个台阶。所以看到这篇文章,别把它当成考点清单背一遍就完事,花点时间把每一个点落到代码里、项目里去验证,你才能真正把知识变成自己的东西。