Local persistence interview lab
Rapid answers
Room versus SQLite?
Room is an abstraction over SQLite that adds compile-time SQL verification, mapping/DAO conveniences, migration support, and reactive integrations while retaining SQLite schema/query/transaction semantics.
Preferences versus Proto DataStore?
Preferences is schema-less key-value; Proto is a typed evolvable schema. Both suit small settings, not relational datasets.
Does Flow emit only when returned rows change?
Room invalidates based on observed tables and reruns the query; unrelated writes can trigger execution. Downstream equality suppression and query optimization are separate decisions.
Scenario: app update wipes offline drafts
fallbackToDestructiveMigration() treated all tables as disposable cache. Classify durable local-only/pending data, supply tested paths, and reserve destructive fallback for explicitly rebuildable stores.
Scenario: UI shows count 6 after two simultaneous increments from 5
Read-modify-write raced. Use atomic SQL increment or transaction/version check; invalidation observation alone does not prevent lost updates.
Scenario: list became slow at 100,000 rows
Inspect query plan, indexes matching filter/order, projection, N+1/relations, stable pagination, invalidation frequency, and blobs. Reproduce with realistic distribution; do not add random indexes.
Case study: offline task manager
- Room owns tasks/projects/outbox/tombstones.
- foreign keys and unique constraints preserve invariants.
- transaction writes task mutation plus outbox entry.
- Flow queries expose project-scoped projections.
- keyset/Paging handles large history.
- files hold attachments; Room holds URI/metadata/checksum.
- Proto DataStore holds typed UI preferences.
- Keystore protects key used for sensitive attachment encryption where threat model requires.
- migrations preserve drafts and pending sync across upgrades.
Review checklist
- Schema encodes nullability, uniqueness, references, units, and valid states.
- Indexes follow measured query shapes.
- Transactions are short and protect business atomicity.
- Entities/DAOs do not leak as application contracts.
- Every supported migration path is tested with data.
- Flow invalidation and collector sharing are understood.
- DataStore has one correctly scoped instance and tested migrations.
- Storage choice matches query, size, sharing, durability, and secrecy.
- Cache has eviction/freshness/invalidation policy.
- Logout/backup/corruption/low-storage behavior is defined.
Describe data meaning and ownership first, then schema/invariants, access patterns, atomicity/concurrency, evolution, failure recovery, security, performance evidence, and tests.
Exercises
- Whiteboard schema and migrations for offline chat.
- Diagnose a migration that forgot indexes and foreign keys.
- Create persistence test matrix for process death, upgrade, corruption, and low storage.