> Какие виды скоупов существуют в Kotlin Coroutines (Kotlin, Android)
Уровень: senior · Роль: mobile · Категория: Технические вопросы
Компании: Radium Finance
Стек: Kotlin, Android
> Пример ответа
Короткий ответ
В Kotlin Coroutines существует три основных вида скоупов: CoroutineScope (общий интерфейс), GlobalScope (глобальный, живёт всё время приложения) и CoroutineScope с Job/SupervisorJob (структурированный, привязанный к жизненному циклу). На практике в Android используются viewModelScope, lifecycleScope и кастомные скоупы с SupervisorJob. Ключевое различие - время жизни и поведение при отмене родительской корутины.
Подробное объяснение
CoroutineScope - это интерфейс, который содержит CoroutineContext. Он определяет область, в которой запускаются корутины. Основные реализации:
-
GlobalScope - синглтон, не привязан к жизненному циклу. Корутины в нём живут, пока работает приложение. Использовать не рекомендуется, так как легко получить утечку памяти.
-
Структурированный скоуп - создаётся через
CoroutineScope(Dispatchers.Main + Job()). Жизненный цикл управляется явно черезcancel()или через родительскийJob. Все дочерние корутины отменяются вместе с родительским скоупом. -
Специализированные скоупы в Android:
viewModelScope- привязан кViewModel, отменяется приonCleared()lifecycleScope- привязан кLifecycleOwner, отменяется приonDestroy()repeatOnLifecycle- дополнительный механизм для реактивных потоков
-
SupervisorJob- вариантJob, где отмена одной дочерней корутины не отменяет остальные. Используется для параллельных независимых задач.
Важный момент: скоуп - это не поток, а контекст. Он определяет Dispatcher, Job и другие элементы контекста.
На практике
В Android-разработке:
- Для UI-событий используем
lifecycleScopeсDispatchers.Main - Для бизнес-логики -
viewModelScope - Для фоновых задач -
Dispatchers.IOвнутри скоупа - Для независимых параллельных задач -
SupervisorJobв кастомном скоупе - Для длительных операций, переживающих смену конфигурации, - скоуп, привязанный к
Application
Правило: скоуп должен быть отменён, когда его владелец уничтожается. Никогда не используем GlobalScope без веской причины.
Пример кода
// viewModelScope - стандартный для Android class MyViewModel : ViewModel() { fun loadData() { viewModelScope.launch { val result = repository.fetchData() _uiState.value = result } } } // Кастомный скоуп с SupervisorJob class MyRepository { private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) fun fetchData(): Deferred<String> = scope.async { delay(1000) "data" } fun cleanup() { scope.cancel() } } // lifecycleScope в Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.uiState.collect { state -> render(state) } } } } }
Как отвечать на собеседовании
Начни с определения скоупа как контейнера контекста. Затем перечисли основные виды: GlobalScope, структурированный скоуп, специализированные Android-скоупы. Обязательно упомяни разницу между Job и SupervisorJob. Приведи пример из реальной практики - viewModelScope для загрузки данных. Подчеркни важность структурированной конкурентности и отмены корутин. Если спросят про Dispatchers - свяжи их со скоупами, но не уходи в детали, если не просят.
Что проверяет интервьюер
- Понимание структурированной конкурентности
- Знание жизненного цикла корутин в Android
- Умение объяснить разницу между
JobиSupervisorJob - Осознание проблем
GlobalScope - Практический опыт с
viewModelScopeиlifecycleScope - Понимание, как скоуп связан с
CoroutineContext
Типичные ошибки
- Путают
CoroutineScopeиCoroutineContext- это разные вещи - Считают, что
GlobalScope- нормальное решение для фоновых задач - Не знают, что
SupervisorJobне отменяет соседние корутины - Забывают про
repeatOnLifecycleдля безопасного сбора потоков - Используют
viewModelScopeдля задач, которые должны пережитьViewModel - Не вызывают
cancel()в кастомных скоупах - Путают
launchиasyncв контексте скоупа
> Похожие задачи по mobile
Какие нововведения в Kotlin и Android за последние полгода запомнились
Как реализовать debounce для поиска с корутинами в Kotlin
Можно ли создать Singleton с параметризованным конструктором в Kotlin
Есть ли проблемы при передаче массива вместо списка в дата класс Kotlin
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью