资讯动态

Android校招笔试高频考点与解题策略:从HashMap到Handler机制深度解析

发布时间:2026/8/31 21:30:34 来源:尧图企业网站定制
1. 这套笔试到底在考什么1.1 从招聘视角看360的出题逻辑先说个题外话。看到“2019校招笔试”这个年份可能有人会觉得“都过去这么久了还看它干嘛”。如果你真这么想那就亏大了。校招题库这玩意儿跟流行时尚不一样它的核心考点变动非常慢——哪怕到了现在各大厂Android岗位笔试里翻来覆去问的还是Activity启动模式、Handler消息机制、HashMap扩容原理、进程间通信那几板斧。360的这套题也不例外它代表的是典型的老牌互联网公司对Android开发者的基础能力预期把这个吃透了再去做别的厂笔试题你会发现到处是熟人。360这家公司的业务盘子很有意思。它虽然以安全起家但移动端产品线非常广手机助手、浏览器、清理加速、应用分发这些业务全都需要Android开发。所以笔试出题的时候不会只盯着某个垂直技术栈而是倾向于考察覆盖面广、底座扎实的通用能力。换句话讲应届生没有太多实际项目经验公司只能通过客观题去筛“基础功是否扎实、思维是否严谨”的人所以整套题呈现出几个明显特征知识点覆盖广、单点深度有限、陷阱题频繁、对细节记忆力要求高。客观题这种形式本身就带着筛选效率的考量。一场笔试60到90分钟三五十道选择题系统自动判卷能在极短时间内从几千份简历里捞人。它不指望你把每道题背后的原理写出小论文但你要能判断出“哪个选项是对的为什么对哪个选项是错的错在哪”。这套判断能力恰恰就是实际开发里排查问题、做技术选型时需要的基本功。1.2 客观题覆盖的知识版图我把这类Android校招笔试客观题的知识点分布梳理了一下大致分为这么几块360这套题基本也是按这个框架出知识板块高频考点大致占比Java基础集合类、HashMap源码、并发编程、JVM内存30%Android四大组件Activity生命周期/启动模式、Service、BroadcastReceiver、ContentProvider25%Android核心机制Handler/Looper、Binder、AsyncTask、RecyclerView20%网络与存储HTTP/HTTPS、TCP三次握手、SQLite、SharedPreferences10%性能优化与异常ANR、OOM、内存泄漏、进程优先级10%其他设计模式、Kotlin基础、算法常识5%Java基础占比这么高很多人不理解我是面Android岗又不是面Java后端为什么Java考这么多原因很简单Android上层应用开发的语言就是Java/Kotlin虚拟机也是基于JVM设计的ART虽然和JVM有差异但内存模型、垃圾回收思路一脉相承。你Java功底不行很难写出高质量的Android代码尤其是并发、内存、集合这三大块几乎天天要跟它们打交道。2. 核心考点的两种考查方式概念辨析与代码输出2.1 Java基础HashMap和并发是永远绕不开的坎Java基础里最常出题的我盘点下来是这三个方向集合类源码、并发编程、JVM内存机制。为什么是这三个因为它们不只是八股文而是直接影响你写出来的App会不会卡、会不会崩、内存会不会爆。集合类里HashMap是绝对的C位。校招笔试考HashMap一般不会直接问“HashMap底层结构是什么”而是喜欢包装成代码执行结果题或者源码细节辨析题。比如已知HashMap初始容量为16负载因子为0.75当元素数量达到多少时触发扩容这就是送分题16乘以0.75等于12答案就是12。但很多题不会这么直白它会问“JDK 8中链表转红黑树的阈值是多少”答案是8链表长度超过8且数组容量大于等于64时转红黑树。还有更细的“JDK 8相比JDK 7HashMap的插入方式有什么变化”答案是头插法改成了尾插法目的是解决并发扩容时的死循环问题。死循环这个坑在JDK 7里是真实存在的因为头插法在多线程扩容时会形成环形链表下次get那个位置的元素就会CPU飙满。JDK 8改成尾插法后就没有这个问题了但代价是牺牲了一点插入性能因为要遍历到尾节点。并发这块常考的是synchronized和ReentrantLock的区别、volatile的可见性和禁止重排、ThreadLocal的原理与内存泄漏。我说几个容易踩坑的点synchronized是JVM层面的关键字ReentrantLock是JDK提供的API后者支持公平锁、可中断、可绑定多个条件volatile只能保证可见性不保证原子性所以volatile修饰的变量做i依然是线程不安全的ThreadLocal的每个线程有自己的副本但如果你用的是线程池线程不销毁ThreadLocal里的值也不会被回收容易泄漏所以用完要remove。JVM内存机制主要考运行时数据区划分和垃圾回收。比如“下列哪些区域是线程私有的”答案是虚拟机栈、本地方法栈、程序计数器堆和方法区是线程共享的。垃圾回收那块的常考点是“哪些对象可以作为GC Root”这个就考验理解了虚拟机栈中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象。做这类题时别死记硬背要理解“GC Root是存活对象入口”这个本质自然就能从代码运行的角度推出来。2.2 Android四大组件生命周期与启动模式是硬骨头四大组件里Activity考题密度最高。生命周期那一套顺序必须滚瓜烂熟onCreate → onStart → onResume → onPause → onStop → onDestroy和onRestart的插入时机。但是笔试题目一般不会单纯让你排序而是会结合场景考。比如“Activity A启动Activity BA的哪些生命周期方法会被调用”答案是onPause先执行B的onCreate、onStart、onResume执行完A再走onStop。注意onPause在B可见之前执行所以不能在onPause里做重活这是Android系统强制要求从Android 7.0开始onPause之后最多只能执行几百毫秒就得交出CPU。启动模式也是高频题四个模式standard、singleTop、singleTask、singleInstance的适用场景必须分清楚。最容易出错的点是singleTask的Activity在启动时会把它上面的Activity全部出栈同时会回调它的onNewIntent而不是onCreatesingleInstance是singleTask的加强版整个系统只有一个实例并且这个Activity所在的Task里只能有它一个Activity。笔试里常考“App主页应该用什么启动模式”答案是singleTask因为从通知栏、浏览器等外部入口再次打开App时需要复用已有的MainActivity实例并且把上面压着的Activity清掉避免用户按返回键回不到主页。Service考的是启动方式和生命周期对应关系。startService对应onStartCommand多次startService只会回调onStartCommand不会重复onCreatestopService或stopSelf才会销毁bindService对应onBind多次bindService只会回调一次onBind解绑时最后一个unbindService触发onDestroy。这个细节判断题出得很多经常有人混淆“只start不stop”和“只bind不unbind”会导致什么后果。BroadcastReceiver的考点在Android 8.0以后有个大坑大部分静态注册的隐式广播已经被限制必须用动态注册或者指定包名。\u8003的是版本适配意识如果你还按老经验答题觉得“清单文件里 配个intent-filter就能收到所有广播”那就错了。ContentProvider反而是相对简单的主要是跨进程数据共享和权限偶尔会问ContentObserver监听数据变化的用法。2.3 Handler消息机制一套机制牵扯出无数考点Handler、Looper、MessageQueue这三者的关系是Android笔试的必考项而且360这套题里大概率不止一道。我把它们的关系用最通俗的方式讲一遍Looper是消息循环泵它不断从MessageQueue里取消息MessageQueue是个消息队列底层用单链表实现按时间顺序排列Handler负责把消息塞进MessageQueue并在消息被Looper取出来之后处理它。围绕这个机制笔试会从几个角度挖坑主线程的Looper是哪来的应用启动时系统会通过Looper.prepareMainLooper()创建一个主线程Looper所以你在主线程里可以直接new Handler。但如果你在子线程里new Handler必须先调用Looper.prepare()创建Looper并调用Looper.loop()让它转起来否则直接抛“Cant create handler inside thread that has not called Looper.prepare()”。Handler消息延迟可靠吗不可靠。MessageQueue只是按时间排序如果前面有耗时消息卡住队列后面的延迟消息即使到了时间也得排队等着。所以不要在onCreate里发一个延迟10秒的消息用来做定时任务这个思路就是错的应该用Handler.postDelayed配合移除回调来模拟或者直接用Choreographer。最常见的内存泄漏考点非静态内部类Handler持有外部Activity的引用如果消息还没处理完Activity就finish了Activity无法被回收。标准做法是使用静态内部类WeakReference或者在onDestroy里removeCallbacksAndMessages(null)。这个点笔试题经常和“正确写法”绑定在一起考不能只知道会泄漏还得会修。2.4 踩过的坑版本适配和进程优先级还有一类题是专门考“版本迭代带来的行为变化”的这类题最坑的地方在于如果你只看旧版本的书很容易掉进陷阱。我做一个汇总版本关键变化笔试常考角度Android 7.0应用间共享文件禁止暴露file:// URI改用FileProvider跨应用传Uri的正确姿势Android 8.0静态注册的隐式广播被限制通知渠道引入后台广播收不到是什么原因Android 9.0默认禁止明文HTTP流量接口访问被拒绝怎么排查Android 10分区存储强制开启后台启动Activity受限图片上传为什么拿不到真实路径Android 11软件包可见性变更getPackageInfo弱化获取已安装应用列表需要加查询权限这类题考的其实就是你有没有持续跟进新版本的习惯。校招应届生很难有大量真机适配经验所以笔试里出现这种题筛的是“平时关不关注技术社区、读不读官方文档”。我个人建议备考阶段至少把Android官方文档的“Behavior Changes”按版本过一遍这是花时间少、回报特别高的复习项。进程优先级也是个经典考点。Android系统内存不足时按优先级杀进程从高到低是前台进程 可见进程 服务进程 后台进程 空进程。笔试喜欢考“下列哪些因素不会提升进程优先级”比如“在Service里做耗时操作”并不会让进程变成前台进程除非你调用了startForeground()把Service提升为前台服务。这个点引申出的最佳实践就是播放音乐的应用要启动前台服务并显示通知否则服务很容易被系统回收。3. 高频题型与解题思路演示3.1 概念辨析型选择题的排除法客观题里有一大类是概念辨析四个选项里三个是干扰项纯靠背知识点很难全对因为出题人故意在干扰项里混杂了“听起来对但细节不对”的说法。做这类题我的习惯是先扫选项把有明显错误的直接划掉再在剩下两个里做细节对比。举个例子下列关于Service的说法正确的是 A. startService启动的Service可以不调用stopService进程被系统回收后Service自动重启 B. bindService启动的ServiceActivity销毁后Service会立即销毁 C. startService和bindService可以同时使用但必须先bind再start D. Service的onStartCommand方法可以返回START_STICKY让系统在Service被杀死后重新创建A选项前半句话是对的但“进程被系统回收后Service自动重启”说得太绝对。Service被系统杀死后是否重启取决于onStartCommand的返回值START_STICKY会尝试重建并回调onStartCommandSTART_NOT_STICKY不会重启。所以A措辞有误。B选项说的是“Activity销毁后Service会立即销毁”实际上只有当所有绑定都解除了Service才会走onDestroy而且如果还同时被startService启动着即使所有绑定解除也不会销毁。C选项说“必须先在bind再start”完全错误两者可以独立调用顺序也没有强制要求。最后D选项是对的这就是START_STICKY的含义。这类题的诀窍在于抓“绝对化表述”。选项里一出现“一定”“必须”“立即”“任何”大概率是错的因为Android系统设计里到处都是特殊情况和兼容性处理。当然这只是一个概率判断最终还是要回到知识点本身。3.2 代码输出题的三步拆解法代码输出型选择题是拉开分数差距的地方。它通常是给你一段十几行的Java代码问你运行结果是什么。这类题拼的不是记忆而是执行顺序的推演能力。我的做题方法是三步走先画变量表和对象引用关系再标执行顺序最后逐个语句代入计算结果。举一个笔试里反复出现的例子public class Test { public static void main(String[] args) { Integer a 128; Integer b 128; Integer c 127; Integer d 127; System.out.println(a b); System.out.println(c d); } }输出结果是false和true。IntegerCache默认缓存-128到127之间的Integer对象所以c和d指向同一个缓存对象引用相等而128超出缓存范围每次装箱都创建新对象因此a和b引用不同。这个考点太经典了几乎每一套校招笔试题都会出现。关键是扩展理解这个缓存范围可以通过JVM参数调整上限而且valueOf方法才会走缓存直接new Integer(127)不会走。还有一种更高频的静态块执行顺序题class Parent { static int x 10; static { System.out.println(Parent static); } { System.out.println(Parent init); } Parent() { System.out.println(Parent constructor); } } class Child extends Parent { static { System.out.println(Child static); } { System.out.println(Child init); } Child() { System.out.println(Child constructor); } } public class Main { public static void main(String[] args) { new Child(); } }执行顺序是Parent static → Child static → Parent init → Parent constructor → Child init → Child constructor。类加载阶段按父类到子类的顺序执行静态代码块且只执行一次实例化阶段先执行父类实例代码块和构造函数再到子类。这里有个容易遗漏的点如果main方法里执行了两次new Child()静态代码块不会重复执行但实例代码块和构造函数会执行两次。3.3 场景题与最优解选择场景题是客观题里最接近真实开发的题型一般题干描述一个开发需求或线上问题然后给四个解决思路要求选最优解。这类题没有绝对的对错但有明显的优劣你需要站在“一个负责任的工程师”的角度去选。典型例子应用需要从网络加载大量图片展示在列表中快速滑动时出现明显卡顿和偶发OOM。以下哪个方案最合理 A. 把图片直接加载到ImageView不经过任何处理 B. 开启线程池每个网络图片请求分配一个线程无上限 C. 使用LruCache做内存缓存并用压缩后的Bitmap加载 D. 将ImageView尺寸设置为固定值图片全尺寸解码A选项显然错全尺寸解码大图必崩。B选项线程无上限会导致频繁上下文切换和资源竞争反而更卡。D选项只限制了View大小但没有解决解码内存占用问题就算ImageView显示很小Bitmap解码时仍然是全尺寸的内存开销。C选项正确LruCache控制内存使用上限配合inSampleSize采样压缩降低单张图片内存占用这是Glide和Picasso这类图片加载库的核心思路之一。场景题有个隐蔽的陷阱它往往会设计一个看似正确但过度设计的选项。比如这个问题里可能会加一个“用三级缓存内存、磁盘、网络”的选项听上去很高级但如果这是单选题它反而不一定是正确答案。因为题目限定了“快速滑动卡顿和OOM”两个问题重点在于内存控制和解码优化三级缓存解决的是重复加载的网络开销问题并没有直接解决OOM。所以做场景题要先圈出题干的约束条件再去匹配方案。4. 笔试实战的策略与时间管理4.1 时间分配与做题顺序客观题合集通常是限时完成的60分钟30题或90分钟50题这种配置比较常见。我见过太多人挂在时间分配上前面几道Java基础题觉得简单就死磕结果最后几道分值高的多选题没时间做白白丢分。我建议拿到试卷先花30秒扫一遍总题量按这个节奏走单选题控制在每题60秒以内会做的直接选纠结的标记下来跳过。不要在一道题上耗超过90秒这不仅是时间问题更是心态问题——你在一道题上卡住后面的题会因为紧张而加速出错。多选题可以放宽到每题90到120秒因为多选要么漏选要么多选需要更充分的判断时间。如果题目包含判断、填空这类附加题型优先做判断和填空因为它们往往是对单一知识点的直接考察耗时短、得分率高。最后至少留10分钟检查重点是看有没有漏选、是不是把“正确的是”看成了“错误的是”。这里我特别想强调一个审题细节题干里“正确”“不正确”“错误”“包括”“不包括”这些词很多人在快速浏览时容易漏看。我的习惯是先把题干里这些否定词圈出来再去看选项相当于给自己提个醒。4.2 多选题的得分技巧与风险控制笔试题里的多选题是丢分重灾区。360这类大厂的多选题通常遵循“少选得部分分、多选错选不得分”的规则所以策略和单选完全不同。如果你对一个选项的把握度不足七成我的建议是宁可不选也不要冒险。部分得分总比一分没有强。多选题还有一种常见出题法五个选项里有四个是同一知识点在不同场景下的不同说法其中一个是凑数干扰。遇到这种题先找出选项之间的共性再判断哪个“画风不一致”。比如四个选项都在讲Context的用法只有一个在讲Application的初始化那大概率正确答案就是那四个同类的选项里筛出来的而不是那个画风突变的。另外多选题往往包含一个“非常正确”的选项和两个“基本正确但细节错误”的选项。你要防范的是“基本正确”这种迷惑项。比如“ContentProvider用于应用间数据共享也可以用于应用内数据访问”这个说法本身没错但如果题目问的是“ContentProvider的优势”那“可以访问应用内数据”就不是核心优势属于正确但偏离考点的干扰项。5. 备考路线与从笔试到面试的能力衔接5.1 针对Android方向的刷题路径备考不能盲目刷题我的建议是按“先基础、再机制、后实战”的顺序推进每一阶段都有明确目标。第一阶段是Java基础加固大约需要一周到两周。重点复习集合类源码、并发关键字、JVM内存模型和GC算法。这一阶段不要只看概念最好打开IDE把HashMap的put方法走一遍源码把线程池的execute方法执行流程梳理一遍。代码读多了选择题里那些细节自然就有了肌肉记忆。第二阶段是Android核心机制精读也是投入产出比最高的阶段。Handler源码、Activity启动流程、Service的绑定过程、Binder通信原理这四大块每一个都值得精读。建议画出调用链时序图比如从Context.startActivity到ActivityThread.handleLaunchActivity的完整链路画一遍比看十遍记忆都牢。Binder可能比较抽象可以拿“客户端到服务端的一个跨进程方法调用”当主线梳理出Proxy、Stub、transact、onTransact这几个关键参与者的协作关系。第三阶段是刷真题和模拟题。找两到三套知名公司的历年Android笔试真题掐表做一遍做完后别急着看解析先每一道题标注“我为什么选这个选项我是怎么排除其他选项的”再和答案核对这样能精准定位自己思维里的漏洞。错题整理成一份知识清单考前过一遍效果远胜于盲目刷一百道新题。5.2 从笔试到面试的能力衔接笔试只是第一关但笔试里涉及的知识点在接下来的技术面试里会被深挖两个量级。笔试考的是“你知道这个结论”面试考的是“你能不能把这个结论推导一遍”。举个例子笔试题里问“HashMap什么时候扩容”你选对12这个数字就行了面试官会接着问“为什么负载因子是0.75改成0.5会怎样改成1会怎样”这就不是背数字能应付的了。我的建议是笔试备考阶段就要带着面试思维去复习。每学一个知识点多问自己三个问题这个设计的目的是什么如果换一种方案行不行极端场景下会出现什么问题比如学Handler就顺带问“为什么不能在子线程里更新UI”“子线程更新UI真的绝对不行吗”学LruCache就顺带问“LruCache底层是LinkedHashMap吗 accessOrder参数有什么作用”。这样笔试和面试的复习就打通了效率会高很多。还有一点容易被忽视校招笔试里偶尔会出现少量算法或逻辑题难度通常不会超过LeetCode简单到中等。我建议每天保持半小时到一小时的刷题量重点掌握数组、链表、二叉树、字符串的常见操作贪心、双指针、BFS/DFS这些基础算法也要有概念。算法题在笔试里占的比重不大但如果完全放弃有可能因为几分之差被卡在简历筛选之后的第一轮。最后说一个我个人在备考和实际带应届生过程中反复验证的体会客观题合集刷再多如果你只是对答案记结论十天之后基本忘干净。真正有效的做法是每题都逼自己说出“为什么选它、为什么不选其他的”哪怕写不出长文脑海里也要能过一遍理由。那些能说出来龙去脉的知识点到了面试环节才是真正属于你的加分项。这套360的合集与其当成题库不如当成一张知识地图——把图上每一个坐标点都点亮你收获的远远不止一场笔试的通过。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价