第2章 Java/Kotlin 核心面试题:面向对象、集合、协程、泛型、反射、注解
本章聚焦Android高级开发面试中 Java 与 Kotlin 混合场景的必考核心。围绕面向对象设计、集合框架、协程、泛型、反射与注解六大主题,拆解高频提问逻辑与回答结构。每个主题下提炼面试官最关注的底层原理与工程落地能力。
面试问答卡片
问题 1:面向对象三大特性及在 Android 中的体现
| 面试官考察点 | 基础扎实程度、是否能用工程案例说明抽象概念、对封装/继承/多态的理解深度 |
| 回答框架 | ① 明确三大特性定义 → ② 分别举 Android 原生例子 → ③ 点出设计原则(如开闭原则)→ ④ 说明 Kotlin 优势(数据类、密封类) |
| 简短示例回答 | 封装:Activity 内私有变量 + getter/setter;继承:BaseActivity 抽取通用逻辑;多态:接口回调实现事件分发。Kotlin 通过 sealed class 优化多态分支,减少 if-else。 |
| 可能追问 | • 继承与组合选哪个?为什么? • 多态在 RecyclerView.Adapter 中如何体现? • Kotlin 密封类相比枚举的优势? |
| 避坑提醒 | • 不要只背定义,必须有真实项目场景。 • 避免过度使用继承导致类爆炸,优先组合。 |
问题 2:Kotlin 协程挂起函数原理与调度器选择
| 面试官考察点 | 是否理解协程底层 CPS 变换、Dispatchers 区别、内存泄漏处理、与 RxJava/Callback 对比 |
| 回答框架 | ① 挂起函数本质 → ② Continuation 传递与状态机 → ③ Dispatchers.IO/Default/Main 适用场景 → ④ withContext 切换线程 → ⑤ 异常处理与结构化并发 |
| 简短示例回答 | 挂起函数编译为 Continuation 状态机,不阻塞线程。Dispatchers.IO 用于网络/IO,Dispatchers.Main 更新 UI。使用 viewModelScope + launch 自动取消,避免泄漏。 |
| 可能追问 | • 协程 vs RxJava 在内存开销上的区别? • supervisorScope 的作用? • 协程遇到挂起函数时线程如何被复用? |
| 避坑提醒 | • 不要在 GlobalScope 内随意启动协程。 • 注意 withContext 切换线程后的异常传播。 |
问题 3:Java 泛型擦除与 Kotlin reified 实现原理
| 面试官考察点 | 对虚拟机泛型机制的理解、Kotlin 内联函数与 reified 如何绕过擦除、实际开发中的类型安全 |
| 回答框架 | ① Java 泛型编译后擦除为 Object(无限制)或边界类型 → ② 无法在运行时获取 T 具体类 → ③ Kotlin 用 inline + reified 将类型参数内联到调用点 → ④ 实现原理:编译期替换为实际类型 |
| 简短示例回答 | Java List |
| 可能追问 | • reified 只能用于 inline 函数的原因? • 如何在不使用 reified 的情况下实现类型安全? • Java 中如何使用 TypeReference 绕过擦除? |
| 避坑提醒 | • reified 会增大字节码体积,注意滥用。 • 理解擦除后在重载时的桥接方法问题。 |
项目案例章节
真实项目模板:直播弹幕实时加载与解析模块
| 业务背景 | 直播 App 需要实时接收服务端推送的弹幕消息,并解析为 UI 组件列表,支持高并发下无卡顿渲染 |
| 规模指标 | DAU 200万+,每秒峰值弹幕 5000 条,弹幕内存池复用减少 GC |
| 技术栈 | Kotlin + Coroutines + Flow + Retrofit + WebSocket + RecyclerView + DiffUtil |
| 核心难点 | • 弹幕解析时频繁创建对象导致内存抖动 → 使用对象池 + ArrayPool • 协程与 WebSocket 生命周期绑定 → 用 lifecycleScope + callbackFlow • 弹幕队列背压处理 → 使用 Channel 的 BUFFERED 模式 + 合并相似弹幕 |
| 面试高频追问 | • 为什么选择 Flow 而不是 LiveData? • 对象池大小如何估算? • 弹幕动画卡顿如何排查? • 协程取消后未完成的任务如何处理? |
| 可迁移回答话术 | “我们通过 Kotlin 协程 + Flow 替代了之前的 RxJava,利用 Dispatchers.IO 处理网络接收,main 安全地提交渲染;针对弹幕对象频繁创建,我们引入自定义环形对象池,预分配 200 个弹幕对象,复用率达 85%;同时使用 callbackFlow 桥接 WebSocket 回调,将消息转换为冷流,借助 lifecycleScope 实现自动取消,避免泄漏。” |
💡 迁移要点:该模板可以适配到任何“高频率 IO + UI 更新”场景(如聊天、股票行情、游戏排行榜),回答时突出协程的结构化并发与内存优化策略。
加分技巧: 讲泛型时提到 Kotlin 的
reified 比 Java 的 Class 更优雅;讲集合时强调 ArrayMap 与 SparseArray 在 Android 低内存场景的适配;讲反射时提及 kotlin-reflect 与 Java 反射的性能差异。
⚠️ 避坑警示:协程面试中易忘回答 非阻塞挂起 与线程的本质关系;泛型擦除问题中误以为 Kotlin 完全消除了擦除(实际只在 inline 函数中有效);反射避免用
setAccessible 绕过访问控制导致安全漏洞。