Kotlin 协程面试题大全(Android 高频版)

Kotlin 协程面试题大全(Android 高频版)

这一篇不是只背答案,而是:

真正理解协程面试底层逻辑

内容包括:协程基础、suspend 原理、Continuation、Dispatcher、Job、Flow、Retrofit、Room、Compose、高频陷阱题、Android 实战。


一、什么是协程?

标准回答

Kotlin 协程是一种:轻量级线程

它可以:

  • 挂起
  • 恢复
  • 非阻塞执行异步任务

核心目标: 用同步代码写异步逻辑

加分回答

协程本质:Continuation + 状态机

不是线程,而是编译器生成的状态机对象。


二、协程和线程区别?

对比 线程 协程
创建成本 很低
调度 OS调度 用户态调度
阻塞 容易阻塞 挂起不阻塞
数量 可非常多
切换成本 极低

高频一句话

协程运行在线程上,但不是线程。


三、什么是 suspend?

标准回答

suspend 表示:函数可以挂起,不会阻塞线程。

加分回答

suspend 编译后会变成:Continuation 参数,即 CPS(Continuation Passing Style)转换


四、suspend 是否会自动开线程?

标准答案

不会。

高频误区

很多人以为:suspend = 异步线程 --- 错误。

正确理解

suspend 只是支持:挂起与恢复 ,是否异步取决于 launch / async / Dispatcher


五、delay 为什么不卡线程?

标准答案

因为 delay 挂起的是协程,不是线程。

底层流程

复制代码
保存Continuation
    ↓
线程释放
    ↓
时间到
    ↓
resume恢复

六、Thread.sleep 和 delay 区别?

对比 Thread.sleep delay
阻塞线程
阻塞协程
是否释放线程

高频一句话

sleep 卡线程,delay 不卡线程。


七、launch 和 async 区别?

launch async
无返回值 有返回值
返回 Job 返回 Deferred
kotlin 复制代码
// launch
launch { }

// async
val result = async { }.await()

八、withContext 和 launch 区别?

launch withContext
开启新协程 切换线程并等待结果

高频点: withContext 是 suspend,会等待执行完成。


九、CoroutineScope 是什么?

标准答案

协程必须运行在 CoroutineScope 中,负责:

  • 生命周期
  • Job 管理
  • 协程取消

十、GlobalScope 为什么不推荐?

原因: 生命周期不可控,容易内存泄漏。

不推荐 Android 推荐
GlobalScope viewModelScope / lifecycleScope

十一、协程取消原理?

标准答案

协程是:协作式取消,不是线程强杀。

原理: 挂起点 delay() / yield() 会检查 isActive


十二、为什么 while(true) cancel 不掉?

错误

kotlin 复制代码
while(true) { }

因为没有检查取消状态。

正确

kotlin 复制代码
while(isActive) { }

十三、Job 是什么?

标准答案

每个协程都有 Job,作用:cancel / join / 父子协程管理


十四、SupervisorJob 是什么?

普通 Job SupervisorJob
一个子协程失败,全部取消 子协程互不影响

Android 高频使用。


十五、CoroutineContext 是什么?

标准答案

协程上下文,内部保存:

  • Dispatcher
  • Job
  • CoroutineName
  • ExceptionHandler

本质: Map 结构


十六、Dispatchers 有哪些?

Dispatcher 用途
Main 主线程
IO IO操作
Default CPU密集型
Unconfined 不推荐

十七、Dispatchers.IO 和 Default 区别?

IO Default
网络、数据库、文件 CPU计算、排序、JSON解析

十八、withContext(IO) 为什么常用?

因为:避免主线程阻塞

kotlin 复制代码
withContext(Dispatchers.IO) {
    // 网络/数据库操作
}

十九、Retrofit 为什么支持 suspend?

标准答案

Retrofit 底层拿到了 Continuation,网络完成后调用 resume() 恢复协程。


二十、Retrofit suspend 为什么不卡主线程?

因为:OkHttp异步线程池 + Continuation恢复


二十一、Room 为什么查询用 Flow?

因为:查询是持续变化的数据源,适合 Flow。


二十二、为什么 insert/update/delete 用 suspend?

因为:一次性操作,不需要持续数据流。


二十三、Flow 是冷流还是热流?

默认 Flow 是:冷流(Cold Flow)

意思: 没人 collect 就不会执行。


二十四、StateFlow 是什么?

热流(Hot Flow)

特点:

  • 有初始值
  • 永远活着
  • 保存最新值

二十五、SharedFlow 是什么?

用于事件流,例如:Toast、Snackbar、页面跳转


二十六、StateFlow 和 SharedFlow 区别?

StateFlow SharedFlow
有状态 无状态
必须初始值 不需要
保存最新值 可不保存
UI状态 事件通知

二十七、LiveData 和 Flow 区别?

