ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Android面试题精选:核心考点、出题逻辑与高效准备方法

Android面试题精选:核心考点、出题逻辑与高效准备方法 干Android面试官这几年我最大的感受是很多候选人不是不会而是不知道面试官到底想问什么。之前我整理过一份内部归档为“01-15-02 Android面试题精选”的文档本来是给自己在面试前划重点用的结果后来越传越广有的朋友拿去当题库有的直接按模块去补基础。今天把这份题单背后的选题逻辑、核心考点和实操过程重新梳理一遍给正在准备Android面试的朋友或者想自己搭面试体系的团队Leader一个参考。这份内容不保证覆盖所有面试题但会把“为什么这么问”“怎么回答才有深度”讲清楚。1. 面试题的选题逻辑面试官到底在考什么1.1 不同年限的候选人题目难度怎么分层面试官手上一份好的题单不是把所有知识点平铺出来而是像一张地图不同阶段的人走不同路线。对于初中级工程师重点考察四大组件、消息机制、RecyclerView和基础布局是否真正掌握这些内容决定了候选人能不能在现有框架下高效完成日常需求。对于三到五年的高级工程师重点就转移到Binder、AMS/WMS、ClassLoader、Jetpack源码、性能优化这些偏底层和架构的模块因为团队开始指望这类人解决疑难Bug和做技术方案选型。五年以上则需要看系统定制、插件化、热修复、编译打包、大型项目重构等这类问题很难靠死记硬背更多是在考验候选人有没有真正遇到过类似场景以及踩坑后的复盘能力。所以我整理题库时不会一开始就铺一堆高难度题。先准备一套“保底题”用来确认候选人基础再准备一套“深挖题”用来区分天花板。比如同样是问“Activity的启动模式”初级候选人能背出四种模式的含义就算合格但高级候选人需要能结合singleTask来给出一个“从浏览器调起App并跳到指定页面”的完整方案还要说清楚taskAffinity和FLAG_ACTIVITY_NEW_TASK之间的关系。1.2 精选标准的三个维度高频、核心、可追问我筛题时只保留三个维度都满足的题。第一是高频指在真实面试里反复出现的题目比如“Handler机制”“事件分发”“内存泄漏”这些题只要面Android就不可能绕过。第二是核心指Android技术栈里独有的内容例如Binder、MessageQueue中的epoll唤醒、Lifecycle的lifecycle-aware设计这些最能拉开候选人之间的差距。第三是可追问也就是说这道题不能只有一个标准答案而是能不断往深处挖。比如“自定义View的measure过程”可以一直追到MeasureSpec的EXACTLY、AT_MOST、UNSPECIFIED再到setMeasuredDimension和resolveSize的核心逻辑最后还可以问“为什么ConstraintLayout能减少嵌套测量次数”。如果一道题问一句就到底没有延展性我就会把它从题库里拿掉。1.3 题目数量控制在多少合适不要贪多。我整理归档时特意用“01-15-02”这种编号是为了按日期和序号管理每一批题。一月份第十五天第二次整理说明这份文档是持续迭代的不是一次写完就放着吃灰。真正一套有效的面试题库核心题控制在30到50道就足够了。数量多反而容易让面试官自己都没吃透问出来东一榔头西一棒子完全无法判断候选人水平。我个人的经验是把每道题都配好“基础问法”“进阶追问”“参考要点”三栏面试时按候选人的回答节奏决定放在哪一栏比背一百道题管用得多。2. 高频考点拆解这些题为什么总被问2.1 四大组件问题不是背概念很多候选人答“Activity有四种启动模式”然后就卡住了。实际上启动模式背后是任务栈的管理规则面试官真正想听的不只是standard、singleTop、singleTask、singleInstance的定义而是你如何理解它们在真实场景下的作用。比如singleInstance的设计初衷是让某个组件独占一个任务栈像来电界面这种需要全局唯一的场景会用到而singleTask更适合作为App的主页或入口配合onNewIntent可以避免重复创建实例。如果只背定义一旦追问“两个App通过deep link跳转栈会变成什么样”就会露馅。再比如Service很多人不明白为什么会有startService和bindService两种启动方式。其实这对应两种使用模型startService适合后台长时间执行的任务例如音乐播放bindService适合需要和组件交互并获取返回结果的场景。真正高频的追问是“如果同时start和bind怎么停止服务”这涉及到Service的内部计数机制能答清楚的人往往对生命周期有真实掌握。2.2 Handler机制问道源码层面才算入门Handler是面试题的常青树。基础问法是“Handler、Looper、MessageQueue之间是什么关系”进阶问法是“为什么主线程能直接new Handler”再往下是“MessageQueue中没有消息时线程在做什么”。候选人只要答到“Looper.loop()会通过epoll机制进入阻塞有消息时由pipe写入唤醒”我就会认为他至少看过源码。这里想特别提醒Handler内存泄漏几乎是必问点。正确的答法是非静态内部类Handler默认持有外部Activity的引用如果消息延迟执行或者队列里堆积消息GC就无法回收Activity。解决方案一般是把Handler写成静态内部类通过WeakReference持有外部引用并在onDestroy时removeCallbacksAndMessages(null)。但更深的点在于为什么Looper本身不持有Handler却仍然会造成泄漏——因为ThreadLocal里存了LooperLooper持有MessageQueueMessageQueue里如果有待处理的MessageMessage持有target也就是Handler而Handler又持有外部引用。这条引用链能顺畅讲出来才算真正理解了Handler机制。2.3 Binder机制理解进程间通信的Android式解法Binder是Android里最绕不开的底层设计同时也是很多人的噩梦。它为什么被设计出来很多人只回答“跨进程通信用的”但面试官往往希望听到对比Linux里已有管道、消息队列、共享内存、Socket多种IPC方式为什么Android还要自己搞一套Binder核心答案有几个一是性能上Binder只做一次拷贝而传统管道需要两次二是安全性高内核为每个进程分配UID/PID可以进行身份校验三是调用方式像方法调用天然适合面向对象的Android框架。实操层面的追问通常是“AIDL生成的Stub和Proxy是怎么回事”。这里最关键的是要让候选人描述清楚客户端调用Proxy的transact驱动层处理数据后服务端Stub的onTransact再被回调。能画得出这个流程的人对Binder机制的理解基本就到了可以独立解决系统级问题的水平。另外我常会补问“Binder线程池的大小”能答出默认是16个线程的候选人很少但这道题能看出候选人有没有真正读过Binder相关的系统源码。2.4 自定义View和事件分发高频手写题这一块是面试里的“手写重灾区”。自定义View的核心是measure、layout、draw三条流程但很多人一上来就背onMeasure是干嘛的却连MeasureSpec中父容器和子View之间的约束关系都说不清。通常我会给一个非常具体的需求写一个正方形的ImageView且宽度不固定、由父容器决定。这道题直接考察是否能处理“宽度由父布局测量得到高度设置为和宽度一致”的逻辑能答出setMeasuredDimension并处理异常尺寸的人才算真的会自定义View。事件分发则是另外一座山。经典的“点击一个按钮为什么不会触发父容器的onTouchEvent”就看候选人能不能把dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三条链路的顺序说清楚。滑动冲突是这里的必考项外部拦截法和内部拦截法都是常规解法但更重要的是理解requestDisallowInterceptTouchEvent的flag机制。我遇到一个不错的候选人用“事件就像快递dispatch是前台onIntercept是门卫onTouchEvent是签收人”这个类比讲解整个流程虽然不完全严谨但能证明他真的理解了机制这是加分项。2.5 性能优化内存、启动、卡顿性能优化是任何年限都会被问的模块因为它在实际开发中最有话语权。内存方面最常问的是“有哪些导致内存泄漏的常见场景怎么排查”。除了前面Handler提到的泄漏还有静态变量持有Activity、单例持有Context、未注销的BroadcastReceiver、匿名内部类的Runnable被线程长期持有、LiveData观察者没有清理等。排查工具可以提LeakCanary但更好的回答会提到Android Studio自带Profiler里的Memory Profiler能实时看对象分配以及用MAT去分析hprof文件中的GC Roots。启动优化也是高频问点。面试官想知道候选人有没有真正优化过冷启动。基本思路包括在Application里减少耗时操作使用懒加载和线程池进行异步初始化使用启动器将任务按依赖关系并行执行首帧前避免主线程做文件IO和SharedPreferences写入。更深一点是了解启动过程里ContentProvider的自动初始化机制因为很多第三方SDK就是靠ContentProvider自动抢占了启动时间这也是为什么现在推荐使用App Startup来合并初始化。卡顿问题则更看重系统性。不要只回答“用Systrace或者CPU Profiler”。好的答案应该先给出一个排查流程先复现现象再抓trace定位到是主线程的哪一段代码耗时然后看是CPU密集、锁竞争还是Layout层级过高导致的重绘太多。只要候选人能说出一套闭环流程不管他用的是Android Studio的CPU Profiler还是Perfetto我都会认为他的性能优化经验是真实的。2.6 Jetpack与架构组件现在面试必问Jetpack已经成了现代Android开发的标配所以面试题里必须有它的一席之地。ViewModel为什么在Activity旋转后还能保存数据如果候选人能回答出“ViewModelStore由Activity保留但ViewModel本身不持有View引用”就已经接近满分了。再追问“ViewModel和onSaveInstanceState有什么不同”需要说清ViewModel适合保存内存态数据而onSaveInstanceState适合保存进程可能被杀死时的小数据两者是互补关系这个认知很关键。Lifecycle机制也值得重点考察。它基于观察者模式核心是LifecycleRegistry利用状态机和事件分发去驱动AppCompatActivity等组件。现在很多自定义组件都会自带lifecycle-aware的设计比如Glide和CameraX能主动感知生命周期从而避免泄漏。面试中我常会让候选人手写一个自定义UI组件要求它监听Activity的onStart和onStop看他会选择在onStart里注册还是在Lifecycle的observer里处理。愿意选择Lifecycle的说明他对现代Android架构是认可的。Kotlin协程在近两年几乎是必问项。基础题是“协程和线程有什么区别”进阶题是“ViewModel中用viewModelScope发起协程取消时机是怎么保证的”。这背后考察的是CoroutineScope和结构化并发。如果候选人能说出“viewModelScope是CloseableCoroutineScope在ViewModel的onCleared时调用cancel”并且能讲清楚协程的挂起是非阻塞式那这条线基本就通了。2.7 Framework与系统定制从应用层逼近系统层虽然很多应用层开发不一定直接改系统但面试官喜欢用Framework题目来筛“潜力选手”。比如“SystemServer启动过程中启动了多少个核心服务”“AMS如何管理ActivityTask”。如果是做应用开发至少应该知道startActivity最终会通过Binder调用到AMSAMS再做任务栈调度然后由ActivityThread负责真正的生命周期回调。能厘清这套链路说明候选人不是只能调用API的“工具人”。对安全方向感兴趣的很多团队会问“APK打包过程”“四大组件的注册作用”甚至可以聊到反编译和Dex加固。我自己在面试里一般不会用特别偏门的问题而是用“为什么系统杀掉进程后还能恢复之前的数据”来考察ActivityRecord和SavedInstanceState的协作这个问题综合了Activity生命周期、AMS和应用进程的关系比单问某个组件更能看水平。2.8 网络、多线程与工程化容易被忽略的加分项基础题经常问“OkHttp拦截器的作用”这其实可以考察设计模式和责任链。候选人不仅要说出添加拦截器可以统一加公共参数、日志、缓存更好的是能画出Request从ApplicationInterceptor到NetworkInterceptor再到尾端处理的一条链并说明自定义拦截器能做什么。多线程方面我会问“线程池核心参数怎么设”主要是考察对CPU密集、IO密集任务的理解。实际项目里线程池设置不能照抄默认值要结合任务类型。再说一个容易被忽略的点题目虽叫Android面试题但很多团队会顺带问一点跨端和工程化问题比如有没有学过Flutter至少要能说出多端一致性的方案选型平时用Android Studio能否熟练做单元测试、基准测试、性能分析。特别是一线团队很看重候选人会不会自己用Profiler定位问题、会不会运行Robolectric写JVM单测。如果还能提一句“我写过用脚本解析APK做一些自动化检测”这类复合经验的候选人我会给很高的加分。3. 实操过程把面试题变成一套可复用的面试题库3.1 按模块归档每道题写好参考答案和追问路径整理题库这件事最忌讳只写题名不写答案。我会用一个简单的表格来管理每道题分为题目、考察点、追问路径、参考要点四列。下面举一个实际例子。题目考察点追问路径参考要点Activity启动模式及使用场景对任务栈和Flag的理解4种模式区别 → singleTask配合onNewIntent → taskAffinity实际作用 → 深链启动的栈情况能说出singleTask会复用已有栈内实例并清空其上方Activity能画出任务栈变化图为佳Handler线程切换原理Handler/Looper/MessageQueue关系post和sendMessage的区别 → 主线程Looper如何创建 → epoll如何唤醒能画出跨线程通信时序图并说明ThreadLocal的作用Binder一次拷贝原理对IPC机制的理解AIDL的Stub/Proxy流程 → Binder线程池大小 → 安全性优势能说出mmap映射机制以及驱动层只做一次数据拷贝内存泄漏排查流程实际定位问题的能力常见泄漏场景 → LeakCanary原理 → MAT分析GC Roots能完整复述从复现、抓hprof、分析引用链到修复的过程这样的表格可以放进文档里持续维护。我会给每个模块比如“四大组件”“Handler”“Binder”“性能优化”“Jetpack”“Kotlin协程”都建一个页签每次面试完之后把候选人的典型答案补充到“常见错误回答”一栏。这样题库不是死的而是随着真实面试越磨越精。3.2 面试过程中怎么用这套题面试时最怕不是问不出问题而是被候选人带着跑。我一般采取“基础题5分钟核心题15分钟项目题20分钟”的结构题库主要服务前两个阶段。基础题快速问两三个判断熟练度如果答得流畅就立刻跳到核心题用一道Handler机制题去追源码深度。如果候选人卡住了我会降低难度从“怎么使用Handler”开始问确认他的使用能力。核心题之后再用一个项目题让候选人描述自己做过的最复杂的技术方案重点听他在方案里怎么决策、怎么权衡而不是仅仅罗列功能。这里有一个经验题库里的每一道题我都建议面试官自己先完整答一遍还必须用语音说一遍。因为很多问题自己以为会但一开口就卡壳。如果面试官自己都说不顺那问出来就容易失真。3.3 候选人也应该刷这套题怎么刷才有效如果你是以候选人身份在看这篇文章那我建议不要只刷“答案”要刷“为什么”。比如看到“Handler内存泄漏”这道题不要满足于记住“静态内部类WeakReference”而是自己动手写一个会泄漏的Demo用LeakCanary看泄漏结果再改成不泄漏的版本比较差异。这个过程比背十遍答案都管用。另一个建议是把每道题当“小项目”去验证。像“Binder机制”这种偏底层的题可以写一个AIDL Demo服务端开一个远程Service客户端绑定然后打日志看Binder的transact调用。用Android Studio带一个模拟器就能做花不了两小时但对理解这套机制立竿见影。光在脑内推演面试时很难画出清晰的数据流图。4. 常见坑点与作答技巧实录4.1 候选人经常答错的几个点我把面试里听到的高频错误总结成了以下几条准备面试的朋友可以对照自查。第一是启动模式相关。很多人在“singleTask和singleInstance的区别”上翻车。singleTask可以用FLAG_ACTIVITY_NEW_TASK启动到某个任务栈中栈内可以有其他Activity而singleInstance是所在任务栈里只允许有这一个Activity。两者很容易混重点在于“栈内是否包含其他Activity”。第二是Handler的post方法。有人会回答“post(Runnable)是开了一个新线程”这明显是错误的。post只是把Runnable塞到MessageQueue中执行线程依然是Looper所在线程。如果主线程Looper被阻塞post的Runnable一样会被卡住。第三是AIDL的适用范围。AIDL只是在“不同应用之间的进程通信”场景下常用并不是Binder机制的代名词。Binder还能用来注册系统服务、调用ContentProvider、实现共享内存。面试中我常问“ContentProvider底层是否使用Binder”这个问题的正确答案是跨进程时通过Binder调用但数据量较大时可能需要配合匿名共享内存。第四是ANR超时时间。很多人笼统说“5秒”实际上ANR类型不同时间也不同。InputDispatching大约是5秒Service前台是20秒后台BroadcastReceiver是10秒ContentProvider卡顿的阈值要看具体情况。能在回答中区分类型的候选人说明确实有线上排查经验。第五是卡顿优化。候选人总喜欢背“使用Systrace、TraceView、Profiler”这些工具名但一旦被问“你在项目里具体发现了什么问题怎么看出来的”就说不出来。面试官真正想看的是找到问题后的分析逻辑而不只是工具列表。4.2 面试官视角的追问技巧其实也是在帮候选人很多候选人在面试时觉得被追问是压力其实好的追问是在帮你展示能力。例如候选人提到“MyApplication里做了很多初始化”我会追问“如果项目已经上线怎么在不改动业务代码的情况下优化启动速度”。这个问题没有标准答案但它允许候选人说出ContentProvider自动初始化、启动器、异步加载、服务保活等多种策略。只要他能清晰表达取舍哪怕方案不全我也会给出较高评价。我常用的追问方式是把题干改成一个模糊场景“现在要做一个IM需求消息接收和UI展示怎么设计”候选人的思考路径比答案更重要。他能不能先问“消息通道是长连接还是推送”会不会考虑到进程存活与重连这些都是隐藏加分项。我建议候选人被问到这种开放问题时先深呼吸按照“场景→约束→方案→可行性”四步去答而不只是抛出一个名词。4.3 我自己的出题体会这几年整理和迭代“01-15-02 Android面试题精选”这类题库我有一个很深的体会面试题的价值不在于题本身而在于它能点亮候选人真正思考过的地方。有些问题看起来简单比如“Activity的启动模式”如果候选人在回答时主动画了任务栈的图或者主动举了项目里遇到的一个深链场景我就会对他的技术深度和表达意愿打高分。反过来有人能把这四种模式倒背如流但问到“为什么会设计singleInstance”就沉默那大概率是背的。我个人还有一个习惯每次面完试都会在题库里给相应题目做一次标记这题问下去的阻尼够不够候选人的错误回答集中在哪是概念混淆还是经验缺失。下一轮面试前翻一翻就能更精准地调整提问方向。这种持续迭代的方式比到处收集“大厂面试题”要靠谱得多。最后再分享一个小技巧不管你是在出题还是准备面试每道题都多问自己一层“为什么”。一个知识点如果能被剥开三层以上并且每一层你都能用真实项目经历来解释基本就不怕被任何形式考到了。这份Android面试题精选的内容我也会一直按模块做拆分和扩展下一批大概率会把Compose和性能优化单独拿出来细化。
返回列表