拓冰建站拓冰建站
首页 / 资讯中心 / 正文

货拉拉Android笔试题深度解析:从Handler到性能优化

这份货拉拉2018秋招Android工程师笔试题卷一B放在今天看依然很有嚼头。虽然年份早了点但Android面试的核心盘面基本没变Java基础、四大组件、Handler、View体系、性能优化翻来覆去就这些底盘。我当年也做过不少这类题目后来也帮朋友整理过面试题今天借这份试卷把我自己的拆解思路和备考方法一并写出来希望能给正在准备Android岗位面试的朋友一些参考。1. 从一套笔试题看面试官的出题逻辑1.1 为什么招聘方要考这些老掉牙的内容很多人拿到笔试题的第一反应是这都什么年代了还在考Handler。但实际上面试官考的不是题目本身而是题目背后暴露的思维方式。2018年货拉拉的这套题表面上考的是知识点实际上是在筛选三类人基础扎实的、有实战经验的、以及只是背了面试题的。举个例子关于Activity启动模式的题目如果只答出standard、singleTop、singleTask、singleInstance四种模式的区别那只是及格水平。面试官真正想看到的是你在什么业务场景下用过singleTask用的时候遇到过什么问题为什么LaunchMode不能乱设这些追问才是拉开差距的地方。1.2 题目结构的隐藏信号我把这套题的考察范围大体梳理了一下结构大概是Java基础与并发约20%到25%Android四大组件与任务栈约25%到30%Handler与异步消息机制约10%到15%View体系与自定义控件约15%到20%性能优化与内存管理约10%到15%网络与数据存储约5%到10%从这个比例能看出货拉拉的Android岗位偏向业务型开发而不是纯粹的系统底层岗位。因为作为货运匹配平台业务迭代快页面交互多网络请求频繁对四大组件、UI性能和内存管理的要求就特别突出。相比之下如果是一套Framework方向的题肯定会在AMS、WMS、Binder这些底层机制上加大比重。1.3 关于答案的最优解思维笔试和面试还有个区别笔试看的是你分析问题和组织答案的能力面试看的是你现场沟通和应变的能力。所以做笔试题时答题的条理性往往比答案本身更重要。同样的知识点有人写三段流水账有人用小标题加要点列出原理、场景、注意点后者显然更容易拿高分。我自己的习惯是先用一句话给出结论再展开原理最后补充实践场景和注意事项。这种结论先行、层层递进的结构在面试官的阅卷体验里是非常加分的。2. Java与并发这部分决定了你的天花板2.1 面向对象不是背概念是看设计笔试题里关于面向对象的题目一般不会直接问什么是封装继承多态而是给一段代码让你分析问题或者让你设计一个类结构。比如让你为一个货运订单系统设计订单状态管理怎么用状态模式或者策略模式让代码更易扩展。这种题目的答题关键是要展示出你理解面向对象是用来管理复杂度的而不只是会背定义。你可以先说清楚这个场景中有哪些角色、哪些行为是会变化的然后说明你把会变化的部分抽象成接口或者抽象类的理由。活学活用才有效。2.2 集合框架的考点集中在选型上HashMap的原理几乎是必考的这题已经快被问烂了。但2018年的题里已经出现了HashMap在并发下会出什么问题这样的追问。这其实非常贴近实战因为早期项目中用HashMap做缓存导致CPU飙到100%的案例并不少见。答题时要能说清楚HashMap为什么线程不安全多线程put可能导致数据覆盖、JDK7里还可能形成环形链表导致死循环、hashtable为何性能差全表加锁、ConcurrentHashMap怎么优化分段锁到CAS加synchronized。如果连这些都说不好后面的并发题基本就悬了。2.3 线程与锁用生活案例理解关于线程的题目很多候选人容易栽在理论全会场景全废上。比如题目问多个线程同时扣减库存怎么保证不错乱有人张口就是synchronized、Lock、原子类但具体选哪个为什么我常用一个类比synchronized像餐馆的包间进去就得关上门简单但粗暴ReentrantLock像排队叫号可以中断、可以限时等待更灵活AtomicInteger像自动售货机单点操作天生安全但做不了复杂的复合操作。明白这个答题自然有层次感。2.4 我的Java题目答题模板遇到Java相关题目我一般分三步回答先给出结论和使用场景一句话说明什么情况下用它解决什么问题。再讲原理包括底层数据结构、锁机制、源码关键逻辑。最后补充一个实战例子说明你在项目里踩过什么坑或者做过什么优化。这个模板看起来简单但真的能帮你把思路理清。特别是踩坑的经历面试官非常吃这一套因为这说明你真的在项目中写过代码而不只是刷了题。3. 四大组件与任务栈Android开发的立身之本3.1 Activity的启动模式要背更要会用Activity启动模式这个考点要是不出面试官都觉得自己不专业。但说实话很多人只背了四种模式的定义没理解背后的使用场景。标准模式standard是默认的每次启动都新建实例适合普通页面跳转singleTop适合接收推送通知跳转的页面避免连续点通知创建一堆相同的页面singleTask适合作为主页或者首页这种只需要一个实例的页面singleInstance适合需要独立任务栈的页面比如来电界面、闹钟界面这种全局唯一且需要与其他应用隔离的场景。真实的业务场景里最常出问题的是singleTask和startActivityForResult的配合。如果你把一个页面设成了singleTask从它startActivityForResult跳转去别的页面返回结果时可能直接回调在onNewIntent里而不是onActivityResult。这个坑我在项目里真实遇到过当时排查了整整一个下午。笔试如果出这类知识组合拳的题光背定义是完全不够的。3.2 Service是重点考察对象2018年的题目里关于Service的题占了不少分值。其中最有代表性的就是startService和bindService的区别以及Service在什么情况下会被系统杀死。其实Service考察的本质是你知道Service不是后台不死的代名词。很多新手以为开了Service应用退到后台就能一直跑这是错觉。系统为了省电和腾内存会根据内存压力杀掉后台Service。你怎么通过startForeground让它变成前台服务怎么在onStartCommand里返回合适的常量START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT来控制重启行为这些都是高频考点。3.3 BroadcastReceiver与LocalBroadcast广播这块题目一般会考察注册方式静态注册和动态注册的区别、启动限制Android 8.0之后静态注册隐式广播受限以及安全方面的问题。这里有个延伸知识点很多人会忽略LocalBroadcastManager已经废弃了官方推荐改用LiveData或者Flow配合生命周期组件。如果在笔试答案里能提一句现在的推荐方案是什么会让面试官觉得你有在持续跟进新东西而不是停留在老框架里出不来。3.4 任务栈与返回键的管理关于任务栈的题最容易翻车的是如何让某个Activity在不同应用间共享和如何清空任务栈。前者是singleInstance的典型场景后者涉及Intent.FLAG_ACTIVITY_CLEAR_TASK和FLAG_ACTIVITY_NEW_TASK的组合。我看到不少候选人对Intent Flag的理解停留在用过但不知道为什么的层面。实际上这些Flag的底层逻辑在ActivityTaskManager的源码里都有清晰的注释和启动流程的判断分支。笔试时如果时间充裕能画一下任务栈的变化过程再配合说明每个Flag的作用这题基本就稳了。4. Handler机制与消息循环为什么总在问4.1 从一道送分题到一道拉分题Handler机制这道题基本是Android面试的必考题。但在笔试题里它的难度梯度可以拉得很开从Handler、Looper、MessageQueue是什么关系到主线程的Looper是怎么启动的再到IdleHandler是什么时候执行的同步屏障是怎么回事。最基础的答法Handler通过sendMessage把消息放进MessageQueueLooper通过loop方法不断从队列里取出消息交给Handler的handleMessage处理。这个流程看似简单但里面藏了很多细节。4.2 深度追问与源码分析真正有区分度的问题在于一个线程可以有几个Looper几个Handler一个Looper多个HandlerThreadLocal保证每个线程只存一个Looper实例Looper.loop()为什么不会阻塞主线程因为Android的UI事件本身就是通过消息循环驱动的没有消息时就阻塞在nativePollOnce省电Handler.postDelayed()一定延迟执行吗不只是把消息按时间排序插入队列如果前面的消息耗时太长照样会延迟很久子线程里怎么使用Handler先Looper.prepare()再Looper.loop()这些细节如果都能写清楚说明你对消息机制的源码有研究过这在笔试里是明显的加分项。4.3 内存泄漏与Handler的经典案例Handler导致的内存泄漏几乎每次笔试面试都会碰到。标准场景内部类Handler持有外部Activity的引用当Activity销毁时MessageQueue里还有未处理的消息导致Activity无法被回收。标准答案大家都会背用静态内部类加WeakReference。但更好的回答是在onDestroy里把消息清掉handler.removeCallbacksAndMessages(null)。这个细节虽然小但在业务里非常实用。笔试时能写出这一句就比只说WeakReference的人高一截。注意对于这类题不要只答一个使用WeakReference就完了。从为什么泄漏到怎么解决再到如何彻底清理这个链路才是把关人真正想看到的完整逻辑。5. View体系与自定义控件动手能力的分水岭5.1 事件分发机制背完流程图也得会画事件分发可以说是自定义View题目里的题眼。常见的考察方式有三种直接问dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent的执行顺序给一段自定义ViewGroup的代码让你分析事件走向或者让你解决一个滑动冲突的实际问题。我的建议是不要只停留在文字层面最好自己画一张顺序图把Activity到ViewGroup再到View的传递过程画清楚。然后针对横向滑动与纵向滑动的冲突说清楚你在哪个方法里做拦截、用什么条件做判断。这种题答好了能给整份试卷抬很多分。5.2 自定义View的测量与绘制流程关于自定义View笔试题里常考onMeasure、onLayout、onDraw的执行顺序和各自作用。这里有一个易错点很多人分不清MeasureSpec的三种模式UNSPECIFIED、EXACTLY、AT_MOST在什么情况下会被用到。简单说match_parent和指定宽高时是EXACTLYwrap_content时是AT_MOSTListView和ScrollView里测量子项时可能是UNSPECIFIED。如果题目让你实现一个自适应正方形的View就需要在onMeasure里根据widthMeasureSpec取宽然后setMeasuredDimension(width, width)同时注意处理好AT_MOST的情况。5.3 布局优化的高频考点布局优化这块常考的点有include、merge、ViewStub的区别和使用场景为什么RecyclerView比ListView更高效ConstraintLayout的优势。其中ConstraintLayout的优势这道题在2018年已经出现了当时很多人还答不利索放在今天就是基础题。如果你能在笔试里写出用ConstraintLayout可以减少布局层级减少measure/layout时间配合constraintDimensionRatio可以轻松实现比例布局这种具体到API的答案那就显得很有实战经验。6. 性能优化与内存管理决定你的项目能走多远6.1 内存泄漏的六个经典场景性能优化这块试卷里列举你遇到过哪些内存泄漏场景几乎是必考题。我能想到的常见场景至少包括Handler持有Activity引用前面提过静态变量引用Activity或View内部类非静态内部类隐式持有外部类引用匿名Thread或AsyncTask持有外部引用未注销BroadcastReceiver、未解绑Service单例模式持有了需要释放的Context答题时不要只是罗列最好挑两个你真实踩过的坑展开说。比如我当时在项目里遇到过一个很隐蔽的泄漏一个全局的单例工具类持有了Activity的Context导致整个Activity栈无法释放内存曲线一路飙升。通过LeakCanary定位到问题后把所有Context引用改成了Application级别的。这个案例在面试里讲出来效果比背十个知识点都好。6.2 ANR的定位与解决思路关于ANR的题先要弄清楚ANR发生的三种场景输入事件5秒无响应、BroadcastReceiver前台10秒后台60秒未完成、Service前台20秒后台200秒未完成。答题时不能只答定义要给出如何定位的思路。一般路径是先看/data/anr/下的traces文件找到主线程卡在哪个方法再用adb shell top或systrace看CPU占用情况重点排查主线程是否做了IO操作、是否死锁、是否被Binder调用阻塞。在笔试题里如果能写出主线程不允许做网络操作和磁盘IO这个基本规矩再补充SharedPreferences的apply和commit在跨进程场景下的差异也容易引发ANR那答题质量就明显不一样了。6.3 渲染优化掉帧到底是怎么来的渲染优化的题目核心关键词是掉帧。当你滑动页面时如果一帧的绘制时间超过16.6ms1000ms/60FPS就会产生掉帧。答题思路可以从三个层面展开App层布局层级过深、过度绘制、onDraw里做了复杂运算系统层vsync信号被阻塞、GPU渲染压力过大工具层怎么用Profile GPU Rendering、Systrace、Layout Inspector定位还有一个非常实战的优化点减少过度绘制。用开发者选项里的调试GPU过度绘制开关能看到页面各区域的overdraw级别。优化的方向包括去掉不必要的背景、用ViewStub延迟加载、复用布局等。7. 网络与数据存储Android开发的体力活7.1 HTTP与HTTPS的考察点网络这块题目一般集中于HTTP协议基础、HTTPS的加密流程、TCP与UDP的区别。比较有区分度的问法是HTTPS的一次完整请求中证书校验和密钥协商是怎么工作的标准回答可以这么组织客户端收到服务端证书后先校验证书的合法性是否由可信CA签发、是否过期、域名是否匹配然后用证书里的公钥加密一个随机生成的对称密钥发给服务端服务端用私钥解密得到对称密钥之后双方就通过这个对称密钥加密通信。如果能在答案里提到非对称加密算法如RSA用于密钥交换对称加密算法如AES用于实际数据传输因为对称加密速度更快那就说明你是真的理解了这个设计而不只是背了流程。7.2 数据存储方案怎么选Android的数据存储方案有SharedPreferences、文件存储、SQLite数据库、Room、ContentProvider以及后来出现的DataStore。考察数据存储的题目一般都不是直接问API怎么用而是抛一个场景让你选方案。比如App需要在本地存一份用户配置信息那答案肯定倾向于SharedPreferences或者DataStore而不是SQLite。但如果数据量大、结构复杂、需要多表关联查询SQLite或Room就合适。还有一个容易被忽略的点SharedPreferences的apply是异步写磁盘commit是同步写磁盘两者的差异在笔试题里经常出现。千万不要混用在主线程commit可能会卡UI。这一点写上能体现出你关注细节。7.3 序列化Serializable与Parcelable序列化在Android笔试题里出现频率不低。考察的核心是Serializable是Java自带的通过反射实现简单但效率低会产生大量临时对象Parcelable是Android特有的基于内存共享的方式实现效率高适合进程间通信和数据传递。答题时如果能提到Intent传递对象必须实现Serializable或Parcelable再加一句为什么官方推荐Parcelable而不是Serializable主要是性能考虑这题就基本满分了。8. 从2018年的真题到2024年的面试新趋势8.1 当年没考的现在成了重点2018年的试卷里没有Kotlin没有Jetpack Compose没有协程也没有Flutter。放在2024年的面试环境里这些都是绕不开的话题。比如ViewModel和LiveData的设计原理协程的挂起和恢复机制Compose的重组与状态管理这些新知识点其实都是在老地基上长出来的。ViewModel能感知生命周期、在配置变更后自动保留数据这个思路和2018年考察的Activity被回收后数据怎么恢复完全是同一个问题只是现在有了更优雅的解决方案。所以我在准备面试时从来不把新知识和老知识割裂开看。学协程时想一想它和Handler消息机制的关系学Compose时想一想它和传统自定义View的区别这样知识体系才是连成片的。8.2 新趋势下的笔试重点会怎么变从我最近了解到的面经来看2024年Android笔试的侧重点有几个明显变化代码题比重变高了不只是手写算法还会要求手写一个简单的自定义View、封装一个网络请求框架Kotlin协程取代了很大一部分Java并发的考察性能优化越来越看重内存泄漏和启动速度而不是简单背概念对第三方框架的原理要求变深了比如Glide的缓存机制、Retrofit的动态代理、OkHttp的拦截器链但无论如何变化四大组件、Handler、View体系、内存管理这些地基题目仍然会出现。把2018年这套题吃透了再补上新知识的缺口知识体系才是完整的。8.3 给准备面试的人几个实用建议结合我自己刷题和帮人改简历的经验最后分享几个实用的备考方法第一不要只刷题要边刷边写。把每道题的关键点用markdown整理成自己的知识库每周复习一遍比反复看别人的面经有效得多。第二准备几个真实项目案例。面试官问你遇到过什么问题时千万不要现场编提前想好三到五个你实际踩过的坑把问题背景、定位过程、解决方案、最终效果都写出来到时候直接结构化地讲。第三关注官方文档和版本更新。很多面试官会问Android 12、13、14里有哪些新变化这些信息官方文档里都有。如果能随口说出Android 13开始通知需要动态申请权限Android 14对前台服务类型有了更严格的限制会显得你一直在跟进社区动态而不是只盯面试题。第四做一个开源项目或者写技术博客。在简历里写熟悉常用框架原理不算什么但如果能贴出一个自己写的技术专栏或者开源小项目说服力完全不一样。这也是我在面试别人时最看重的信号。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门