一、基础组件与生命周期
-
Activity生命周期
-
问题 :描述Activity从启动到销毁的完整生命周期方法,并说明
onSaveInstanceState()
的调用时机。 -
参考答案:
-
onCreate()
→onStart()
→onResume()
(活跃状态) →onPause()
(失去焦点) →onStop()
(完全不可见) →onDestroy()
。 -
onSaveInstanceState()
:在Activity可能被销毁前调用(如屏幕旋转),用于保存临时数据到Bundle。
-
-
考察点:生命周期顺序、状态恢复、资源释放时机。
-
-
Fragment通信方式
-
问题:列举3种Fragment间通信方式,并对比优缺点。
-
参考答案:
-
ViewModel共享:通过同一Activity作用域的ViewModel共享数据(推荐,解耦性强)。
-
Fragment Result API :使用
setFragmentResult()
传递Bundle(无需直接引用)。 -
接口回调:Fragment定义接口,Activity实现并转发(代码冗余,适合简单场景)。
-
-
二、UI系统与自定义View
-
View绘制流程
-
问题 :解释View的
onMeasure()
,onLayout()
,onDraw()
的作用,并说明如何优化自定义View的性能。 -
参考答案:
-
onMeasure()
:计算View尺寸(需处理MeasureSpec
模式)。 -
onLayout()
:确定子View位置。 -
onDraw()
:绘制内容(避免在此创建对象或耗时操作)。 -
优化 :使用
ViewStub
延迟加载、减少布局层级、启用硬件加速。
-
-
-
事件分发机制
-
问题:描述触摸事件从Activity到View的分发流程,并解决嵌套滑动冲突(如ScrollView内嵌RecyclerView)。
-
参考答案:
-
流程:
Activity.dispatchTouchEvent()
→ViewGroup.onInterceptTouchEvent()
→View.onTouchEvent()
。 -
冲突解决 :重写父容器的
onInterceptTouchEvent()
,根据滑动方向决定是否拦截(如垂直滑动时父容器不拦截)。
-
-
三、多线程与异步处理
-
Handler机制
-
问题:解释Handler、Looper、MessageQueue的关系,并说明如何避免内存泄漏。
-
参考答案:
-
关系:Looper轮询MessageQueue,Handler发送和处理Message。
-
防泄漏 :使用静态内部类 + WeakReference持有Context,或在
onDestroy()
中调用handler.removeCallbacks()
。
-
-
-
Kotlin协程优势
-
问题:对比协程与RxJava的适用场景,并说明协程如何简化网络请求。
-
参考答案:
-
协程:轻量级线程、结构化并发(适合顺序逻辑,如链式请求)。
-
RxJava:复杂数据流处理(如合并多个API响应)。
-
示例:
-
viewModelScope.launch {
val data = withContext(Dispatchers.IO) { api.fetchData() }
updateUI(data)
} -
四、性能优化策略
-
内存泄漏场景与解决
-
问题:列举3个常见内存泄漏场景(如静态Context),并提供解决方案。
-
参考答案:
-
静态Context → 改用
ApplicationContext
或弱引用。 -
未注销广播 → 在
onDestroy()
中调用unregisterReceiver()
。 -
匿名内部类持有外部引用 → 静态内部类 + 弱引用。
-
-
-
冷启动优化
-
问题:应用冷启动耗时超过1秒,如何定位和优化?
-
参考答案:
-
定位工具:Android Studio Profiler的启动时间分析。
-
优化方案:
-
延迟初始化第三方库(使用
App Startup
)。 -
减少主线程任务(用线程池处理IO操作)。
-
使用SplashScreen API避免白屏。
-
-
-
五、架构设计与模式
-
MVVM与MVI对比
-
问题:解释MVVM和MVI架构的区别,并说明MVI如何解决状态管理问题。
-
参考答案:
-
MVVM:数据驱动UI(LiveData + ViewModel),但状态分散。
-
MVI:单向数据流(ViewState → 事件 → 更新状态),状态集中管理(如用Kotlin Flow实现)。
-
-
-
模块化方案
-
问题:如何将单模块App拆分为模块化架构?需考虑哪些问题?
-
参考答案:
-
步骤:按功能划分模块(登录、支付等),基础库抽离为独立Module。
-
关键点:
-
依赖注入解耦(使用Hilt)。
-
路由框架(如ARouter)解决跨模块跳转。
-
Gradle配置按需编译。
-
-
-
六、系统原理与新技术
-
Binder机制
-
问题:解释Binder在IPC中的一次拷贝原理,并说明其与Socket通信的性能差异。
-
参考答案:
-
原理 :通过
mmap
内存映射共享内核空间,减少数据拷贝次数。 -
性能:Binder传输速度比Socket快3倍,适合高频调用(如系统服务)。
-
-
-
Compose优势
-
问题:对比Compose与XML布局的渲染性能差异,并说明声明式UI的核心思想。
-
参考答案:
-
性能:Compose跳过冗余measure/layout阶段,减少嵌套层级。
-
声明式:UI = f(State)(状态变化自动触发重组,无需手动更新View)。
-
-
附:面试准备建议
-
基础巩固:
- 必刷:Activity/Fragment生命周期、四大组件通信、Handler机制。
-
进阶重点:
- 深入View绘制/事件分发、内存优化、协程原理。
-
架构设计:
- 准备1-2个模块化/MVVM项目案例,说明技术选型原因。
-
工具使用:
- 熟练使用Profiler、LeakCanary、Systrace定位问题