Работали ли вы с потоками напрямую без корутин
Что проверяют
Понимаете ли вы, что корутины это надстройка над обычными потоками, а не замена им. В любом живом проекте есть старый код на Thread и Handler, и человек, который умеет только viewModelScope.launch, встанет на первом же дефекте в нём.
Как отвечать
Расскажите про конкретный опыт по слоям:
- главный поток это
Looperс очередью сообщений. Интерфейс трогаем только оттуда, результат возвращаем черезHandler(Looper.getMainLooper())илиView.post; - голый
Threadсоздают редко: у него нет ни управления жизненным циклом, ни отмены, ни переиспользования; ExecutorServiceизExecutorsдаёт пул и очередь, для фоновой работы это рабочий вариант и сегодня;HandlerThreadнужен, когда своя последовательная очередь удобнее пула: например, запись в файл;AsyncTaskиз платформы убран, но в старом коде встречается, и надо уметь его расплести;- синхронизация:
synchronized,volatile,AtomicInteger, потокобезопасные коллекции.
Хорошо закрывает ответ мысль о том, что корутины ничего не отменяют: Dispatchers.IO это тот же пул потоков, а отмена корутины не убивает поток, она проверяется в точках приостановки.
Где спотыкаются
Обновляют интерфейс из фонового потока и получают CalledFromWrongThreadException. Ошибка выглядит случайной, потому что часть вызовов проходит, а падает первая же реальная перерисовка.
Держат в потоке или в Handler ссылку на активити. Экран закрыли, поток живёт, результат приходит в мёртвый объект: утечка памяти, а иногда и падение. Ссылку делают слабой, задачу отменяют при уничтожении экрана.
Путают видимость и атомарность. volatile гарантирует, что другой поток увидит свежее значение, но count++ всё равно состоит из чтения и записи, и без AtomicInteger или блокировки счётчик врёт.