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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python17 126
  • Облачные технологии14 083
  • QA вакансии3 456
  • Backend вакансии2 115
  • Инженер данных1 809
  • Продакт-менеджер1 261

Разработка

  • Android1 862
  • iOS1 700
  • Fullstack вакансии986
  • AI вакансии950
  • Frontend вакансии744
  • Mobile вакансии44

По стеку

  • Go8 688
  • Java6 537
  • Node.js2 026
  • .NET1 722
  • Kotlin1 611
  • Rust1 458
  • C#710
  • PHP682
  • C++571

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

  • Kubernetes7 772
  • DevOps вакансии6 054
  • Linux-инфраструктура5 493
  • Terraform / IaC4 275
  • CI/CD3 239
  • Мониторинг и Observability1 790
  • SRE568
  • Кибербезопасность458

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

  • Data Scientist1 143
  • Бизнес-аналитик923
  • Аналитик данных857
  • Системный аналитик152

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

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

По регионам

  • Вакансии в США44 276
  • Вакансии в Европе23 819
  • Вакансии в Канаде4 471
  • Работа в России3 904

По формату

  • Удалённые вакансии74 928
  • Релокация в США44 273
  • Гибридная работа12 388
  • Офисная работа7 083

По уровню

  • Senior вакансии42 625
  • Middle вакансии20 854
  • Junior вакансии6 721

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

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab137 вакансий
  • Celonis39 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

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

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

Как KMP обрабатывает параллелизм на iOS (с учётом отсутствия разделяемого изменяемого состояния)?

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

KMP на iOS использует Dispatchers.Main через RunLoop главного потока и Dispatchers.Default через GCD. Для thread-safe состояния применяют Mutex и atomicfu; suspend-функции экспортируются в Swift через SKIE или ручные callback-обёртки.

Dispatchers на iOS

Kotlin/Native реализует Dispatchers.Main через RunLoop главного потока iOS. Dispatchers.Default использует пул потоков через GCD (libdispatch). Без явного указания dispatcher coroutine выполняется в том потоке, откуда запущена.

// commonMain — suspend-функция в репозитории
class NewsRepository(
    private val api: NewsApi,
    private val cache: NewsCache
) {
    // suspend-функция безопасна для вызова с любого dispatcher
    suspend fun getNews(category: String): List<Article> =
        withContext(Dispatchers.Default) { // IO-работа на background thread
            val cached = cache.get(category)
            if (cached != null) return@withContext cached
            val remote = api.fetchNews(category)
            cache.put(category, remote)
            remote
        }
}

// commonMain — ViewModel с явными dispatcher-ами
class NewsViewModel(
    private val repo: NewsRepository,
    private val scope: CoroutineScope
) {
    private val _articles = MutableStateFlow<List<Article>>(emptyList())
    val articles: StateFlow<List<Article>> = _articles.asStateFlow()

    fun loadNews(category: String) {
        scope.launch(Dispatchers.Main) { // UI-обновление на main thread
            val news = repo.getNews(category) // переключается внутри
            _articles.value = news // StateFlow.value обновляется на Main
        }
    }
}

Параллелизм KMP на iOS: от старой memory model к новой

До Kotlin 1.7.20 Kotlin/Native использовал strict memory model с концепцией ownership: объект принадлежал одному потоку, передача между потоками требовала freeze(). С Kotlin 1.7.20 введена новая memory model (по умолчанию с 1.9), совместимая с JVM-семантикой. Однако iOS runtime накладывает собственные ограничения: UI можно обновлять только с main thread, а NSObject не является thread-safe.

Экспорт coroutines в Swift

Swift не умеет вызывать suspend-функции напрямую. Два основных подхода: обёртка через callback или использование библиотеки KMP-NativeCoroutines / SKIE.

// Вариант 1: ручная обёртка через callback
// iosMain
fun NewsViewModel.loadNewsCallback(
    category: String,
    onSuccess: (List<Article>) -> Unit,
    onError: (Throwable) -> Unit
) {
    scope.launch {
        try {
            val news = newsRepo.getNews(category)
            withContext(Dispatchers.Main) { onSuccess(news) }
        } catch (e: Exception) {
            withContext(Dispatchers.Main) { onError(e) }
        }
    }
}
// Вариант 2: SKIE — автоматически генерирует Swift async/await
// build.gradle.kts
plugins {
    id("co.touchlab.skie") version "0.9.3"
}

