Repository & Data Layer Interview Questions

ARCHITECTURE › Patterns

Walk me through how you'd design a repository for a feature that needs both a fast local cache and a network source, and why the merging and conflict logic belongs there rather than in the ViewModel.

What a strong answer covers: A strong answer describes the repository as the single entry point that composes multiple data sources, exposing one unified Flow that reflects the cache and refreshes it from the network in the background, so callers never see the sources directly. Conflict resolution, cache invalidation, and retry policy live in the repository because they're business rules about data, not UI state, and keeping them out of the ViewModel keeps it testable and reusable across screens; the common miss is putting Retrofit or Room calls directly in a ViewModel.

How do you unit test a repository that depends on both a Room DAO and a Retrofit service, without spinning up a real database or making real network calls?

What a strong answer covers: You define the DAO and API service behind interfaces and inject fakes or in-memory implementations that return canned data, then drive the repository with runTest and a TestDispatcher so coroutines execute deterministically. A common miss is defaulting to an actual in-memory Room database for every test, which is slower and couples the test to SQL behavior when a plain fake list-backed implementation of the DAO interface is usually enough to verify the repository's own logic.

When would you introduce a UseCase or Interactor layer between your ViewModel and repository instead of having the ViewModel call the repository directly, and what's the trade-off?

What a strong answer covers: A UseCase earns its keep when business logic is shared across multiple ViewModels or features, or when it composes calls across more than one repository into a single meaningful operation; it isolates that logic for reuse and testing independent of any screen. The trade-off is extra indirection and boilerplate for a simple one-line delegation, and the trap is cargo-culting a UseCase for every trivial repository call in the name of 'Clean Architecture' when the ViewModel calling the repository directly would be simpler and just as testable.

Back to Repository & Data Layer