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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python17 105
  • Облачные технологии14 073
  • QA вакансии3 460
  • Backend вакансии2 098
  • Инженер данных1 805
  • Продакт-менеджер1 266

Разработка

  • Android1 866
  • iOS1 699
  • Fullstack вакансии979
  • AI вакансии951
  • Frontend вакансии742
  • Mobile вакансии44

По стеку

  • Go8 651
  • Java6 544
  • Node.js2 018
  • .NET1 719
  • Kotlin1 623
  • Rust1 453
  • C#709
  • PHP683
  • C++571

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

  • Kubernetes7 763
  • DevOps вакансии6 057
  • Linux-инфраструктура5 492
  • Terraform / IaC4 261
  • CI/CD3 240
  • Мониторинг и Observability1 783
  • SRE566
  • Кибербезопасность453

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

  • Data Scientist1 140
  • Бизнес-аналитик930
  • Аналитик данных853
  • Системный аналитик154

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

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

По регионам

  • Вакансии в США43 685
  • Вакансии в Европе23 862
  • Вакансии в Канаде4 413
  • Работа в России3 909

По формату

  • Удалённые вакансии73 887
  • Релокация в США43 685
  • Гибридная работа12 392
  • Офисная работа7 088

По уровню

  • Senior вакансии42 236
  • Middle вакансии20 545
  • Junior вакансии6 653

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

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab138 вакансий
  • Celonis39 вакансий
  • Spotify36 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

Вакансии из 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, возвращающей одно значение?