Android 开发面试准备指南
简历的准备
简历重点是突出自我介绍、擅长技能、项目经验。
- 自我介绍:要做到一句话就能表述清楚自己的优势,例如学习能力(短时间熟练掌握技能)、个人履历(BAT 背景优势)、积极努力(个人推动什么项目等)。
- 擅长技能:专业技能的描述词无非就那么几种:精通、熟练、熟悉、了解。精通感觉一般还是不要写,除非你在某个技术点上真的有足够的把握,真正能做到精通一门语言、一个分布式框架这才是精通。熟悉、熟练居多,精通是典型的金字塔顶部。总之,简历不要过于突出精通项数,而是突出精通的领域。
- 项目经验:突出自己的王牌项目,最有技术含量、挑战和帮助最大的一个项目讲就足够了。面试的过程中面试官也会重点让你描述这个擅长的项目,提前模拟这个项目的讲解顺序和重点,而不是临场讲解。
复习技巧
学习没有捷径可言。信奉好记性不如烂笔头,也信奉书读百遍其义自见。
- 一定要去实践:对于程序员而言,不单单是死记硬背,我们有更好的方式去学习,比如写 demo 去验证,比如学习源码的过程中,一定要自己去翻看源码,多翻几遍看熟了再说。
- 边学边做笔记总结:学习笔记很重要,不仅要记笔记,还要写心得体会,文字笔记、画图、总结等,方式很多,但是一定要自己认真去做,不要太相信自己的记忆,只有反复记忆,加深理解才行。
- What、How、Why:学习知识点的过程中,可以遵循 What、How、Why 这个三板斧。即这个东西是什么?它是怎么做的?它为什么这么做,原理是什么,有没有更好的方式?
- 由浅到深,由点及面:在复习的过程中,都是从一个个小的知识点开始学的,复习到一定阶段,可以尝试着去把这些东西串联起来,由点及面。
- 复盘项目:在复习的过程中,一定要及时跟你做过的项目结合起来,这样也可以反哺你的项目,你在面试时就知道怎么聊了,就会有项目讲到知识点,由一个知识点串联到另一个知识点,这样你的知识体系就建立起来了。
面试前的心态调整
心态的调整决定了事半功倍或是事倍功半。笔试的状态,实力的发挥,可以影响一个面试过程的方方面面。心态崩了,就只剩运气了,offer 估计也就走远了。
那怎么调整自己的心态呢?
- 首先是要正视自己的能力:不轻视,不高估。不高估就是要清楚自己的能力范围,不是说期望过高不好,但过高的期望会让你的心理变得脆弱,稍有不顺心态就有崩掉的趋势。因为面试毕竟有太大的偶然性,就算你达到了一定的水平,相应水平的岗位也不是百发百中的。
- 不要总给自己消极的暗示:心态差了,积极调整。大多数的人,总暗示自己说什么时间不多了,怎么每天过这么快效率怎么这么低。到笔试了,跟自己说这个算法太难了,肯定做不出来。临到面试了,跟自己说千万别问我 linux 内核,别问我分布式,问我肯定完;面试过之后,没有结果,就天天想肯定又挂了,唉,我怎么这么菜。
- 如果这一系列的表现形成习惯:那心态这个系数最多 0.5,能发挥出来的东西也都打了一半的折扣。凡事都不要太悲观,就算一个 offer 没拿到,正常情况是这个失败的经历产生的经验和总结是会让下一次的成功率提高的,千万不要在哪里跌倒就在哪里躺下了,站起来把绊脚石挪开就好了!
- 心态差的时候反而要停下你重复而没有效率的工作:可以静下心来去复盘调整一下。对于身边的朋友,多交流,不比较。能有一些一起准备的好伙伴是件非常好的事情,不仅可以互相督促,而且可以在交流和分享的过程中取长补短。
对自己的水平有个很清楚的认识,并选择自己合适的公司,好好准备自己的笔试、面试,不怕失败,但保证每次面试都有收获和提高,那满意的 offer 早晚会来。
各大厂常见真题分享
以下整理了部分大厂常见的 Android 面试题目,涵盖基础、原理、架构及算法等方面。
阿里巴巴
- LRUCache 原理
- 图片加载原理
- 模块化实现(好处,原因)
- JVM
- 视频加密传输
- 统计启动时长,标准
- 如何保持应用的稳定性
- ThreadLocal 原理
- 谈谈 classloader
- 动态布局
- 热修复,插件化
- HashMap 源码,SpareArray 原理
- 性能优化,怎么保证应用启动不卡顿
- 怎么去除重复代码
- SP 是进程同步的吗?有什么方法做到同步
- 介绍下 SurfView
- HashMap 实现原理,ConcurrentHashMap 的实现原理
- BroadcastReceiver,LocalBroadcastReceiver 区别
- Bundle 机制
- Handler 机制
- android 事件传递机制
- 线程间操作 List
- App 启动流程,从点击桌面开始
- 动态加载
- 类加载器
- OSGI
- Https 请求慢的解决办法,DNS,携带数据,直接访问 IP
- GC 回收策略
- 画出 Android 的大体架构图
- 描述清点击 Android Studio 的 build 按钮后发生了什么,大体说清一个应用程序安装到手机上时发生了什么
- 对 Dalvik、ART 虚拟机有基本的了解
- Android 上的 Inter-Process-Communication 跨进程通信时如何工作的
- App 是如何沙箱化,为什么要这么做
- 权限管理系统(底层的权限是如何进行 grant 的)
- 进程和 Application 的生命周期
- 系统启动流程 Zygote 进程 –> SystemServer 进程 –> 各种系统服务 –> 应用进程
- recycleview listview 的区别,性能
- 排序,快速排序的实现
- 树:B 树的介绍
- 图:有向无环图的解释
- TCP/UDP 的区别
- synchronized 与 Lock 的区别
- volatile
- Java 线程池
- Java 中对象的生命周期
- 类加载机制
- 双亲委派模型
- Android 事件分发机制
- MVP 模式
- RxJava
- 抽象类和接口的区别
- 集合 Set 实现 Hash 怎么防止碰撞
- JVM 内存区域 开线程影响哪块内存
- 垃圾收集机制 对象创建,新生代与老年代
- 二叉树 深度遍历与广度遍历
- B 树、B+ 树
- 消息机制
- 进程调度
- 进程与线程
- 死锁
- 进程状态
- JVM 内存模型
- 并发集合了解哪些
- ConCurrentHashMap 实现
- CAS 介绍
- 开启线程的三种方式,run() 和 start() 方法区别
- 线程池
- 常用数据结构简介
- 判断环(猜测应该是链表环)
- 排序,堆排序实现
- 链表反转
- 动态权限适配方案,权限组的概念
- 网络请求缓存处理,okhttp 如何处理网络缓存的
- 图片加载库相关,bitmap 如何处理大图,如一张 30M 的大图,如何预 - 防止 OOM
- 进程保活
- listview 图片加载错乱的原理和解决方案
- https 相关,如何验证证书的合法性,https 中哪里用了对称加密,哪里用了非对称加密,对加密算法(如 RSA)等是否有了解
美团
- static synchronized 方法的多线程访问和作用,同一个类里面两个 synchronized 方法,两个线程同时访问的问题
- 内部类和静态内部类和匿名内部类,以及项目中的应用
- handler 发消息给子线程,looper 怎么启动
- View 事件传递
- activity 栈
- 封装 view 的时候怎么知道 view 的大小
- arraylist 和 linkedlist 的区别,以及应用场景
- 怎么启动 service,service 和 activity 怎么进行数据交互
- 下拉状态栏是不是影响 activity 的生命周期,如果在 onStop 的时候做了网络请求,onResume 的时候怎么恢复
- view 渲染
今日头条
- 数据结构中堆的概念,堆排序
- 死锁的概念,怎么避免死锁
- ReentrantLock、synchronized 和 volatile
- HashMap
- singleTask 启动模式
- 用到的一些开源框架,介绍一个看过源码的,内部实现过程
- 消息机制实现
- ReentrantLock 的内部实现
- App 启动崩溃异常捕捉
- 事件传递机制的介绍
- ListView 的优化
- 二叉树,给出根节点和目标节点,找出从根节点到目标节点的路径
- 模式 MVP,MVC 介绍
- 断点续传的实现
- 集合的接口和具体实现类,介绍
- TreeMap 具体实现
- synchronized 与 ReentrantLock
- 手写生产者/消费者模式
- 逻辑地址与物理地址,为什么使用逻辑地址
- 一个无序,不重复数组,输出 N 个元素,使得 N 个元素的和相加为 M,给出时间复杂度、空间复杂度。手写算法
- Android 进程分类
- 前台切换到后台,然后再回到前台,Activity 生命周期回调方法。弹 Dialog,生命值周期回调方法
- Activity 的启动模式
爱奇艺
- RxJava 的功能与原理实现
- RecycleView 的使用,原理,RecycleView 优化
- ANR 的原因
- 四大组件
- Service 的开启方式
- Activity 与 Service 通信的方式
- Activity 之间的通信方式
- HashMap 的实现,与 HashSet 的区别
- JVM 内存模型,内存区域
- Java 中同步使用的关键字,死锁
- MVP 模式
- Java 设计模式,观察者模式
- Activity 与 Fragment 之间生命周期比较
- 广播的使用场景
百度
- Bitmap 使用时候注意什么?
- Oom 是否可以 try catch?
- 内存泄露如何产生?
- 适配器模式,装饰者模式,外观模式的异同?
- ANR 如何产生?
- String buffer 与 string builder 的区别?
- 如何保证线程安全?
- java 四中引用
- Jni 用过么?
- 多进程场景遇见过么?
- 关于 handler,在任何地方 new handler 都是什么线程下
- sqlite 升级,增加字段的语句
- bitmap recycler 相关
- 强引用置为 null,会不会被回收?
- glide 使用什么缓存?
- Glide 内存缓存如何控制大小?
- 如何保证多线程读写文件的安全?
携程
- Activity 启动模式
- 广播的使用方式,场景
- App 中唤醒其他进程的实现方式
- AndroidManifest 的作用与理解
- List,Set,Map 的区别
- HashSet 与 HashMap 怎么判断集合元素重复
- Java 中内存区域与垃圾回收机制
- EventBus 作用,实现方式,代替 EventBus 的方式
- Android 中开启摄像头的主要步骤
网易
- concurrenthashmap
- volatile
- synchronized 与 Lock
- Java 线程池
- wait/notify
- NIO
- 垃圾收集器
- Activity 生命周期
- AlertDialog,popupWindow,Activity 区别
小米
- String 为什么要设计成不可变的?
- fragment 各种情况下的生命周期
- Activity 上有 Dialog 的时候按 home 键时的生命周期
- 横竖屏切换的时候,Activity 各种情况下的生命周期
- Application 和 Activity 的 context 对象的区别
- 序列化的作用,以及 Android 两种序列化的区别
- List 和 Map 的实现方式以及存储方式
- 静态内部类的设计意图
- 线程如何关闭,以及如何防止线程的内存泄漏
备考建议
以上是在一些面经分享平台上整理的一些大厂比较常见的 Android 面试题目。真正面试中,尤其是大公司中面试,没有固守成规的问法,唯有实力认真才能赢。
建议考生在使用这份题库时:
- 针对性复习:根据目标公司的业务特点,侧重复习相关领域的知识点。
- 深入原理:对于高频考点如 Handler、Binder、JVM、GC 等,务必深入源码或官方文档理解底层机制。
- 模拟演练:尝试用自己的语言复述答案,确保逻辑清晰,表达流畅。
- 持续积累:技术更新快,保持阅读技术博客、关注社区动态的习惯,不断更新知识库。
在很多公司,尤其是大厂,特别喜欢主动性和积极性的人才。主动性的人更加擅长于克服当前的困难,并把事情做好,在遇到挫折后,更容易调整好心态,且积极去推进项目。这一点,不管是对于在复习准备的整个过程中,还是在后面的面试的沟通过程中,有经验的大厂面试官可以通过与你的交流细节,可以捕获到部分你的性格优势和劣势。总之,主动性和乐观性的人,更有利于今后的发展,这一点不仅仅适用于面试,更适用于今后的工作发展。


