跳到主要内容1-3 年 Android 开发工程师面试指南:精选核心面试题解析 | 极客日志Javajava算法
1-3 年 Android 开发工程师面试指南:精选核心面试题解析
Android 开发面试涵盖 Java 基础、UI 绘制、组件机制及框架原理。本文整理了 40 道高频面试题,包括抽象类与接口选择、重载重写区别、内部类机制、字符串常量池、View 绘制流程、Activity Window View 关系、RecyclerView 嵌套优化、以及音视频、Flutter、算法和 Framework 等进阶内容。旨在帮助开发者系统复习技术栈,提升面试通过率。
2924408370 浏览 一、前言
Android 开发领域技术更新迅速,面试不仅考察基础知识的掌握程度,更关注对原理的理解及实际问题的解决能力。本文整理了 1-3 年经验开发者在面试中高频遇到的 40 道核心题目,涵盖 Java 基础、UI 绘制、组件机制、Framework 原理及算法等多个维度,旨在帮助开发者系统复习技术栈,提升面试通过率。
二、Java 基础面试题
1. Java 中提供了抽象类还有接口,开发中如何去选择呢?
抽象类的设计目的是代码复用;接口的设计目的是对类的行为进行约束。
- 抽象类:当需要表示 is-a 的关系,并且需要代码复用时用抽象类。例如父类提供部分默认实现,子类继承并扩展。
- 接口:当需要表示 has-a 的关系,或者需要多态扩展功能时使用接口。接口强调功能契约,一个类可以实现多个接口。
示例对比:
定义狗的行为,如果所有狗都需要睡觉(通用实现),使用抽象类;如果只有训练过的狗能握手(特定技能),使用接口。
public abstract class Dog {
public void sleep() {
System.out.println("Dog is sleeping");
}
public abstract void eat();
}
public interface Handshake {
void doHandshake();
}
public class HandShakeDog extends Dog implements Handshake {
@Override
public void eat() { System.out.println("Eating..."); }
@Override
public void doHandshake() { System.out.println("Shaking hand"); }
}
- 抽象类强调从属关系,接口强调功能。
- 抽象类可以有构造方法,接口不能有。
- 抽象类成员变量可以是各种类型,接口成员变量只能是 static final 常量。
- 抽象类可以包含非抽象方法,接口在 Java 8 之前只能有抽象方法(Java 8+ 支持 default/static 方法)。
2. 重载和重写是什么意思,区别是什么?
重写 (Override):
子类重新定义父类中已有的方法。要求方法名、参数列表相同,返回类型兼容,访问权限不能更低。常用于多态场景。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
重载 (Overload):
同一个类中,方法名相同但参数列表不同(类型、个数、顺序)。与返回类型无关。常用于提供便捷的方法入口。
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
}
3. 静态内部类是什么?和非静态内部类的区别是什么?
静态内部类:使用 static 修饰的内部类。它不持有外部类的实例引用,可以直接通过 new Outer.Inner() 创建,且只能访问外部类的静态成员。
非静态内部类:默认的内部类。隐式持有外部类实例引用 (OuterClass.this),必须依赖外部类实例才能创建 (outer.new Inner()),可以访问外部类的所有成员。
字节码差异:
非静态内部类构造函数会接收外部类实例作为参数,而静态内部类不会。
4. String s = new String("xxx");创建了几个 String 对象?
- 如果常量池中没有 "xxx":JVM 先在堆中创建 "xxx" 对象并存入常量池,然后
new 关键字在堆中再创建一个新对象。共 2 个。
- 如果常量池中已有 "xxx":
new 关键字仅在堆中创建一个新对象。共 1 个。
三、高级 UI 面试题
1. View 的绘制流程是从 Activity 的哪个生命周期方法开始执行的?
View 的绘制流程通常认为是在 onResume 之后触发,具体由 WindowManager.addView 启动。
ActivityThread.handleResumeActivity -> performResumeActivity -> activity.performResume -> activity.onResume()。
- 在
handleResumeActivity 中,调用 wm.addView(decor, l)。
WindowManagerImpl.addView -> WindowManagerGlobal.addView。
- 创建
ViewRootImpl 对象,调用 root.setView(view, wparams, ...)。
setView 内部调用 requestLayout() 和 performTraversals(),从而开始 Measure、Layout、Draw 流程。
2. Activity, Window, View 三者的联系和区别
- Activity:四大组件之一,负责界面交互和业务逻辑,是用户可见窗口的载体。
- Window:窗体抽象,顶级容器。
PhoneWindow 是其唯一实现类。Activity 内部持有一个 mWindow 对象来管理 View。
- View:UI 元素,被放置在 Window 容器中显示。
关系:
Activity 通过 attach 方法初始化 PhoneWindow。事件分发时,Activity 将事件交给 Window,Window 通过 DecorView 向下分发给具体的 View。WindowManager 负责管理 Window 的添加、删除和布局更新。
3. ScrollView 下嵌套一个 RecyclerView 通常会出现什么问题?
问题:滚动冲突。ScrollView 会消耗触摸事件,导致 RecyclerView 无法滑动;或者两者同时滚动,体验极差。
- 禁用 RecyclerView 滚动:在
onMeasure 中动态设置 RecyclerView 高度为父容器高度之和。
- 自定义嵌套滚动控件:使用 NestedScrollView 或第三方库如
NestedRecyclerView。
- 监听滚动方向:根据 ScrollView 的滚动状态动态控制 RecyclerView 的滚动。
四、Java 进阶专题
1. Java 集合框架
- ArrayList vs LinkedList:ArrayList 基于数组,随机访问快,插入删除慢;LinkedList 基于双向链表,插入删除快,随机访问慢。
- HashMap 原理:数组 + 链表 + 红黑树(JDK 1.8+)。哈希冲突时链表转红黑树(长度>8 且数组长度>64)。扩容因子 0.75。
- ConcurrentHashMap:JDK 1.7 分段锁,JDK 1.8 CAS+synchronized 保证线程安全,性能更高。
2. Java 多线程
- 线程创建:继承 Thread、实现 Runnable、实现 Callable、线程池。
- 线程池参数:corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, handler。
- volatile 关键字:保证可见性,禁止指令重排,不保证原子性。
- synchronized:可重入锁,JVM 层面实现,底层依靠 Monitor。
3. Java 虚拟机 (JVM)
- 内存区域:堆(Heap)、栈(Stack)、方法区(Method Area)、程序计数器、本地方法栈。
- 垃圾回收:标记 - 清除、复制、标记 - 整理、分代收集。常见 GC 算法:Serial, Parallel, CMS, G1。
- 类加载机制:加载、验证、准备、解析、初始化。双亲委派模型。
五、Android 进阶专题
1. Android 四大组件相关
- Activity:单例模式(进程内),生命周期管理,启动模式(Standard, SingleTop, SingleTask, SingleInstance)。
- Service:前台服务(Foreground Service)保活,绑定服务(Bound Service)通信。
- BroadcastReceiver:静态注册(Manifest),动态注册(Context)。有序广播、粘性广播。
- ContentProvider:跨进程数据共享,URI 匹配规则。
2. Android 异步任务和消息机制
- Handler 机制:MessageQueue(队列)-> Handler(发送/处理)-> Looper(循环取消息)-> Message(消息对象)。
- 主线程 Looper:Application 启动时创建,子线程需手动创建 Looper。
- AsyncTask:已废弃,推荐使用 Executor 或 Kotlin Coroutines。
3. Android UI 绘制相关
- View 绘制流程:
measure -> layout -> draw。
- 硬件加速:开启后利用 GPU 渲染,关闭后走 CPU 路径。注意某些 API 不支持硬件加速。
- 过度绘制优化:使用 Systrace 分析,减少背景色重叠。
4. Android 性能调优相关
- 启动优化:延迟初始化,异步加载,减少主线程耗时操作。
- 内存优化:避免内存泄漏(WeakReference),监控 OOM,图片压缩(BitmapFactory.Options)。
- 包体积优化:ProGuard/R8 混淆,移除无用资源,拆分 APK/Dex。
5. Android 中的 IPC
- Binder:Android 特有的 IPC 机制,C/S 架构,高效安全。
- AIDL:Android Interface Definition Language,用于定义接口。
- Messenger:基于 Handler 的轻量级 IPC。
- Socket:网络通信方式,适用于跨设备。
6. Android 系统 SDK 相关
- BuildConfig:编译时生成的配置信息。
- Manifest 合并:Library 模块 Manifest 与 App 模块合并规则。
- Gradle 构建:Task 依赖,SourceSet 配置。
7. 第三方框架分析
- Glide/Picasso:图片加载,缓存策略,占位图。
- Retrofit:HTTP 客户端,OkHttp 封装,RxJava 集成。
- Room:SQLite 封装,Entity, DAO, Database。
8. 综合技术及设计模式
- 单例模式:双重检查锁(DCL)。
- 观察者模式:EventBus, LiveData。
- 工厂模式:Fragment 创建。
9. 数据结构方面
- 链表、树、图:基本遍历算法。
- 哈希表:碰撞解决。
- 排序算法:快速排序、归并排序、堆排序。
10. 计算机网络方面
- TCP/IP:三次握手、四次挥手。
- HTTP/HTTPS:请求响应头,状态码,SSL/TLS 加密。
- DNS:域名解析过程。
11. Kotlin 方面
- 空安全:?., !!, ?:。
- 协程:suspend 函数,CoroutineScope,Dispatchers。
- 扩展函数:String.length 等。
六、音视频开发高频面试题
1. 为什么巨大的原始视频可以编码成很小的视频呢?
通过视频编码压缩技术(如 H.264/H.265)。利用帧间冗余(运动补偿)和帧内冗余(离散余弦变换 DCT)去除重复信息,量化降低精度,熵编码进一步压缩。
2. 怎么做到直播秒开优化?
- 预加载:连接建立前预留资源。
- 首屏优化:关键帧同步,CDN 加速。
- 协议选择:WebRTC 低延迟,HLS 兼容性高。
3. 直方图在图像处理里面最重要的作用是什么?
反映图像亮度分布情况,用于自动曝光调整、对比度增强、阈值分割等。
4. 数字图像滤波有哪些方法?
- 线性滤波:均值滤波、高斯滤波。
- 非线性滤波:中值滤波(去噪效果好)。
- 边缘检测:Sobel, Canny。
5. 图像可以提取的特征有哪些?
颜色特征、纹理特征、形状特征、关键点特征(SIFT, SURF, ORB)。
七、Flutter 高频面试题
1. Dart 语言特性
- 强类型:可选类型注解。
- Isolate:并发模型,类似多线程但不共享内存。
- Mixin:代码复用机制。
- Future/Stream:异步编程。
2. Flutter 特性
- 热重载:修改代码即时生效。
- Widget 树:一切皆 Widget。
- Skia 引擎:自绘 UI,跨平台一致。
3. Widget, Element, RenderObject 关系
- Widget:不可变配置描述。
- Element:Widget 在树中的实例,负责生命周期和更新。
- RenderObject:负责布局和绘制。
4. Flutter 和 Dart 的关系
Dart 是 Flutter 的开发语言,Flutter 是基于 Dart 实现的 UI 框架。
八、算法高频面试题
1. 如何高效寻找素数
使用埃拉托斯特尼筛法(Sieve of Eratosthenes),时间复杂度 O(n log log n)。
2. 如何运用二分查找算法
适用于有序数组。维护左右指针,计算中间值比较,缩小区间。注意边界条件防止死循环。
3. 如何高效解决接雨水问题
双指针法或单调栈。记录左右最大高度,当前水位取决于 min(leftMax, rightMax) - height[i]。
4. 如何去除有序数组的重复元素
双指针。快指针遍历,慢指针指向不重复元素的末尾位置,覆盖重复项。
5. 如何进行模幂运算
快速幂算法。将指数二进制分解,平方底数并根据二进制位累乘结果,时间复杂度 O(log n)。
九、Android Framework 方面
1. 系统启动流程
Zygote 进程孵化 -> SystemServer 启动 -> AMS/WMS 初始化 -> Launcher 启动。
2. Binder 面试题解析
Binder 驱动层、HAL 层、应用层。一次拷贝机制,Token 认证。
3. Handler 面试题解析
Message 对象池复用,Looper 死循环,ThreadLocal 存储 Looper。
4. AMS 面试题解析
ActivityManagerService,管理所有 Activity 状态,进程调度,任务栈管理。
十、企业常见面试题
- SD 卡:Android 6.0+ 不再支持 SD 卡作为内部存储,仅作为便携存储。
- 数据存储方式:SharedPreferences, SQLite, File, ContentProvider, Network。
- BroadcastReceiver:动态注册需在 Context 销毁时注销,防止内存泄漏。
- SP 频繁操作后果:阻塞主线程,影响性能。建议异步写入或使用 DataStore。
- DVM 与 JVM 的区别:DVM 针对移动设备优化,寄存器架构;JVM 栈架构。ART 取代了 DVM。
- ART:Android Runtime,AOT 编译,提升运行效率,增加安装时间。
- Activity 生命周期:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。
- Application 启动 Activity:可以,但需注意上下文权限和启动模式。
- Activity 状态:Running, Paused, Stopped, Killed。
- 横竖屏切换:销毁重建,保留状态可使用 onRetainNonConfigurationInstance 或 ViewModel。
- Intent 传递大数据:使用 Bundle 限制大小,大文件建议使用 FileProvider 或 URI。
- Service 保活:前台服务,JobScheduler,系统白名单。
- ANR 原因:主线程耗时超过 5 秒,输入事件超时 5 秒。优化方案:异步处理,减少主线程负载。
- OOM 原因:内存泄漏,大对象未释放。优化方案:LeakCanary 检测,图片压缩。
- Fragment 生命周期:onAttach -> onCreate -> onCreateView -> onViewCreated -> onStart -> onResume。
- Adapter 刷新:notifyDataSetChanged 慎用,使用 DiffUtil 局部刷新。
- Kotlin 空安全:? 允许为空,!! 强制非空,?. 安全调用。
- Jetpack 组件:Lifecycle, ViewModel, LiveData, Room, Navigation。
- Gradle 增量编译:利用上次构建结果,只编译变更文件。
- ProGuard 混淆:保留反射类,保留 Native 方法,移除无用代码。
- NDK 开发:C/C++ 编写高性能模块,JNI 桥接。
- OpenGL ES:图形渲染标准,用于游戏和特效。
- 多媒体播放:MediaPlayer, ExoPlayer。
- 蓝牙开发:BLE 低功耗蓝牙,配对流程。
- 定位服务:GPS, Network, Fused Location Provider。
- 推送通知:FCM, 厂商通道。
- WebView 优化:JSBridge,缓存策略,内存清理。
- 安全性:SSL Pinning,代码加固,敏感数据加密。
- 测试:JUnit, Espresso, Robolectric。
- CI/CD:Jenkins, GitLab CI,自动化打包发布。
- 版本管理:Semantic Versioning。
- 依赖管理:Maven, JitPack。
- 模块化:业务解耦,独立编译。
- 架构模式:MVC, MVP, MVVM, Clean Architecture。
- 数据库迁移:Room Migration。
- 网络请求:OkHttp Interceptor,日志拦截。
- 图片加载:LruCache,磁盘缓存。
- 动画:属性动画,帧动画,矢量动画。
- 权限管理:运行时权限,Android 10+ 分区存储。
- 兼容性:最小 SDK 版本,适配深色模式,适配折叠屏。
以上涵盖了 Android 开发的核心知识点,建议结合实际项目经验深入理解每个概念的原理与应用场景。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online