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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python7 042
  • Облачные технологии5 085
  • QA вакансии1 814
  • Android1 199
  • Инженер данных831
  • Продакт-менеджер339

Разработка

  • iOS1 135
  • Backend вакансии1 131
  • Fullstack вакансии475
  • AI вакансии458
  • Frontend вакансии404
  • Mobile вакансии27

По стеку

  • Go4 093
  • Java2 435
  • Kotlin990
  • Node.js827
  • Rust665
  • .NET525
  • PHP282
  • C++223
  • C#199

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

  • Kubernetes2 931
  • Linux-инфраструктура2 312
  • DevOps вакансии2 110
  • Terraform / IaC1 714
  • CI/CD872
  • Мониторинг и Observability825
  • SRE253
  • Кибербезопасность50

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

  • Аналитик данных497
  • Data Scientist463
  • Бизнес-аналитик374
  • Системный аналитик54

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

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

По регионам

  • Вакансии в США25 531
  • Вакансии в Европе9 792
  • Работа в России3 193
  • Вакансии в Канаде2 236

По формату

  • Удалённые вакансии43 578
  • Релокация в США25 531
  • Гибридная работа4 289
  • Офисная работа3 340

По уровню

  • Senior вакансии21 650
  • Middle вакансии12 211
  • Junior вакансии3 886

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

Все компании
  • Rakuten188 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Wise125 вакансий
  • Celonis28 вакансий
  • Infobip28 вакансий
  • Spotify24 вакансии
  • Adyen17 вакансий
  • Darktrace17 вакансий
  • Monzo13 вакансий

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

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

В чём разница между cancelAndJoin() и cancel()?

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

cancel() лишь инициирует отмену и возвращается немедленно, тогда как cancelAndJoin() — suspend-функция, которая ждёт полного завершения Job включая finally-блоки. Используйте cancelAndJoin() перед перезапуском задачи или закрытием ресурсов.

Пример: когда разница критична

import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch(Dispatchers.IO) {
        try {
            repeat(10) { i ->
                delay(200)
                println("Working $i")
            }
        } finally {
            // cleanup может занять время
            withContext(NonCancellable) {
                println("Cleanup start")
                delay(500) // запись в БД, закрытие соединения
                println("Cleanup done")
            }
        }
    }

    delay(500)

    // Вариант 1: cancel() — не ждём cleanup
    job.cancel()
    println("After cancel — cleanup may still be running!") // выводится до "Cleanup done"

    // Вариант 2: cancelAndJoin() — ждём полного завершения
    // job.cancelAndJoin()
    // println("After cancelAndJoin — cleanup is complete") // выводится после "Cleanup done"

    println("Job state: ${job.isCompleted}")
}

Разница между cancel() и cancelAndJoin()

cancel() — функция на Job, которая инициирует отмену: выставляет флаг отмены и выбрасывает CancellationException при ближайшей точке остановки внутри корутины. Вызов не blocking и не ждёт завершения — он возвращается немедленно, пока корутина ещё может выполнять код в finally-блоке или cleanup-лямбдах.

cancelAndJoin() — suspend-функция, которая вызывает cancel() и затем join(). Она suspend-ится до тех пор, пока Job не перейдёт в состояние Cancelled, то есть пока все finally-блоки и cleanup-корутины не завершатся. Это гарантирует, что ресурсы освобождены до продолжения.

Практическое применение

class DataRepository(
    private val scope: CoroutineScope,
    private val db: Database
) {
    private var syncJob: Job? = null

    suspend fun restartSync() {
        // Неправильно: cancel() без join — старый job ещё пишет в БД
        // syncJob?.cancel()

        // Правильно: ждём завершения перед запуском нового
        syncJob?.cancelAndJoin()
        syncJob = scope.launch {
            db.syncAll()
        }
    }

    // В onDestroy / onCleared
    suspend fun shutdown() {
        syncJob?.cancelAndJoin() // гарантируем flush перед выходом
        db.close()
    }
}

Состояния Job после cancel/cancelAndJoin

  • После cancel(): Job в состоянии Cancelling — isActive = false, isCancelled = true, isCompleted = false
  • После cancelAndJoin(): Job в состоянии Cancelled — isActive = false, isCancelled = true, isCompleted = true
val job = launch { delay(Long.MAX_VALUE) }
job.cancel()
println(job.isCompleted) // false — ещё в Cancelling

// vs
runBlocking {
    job.cancelAndJoin()
    println(job.isCompleted) // true — полностью завершён
}

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

  • Race condition после cancel() — запуск новой операции сразу после cancel() может привести к параллельной работе старого и нового job-а
  • finally + suspend без NonCancellable — если в finally вызывать suspend-функции без withContext(NonCancellable), они выбросят CancellationException снова
  • cancelAndJoin в неотменяемом контексте — если сам вызывающий код в состоянии отмены, cancelAndJoin тоже может быть прерван; используйте withContext(NonCancellable) при shutdown
  • Дедлок при cancel из того же потока — если корутина и вызывающий код на одном single-threaded dispatcher-е, join() может не завершиться
  • SupervisorJob и отмена — отмена дочернего job не отменяет родителя при SupervisorJob, но cancelAndJoin на дочернем всё равно ждёт его cleanup
  • Игнорирование возвращаемого значения cancel() — cancel() возвращает Boolean, указывая, была ли отмена успешной; при уже завершённом job вернёт false

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

  • Объяснять «cancelAndJoin() и cancel()» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: После cancel без join код может продолжить работу параллельно с finally-блоком отменяемой coroutine.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

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

  • Формулирует суть темы «cancelAndJoin() и cancel()» своими словами и связывает ее с кодом.
  • Называет механизм: Разница важна, когда после отмены нужно безопасно освободить ресурс или запустить следующую операцию.
  • Видит production-последствие: После cancel без join код может продолжить работу параллельно с finally-блоком отменяемой coroutine.

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

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

Источники

  • https://kotlinlang.org/docs/cancellation-and-timeouts.html
  • https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/

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

Kotlin Coroutinescancel-and-join-reasoningconcurrencykotlin coroutines

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

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