Site icon AppTractor

50 вопросов о System Design, ответы на которые должен знать каждый Senior iOS-разработчик: часть 3

Первая часть, про архитектуру приложения. Вторая про сетевой слой.

Часть3: Локальное хранилище и Offline-First архитектура

Вопрос 11. Когда вы бы использовали Core Data?

Почему интервьюеры задают этот вопрос

Многие разработчики работали с Core Data, но далеко не все понимают, в каких ситуациях этот инструмент действительно является правильным выбором.

Интервьюер хочет убедиться, что вы умеете выбирать подходящее решение для хранения данных с учётом бизнес-требований, а не просто используете привычную технологию.

Ответ уровня Senior

Core Data — это фреймворк для управления структурированными данными приложения.

Помимо непосредственного хранения информации, он предоставляет такие возможности, как управление графом объектов, работа со связями между сущностями, ленивая загрузка, работа со сбоями, отслеживание изменений, эффективное выполнение запросов.

Обычно я выбираю Core Data, когда:

Примеры таких приложений:

Core Data — это не просто локальная база данных. Его основное преимущество заключается в эффективном управлении большими графами объектов и глубокой интеграции с экосистемой iOS.

Пример из реального проекта

Представим приложение интернет-магазина.

После загрузки тысяч товаров, категорий и сведений об остатках хранить всю эту информацию только в оперативной памяти непрактично.

Вместо этого приложение сохраняет данные локально с помощью Core Data.

Когда пользователь снова открывает приложение, товары мгновенно отображаются из локального хранилища, а актуальные изменения загружаются с сервера в фоновом режиме.

В результате приложение работает быстрее и кажется пользователю более отзывчивым.

Распространённая ошибка

Многие разработчики используют Core Data для хранения очень небольших объёмов данных.

Если приложению требуется сохранить только несколько пользовательских настроек или простой токен, Core Data создаёт ненужную сложность.

Следует выбирать самое простое решение, которое удовлетворяет требованиям проекта.

Дополнительные вопросы

Вопрос 12. Когда вы бы выбрали SQLite вместо Core Data?

Почему интервьюеры задают этот вопрос

Этот вопрос проверяет понимание компромиссов между технологиями, а не знание конкретных API.

Интервьюер хочет понять, можете ли вы объяснить, почему одно решение для хранения данных в определённой ситуации подходит лучше другого.

Ответ уровня Senior

SQLite — это лёгкая реляционная база данных. В отличие от Core Data, SQLite предоставляет разработчику прямой контроль над таблицами, индексами, запросами и транзакциями.

Обычно я выбираю SQLite, когда:

Во многих корпоративных приложениях работа с SQLite скрывается за слоем репозитория. Благодаря этому остальные части приложения не зависят от конкретной технологии хранения данных.

Пример из реального проекта

Предположим, компания уже использует структуру базы данных, общую для приложений на Android, iOS и настольных компьютерах.

Прямая работа с SQLite позволяет всем платформам использовать одну и ту же структуру без добавления дополнительного уровня абстракции.

Распространённая ошибка

Некоторые кандидаты утверждают, что SQLite всегда работает быстрее Core Data.

Это чрезмерное упрощение.

Core Data сам может использовать SQLite в качестве одного из вариантов физического хранения данных. При этом Core Data дополнительно предоставляет высокоуровневые возможности, включая управление объектами и связями между ними.

Выбор следует делать исходя из требований приложения, а не только на основе предполагаемой производительности.

Дополнительные вопросы

Вопрос 13. Как спроектировать Offline First iOS-приложение?

Почему интервьюеры задают этот вопрос

Offline-first-архитектура становится всё более важной как для корпоративных, так и для массовых приложений.

Интервьюер хочет понять, умеете ли вы проектировать приложение, которое продолжает работать даже при нестабильном или отсутствующем интернет-соединении.

Ответ уровня Senior

В offline-first-приложении локальное хранилище рассматривается как основной источник истины.

Вместо ожидания ответа сервера при каждом действии приложение сразу считывает данные из локального хранилища и синхронизирует их с сервером, когда становится доступно подключение к сети.

Упрощённая архитектура может выглядеть следующим образом:

SwiftUI / UIKit
↓
ViewModel
↓
Repository
↓
Local Database
↕
Background Synchronization
↓
Backend API

Когда пользователь открывает экран, приложение выполняет следующие действия:

  1. Сразу отображает кэшированные данные.
  2. В фоновом режиме запрашивает обновлённую информацию.
  3. Сохраняет полученные данные локально.
  4. Автоматически обновляет пользовательский интерфейс.

