Систем-дизайн iOS
Систем-дизайн на iOS — это проектирование модулей и библиотек, а не алгоритмов. Интервьюер даёт открытую задачу («спроектируйте экран», «спроектируйте библиотеку аналитики») и смотрит, как вы раскладываете её на слои: откуда берутся данные, что происходит при обрыве связи, как разные потоки безопасно работают с общим состоянием и насколько легко расширить модуль под новые требования.
Ловушки здесь не синтаксические, а архитектурные. Хранить ответы только в памяти — терять их при крэше. Принимать события с любого потока без синхронизации — ловить гонки данных. Обновлять UI не с главной очереди — получать непредсказуемые сбои. Зашивать один бэкенд и фиксированный набор экранов — ломать модуль на первом изменении. Слои ниже разбирают четыре опоры, из которых собирается почти любой ответ.
Карта темы
- Сеть через URLSession — асинхронная загрузка данных через data task и модель data/response/error.
- Офлайн-кэш — сохранение успешных ответов на диск и отдача их при сбое запроса.
- Очереди GCD — последовательные и параллельные dispatch-очереди и правило «UI — только на главной».
- Потокобезопасность — защита общего изменяемого состояния последовательной очередью или барьером вместо гонок.
- Backend-driven UI — экран, чей состав задаётся ответом бэкенда, ради расширяемости без релиза.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Хранить данные только в памяти | Крэш или выгрузка приложения теряет всё несохранённое |
| Принимать/менять общее состояние с любого потока без синхронизации | Гонки данных и трудноуловимые падения |
| Обновлять UI с фоновой очереди | Непредсказуемые сбои отрисовки и падения |
| Считать, что офлайн работает сам | iOS не повторяет запросы за вас — кэш надо строить руками |
| Зашивать один бэкенд и фиксированный набор экранов | Любое изменение API или набора вкладок требует релиза |
Считать URLSession блокирующим вызвавший поток | Неверная модель — task'и выполняются асинхронно |
Значение для собеседований
Систем-дизайн спрашивают, чтобы отделить того, кто «пишет по гайду», от того, кто принимает инженерные решения под ограничения. Сильный кандидат сам называет риски — «а что при обрыве сети?», «а с какого потока это меняется?» — и закрывает их слоями: персистентность, синхронизация, главная очередь для UI, подключаемые абстракции.
Что обычно проверяют:
- Как устроена загрузка через
URLSessionи почему она асинхронна. - Как пережить офлайн и не потерять данные при крэше (диск, а не только память).
- Разницу последовательной и параллельной очередей и где обязателен главный поток.
- Как защитить общее состояние от гонок и как оставить модуль расширяемым.
Типичный неверный ответ: «сохраню всё в массив в памяти и буду обновлять UI прямо из колбэка сети». На деле такой модуль теряет данные при крэше, ловит гонки при доступе с разных потоков и падает при обновлении UI не с главной очереди.