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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python11 079
  • Облачные технологии4 127
  • QA вакансии1 598
  • Android1 395
  • Инженер данных767
  • Продакт-менеджер295

Разработка

  • Backend вакансии1 342
  • iOS1 307
  • AI вакансии660
  • Fullstack вакансии524
  • Frontend вакансии465
  • Mobile вакансии28

По стеку

  • Go6 622
  • Java3 670
  • Kotlin1 199
  • Node.js1 190
  • Rust1 181
  • .NET780
  • PHP329
  • C++301
  • C#211

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

  • DevOps вакансии3 024
  • Kubernetes2 336
  • Linux-инфраструктура1 899
  • Terraform / IaC1 428
  • CI/CD917
  • Мониторинг и Observability650
  • SRE220
  • Кибербезопасность35

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

  • Аналитик данных464
  • Data Scientist434
  • Бизнес-аналитик337
  • Системный аналитик48

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

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

По регионам

  • Вакансии в США23 332
  • Вакансии в Европе9 074
  • Работа в России2 931
  • Вакансии в Канаде2 054

По формату

  • Удалённые вакансии40 752
  • Релокация в США23 332
  • Гибридная работа3 446
  • Офисная работа2 568

По уровню

  • Senior вакансии19 645
  • Middle вакансии11 602
  • Junior вакансии3 620

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

Все компании
  • Wise196 вакансий
  • Rakuten188 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Celonis48 вакансий
  • Spotify38 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace17 вакансий

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

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

Что такое модель акторов (actor model) и как её реализовать с помощью coroutines?

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

Модель акторов — паттерн конкурентности, где актор обрабатывает сообщения последовательно через собственный mailbox; в Kotlin реализуется через Channel или устаревший actor{} builder, а в современном коде — через sealed class + Channel в ViewModel.

Устаревший actor{} builder

В Kotlin Coroutines существует actor() builder, но он помечен @ObsoleteCoroutinesApi:

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

sealed class CounterMsg
object IncCounter : CounterMsg()
class GetCounter(val response: CompletableDeferred<Int>) : CounterMsg()

@OptIn(ObsoleteCoroutinesApi::class)
fun CoroutineScope.counterActor() = actor<CounterMsg> {
    var counter = 0
    for (msg in channel) {
        when (msg) {
            is IncCounter -> counter++
            is GetCounter -> msg.response.complete(counter)
        }
    }
}

fun main() = runBlocking {
    val counter = counterActor()
    repeat(1000) {
        counter.send(IncCounter)
    }
    val result = CompletableDeferred<Int>()
    counter.send(GetCounter(result))
    println("Counter: ${result.await()}") // 1000
    counter.close()
}

Модель акторов (Actor Model)

Модель акторов — концепция конкурентного программирования, в которой каждый актор:

  • имеет приватное состояние, недоступное извне
  • общается с другими только через передачу сообщений
  • обрабатывает сообщения строго последовательно (нет race conditions)
  • может создавать новых акторов и отправлять им сообщения

Современная реализация через Channel

Рекомендованная альтернатива — явный Channel с coroutine-обработчиком:

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

sealed interface Action {
    data class Deposit(val amount: Int) : Action
    data class Withdraw(val amount: Int) : Action
    data class GetBalance(val deferred: CompletableDeferred<Int>) : Action
}

class AccountActor(scope: CoroutineScope) {
    private val mailbox = Channel<Action>(Channel.UNLIMITED)
    private var balance = 0

    init {
        scope.launch {
            for (action in mailbox) {
                when (action) {
                    is Action.Deposit -> balance += action.amount
                    is Action.Withdraw -> {
                        if (balance >= action.amount) balance -= action.amount
                    }
                    is Action.GetBalance -> action.deferred.complete(balance)
                }
            }
        }
    }

    suspend fun deposit(amount: Int) = mailbox.send(Action.Deposit(amount))
    suspend fun withdraw(amount: Int) = mailbox.send(Action.Withdraw(amount))
    suspend fun getBalance(): Int {
        val d = CompletableDeferred<Int>()
        mailbox.send(Action.GetBalance(d))
        return d.await()
    }
    fun close() = mailbox.close()
}

fun main() = runBlocking {
    val account = AccountActor(this)
    repeat(100) { launch { account.deposit(10) } }
    println("Balance: ${account.getBalance()}") // 1000
    account.close()
}

Применение в Android ViewModel

class CartViewModel : ViewModel() {
    private val _state = MutableStateFlow(CartState())
    val state: StateFlow<CartState> = _state.asStateFlow()

    // Mailbox актора
    private val actions = Channel<CartAction>(Channel.UNLIMITED)

    init {
        viewModelScope.launch {
            for (action in actions) {
                _state.update { reducer(it, action) }
            }
        }
    }

    fun dispatch(action: CartAction) {
        actions.trySend(action) // не suspend — безопасно из UI
    }

    private fun reducer(state: CartState, action: CartAction): CartState =
        when (action) {
            is CartAction.AddItem -> state.copy(items = state.items + action.item)
            is CartAction.RemoveItem -> state.copy(items = state.items - action.item)
        }
}

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

  • actor{} builder помечен @ObsoleteCoroutinesApi — может быть удалён в будущих версиях.
  • Неограниченный (UNLIMITED) канал может привести к OutOfMemoryError при медленном потребителе.
  • Отправка в закрытый канал бросает ClosedSendChannelException — нужно обрабатывать после cancel.
  • CompletableDeferred для запросов-ответов не имеет таймаута — используйте withTimeout вокруг await().
  • Актор не даёт backpressure по умолчанию — медленный актор накапливает сообщения без ограничений.
  • Ошибка внутри обработчика сообщений завершает весь цикл for — нужно обернуть в try/catch.
  • Разделение нескольких Channel между coroutines без явной документации превращает код в запутанную сеть зависимостей.

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

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

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

  • Объяснять «actor model на coroutines» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: Actor может стать бутылочным горлышком, а неверная стратегия закрытия mailbox теряет сообщения.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

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

  • Формулирует суть темы «actor model на coroutines» своими словами и связывает ее с кодом.
  • Называет механизм: На kotlinx.coroutines это обычно Channel плюс loop receive, где все mutation происходят внутри владельца состояния.
  • Видит production-последствие: Actor может стать бутылочным горлышком, а неверная стратегия закрытия mailbox теряет сообщения.

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

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

Источники

  • https://kotlinlang.org/docs/channels.html

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

Kotlin Coroutinesactor-model-reasoningconcurrencykotlin coroutines