第2章 Java/Kotlin 核心面试题:面向对象、集合、协程、泛型、反射、注解

本章聚焦Android高级开发面试中 Java 与 Kotlin 混合场景的必考核心。围绕面向对象设计、集合框架、协程、泛型、反射与注解六大主题,拆解高频提问逻辑与回答结构。每个主题下提炼面试官最关注的底层原理与工程落地能力。

面向对象回答框架 封装 → 信息隐藏 继承 → 复用与扩展 多态 → 接口/抽象 SOLID 原则实际落地 面试加分点:结合 Android 组件(如 View 层级、Fragment 生命周期)举例

面试问答卡片

问题 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 运行时只剩 List,无法用 instanceof 判断元素类型。Kotlin 写 inline fun getType() = T::class,编译时直接插入 class 常量,实现类型保留。
可能追问• 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 绕过访问控制导致安全漏洞。