Корутины
Дедлайн 04.12.2025 в 20:59
Задание 1. Базовая корутина с выводом потока
Создайте suspend fun fetchData(), которая делает delay(1000) и возвращает строку.
Запустите её через CoroutineScope(Dispatchers.Default).launch { ... } и выведите результат и Thread.currentThread().name.
Вопрос: Почему корутина выполняется именно в этом потоке и блокирует ли она основной поток?
Задание 2. Наследование контекста в дочерних корутинах
Создайте CoroutineScope(Dispatchers.Default) и запустите корутину-родителя.
Внутри родителя создайте две дочерние корутины launch — одну с явно указанным диспетчером Dispatchers.IO, другую без диспетчера.
Выведите для всех поток и Job.
Вопрос: Какой диспетчер и Job унаследовала каждая дочерняя корутина и почему?
Задание 3. Параллельные вычисления с async/await
Создайте функции calculateA() и calculateB(), которые делают delay и возвращают результат.
Запустите их параллельно через async и получите результат через await.
Измерьте время выполнения и сравните с последовательным вызовом.
Вопрос: Почему параллельное выполнение быстрее и как это влияет на потоки?
Задание 4. Отмена с cooperative cancellation
Создайте корутину, которая выводит числа от 1 до 10 с delay(500) внутри цикла.
Через 2 секунды отмените её (job.cancel()).
Добавьте проверку isActive и вывод "Coroutine gracefully cancelled".
Вопрос: Почему важно проверять isActive внутри цикла?
Задание 5. Таймаут с withTimeout
Создайте корутину, которая выполняется 3 секунды, но оберните её в withTimeout(1000).
Обработайте исключение TimeoutCancellationException.
Вопрос: Чем отличается withTimeout от обычной отмены корутины через cancel()?
Задание 6. Иерархия корутин и отмена родителя
Создайте корутину-родителя и две дочерние через launch.
Добавьте delay и вывод внутри дочерних.
Отмените родителя через cancel() и проверьте, что дочерние корутины также завершились.
Вопрос: Почему структурированная конкуренция помогает безопасно управлять жизненным циклом корутин?
Задание 7. Обработка ошибок и CoroutineExceptionHandler
Создайте корутину, которая выбрасывает исключение.
Используйте try/catch и CoroutineExceptionHandler.
Добавьте ещё дочернюю корутину без try/catch, чтобы увидеть разницу.
Вопрос: Как ошибки в дочерних корутинах обрабатываются при обычном Job и при SupervisorJob?
Задание 8. Flow и операторы
Создайте flow чисел от 1 до 5 с delay(300).
Соберите поток через collect.
Добавьте map и filter.
Вопрос: Чем холодный flow отличается от горячего и что происходит, если несколько раз вызвать collect?
Задание 9. Flow + параллельное выполнение
Создайте два потока (flow1 и flow2) с разной задержкой.
Объедините их через combine и выведите результат.
Вопрос: Почему combine не выводит значения синхронно, а ждёт обновления обоих потоков?
Задание 10. SupervisorJob и независимые дочерние корутины
Создайте CoroutineScope(SupervisorJob() + Dispatchers.Default).
Запустите несколько дочерних корутин через launch, одну из которых выбрасывает исключение.
Проверьте, что остальные продолжают работать.
Вопрос: В чем ключевое отличие SupervisorJob от обычного Job при обработке ошибок?
Задание 11. Переключение контекста внутри корутины
Создайте корутину с Dispatchers.Default.
Используйте withContext(Dispatchers.IO) для имитации загрузки файла.
Выведите название потока до и после переключения.
Вопрос: Почему withContext не создаёт новую корутину, а просто переключает контекст текущей?