Такой подход сокращает время запуска, повышает отзывчивость интерфейса и делает приложение более надёжным.

Пример из реального проекта

Рассмотрим приложение для доставки еды. Пользователь открывает экран заказов, находясь в месте с плохим покрытием мобильной сети. Вместо страницы с ошибкой приложение немедленно показывает ранее загруженные заказы из локального хранилища.

Когда интернет-соединение восстанавливается, приложение незаметно синхронизируется с сервером и обновляет текущие статусы заказов. С точки зрения пользователя приложение остаётся работоспособным даже при временных проблемах с сетью.

Распространённая ошибка

Некоторые разработчики считают, что поддержка офлайн-режима означает только сохранение ответов API в локальном хранилище.

Полноценная offline-first-архитектура также должна учитывать:

Без этих компонентов приложение поддерживает автономную работу только частично.

Дополнительные вопросы

Вопрос 14. Как синхронизировать локальные и серверные данные?

Почему интервьюеры задают этот вопрос

Синхронизация — одна из наиболее сложных задач в мобильной разработке.

Интервьюер хочет понять, умеете ли вы поддерживать согласованность локальных и серверных данных, не создавая дубликатов и не теряя изменения.

Ответ уровня Senior

Обычно я разделяю процесс синхронизации на три этапа.

Этап 1. Обнаружение изменений

Сначала необходимо определить, содержатся ли на сервере более новые данные, чем в локальной базе.

Для этого обычно используются:

Этап 2. Объединение данных

Полученный от сервера ответ сравнивается с локальными записями.

Возможные действия:

Этап 3. Обновление пользовательского интерфейса

После завершения синхронизации необходимо уведомить ViewModel, чтобы пользовательский интерфейс автоматически обновился.

Так процесс синхронизации остаётся независимым от логики отображения данных.

Пример из реального проекта

Представим CRM-приложение. Менеджер по продажам изменяет информацию о клиенте, находясь без подключения к интернету.

Когда соединение восстанавливается, приложение загружает отложенные изменения на сервер и одновременно скачивает обновления, сделанные другими сотрудниками.

Пользователю не требуется вручную обновлять приложение.

Синхронизация автоматически выполняется в фоновом режиме.

Распространённая ошибка

После каждого ответа API некоторые разработчики полностью заменяют локальную базу данных.

Такой подход:

Инкрементальная синхронизация, при которой передаются только изменения, обычно значительно эффективнее.

Дополнительные вопросы

Вопрос 15. Как разрешать конфликты синхронизации?

Почему интервьюеры задают этот вопрос

Умение разрешать конфликты отличает опытных мобильных разработчиков от специалистов, которые работали только с простыми CRUD-приложениями.

В реальных системах изменения нередко поступают одновременно от нескольких пользователей или устройств.

Интервьюер хочет понять, как вы будете действовать в таких ситуациях.

Ответ уровня Senior

Способ разрешения конфликтов зависит от бизнес-требований.

Наиболее распространённые стратегии перечислены ниже.

Пример из реального проекта

Представим, что два сотрудника одновременно редактируют профиль одного клиента. Сотрудник A изменяет номер телефона. Сотрудник B почти в то же время изменяет адрес электронной почты.

Надёжная система синхронизации определяет, что были изменены разные поля, и объединяет изменения вместо того, чтобы полностью отбросить результат работы одного из пользователей.

Выбор подходящей стратегии разрешения конфликтов зависит как от технических ограничений, так и от бизнес-правил.

Распространённая ошибка

Некоторые разработчики предполагают, что конфликты возникают редко. Но как только приложение начинает поддерживать несколько устройств, автономное редактирование или совместную работу, конфликты становятся неизбежными.

Если предусмотреть их обработку на раннем этапе разработки, система будет значительно надёжнее.

Дополнительные вопросы

Итоги

Локальное хранение больше не является только способом оптимизации производительности. Это важнейшая часть создания надёжного мобильного приложения.

Senior iOS-разработчики не просто сохраняют данные. Они думают о синхронизации, согласованности, масштабируемости, поведении приложения при медленном или отсутствующем интернет-соединении.

Во время собеседования необходимо объяснять не только то, какую технологию вы бы использовали, но и почему вы приняли именно такое архитектурное решение.

Понимание компромиссов и реальных производственных проблем часто производит на интервьюера более сильное впечатление, чем простое перечисление названий фреймворков.

В четвёртой части мы рассмотрим оптимизацию производительности: время запуска приложения, управление памятью, производительность прокрутки, загрузку изображений и поиск узких мест. Эти темы часто встречаются на собеседованиях Senior iOS-разработчиков в продуктовых компаниях.

Источник

Exit mobile version