维度 LiveData Flow
归属 Android 框架组件 Kotlin 协程库
生命周期 自带感知,自动防泄漏 无感知,需要自己结合 repeatOnLifecycle
线程切换 不方便,只能 observe 主线程 天然支持 flowOn 随意切线程
数据变换 只有简单 map、switchMap 算子超多:map/filter/transform/flatMapConcat 等
冷热流 属于热流:有观察者才发数据 默认冷流:没人收集就不生产数据
依赖 安卓专属,离不开 Android 纯 Kotlin,跨平台可用
适用场景 页面 UI 状态简单观察 复杂数据流、连续事件、网络轮询、本地数据库

现代 Android:Flow 已逐渐替代 LiveData,

最简总结

  • LiveData:专为UI 观察设计,生命周期感知,只能在主线程用,功能简单。
  • Flow:Kotlin 协程的数据流,跨线程、可变换、可链式操作、功能更强,不绑定 UI,全场景通用。
  • 新项目直接 抛弃 LiveData,用 StateFlow 代替

二十八、collect 和 collectLatest 区别?

collect collectLatest
前一个没结束,后一个等待 新数据到来,取消旧任务

搜索场景高频使用。


二十九、flatMapLatest 为什么重要?

核心作用: 自动取消旧请求

搜索框场景: 用户输入 a → ab → abc,旧搜索自动取消。


三十、Compose 中为什么不能直接 launch?

因为:Compose 会重组,可能重复创建协程。

正确: LaunchedEffect / rememberCoroutineScope


三十一、LaunchedEffect 和 rememberCoroutineScope 区别?

API 用途
LaunchedEffect 自动生命周期协程
rememberCoroutineScope 用户事件协程

三十二、collectAsState 本质?

Flow → Compose State(把 Flow 数据流,变成 Compose 能刷新 UI 的 State 变量。),Flow emit 时自动重组 UI。


三十三、协程为什么轻量?

因为:本质只是对象 + 状态机,不是 OS 线程。


三十四、Continuation 是什么?

协程执行现场,保存:

  • label(状态机位置)
  • 局部变量
  • 执行位置

三十五、协程为什么能恢复?

因为:continuation.resume()


三十六、label 是什么?

状态机位置

label 位置
0 开始
1 delay后
2 第二次挂起后

三十七、协程本质是什么?

编译器把 suspend 转成状态机 ,核心是 Continuation + resume + 状态机


三十八、为什么 suspend 只能在协程里调用?

因为:需要 Continuation,普通函数没有。


三十九、Flow 为什么默认不卡线程?

因为:Flow 本身不指定线程,线程由 flowOn() 决定。


四十、flowOn 和 withContext 区别?

flowOn withContext
改变上游线程 改变当前协程线程

四十一、为什么推荐 viewModelScope?

因为:生命周期自动管理,ViewModel 销毁时协程自动 cancel。


四十二、协程异常传播?

  • 普通: 子协程异常 → 父协程取消
  • SupervisorJob: 互不影响

四十三、CoroutineExceptionHandler 有什么用?

全局协程异常处理

kotlin 复制代码
CoroutineExceptionHandler { _, e ->
    // 全局处理
}

四十四、企业级最佳实践(高频)

不要
GlobalScope viewModelScope
UI直接请求网络 UI → ViewModel → Repository → Retrofit/Room

四十五、终极面试题(压轴)

Kotlin 协程本质是什么?

推荐答案:

Kotlin 协程本质是:编译器把 suspend 函数转换成状态机,通过 Continuation 保存执行现场,在挂起后通过 resume 恢复执行,从而实现非阻塞异步编程。


四十六、真正的大脑模型(最重要)

看到 自动想到
suspend Continuation + 状态机
delay() 挂起协程,不阻塞线程
Flow 持续数据流
StateFlow Compose UI状态

最后一段(真正拉开差距)

普通开发者 高级开发者
会写 launch 理解 Continuation + 状态机 + Flow + 响应式架构 + Compose状态驱动

真正决定你水平的,不是会不会 API,而是你是否真正理解协程运行机制。

相关推荐
烟雨江南aabb1 小时前
Python第四弹:python进阶-匿名函数和内置函数
开发语言·python
不瘦80斤不改名1 小时前
JavaScript 基础语法完全指南
开发语言·javascript·ecmascript
y小花2 小时前
DRM-Direct Rendering Manager
android·drm
小陈的进阶之路2 小时前
Python系列课(9)——面向对象
开发语言·python
特立独行的猫a2 小时前
鸿蒙 PC 命令行工具迁移实战 · 直播PPT
android·华为·harmonyos·vcpkg·三方库移植·鸿蒙pc
两年半的个人练习生^_^2 小时前
什么是内存泄漏?什么是内存溢出?
java·开发语言
曦夜日长2 小时前
C++ STL容器string(二):删除与插入、数据查找、自定义输入
java·开发语言·c++
jimy12 小时前
C语言中的inline function specifier(函数说明符、关键字)
c语言·开发语言
赏金术士2 小时前
Kotlin 协程底层原理(Continuation)详解
java·开发语言·kotlin