MVVM & Unidirectional Data Flow Interview Questions

ARCHITECTURE › Patterns

Walk me through how you'd model a screen that needs to show a loading spinner, then either a success list or an error message. What does the UiState actually look like?

What a strong answer covers: A strong answer models this as a single sealed interface or class, Loading, Success(data), Error(message), rather than separate booleans like isLoading and hasError, because independent flags can represent impossible combinations, like isLoading and hasError both true, that the UI then has to defensively handle. The nuance: this should be exhaustive in a when expression so the compiler forces every branch to be handled, and the Error case should carry enough context, like a message or the failed action, to render a useful retry UI rather than just a generic flag.

Why is 'state down, events up' easy to violate accidentally, and what's an example of a subtle violation?

What a strong answer covers: It gets violated when a nested composable or View reaches past its given parameters to read shared state directly, like calling into a singleton or pulling a ViewModel it wasn't explicitly handed, instead of receiving everything it needs as parameters and emitting everything it produces as callbacks; this works short-term but breaks the ability to preview or test the composable in isolation and hides where state actually changes. A concrete example: a supposedly stateless list item composable that calls viewModel.onItemClicked() directly instead of exposing an onClick lambda, quietly coupling that item to one specific ViewModel and making it impossible to reuse or unit test without the whole screen's ViewModel.

Two features on the same screen need to share transient state that shouldn't belong in the persisted UiState, like a multi-step form draft that shouldn't survive process death. Walk me through how you'd design that without breaking single-source-of-truth.

What a strong answer covers: The state should still live in exactly one place, typically the ViewModel or a dedicated form-state holder scoped to it, exposed as its own StateFlow separate from the screen's primary UiState, rather than being tracked independently in local remember blocks in two different composables, which creates two sources of truth that can drift. The nuance a weak answer misses: 'doesn't belong in persisted state' is about SavedStateHandle and process-death survival, not about which class owns the data; you can have transient, non-survivable state that still has a single owner and flows down to both features as parameters, instead of each composable keeping its own copy and syncing via callbacks.

Back to MVVM & Unidirectional Data Flow