Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 137новых вакансий за сутки·64 958вакансий открыто сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 953
РезюмеAIПодготовкаСтатьи
ТарифыТарифы
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 394 кандидата открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python13 555
  • Облачные технологии9 649
  • QA вакансии2 810
  • Android1 650
  • Инженер данных1 068
  • Продакт-менеджер414

Разработка

  • Backend вакансии1 534
  • iOS1 533
  • AI вакансии749
  • Fullstack вакансии623
  • Frontend вакансии536
  • Mobile вакансии28

По стеку

  • Go7 558
  • Java4 778
  • Node.js1 528
  • Kotlin1 348
  • Rust1 252
  • .NET1 154
  • PHP506
  • C++327
  • C#314

DevOps и инфраструктура

  • Kubernetes5 503
  • Linux-инфраструктура4 223
  • DevOps вакансии4 089
  • Terraform / IaC3 059
  • Мониторинг и Observability1 414
  • CI/CD1 240
  • SRE411
  • Кибербезопасность61

Аналитика и данные

  • Аналитик данных612
  • Бизнес-аналитик572
  • Data Scientist528
  • Системный аналитик69

Другие направления

  • Проджект-менеджер147
  • UI/UX дизайн80
  • Ручное тестирование14

По регионам

  • Вакансии в США30 650
  • Вакансии в Европе12 551
  • Работа в России3 510
  • Вакансии в Канаде2 658

По формату

  • Удалённые вакансии48 186
  • Релокация в США30 650
  • Гибридная работа7 410
  • Офисная работа5 407

По уровню

  • Senior вакансии26 826
  • Middle вакансии12 754
  • Junior вакансии4 519

Сейчас нанимают

Все компании
  • Rakuten189 вакансий
  • Wise189 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Celonis47 вакансий
  • Spotify37 вакансий
  • Infobip28 вакансий
  • Adyen27 вакансий
  • Darktrace17 вакансий
  • Monzo17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме Kotlin CoroutinesВсе вопросы
Kotlin CoroutinesSeniorТеория

Что такое structured concurrency и почему это важно?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Structured concurrency — гарантия, что дочерние корутины не переживают родительский scope; Job образует дерево, где отмена и ошибки распространяются по иерархии, предотвращая утечки.

Иерархия Job

Каждая корутина имеет Job, который образует дерево. Родительский Job отслеживает все дочерние:

import kotlinx.coroutines.*

fun main() = runBlocking { // root scope
    val job = launch { // дочерний Job
        launch { // внук
            delay(1000)
            println("grandchild done")
        }
        println("child done")
    }
    // runBlocking ждёт ALL дочерних корутин
    println("parent done")
}
// Порядок: "child done" -> "grandchild done" -> "parent done"

Structured Concurrency в Kotlin Coroutines

Structured concurrency — принцип, при котором время жизни корутин ограничено явным scope. Корутина не может «вытечь» за пределы блока кода, в котором была запущена. Это делает конкурентный код предсказуемым: если scope завершён, все его дочерние корутины тоже завершены.

coroutineScope — ключевой строительный блок

coroutineScope создаёт новый scope и приостанавливается до завершения всех дочерних корутин. При ошибке в любой дочерней — отменяет остальных и пробрасывает исключение:

suspend fun loadUserData(userId: String): UserData = coroutineScope {
    val profile = async { userRepo.getProfile(userId) }
    val orders = async { orderRepo.getOrders(userId) }
    val prefs = async { prefsRepo.getPrefs(userId) }

    // Если любой из них упадёт — все три будут отменены
    UserData(
        profile = profile.await(),
        orders = orders.await(),
        prefs = prefs.await()
    )
}

SupervisorScope для независимых задач

Когда ошибка одной задачи не должна отменять остальные — используем supervisorScope:

suspend fun loadDashboard(): Dashboard = supervisorScope {
    val news = async {
        try { newsApi.getLatest() }
        catch (e: Exception) { emptyList() } // деградирует gracefully
    }
    val stats = async { statsApi.getStats() } // падение не отменяет news

    Dashboard(news = news.await(), stats = stats.await())
}

Отмена и CancellationException

val scope = CoroutineScope(Job() + Dispatchers.IO)

val job = scope.launch {
    try {
        repeat(100) { i ->
            delay(100)
            println("Working $i")
        }
    } finally {
        // Cleanup всегда выполняется при отмене
        withContext(NonCancellable) {
            saveState() // cleanup может быть suspend
        }
    }
}

job.cancel() // немедленно отменяет всё поддерево
job.join()   // ждём завершения cleanup

Почему это важно

  • Без structured concurrency корутины могут жить дольше, чем нужно, удерживая память и соединения.
  • Гарантирует освобождение ресурсов (finally блоки) при отмене.
  • Упрощает рассуждение о коде: область жизни корутины — это лексическая область кода.
  • Ошибки всплывают корректно, не теряются в фоновых задачах.

Подводные камни

  • GlobalScope нарушает structured concurrency — корутины не привязаны ни к какому lifecycle.
  • CoroutineScope(Job()) как поле класса без cancel() в onCleared/onDestroy — ручная утечка.
  • async внутри GlobalScope: исключение не propagates в parent — теряется.
  • CancellationException, пойманный в catch(e: Exception) и не переброшенный, блокирует отмену.
  • withContext не создаёт новый Job — он использует Job текущей корутины, поэтому отмена родителя отменит его.
  • launch внутри suspend-функции (без receiver scope) требует GlobalScope или инжекции scope — архитектурный запах.
  • coroutineScope при ошибке отменяет ВСЕ дочерние — если нужна независимость, нужен supervisorScope.

Частые вопросы на собеседовании

  • В чём разница между билдерами coroutine launch и async?
  • Что такое suspend-функция и где её можно вызывать?
  • Что такое Flow в Kotlin и чем он отличается от suspend fun, возвращающей одно значение?
  • Что такое CoroutineDispatchers и в чём разница между Main, IO, Default и Unconfined?

Типичные ошибки

  • Объяснять «structured concurrency» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: Неструктурированные jobs переживают запросы, экраны и тесты, поэтому production-система получает утечки и потерянную observability.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

Что проверяет интервьюер

  • Формулирует суть темы «structured concurrency» своими словами и связывает ее с кодом.
  • Называет механизм: coroutineScope, supervisorScope и withContext задают разные границы распространения ошибки и cancellation.
  • Видит production-последствие: Неструктурированные jobs переживают запросы, экраны и тесты, поэтому production-система получает утечки и потерянную observability.

Как вы знаете этот вопрос?

Проверить себя по теме Kotlin Coroutines →

Источники

  • https://kotlinlang.org/docs/coroutines-basics.html
Следующий вопрос→В чём разница между билдерами coroutine `launch` и `async`?

Связанные темы

Kotlin Coroutinesconcurrencykotlin coroutinesstructured-concurrency-reasoning