Задать вопрос
Ответы пользователя по тегу Проектирование программного обеспечения
  • Как обосновать применение реляционной БД на интервью по System Design?

    Дополню, что на system design смотрят на твой кругозор в том числе, так что:

    1. Хоть реляционка и подходит тут, но стоит также упомянуть альтернативные решения с их плюсами и минусами

    2. А как же аргументация к наличию специалистов? Вполне можно аргументировать выбор реляционной базы тем, что гораздо легче найти людей, которые умеют с ней работать.

    3. Ну и как уже написали - можно использовать аргумент "на вырост". Может на момент проработки архитектурного решения нам и подходит какая-то key-value или документ-ориентированная система, но это не значит, что при расширении нам будет её хватать.

    Если предлагаешь только реляционную бд без рассмотрения альтернатив - это выглядит так, будто ты больше ничего и не знаешь, потому и предлагаешь просто знакомое решение/решение с которым сам умеешь работать.
    Ответ написан
    2 комментария
  • Как организовать систему обновлений БД?

    Если это какая-то игра, то должно быть несколько файлов сохранений и меняться они должны не автоматически при установке обновления, а только при обращении.

    Менять сохранение нужно только тогда, когда пользователь явно попросит загрузить сохранение из старой версии. Предварительно напомнить пользователю сделать резервную копию (либо вообще сделать её автоматом)

    Если возникла ошибка - придётся смириться. Пусть пользователь скинет пример сохранения с которым произошла проблема - возможно исправишь в следующей версии.
    Если посмотришь на практику - так все и поступают.

    И по возможности лучше стараться делать обратно-совместимые форматы данных.

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

    В остальном всё так, как написал в вопросе
    Ответ написан
    Комментировать
  • Можно ли обращаться к фасаду из класса, который этот фасад вызывает?

    Весь вопрос звучит как какой-то оверинжиниринг.
    0. Без диаграмм вообще поток мыслей сложно понять.
    1. Фасад - это не способ легализовать божественный класс.
    2. Циклические зависимости - это не всегда смертельно плохо, но всегда очень подозрительно.
    3. Не нужно накидывать все паттерны, какие ты знаешь, если только что прочитал какую-то умную книжку или статью. Иногда лучше всё-таки сделать по принципу KISS и YAGNI.

    Или мне нужно создать объект PriceConvert и вызвать нужный метод?

    Зачем на каждую мелкую операцию делать отдельный класс и создавать постоянно новые объекты?

    Просто с одной стороны фасад Payments лежит ниже чем эти классы - это просто точка доступа для контроллеров итд.

    Фасад же типа по определению должен быть выше всех, как наиболее высокий уровень абстракции. С чего это вдруг он оказался ниже всех? И что у тебя подразумевается под контроллерами? Обычно контроллерами в вебе называют обработчики http-запросов. Тогда контроллеры должны зависеть от фасада, а не наоборот.

    и у них внутренние связи налажены через parent
    .
    Что это вообще значит?

    Payments::priceConvert

    Почему вообще платежи отвечают за конвертацию курсов валют? Или что делает priceConvert?
    Ответ написан
    8 комментариев
  • Чем отличается папка public от shared/assets/images?

    Попробую предположить, что в assets лежит то, что используется приложением (всякие иконки, иллюстрации итд), а в public - то что непосредственно приложением не используется, но необходимо для сайта.
    Ответ написан
    1 комментарий
  • Можно ли в одном микросервисе использовать Postgres и MongoDB?

    Можно, разрешаю, но выглядит как-то странно.
    Я бы задумался над возможностью переноса всех данных либо в монгу, либо в постгрес, чтобы в будущем не возникало проблем с консистентностью данных.
    Ответ написан
  • Какой проект можно сделать на базе rpc?

    Ну давай начнём с самого простого: пусть клиент передаёт два числа, а сервер отвечает суммой этих чисел
    Ответ написан
  • Есть ли такая архитектура?

    то уже нет смысла ни в UnitOfWork, ни в Repository. То есть можно избавиться от Infrastructure слоя, чтобы схема была уже такая: UI, Application, Domain.

    Infrastructure слой нужен не для того чтобы заменять базу в будущем, а чтобы работа с базой не захламляла домен.
    Да и "никогда переходить не планируется" - это достаточно громкое заявление.

    Просто в случае с UnitOfWork и Repository накладывают только лишнюю нагрузку, потому что это и так реализовано в EntityFramework.

    Тогда будет усложнено тестирование, так как ты не сможешь замокать EF.
    Лучше всю работу по построению запроса тоже вынести куда-то в инфраструктурный слой - тогда и UoW и "Repository" не придётся тащить в домен.
    Ответ написан
    Комментировать
  • Вопрос с собеседования на Java Бекенд. Как гарантировать согласованность операций?

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

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

    Самый простой и часто используемый вариант - Outbox.

    Смысл в том, что мы должны в нашей основной базе завести таблицу, в которой будет записано, что нам нужно отправить запрос в тот сервис и с какими параметрами. (Например отправить письмо по электронной почте)

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

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

    Переносить взаимодействие со сторонним сервисом в Outbox также имеет смысл из-за того что ты не можешь гарантировать его доступность и задержки - если будешь работат с ним при обработке запроса от клиента по API, то можешь просто упасть по тайм-аут.

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

    66ab5b548e5a9142225375.png

    Благодаря тому что мы записываем основные бизнес-данные и намерение сделать запрос в сторонний сервис в одной транзакции - мы гарантируем, что мы не будем отправлять запрос, если данные не записались и наоборот - если данные записались, то мы гарантируем, что попытаемся рано или поздно отправить запрос.
    Ответ написан
    3 комментария
  • Как правильно создается и поддерживается архитектура для микро сервисов?

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

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

    Но как быть с задачами, когда она касается клиентского сервиса и одного из серверов?

    Это две разные задачи: одна на сервер и одна на клиент.
    API должен быть спроектирован так, чтобы сервер был обратно совместим с клиентом.
    Если всё-таки клиент и сервер должны будут обновляться одновременно, то тогда нужно координировать релизы - опять же к веткам в репозитории никакого отношения не имеет.
    Ответ написан
    Комментировать
  • На чём писать клиентское приложение с GUI?

    Можно посмотреть в сторону PWA и кэшировать данные в local storage или на диск.
    Ответ написан
    Комментировать
  • Как должна работать интеграция VK ID в SPA в описанном случае?


    Что должен возвращать mysite.com/redirect пользователю?

    Тот же самый токен, который бы твой сайт вернул при обычной аутентификации и отправить пользователя дальше
    Ответ написан
    3 комментария
  • Как организовать БД, если данные нужно отправлять по разным АПИ, в запросах которых поля отличаются?

    Если не упарываться в NoSQL, то можно классическим реляционным подходом - EAV-паттерн применить.
    Если постгрес, то можно его в документ-ориентированную базу превратить, благодаря jsonb полям.

    Я бы ввёл две таблицы:
    1. "Описание услуги" - с перечислением всех полей, которые должны быть указаны в заявке. (чтобы можно было сформировать форму)
    2. "Заявка" - там все специфичные поля записываются в jsonb-колонку.

    GraphQL позволит гибко настраивать payload для внешних API

    Мне кажется, что в этом случае GraphQL не очень подходит, так как у контрагентов может быть свой интерфейс взаимодействия => всё равно в коде нужно будет реализовать коннектор для каждого.
    Ответ написан
    1 комментарий
  • Какая архитектура бекенда для временной информации(капча и пр.)?

    Тут напрашивается Redis.
    1. Ничего страшного не произойдёт, если разок при вводе капчи пользователя попросят ввести её ещё раз, если на стороне твоего Бэка что-то потеряется.

    2. Если ты создаёшь большой сервис с кучей клиентов, то ты можешь захотеть горизонтально масштабироваться - тогда твой сервис должен быть stateless, а по тому никакого состояния в памяти у отдельного экземпляра быть не должно.

    3. Сессия - это по определению состояние, которое привязано к конкретному пользователю, но при этом не говорится, где оно хранится.
    В случае сервиса капч сессии неприменимы, тк ты не занимаешься идентификацией пользователей.
    Ответ написан
  • Как правильно инициализировать библиотеку классов в .NET?


    Чтобы данный сервис был доступен в окружении Lib.Controls, я реализую в этой библиотеке статический класс:

    Фатальная ошибка.


    Является ли такая архитектура единственно возможной или у нее есть достойные альтернативы?

    Раз у тебя уже есть DI, то следующий шаг прямо напрашивается. Создавать формы тоже при помощи DI и прокидывать все такие зависимости через конструктор.
    Ответ написан
    2 комментария
  • GRPC или RabbitMQ что лучше использовать для взаимодействия между API Gateway и микросервисами?

    1. Зачем вообще нужны усложнения, почему в рамках ваших сервисов не использовать rest api (обычный голый http с json-ами)?
    2. grpc vs rabbitmq - это больше вопрос про синхронное vs асинхронное взаимодействие.
    В зависимости от конкретного случая может быть лучше одно, а может быть лучше другое.
    Как правило при использовании api gateway имеет место синхронное взаимодействие, тк ожидается, что сервер ответит на http-запрос в течение пары секунд (как правило меньше секунды).

    При желании, можно поверх rabbitmq устроить rpc, но там всё равно будет более высокая нагрузка на железо, чем если бы напрямую происходил вызов.
    Ответ написан
    2 комментария
  • Как лучше возвращать ошибку API?

    Лучше возвращать какой-то код ошибки (можно несколько слов. Главное чтобы они никогда не менялись и значили одно и то же) и дополнительную информацию (например id не найденного объекта, роль, которой не хватило, дополнительные коды, и тд), а на фронте по этому коду находить человеческое описание и наполнять его дополнительной инфой.

    Но если хочется облегчить жизнь фронту (и усложнить бэку), язык на сайте только русский, и API будет пользоваться только сайтом, то можно на бэке формировать сообщение об ошибке.
    Ответ написан
    Комментировать
  • Где лучше всего хранить sms коды?

    Тут нет "более правильного" варианта.
    Программная инженерия - это всегда про компромисс.

    Я бы выбрал вариант с уже имеющейся базой данных, тк это:
    1. Уже проверенное решение
    2. Это решение очень простое и понятное
    3. Оно не подразумевает усложнение инфраструктуры
    4. Оно точно устроит тебя по производительности.
    Ответ написан
    Комментировать
  • Что лучше выбрать для взаимодействия в микросервисной архитектуре? MessageBroker или REST?

    Зависит от того что именно за данные (для какой цели) будут передаваться и между кем и кем.
    Rest как и любой другой синхронный метод взаимодействия несёт плюсы:
    + Сравнительно быстрая реакция на запрос и ответ. (как правило от запроса до получения ответа менее секунды)
    + Очень прост в использовании, нет никаких проблем с поддержкой на клиенте
    + Очень простая инфраструктура (в минимальном варианте она не нужна вообще)
    + Всё хорошо изучено. Та же аутентификация и авторизация очень легко реализуется в рамках http.
    + Достаточно легко разрабатывать и тестировать
    + Есть grpc и openapi - нет никакой проблемы с документированием такого API.
    + В http запрос с каким-нибудь multipart form data может спокойно быть размером в десятки мегабайт, а может и больше - полезно при загрузке файлов.
    И минусы:
    - Не понятно что делать, в случае недоступности ответной стороны
    - При неправильной реализации клиента (политики ретраев) - можно легко заддосить сервер

    Всякие разнообразные брокеры сообщений тоже имеют свои плюсы:
    + Строгая очерёдность обработки данных (событий) из коробки
    + В случае недоступности ответной стороны - брокер у себя может хоть несколько дней держать данные
    + Все политики ретраев реализуются на стороне брокера
    + Если это rabbit, то можно разные сложные механики рассылки и маршрутизации реализовать
    + Если это кафка или какой-то другой лог, то можно вычитывать события повторно

    Но есть и минусы:
    - Инфраструктура обычно сложнее
    - Достаточно большие задержки
    - Использовать можно будет только у себя внутри - внешнему клиенту (браузер, мобильное приложение, публичный API) такое дать не получится.
    - Сложнее разграничивать в правах.
    - Сложно разрабатывать и тестировать. На примере той же кафки - подключиться к топику и записать в него что-то через гуй - это отдельный челендж.
    - Запросы должны быть небольшими (сотни кб)
    Ответ написан
    2 комментария
  • Как реализовать чексуммы для сетевого протокола уровня приложения?

    При использовании TCP стека (Ethernet, IP, TCP) не гарантируется сохранение целостности.

    Гарантируется.
    Ответ написан
    7 комментариев