cookie

نحن نستخدم ملفات تعريف الارتباط لتحسين تجربة التصفح الخاصة بك. بالنقر على "قبول الكل"، أنت توافق على استخدام ملفات تعريف الارتباط.

avatar

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

Вопросы и авторские статьи по микросервисам, архитектуре, БД Контент по Kotlin/Java: t.me/KotlinQuestions

إظهار المزيد
مشاركات الإعلانات
3 412
المشتركون
-324 ساعات
+47 أيام
+1830 أيام

جاري تحميل البيانات...

معدل نمو المشترك

جاري تحميل البيانات...

Photo unavailableShow in Telegram
Token bucket rate limiting Один из алгоритмов для ограничения числа входящих запросов. На данный момент используется во многих системах, например, AWS. Принцип работы: Есть ограниченный набор токенов, наличие токена = право исполнить запрос. Когда приходит входящий запрос, сначала проверяем, есть ли свободный токен, если есть - забираем его и исполняем запрос, если нет - отдаем 429. И поскольку токены назад не возвращаются, их надо как-то восстанавливать. Этим занимается фоновый процесс, который по крону (обычно раз в секунду) восстанавливает число свободных токенов до максимума.
إظهار الكل...
👍 23🔥 6 2💅 1
⚡Пара подходов к описанию деревьев в реляционной БД Зачастую требуется хранить какие-то иерархичные данные, например, подобие файловой системы или какую-то организационную структуру. 1. id + parent_id
create table folders
(
    id              bigserial not null,
    parent_id bigint      null references folders (id),
    data          jsonb      not null
); 
Самый простой подход, при котором храним идентификатор родительской сущности (либо null, если сущность и так корневая). Плюсы: - Простота модели - Простая вставка - Простой перенос поддерева Минусы: - “Дерево” может стать не деревом - МД не запрещает циклические ссылки - Рекурсивные запросы, чтобы доставать поддерево по id корня 2. id, path + parent_id, parent_path Помимо id добавляется path - путь по айдишникам до текущей сущности. Это нам позволяет сделать более интересные констрейнты и гарантировать, что мы гарантированно имеем дело с деревом.
create table folders
(
    id          bigserial not null,
    path        varchar   not null,
    parent_id   bigint    null,
    parent_path varchar   null,
    data        jsonb     not null

    constraint ck__folders__path
            check (path = coalesce(parent_path, '/') || id || '/'),

    -- нужен для FK
    constraint uc__folders__path__id
        unique (path, id),

    constraint fk__folders__parent_id__parent_path
        foreign key (parent_path, parent_id) references folders (path, id)
            match full
);
Здесь мы гарантируем, что 1) path корневой папки - это /<id>/ 2) path некорневой папки - это <parent_path><id>/ Что позволяет обеспечить отсутствие циклов Плюсы: - Гарантия отсутствия циклов - Простой запрос поддерева - where path like ‘/1/2/3/%’ Минусы: - Сложность модели - Более сложная вставка - Сложный перенос поддерева
إظهار الكل...
👍 31🔥 3 3🤔 1 1
Caching patterns При работе с кешом возникает вопрос “в какой момент нужно синхронизировать данные из бд и кеша?”. Рассмотрим три часто встречающихся паттерна: 1. Read-aside caching Наиболее простой и часто используемый паттерн. Как происходит чтение: - Пробуем достать данные из кеша - Если не получилось, идем в БД, складываем в кеш Как происходит запись: - Просто пишем в БД 2. Write-aside caching Паттерн с чтением аналогичным предыдущему варианту, но при записи сразу обновляем и кеш, что в теории может позволить увеличить hit rate ценой того, что в кеш могут попадать данные, которые не нужны для чтения. Как происходит чтение: - Пробуем достать данные из кеша - Если не получилось, идем в БД, складываем в кеш Как происходит запись: - Пишем в БД - Пишем в кеш 3. Full caching Кеш (обычно по крону) сам себя обновляет, подгружая все необходимые данные из БД. Подходит для случаев, когда хотим добиться ~100% hit rate, и данные целиком влезают в кеш. Как происходит чтение: - Просто читаем из кеша Как происходит запись: - Просто пишем в БД
إظهار الكل...
👍 27🔥 6💅 3 2
Школы 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 корректно сохранил пользователя). А какую школу используете вы и почему?
إظهار الكل...
💅 8👍 6🔥 5
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, также есть кастомные пользовательские реализации для многих других языков.
إظهار الكل...
👍 29🔥 13💅 4
Photo unavailableShow in Telegram
Temporal Temporal - оркестрационный движок, который координирует работу распределенных воркеров, сохраняет промежуточные результаты, делает ретраи и т.д. Temporal cluster состоит из следующих компонентов: - Frontend gateway: авторизация, rate limit - History subsystem: хранит состояние задач в БД - Matching subsystem: управляет очередьми задач - Worker Service: исполняет внутренние (не пользовательские) фоновые процессы ❗️Пользовательские workflow исполняются не temporal кластером, а внешними пользовательскими воркерами. Temporal лишь координирует их работу. Возможности: - Обработка распределенных транзакций - Запускание задач по крону - Исполнение стейт машин - И еще некоторые вещи Как описываются задачи: Activity - некоторое атомарное действие, например, вызов API или запрос в базу. Это действие должно быть идемпотентным, чтобы, например, в случае ретраев из-за сетевых проблем не сделать некоторое действие дважды. Workflow состоят из вызовов activity и некоторой дополнительной логики. И как раз в местах вызова activity сохраняются промежуточные результаты workflow. Всё это описывается с помощью SDK на стороне приложения, на текущий момент существуют реализации для Go, Java, PHP, Python, Typescript, .NET. Посмотреть пример описания workflow можно тут.
إظهار الكل...
👍 12🔥 7💅 5
Ставьте 💅 на этот пост, если нужен рассказ про возможности Temporal
إظهار الكل...
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.

