System Design: frontend
Сегодня разберём задачу с собеса в геодезическую компанию — из тех, где приложение для полевых работ должно работать там, где связи нет в принципе. Спроектируй фронт, который живёт без интернета: специалист видит данные, что-то в них меняет, а когда сеть возвращается — всё уезжает на сервер и синхронизируется.
Почему такое вообще спрашивают. Геодезист выезжает на объект — поле, стройка, лес за городом, — и связи там может не быть весь день. А работать надо: открыть карту участка, занести замеры, отметить точки, что-то поправить. Если приложение при потере сети показывает белый экран, им попросту нельзя пользоваться в поле. Значит, оно должно работать так, будто интернет и не нужен, а сеть подхватывать само, когда специалист вернётся в зону покрытия.
Первое, что хочется ляпнуть, — «закешируем данные и всё». И вот это ловушка. Как только ты разрешаешь не только читать офлайн, но и менять данные, ты, по сути, строишь маленькую распределённую систему: у тебя появляется две копии правды (на устройстве и на сервере), и они умеют разъезжаться. Все классические боли распределёнки — конфликты, рассинхрон, порядок операций — теперь твои. Не подумал про них — решение развалится на первом же реальном сценарии.
Поэтому до того как проектировать, спроси интервьюера две вещи. Первая: что именно должно пахать офлайн — только чтение или запись тоже? Это небо и земля по сложности. Чисто чтение — задачка на кэш. Запись — уже та самая распределёнка. Вторая, и это гвоздь всей задачи: что делать, если геодезист поменял данные офлайн, а на сервере их за это время тоже кто-то поменял — например, коллега в офисе? Пока ты не ответил, как разруливать такой конфликт, — задача не закрыта.
Теперь как устроено внутри. Данные храним прямо на устройстве. Для структурированных данных — IndexedDB (это встроенная в браузер база; localStorage не годится — он крохотный и синхронный, тормозит всё вокруг). Картинки, стили, саму оболочку приложения кладём через Service Worker — это прослойка между приложением и сетью, которая отдаёт сохранённое, когда интернета нет. Читаем офлайн — берём из локальной базы. А с записью интереснее: когда человек что-то меняет без сети, мы не пытаемся тут же достучаться до сервера, а складываем изменение в локальную очередь. Появилась сеть — по очереди, в том же порядке, отправляем всё накопленное.
И вот мы уперлись в главное — в конфликты. Тут надо не просто сказать «ну разрулим», а назвать конкретный подход и объяснить, почему он. Самый простой — кто последний записал, того и правда. Работает, но молча затирает чужие изменения, а для замеров по объекту это чревато: перезатёр чью-то правку — и на объект поедут неверные координаты. Честнее — версии: у каждой записи есть номер версии, и если геодезист пытается сохранить поверх данных, которые на сервере уже обновились, сервер такое отклоняет, и мы решаем, что делать. Самый аккуратный, но и самый муторный вариант — сливать изменения по отдельным полям: один поправил координаты точки, другой — её описание, оба изменения выживают. Важно не назвать «правильный» ответ (его нет), а показать, что ты понимаешь разницу и осознанно выбираешь под ситуацию.
Ещё пара вещей, без которых разбор неполный. Синхронизацию лучше делать в фоне — есть Background Sync, который сам достучится до сервера, когда связь вернётся, даже если вкладку уже закрыли. И обязательно — честно показывать статус. Если человек поменял что-то офлайн, а на экране всё выглядит как «сохранено», он уйдёт довольный, а изменения висят в очереди и могут вообще не уехать. Маленькая плашка «изменения ещё не отправлены» снимает кучу боли.
Если совсем коротко: тут проверяют, понял ли ты, что offline-first — это не «кэш прикрутить», а полноценная распределёнка со своими конфликтами и с тем, что данные какое-то время живут несогласованными. Назвал конкретную стратегию разрешения конфликтов и вспомнил про честный статус для пользователя — значит, в теме.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Post #331
2.18K
- 🔥 3