Microservices | Вопросы с Собеседований

Description
Вопросы и авторские статьи по микросервисам, архитектуре, БД

По сотрудничеству: t.me/qsqnk

По рекламе: https://telega.in/c/MicroservicesQuestions

Контент по Kotlin/Java: t.me/KotlinQuestions
Advertising
We recommend to visit

Бизнес блог #1
Выжимаю книги до самой сути.

👉 Реклама - @jaMasha

📇 Хотите свою книгу? Мы напишем её за вас и сделаем книгу бестселлером. Подробности в боте @Summary_library_bot

🏆 Оставьте след в истории с помощью книги
https://expert-book.pro

Фильмы и сериалы со всей планеты. Мы знаем, что посмотреть, где посмотреть и на что сходить в кино.

Last updated 8 hours ago

Все материалы размещены по партнёрской програме ivi.ru | All materials are posted on the partner program ivi.ru

По всем вопросам: @kuzr103
Купить рекламу: https://telega.in/c/k1noxa103
Основной канал: https://t.me/kino_hd2

Last updated 1 month, 2 weeks ago

5 months ago

Взаимно-рекурсивные внешние ключи

Самый частый юзкейс:

- Есть главная сущность
- Есть дочерние сущности
- Главная сущность ссылается на конкретную дочернюю

Пример: у вопроса может быть несколько ответов, но лишь один корректный:

```
create table questions (
id bigserial not null primary key,
correct_answer_id bigint not null,
question varchar not null
);

create table answers (
id bigserial not null primary key,
question_id bigint not null,
answer varchar not null
);

alter table questions
add foreign key (correct_answer_id) references answers (id);

alter table answers
add foreign key (question_id) references questions (id);
```

Как тут могут помочь CTE:

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

Но можно воспользовать тем, что CTE проверяет констрейнты лишь после полного своего выполнения и сделать вставку за один запрос:

with question\_id as (select nextval('questions\_id\_seq')), answer\_id as ( insert into answers (answer, question\_id) values ('Some answer', (select * from question\_id)) returning id) insert into questions (id, correct\_answer\_id, question) values ((select * from question\_id), (select * from answer\_id), 'Some question’);

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

5 months, 1 week ago

Каскадное удаление за один запрос

Нет, речь не про on delete cascade

Во многих случаях мы не хотим использовать внешние ключи с каскадным удалением, как минимум потому что они существенно повышают цену ошибки - когда случайно удаляется одна сущность и каскадно пол базы

Но как тогда быть, если у нас достаточно глубокая иерархия сущностей, например

a <- b <- c

и хочется по a_id удалить все связанные b и c?

```
create table a (
id bigserial not null primary key
);

create table b (
id bigserial not null primary key,
a_id bigint not null references a (id)
);

create table c (
id bigserial not null primary key,
b_id bigint not null references b (id)
);
```

Наивное решение:

- поселектить из b по a_id
- удалить записи из c по полученным b_id
- удалить записи из b
- удалить записи из a

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

Решение через CTE:

with a\_deleted as ( delete from a where id = <a\_id> returning * ), b\_deleted as ( delete from b where a\_id in (select id from a\_deleted) returning * ) delete from c where b\_id in (select id from b\_deleted)

Почему это работает? CTE трактуется как единый стейтмент, соответственно все проверки констрейнтов будут осуществляться только после его полного выполнения

Это нам позволяет удалить все связанные с таблицей a сущности за один раундтрип до базы, и при необходимости легко масштабировать этот подход, просто добавляя новые строки в CTE, если иерархия вырастет

Ставьте ? на этот пост, если нужен рассказ про еще один интересный вариант применения CTE в контексте внешних ключей

5 months, 2 weeks ago
7 months, 3 weeks ago

Школы unit-тестирования

Лондонская:

- Все зависимости (изменяемые) заменяются на моки
- Под юнитом подразумевается один класс
- Акцент на проверку взаимодействия компонентов

Пример:

@Test fun `test user creation`() { // given val userSaver = mock<UserSaver>() val userService = UserService(userSaver) // when userService.createUser("username") // then verify(userSaver).save(any<User>()) }

Классическая:

- За редким исключением только внепроцессные зависимости (БД, брокер) заменяются на моки
- Под юнитом может подразумеваться набор классов
- Акцент на проверку результатов вызова методов и состояния

Пример:

@Test fun `test user creation`() { // given val userService = UserService(UserSaver()) // when userService.createUser("username") // then assertEquals(User(“username”), userService.getUser(“username”)) }

Лондонская школа позволяет разрабатывать в стиле TDD, начиная с высокоуровневых тестов, поскольку нам не требуются реальные зависимости. И проверяют какой-то аспект поведения класса (что был вызов UserSaver::save при вызове UserService::createUser). В классической школе зачастую проверяется корректная работа конкретного сценария (что UserService::createUser корректно сохранил пользователя).

А какую школу используете вы и почему?

7 months, 3 weeks ago

Testcontainers

Проблема:

В рамках интеграционного тестирования хочется не мокать, а честно поднимать зависимости, такие как БД, брокер сообщений и т.д.

Решение:

Testcontainers - фреймворк, позволяющий запускать контейнеры с различными зависимостями прямо из кода.

Пример на Java:

```
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
"postgres:15-alpine"
);

@BeforeAll
static void beforeAll() {
postgres.start();
}

@AfterAll
static void afterAll() {
postgres.stop();
}
```

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

И сама реализация фреймворка существует для .NET, Go, Java, Node.js, также есть кастомные пользовательские реализации для многих других языков.

8 months, 3 weeks ago

Ставьте ? на этот пост, если нужен рассказ про возможности Temporal

temporal.io

Open Source Durable Execution

Build invincible apps with Temporal's open-source durable execution platform to guarantee successful execution, even in the presence of failures.

9 months, 2 weeks ago
9 months, 2 weeks ago
***⚡*****Asynchronous Request-Reply pattern**

Asynchronous Request-Reply pattern

Проблема:

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

Решение:

Использовать поллинг на клиенте:
- Клиент идет в апи запуска операции

- Бэкенд отдает operationId

- Клиент раз в какое-то время идет в эндпоинт проверки статуса операции по operationId

- Когда операция завершится, бэкенд отдает uri, по которому можно найти результат операции (либо клиент сам знает, куда сходить)

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

9 months, 3 weeks ago
***⚡*****Reverse Proxy**

Reverse Proxy

Тип прокси-сервера, который стоит перед группой серверов, и обеспечивает, что все запросы, адресованные этим серверам, проходят через него.

Возможные применения:
- Балансировка нагрузки: прокси будет равномерно распределять нагрузку на стоящие за ним серверы

- Rate-limiting: например, ограничения общего числа запросов в секунду (1k RPS) и ограничение числа запросов от одного ip адреса (20 RPS)

- Кеширование контента: например, чтобы напрямую клиенту отдавать какой-то статический контент, не совершая запрос к серверу

- Производить TLS шифрование/дешифрование, снимая нагрузку с целевых серверов

Без reverse-proxy пришлось бы дублировать всю эту логику на каждом сервере, а также раскрывать внутреннюю структуру сети, чтобы клиенты могли делать запросы напрямую целевым серверам.

We recommend to visit

Бизнес блог #1
Выжимаю книги до самой сути.

👉 Реклама - @jaMasha

📇 Хотите свою книгу? Мы напишем её за вас и сделаем книгу бестселлером. Подробности в боте @Summary_library_bot

🏆 Оставьте след в истории с помощью книги
https://expert-book.pro

Фильмы и сериалы со всей планеты. Мы знаем, что посмотреть, где посмотреть и на что сходить в кино.

Last updated 8 hours ago

Все материалы размещены по партнёрской програме ivi.ru | All materials are posted on the partner program ivi.ru

По всем вопросам: @kuzr103
Купить рекламу: https://telega.in/c/k1noxa103
Основной канал: https://t.me/kino_hd2

Last updated 1 month, 2 weeks ago