💅 141 1🤔 1
Durable executions Представим, что есть некоторая задача
workflow {
    firstCall()
    sleep(1 hour)
    secondCall()
    sleep(1 hour)
    thirdCall()
}
Если мы ее запустим, то нужно, чтобы воркер, который ее будет исполнять, был жив минимум два часа подряд. Если по-середине ожидания что-то пойдет не так, то весь прогресс потеряется. Именно на этом примере можно описать концепцию Durable executions: После того, как мы сделали firstCall(), мы не будем ждать, а сделаем следующее: - Сохраним в состояние задачи, что мы уже сделали firstCall() - Зашедулим ее на +1 час Спустя час какой-то другой воркер сможет взять эту задачу и продолжить с прыдыдущего “чекпоинта”. То есть мы сохраняем прогресс по определенным частям задачи, что позволяет переживать отказы воркеров и позволяет исполнять задачу по частям разными воркерами. И сейчас существует довольно много Workflow engines, которые строятся на этой концепции.
إظهار الكل...
GitHub - meirwah/awesome-workflow-engines: A curated list of awesome open source workflow engines

A curated list of awesome open source workflow engines - meirwah/awesome-workflow-engines

👍 24🔥 7💅 5
🔥 Это база с 1700 вопросами с собеседований на Java разработчика. Фишка в том, что просчитана вероятность с которой вопрос буден задан и есть примеры ответов. Теперь можно легко получить оффер, подготовившись к самым популярным вопросам 😏
إظهار الكل...
Java | Вопросы собесов

Разбираем вопросы с собеседований на Java разработчика. Spring, Hibernate Сайт:

https://easyoffer.ru/

Реклама:

https://telega.in/c/easy_java_ru

Предложения: @easyoffer_ads

🔥 4
Structured logging ❓Проблема: По логам в виде plain текста тяжело осуществлять поиск, фильтрацию. ✅ Решение: Использовать идею Structured logging: Вместо того, чтобы записывать лог в виде plain текста
[info] [Friday, 20-Jan-23 11:17:55 UTC] The application has started.
Будем записывать его в виде структуры определенного формата
{
  "timestamp": "Friday, 20-Jan-23 11:17:55 UTC",
  "level": "info",
  "message": "The application has started."
}
Это позволит складывать логи в какую-нибудь БД, например, Elasticsearch, индексировать и эффективно производить поиск и фильтрацию.
إظهار الكل...
🔥 20💅 5👍 4🤯 3
اختر خطة مختلفة

تسمح خطتك الحالية بتحليلات لما لا يزيد عن 5 قنوات. للحصول على المزيد، يُرجى اختيار خطة مختلفة.