Элементы System Design уже прочно вошли в процесс собеседований. Однако в мобильной разработке довольно часто возникает недопонимание что же все-таки необходимо продемонстрировать чтобы получить заветный офер. В этой статье я разберу один из кейсов, который может встретиться на реальном собеседовании и кроме этого покажу примерный сценарий такого интервью. Данная статья будет интересна мобильным разработчикам, как Android, так и iOS. Сам формат System Design Interview я разбирал в предыдущей статье. Здесь же мы сконцентрируемся на практике.
Итак, задача: спроектировать новостную ленту.
Этап 1. Понять проблему и собрать необходимые требования. Время 10 минут.
Ваша задача №1 при прохождении System Design Interview (хоть для mobile, хоть для backend) — это сбор требований и всей необходимой информации, которая поможет вам спроектировать систему. Поэтому в первую очередь уточняем требования. Какие вопросы тут стоит задать? Необходимо определиться с функциональными требованиями. Обычно функциональные требования звучат как какое-то целевое действие, которое может выполнить пользователь, например:
-
Пользователи могут просматривать бесконечную ленту постов.
-
Пользователи могут делиться постами и ставить лайки.
-
Пользователи могу просматривать детали постов и создавать новый контент
-
Как приложение должно работать при отсутствии сети? Нужно ли добавить поддержку offline-режима?
-
Какие типы контента может добавлять пользователь? Например текст, картинки, видео, аудио?
Помимо этих требований, необходимо также учесть и нефункциональные требования, это могут быть:
-
Локализация. Для каких стран мы планируем выпускать наше приложение? Тема локализации может пригодиться при последующем проектировании API или особенностей интерфейса.
-
Эффективность использования данных. Приложение должно минимизировать потребление трафика, за счет кэширования/ленивой загрузки контента.
-
Масштабируемость. Например, необходимо обслуживать сотни миллионов активных пользователей в месяц. Возможно, в контексте мобильных приложений это требование не так актуально, как для проектирования backend-систем, однако это может быть важно для приложений E-commerce (кол-во запросов увеличивается в разы во время распродаж и вас попросят оптимизировать поиск) или вы используете платное API карт, соответственно кол-во запросов/кэширование тоже стоит обдумывать тщательно.
Кроме явных требований на которые стоит опираться при последующих этапах проектирования моделей данных/API и архитектуры, обычно стоит прояснить какие-то вещи, которые могут явно выходить из скоупа, но мы бы их добавили в будущем или проектируем систему исходя из того, что они уже разработаны.
Это могут быть
-
Аутентификация. Будем разрабатывать систему исходя из того, что модуль авторизации разработан и пользователь уже вошел в мобильное приложение.
-
Пуш-нотификации о новых постах. Пользователю было бы удобно видеть оповещения о новых постах, но мы вынесем это из скоупа требований.
Тут дополню, что лучше такие вещи уточнять на интервью. Важно проговорить эти детали. Вдруг у вас задача спроектировать сценарий онбординга — и процесс аутентификации тоже. Каждая задача уникальна, поэтому лучше уточнить, что требуется в первую очередь, а что вынести на потом. Обычно, процесс сбора требований занимает около 10 минут. Очевидно, что можно задать еще множество вопросов, однако, стоит помнить, что мы ограничены во времени и необходимо выбрать только самое важное.
Этап 2. Проектирование API и модели данных. Время 10-15 минут.
Цель этого этапа: спроектировать API для коммуникации мобильного приложения и Backend. Спроектированный контракт должен покрывать необходимые функциональные требования, собранные на 1-ом этапе. В этой части мы обсудим методы Backend, которые будет вызывать мобильный клиент, модель данных для обмена информацией а также протоколы взаимодействия и формат ответа.
2.1 Проектирование API
Давайте вернемся к пункту 1, где мы собирали требования и спроектируем возможные методы, которые нам понадобятся:
-
Метод который запросит список постов/ленту постов. При открытии приложения необходимо запросить последние посты с Backend.
-
Взаимодействие с постами. Ранее, мы обсуждали, что необходимо добавить возможность лайкать пост. Соответственно, необходим метод для лайка/дизлайка.
-
Метод для запроса деталей поста. Так как есть требование дать возможность пользователю переходить на экран деталей.
-
Метод для создания поста. Пользователь может создать пост и добавить в него контент.
Перед тем, как перейти непосредственно к проектированию API, еще важно обсудить протокол взаимодействия (Rest/GraphQL/gRPC/WebSocket) И тут выбор, очевидно, зависит от задачи. Если это приложение для трейдинга — то выбором может стать использование WebSocket, для интернет-магазина, возможно, понадобится REST и так далее. Важно отталкиваться от требований и уметь аргументировать свой выбор.
Например, аргумент за использование REST в этом примере:
-
Широкая распространенность и простота интеграции. Разработчики хорошо знакомы с REST, что упрощает внедрение и поддержку. REST использует стандартные HTTP-методы (GET, POST, PUT, DELETE) и подходит для простых CRUD-приложений с предсказуемыми запросами. Большое количество документации, библиотек и готовых решений.
-
Stateless (без сохранения состояния сервера). Каждый запрос самодостаточен и содержит всю необходимую информацию (например, токены аутентификации).Упрощает горизонтальное масштабирование (можно легко добавлять серверы).
-
Поддержка кэширования HTTP. Можно использовать стандартные механизмы кэширования (Cache-Control), снижая нагрузку на сервер и ускоряя ответы.
Недостатки
-
Сложности с версионированием API. При изменении API может потребоваться поддерживать несколько версий (/v1/, /v2/), что усложняет поддержку. Риск «раздувания» API из-за обратной совместимости.
-
Избыточность данных в Stateless-архитектуре. Каждый запрос должен включать одни и те же метаданные (например, токены), что увеличивает нагрузку на сеть. Особенно критично для мобильных устройств: дополнительные данные → больший трафик и задержки.
-
Проблемы over-fetching и under-fetching. Over-fetching: Клиент получает больше данных, чем нужно (например, весь профиль пользователя, когда требуется только имя). Under-fetching: Клиенту приходится делать несколько запросов для сбора всех необходимых данных (например, сначала пост, потом комментарии).
В целом, нам подходит использование REST, но вы также можете упомянуть плюсы и минусы GraphQL и выбрать инструмент подходящий под конкретную ситуацию. Для разбора этого кейса REST нам подойдет.
Кроме этого, мы также можем обосновать выбор формата сериализации данных: JSON, XML или например Protocol Buffers:
Сравнение форматов данных: JSON, XML, Protocol Buffers
|
Критерий |
JSON |
XML |
Protocol Buffers (protobuf) |
|---|---|---|---|
|
Читаемость |
✅ Да (удобен для людей) |
❌ Сложнее из-за тегов |
❌ Бинарный (нечитаем без декодирования) |
|
Размер данных |
⚡ Компактный (меньше XML) |
📏 Громоздкий (много тегов) |
🏆 Самый компактный (бинарный формат) |
|
Поддержка |
Встроен во все языки |
📜 Широкая, но устаревающая |
🔧 Требует генерации кода ( |
|
Использование |
REST API, веб-приложения |
Устаревшие SOAP-сервисы, конфиги |
Микросервисы, gRPC, high-load системы |
|
Производительность |
🚀 Быстрый парсинг |
🐢 Медленнее из-за объёма |
⚡ Максимальная скорость (бинарный) |
|
Гибкость |
🔄 Динамическая структура |
🏷️ Строгая схема (XSD) |
🏗️ Жёсткая типизация (схема обязательна) |
Для ленты постов мы выберем JSON за счет читаемости и простоты отладки, меньшего размера, чем у XML и JSON не требует сложной настройки (в отличие от protobuf).
2.2 Проектирование методов API
Итак, мы выбрали инструменты для реализации клиент-серверного взаимодействия, теперь, необходимо спроектировать методы API.
2.2.1 Получение ленты (метод) и ответ (FeedApiResponse) могут выглядеть так:
GET /v1/feed?after=<some-value>&limit=30 Body: empty Response: 200 OK. Ответ FeedApiResponse { "feed": [ { "postId": 123, "contentSummary": "Краткое содержание поста...", "author": { "id": 987654321, "name": "User Name", "profileImageThumbnailUrl": ".../profiles/image.jpg" }, "createdAt": "2025-11-15T14:30:00Z", "liked": false, "likeCount": 42, "attachmentCount": 1, "attachmentPreviewImageUrl": ".../posts/preview.jpg" }, … ], "paging": { "nextPageId": "abcdef123456", "totalItems": 2, "pageSize": 20 } }
Обратите внимание, что мы используем пагинацию — и это 100% то, что спрашивают на собеседованиях по мобильной разработке при проектировании систем. Вы должны знать виды пагинации и их плюсы/минусы. Например, чем отличается курсорная и офсетная типы.
2.2.2 Создание поста. В отличие от предыдущего метода, здесь мы будем использовать Post.
POST /v1/posts Body: NewPostRequest { "requestId": 123456789012345, "content": "Новый пост", "attachments": [ { "type": "image", "contentUrl": "...cdn.example.com/uploads/photo123.jpg", "caption": "Мое фото с отпуска" } ] }
2.2.3 Детали поста
GET /v1/posts/{postId} { "post": { "postId": 123456789, "content": "This is the full content of the post with all details...", "author": { "id": 987654321, "name": "John Doe", "profileImageThumbnailUrl": "base_api_url/profiles/thumb.jpg" }, "createdAt": "2023-11-15T14:30:00Z", "liked": true, "likeCount": 42, "shareCount": 7, "attachments": [ { "type": "image", "url": "base_api_url/posts/123456789_1.jpg", "width": 1080, "height": 720, "caption": "Beautiful sunset" }, { "type": "video", "url": "base_api_url/posts/123456789_2.mp4", "duration": 120, "thumbnailUrl": "base_api_url/posts/123456789_2_thumb.jpg" } ] } }
2.2.4 Взаимодействие пользователя с постом:
POST /v1/posts/{postId}/interactions Body: PostInteractionRequest { "requestId": "550e8400-e29b-41d4-a716-446655440000", "type": "LIKED", "postId": 123456789, "timestamp": "2023-11-16T09:30:00Z" }
Таким образом, мы спроектировали API и модель данных, которую будем использовать, опираясь на собранные требования из 1-ого этапа. Нужно понимать, что это одно из множества решений. Цель статьи — объяснить подход к System Design простым языком и предложить решение реальной задачи, которую могут спросить на собеседовании.
Далее необходимо спроектировать диаграмму компонентов/архитектуру нашего приложения: какие будут сущности и за что они будут отвечать, какие у них будут зависимости. Этот этап я планирую описать в следующей части.
Ну, а если вы готовитесь к собеседованиям прямо сейчас или хотите структурировать свои знания, то приглашаю на короткий практический курс по System Design адаптированный специально для мобильных разработчиков. Чтобы не пропустить следующие статьи на тему Android и мобильной разработки подписывайтесь на Telegram-канал
ссылка на оригинал статьи https://habr.com/ru/articles/930898/
Добавить комментарий