// После этого Kotlin suspend-функции экспортируются как Swift async
// Swift-код:
// let news = try await viewModel.getNews(category: "tech")

Управление shared mutable state

Новая memory model позволяет обращаться к объектам из разных потоков, но race conditions по-прежнему возможны. Для thread-safe доступа используйте Mutex из kotlinx.coroutines или атомарные операции из kotlinx-atomicfu.

// commonMain — thread-safe кэш через Mutex
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

class TokenStore {
    private val mutex = Mutex()
    private var token: String? = null

    suspend fun getToken(): String? = mutex.withLock { token }

    suspend fun setToken(value: String?) = mutex.withLock {
        token = value
    }
}

// AtomicFu для счётчиков без Mutex
import kotlinx.atomicfu.atomic

class RequestCounter {
    private val count = atomic(0)

    fun increment() = count.incrementAndGet()
    fun get() = count.value
}

Отмена coroutines и lifecycle iOS

В iOS нет ViewModel с автоматической отменой scope. Scope нужно создавать и отменять вручную, привязывая к lifecycle ViewController или SwiftUI View.

// commonMain — scope factory
object CoroutineScopeFactory {
    fun createMainScope(): CoroutineScope =
        CoroutineScope(SupervisorJob() + Dispatchers.Main)
}
// Swift — управление lifecycle
class NewsViewController: UIViewController {
    private let scope = CoroutineScopeFactory.shared.createMainScope()
    private let viewModel: NewsViewModel

    init() {
        self.viewModel = NewsViewModel(
            repo: NewsRepository(),
            scope: scope
        )
        super.init(nibName: nil, bundle: nil)
    }

    deinit {
        // Отменяем все coroutines при уничтожении VC
        scope.cancel()
    }
}

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

  • Вызов runBlocking с main thread iOS приводит к deadlock: iOS RunLoop и coroutine dispatcher конкурируют за main thread.
  • Без явного scope.cancel() в deinit coroutines продолжают работать после уничтожения ViewController — утечка памяти и ghost-обновления UI.
  • StateFlow собирается в Swift через .watch { } (из KMP-NativeCoroutines) — без отмены подписки Flow не завершается и держит ViewController в памяти.
  • Старые библиотеки, не обновлённые под новую memory model, могут бросать InvalidMutabilityException даже в Kotlin 1.9+.
  • Dispatchers.IO недоступен в Kotlin/Native — используйте Dispatchers.Default для фоновых операций на iOS.
  • Исключения из Kotlin coroutines не автоматически конвертируются в Swift Error — нужен @Throws аннотация или обёртка через Result.
  • Thread Sanitizer в Xcode может показывать ложные срабатывания для Kotlin/Native кода — проверяйте через Unit-тесты в commonTest.
  • Если CoroutineScope создан без SupervisorJob, падение одной дочерней coroutine отменяет весь scope — на iOS это убьёт все активные запросы.

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

  • Что такое структура source set: commonMain, androidMain, iosMain?
  • Какой код можно разделять между платформами, а какой должен оставаться платформо-зависимым?
  • Как структурировать KMP-проект (shared module, платформо-зависимые модули)?
  • Что такое Kotlin Multiplatform (KMP) и какие платформы он поддерживает?

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

  • Объяснять «параллелизм на iOS» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: Если не зафиксировать ownership состояния, баги проявятся как гонки, зависания UI или разные результаты на simulator/device.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

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

  • Формулирует суть темы «параллелизм на iOS» своими словами и связывает ее с кодом.
  • Называет механизм: Shared mutable state лучше ограничивать immutable моделями, state holders и explicit synchronization через coroutines primitives.
  • Видит production-последствие: Если не зафиксировать ownership состояния, баги проявятся как гонки, зависания UI или разные результаты на simulator/device.

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

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

Источники

  • https://kotlinlang.org/docs/native-overview.html
  • https://kotlinlang.org/docs/coroutines-overview.html

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

Kotlin Multiplatformios-concurrency-reasoningplatform-boundaries