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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python15 317
  • Облачные технологии11 512
  • QA вакансии3 347
  • Backend вакансии1 829
  • Инженер данных1 397
  • Продакт-менеджер842

Разработка

  • Android1 758
  • iOS1 639
  • AI вакансии875
  • Fullstack вакансии727
  • Frontend вакансии631
  • Mobile вакансии31

По стеку

  • Go8 413
  • Java5 383
  • Node.js1 730
  • Kotlin1 427
  • Rust1 387
  • .NET1 303
  • PHP554
  • C++394
  • C#373

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

  • Kubernetes6 474
  • DevOps вакансии4 845
  • Linux-инфраструктура4 834
  • Terraform / IaC3 590
  • Мониторинг и Observability1 636
  • CI/CD1 557
  • SRE504
  • Кибербезопасность245

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

  • Data Scientist769
  • Аналитик данных748
  • Бизнес-аналитик722
  • Системный аналитик94

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

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

По регионам

  • Вакансии в США40 526
  • Вакансии в Европе16 981
  • Вакансии в Канаде3 889
  • Работа в России3 872

По формату

  • Удалённые вакансии64 846
  • Релокация в США40 528
  • Гибридная работа9 711
  • Офисная работа6 760

По уровню

  • Senior вакансии36 345
  • Middle вакансии17 248
  • Junior вакансии5 866

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

Все компании
  • Wise193 вакансии
  • Rakuten189 вакансий
  • ASML164 вакансии
  • Grab134 вакансии
  • Celonis45 вакансий
  • Spotify37 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo19 вакансий
  • Darktrace17 вакансий

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

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

Как Jetpack Compose интегрируется с компонентом архитектуры ViewModel?

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

Jetpack Compose получает ViewModel через hiltViewModel() или viewModel() из compose-lifecycle-viewmodel, подписывается на StateFlow/LiveData через collectAsStateWithLifecycle(), а ViewModel живёт дольше composable — до уничтожения NavBackStackEntry.

Подключение зависимостей

// build.gradle.kts
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.0")
// Для Hilt:
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")

Интеграция ViewModel с Jetpack Compose

ViewModel — компонент Android Architecture Components, хранящий UI-состояние пережив recomposition и повторное создание Activity/Fragment. Compose предоставляет специальные API для работы с ViewModel без потери lifecycle-безопасности.

Получение ViewModel в Composable

import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.hilt.navigation.compose.hiltViewModel

// Без DI — для простых случаев
@Composable
fun ProfileScreen(
    viewModel: ProfileViewModel = viewModel()
) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
    ProfileContent(state = uiState, onEvent = viewModel::onEvent)
}

// С Hilt — рекомендованный подход для production
@Composable
fun ProfileScreen(
    viewModel: ProfileViewModel = hiltViewModel()
) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
    ProfileContent(state = uiState, onEvent = viewModel::onEvent)
}

Подписка на StateFlow и LiveData

class ProfileViewModel @Inject constructor(
    private val repo: UserRepository
) : ViewModel() {

    private val _uiState = MutableStateFlow(ProfileUiState())
    val uiState: StateFlow<ProfileUiState> = _uiState.asStateFlow()

    // Также LiveData поддерживается
    val liveData: LiveData<String> = MutableLiveData("hello")

    fun onEvent(event: ProfileEvent) { /* ... */ }
}

@Composable
fun ProfileContent(viewModel: ProfileViewModel = hiltViewModel()) {
    // StateFlow — предпочтительный способ
    val state by viewModel.uiState.collectAsStateWithLifecycle()

    // LiveData — для совместимости с legacy-кодом
    val ldValue by viewModel.liveData.observeAsState(initial = "")
}

ViewModel scope в Navigation Compose

По умолчанию hiltViewModel() создаёт ViewModel в scope текущего NavBackStackEntry. Для shared ViewModel между экранами используют родительский NavBackStackEntry:

@Composable
fun CheckoutScreen(
    navController: NavController,
    viewModel: CheckoutViewModel = hiltViewModel(
        navController.getBackStackEntry("checkout_graph") // scope на граф
    )
) { ... }

SavedStateHandle для аргументов навигации

class ItemViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle,
    repo: ItemRepository
) : ViewModel() {

    // Получаем аргумент из Navigation Compose
    private val itemId: String = checkNotNull(savedStateHandle["itemId"])

    val item: StateFlow<Item?> = repo
        .getItem(itemId)
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
}

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

  • Передача ViewModel напрямую вглубь дерева composable создаёт жёсткую зависимость и ломает preview.
  • viewModel() без явного указания scope может создать несколько экземпляров в Navigation Compose.
  • collectAsState() вместо collectAsStateWithLifecycle() не останавливает сбор в background — лишняя нагрузка на CPU и батарею.
  • Хранение Context или View в ViewModel вызывает утечку памяти — ViewModel переживает Activity.
  • Запуск корутин в ViewModel без viewModelScope теряет cancellation при очистке.
  • SharingStarted.Eagerly в stateIn держит Flow активным, даже когда UI не видит экран.
  • Изменяемый state напрямую из UI (минуя onEvent) нарушает Single Source of Truth.

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

  • Что такое State в Jetpack Compose и как работает state hoisting?
  • Что такое recomposition и что её вызывает в Jetpack Compose?
  • В чём разница между remember и rememberSaveable?
  • Каковы лучшие практики производительности в Jetpack Compose (стабильность, пропускаемость)?

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

  • Объяснять «ViewModel и Compose» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: Хранение NavController, Context или mutable UI state без границ во ViewModel усложняет lifecycle и тесты.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

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

  • Формулирует суть темы «ViewModel и Compose» своими словами и связывает ее с кодом.
  • Называет механизм: StateFlow обычно collectAsStateWithLifecycle на Android, а одноразовые эффекты требуют отдельной модели событий.
  • Видит production-последствие: Хранение NavController, Context или mutable UI state без границ во ViewModel усложняет lifecycle и тесты.

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

Проверить себя по теме Jetpack Compose →

Источники

  • https://developer.android.com/develop/ui/compose/libraries
  • https://developer.android.com/topic/libraries/architecture/coroutines
←Предыдущий вопросКакие production-риски есть у Jetpack Compose: memory, lifecycle bugs, accessibility, offline mode, app size или platform-specific behavior?Следующий вопрос→В чём разница между stateful и stateless composable?

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

Jetpack Composeui-stateviewmodel-integration-reasoning