Rate Limiting vs Throttling
Rate limiting = отклонение запросов после достижения лимита
Throttling = замедление обработки запросов вместо их отклонения
Пример:
Клиент отправляет 100 запросов/сек
Rate limiting
→ разрешить первые 50
→ остальные отклонить с ошибкой 429 Too Many Requests
Throttling
→ поставить запросы в очередь или задержать
→ обрабатывать их постепенно
Rate limiting — отбрасывает лишний трафик
Throttling — контролирует скорость обработки трафика
Оба подхода защищают систему от перегрузки.
Как это реализуют
Rate limiting → алгоритмы token bucket или sliding window counters
Throttling → очередь запросов + пул воркеров (контролируемая скорость обработки)
👉 @BackendPortal
Rate limiting = отклонение запросов после достижения лимита
Throttling = замедление обработки запросов вместо их отклонения
Пример:
Клиент отправляет 100 запросов/сек
Rate limiting
→ разрешить первые 50
→ остальные отклонить с ошибкой 429 Too Many Requests
Throttling
→ поставить запросы в очередь или задержать
→ обрабатывать их постепенно
Rate limiting — отбрасывает лишний трафик
Throttling — контролирует скорость обработки трафика
Оба подхода защищают систему от перегрузки.
Как это реализуют
Rate limiting → алгоритмы token bucket или sliding window counters
Throttling → очередь запросов + пул воркеров (контролируемая скорость обработки)
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
Интересный факт: Stripe использует MongoDB для хранения своих основных данных, и при этом система обрабатывает 5 миллионов QPS и работает с 2000+ шардами
Некоторое время назад Stripe опубликовали инженерный блог, в котором рассказали о своей архитектуре баз данных и о том, как они масштабировали MongoDB-кластер, чтобы поддерживать нагрузку в 5 млн QPS, при этом сохраняя стабильность и управляемость системы.
В статье также подробно разбираются:
- платформа перемещения данных (data movement platform)
- логическое и физическое шардинг-разделение
- и, что особенно интересно, механизм “flip switch” — переключатель, позволяющий безопасно менять маршрутизацию или конфигурацию системы.
Всё это реализовано очень аккуратно и производит действительно сильное впечатление.
👉 @BackendPortal
Некоторое время назад Stripe опубликовали инженерный блог, в котором рассказали о своей архитектуре баз данных и о том, как они масштабировали MongoDB-кластер, чтобы поддерживать нагрузку в 5 млн QPS, при этом сохраняя стабильность и управляемость системы.
В статье также подробно разбираются:
- платформа перемещения данных (data movement platform)
- логическое и физическое шардинг-разделение
- и, что особенно интересно, механизм “flip switch” — переключатель, позволяющий безопасно менять маршрутизацию или конфигурацию системы.
Всё это реализовано очень аккуратно и производит действительно сильное впечатление.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3💊1
Топ-ресурсы для изучения backend и системного программирования:
▪️ OSDev Wiki
▪️ Beej's Guides to Network Programming
▪️ Julia Evans' Blog
▪️ Low Level Programming University
▪️ Computer Science from the Bottom Up
▪️ Crafting Interpreters
▪️ The Linux Documentation Project
▪️ Writing an OS in Rust
▪️ Destroy All Software
▪️ Курсы Casey Muratori
▪️ MIT OpenCourseWare
▪️ Compiler Explorer
▪️ Computer Systems: A Programmer's Perspective
▪️ Hacker News
▪️ Lobsters
▪️ /r/systems
▪️ ByteByteGo
▪️ High Scalability
▪️ Martin Kleppmann's Blog
▪️ Architecture Notes
▪️ The Morning Paper
▪️ Brendan Gregg's Blog
▪️ Dan Luu's Blog
▪️ Phil Eaton's Blog
▪️ Database Internals
▪️ Designing Data‑Intensive Applications
▪️ Systems We Love
▪️ Strange Loop Conference (видеозаписи)
▪️ Papers We Love
▪️ CMU Database Group
👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
Большинство разработчиков используют Spring каждый день… но многие до сих пор не до конца понимают AOP
Давайте разберёмся.
Что такое AOP?
AOP — это способ добавлять общий (cross-cutting) функционал без изменения основного бизнес-кода.
Примеры cross-cutting логики:
- логирование (Logging)
- проверки безопасности (Security checks)
- транзакции (Transactions)
- кэширование (Caching)
- отслеживание производительности (Performance tracking)
- обработка ошибок (Error handling)
Такой функционал нужен почти везде, но он не должен загромождать бизнес-логику.
Зачем нужен AOP?
Без AOP:
одна и та же логика повторяется во множестве методов.
С AOP:
вы пишете эту логику один раз и применяете ко всем нужным местам.
Плюсы:
- чистый код
- повторное использование
- отсутствие вмешательства в бизнес-логику (non-intrusive)
Как AOP работает в Spring
В Spring создаётся proxy (объект-обёртка) вокруг вашего bean.
Этот proxy решает:
- нужно ли запускать аспектную логику
- когда её запускать
- вокруг каких методов её применять
Вы продолжаете вызывать тот же самый bean, но Spring незаметно оборачивает его proxy-объектом.
Где AOP используется в реальных проектах
-
-
-
- Spring Security
- системы логирования
- аудит (Auditing)
- rate limiting
- таймеры производительности
Практически каждый серьёзный проект на Spring Boot использует AOP “под капотом”.
👉 @BackendPortal
Давайте разберёмся.
Что такое AOP?
AOP — это способ добавлять общий (cross-cutting) функционал без изменения основного бизнес-кода.
Примеры cross-cutting логики:
- логирование (Logging)
- проверки безопасности (Security checks)
- транзакции (Transactions)
- кэширование (Caching)
- отслеживание производительности (Performance tracking)
- обработка ошибок (Error handling)
Такой функционал нужен почти везде, но он не должен загромождать бизнес-логику.
Зачем нужен AOP?
Без AOP:
одна и та же логика повторяется во множестве методов.
С AOP:
вы пишете эту логику один раз и применяете ко всем нужным местам.
Плюсы:
- чистый код
- повторное использование
- отсутствие вмешательства в бизнес-логику (non-intrusive)
Как AOP работает в Spring
В Spring создаётся proxy (объект-обёртка) вокруг вашего bean.
Этот proxy решает:
- нужно ли запускать аспектную логику
- когда её запускать
- вокруг каких методов её применять
Вы продолжаете вызывать тот же самый bean, но Spring незаметно оборачивает его proxy-объектом.
Где AOP используется в реальных проектах
-
@Transactional — транзакционный AOP-
@Cacheable — AOP для кэширования-
@Async — асинхронный AOP- Spring Security
- системы логирования
- аудит (Auditing)
- rate limiting
- таймеры производительности
Практически каждый серьёзный проект на Spring Boot использует AOP “под капотом”.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Недавний вопрос с code review на собеседовании по Java: что не так с этим сервисом?
Код компилируется, тесты проходят (green), но в production всё ломается.
[Дано]
Сервис обрабатывает запросы на вывод средств. Требования простые:
- нельзя вывести больше, чем есть на балансе;
- нельзя создать два запроса одновременно.
(код на прикреплённом изображении)
[Задача]
Два запроса от одного пользователя пришли одновременно. В результате баланс ушёл в минус, и было создано два запроса.
[Объясните]
- точную последовательность событий при конкурентных запросах;
- спасёт ли ситуацию аннотация
- как правильно исправить эту проблему.
👉 @BackendPortal
@Service
@RequiredArgsConstructor
public class СервисВывода {
private final РепозиторийАккаунтов accountRepository;
private final РепозиторийВыводов withdrawalRepository;
public void запросВывода(Long userId, BigDecimal amount) {
Account account =
accountRepository.findByUserId(userId)
.orElseThrow();
if (account.getBalance().compareTo(amount) < 0) {
throw new ИсключениеНедостаточноСредств();
}
boolean hasPending = withdrawalRepository
.existsByUserIdAndStatus(uid, Status.PENDING);
if (hasPending) {
throw new ИсключениеВыводУжеВОбработке();
}
account.setBalance(account.getBalance().subtract(amount));
accountRepository.save(account);
withdrawalRepository.save(
new Withdrawal(uid, amount, Status.PENDING)
);
}
}
Код компилируется, тесты проходят (green), но в production всё ломается.
[Дано]
Сервис обрабатывает запросы на вывод средств. Требования простые:
- нельзя вывести больше, чем есть на балансе;
- нельзя создать два запроса одновременно.
(код на прикреплённом изображении)
[Задача]
Два запроса от одного пользователя пришли одновременно. В результате баланс ушёл в минус, и было создано два запроса.
[Объясните]
- точную последовательность событий при конкурентных запросах;
- спасёт ли ситуацию аннотация
@Transactional над методом или нет? Почему?- как правильно исправить эту проблему.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Разработчики на Go знают эту боль:
Dingo пробует кое-что интересное.
Мета-язык, который компилируется в чистый Go, но добавляет такие вещи, как:
• типы Result
• сопоставление с образцом (pattern matching)
• распространение ошибок через
Пишешь на современном синтаксисе → на выходе получаешь чистый Go.
👉 @BackendPortal
if err != nil
if err != nil
if err != nil
Dingo пробует кое-что интересное.
Мета-язык, который компилируется в чистый Go, но добавляет такие вещи, как:
• типы Result
• сопоставление с образцом (pattern matching)
• распространение ошибок через
?Пишешь на современном синтаксисе → на выходе получаешь чистый Go.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6❤2
Алгоритм Sliding Window Log в основном используется для rate limiting в системе. Он использует логи (журнал временных меток), чтобы проверять и разрешать запросы от пользователей.
Как это работает?
Алгоритм сохраняет временные метки запросов и постоянно проверяет их, удаляя те, которые вышли за пределы заданного временного окна.
Например, представим окно 5 секунд, и разрешено не более 5 запросов за 5 секунд.
Сервер принимает запросы в текущем окне. Если количество запросов меньше или равно 5, сервер их обрабатывает.
Когда мы переходим к 6-й секунде, удаляется временная метка запроса, который был получен на 1-й секунде. После этого сервер может принять новый запрос, полученный на 6-й секунде.
Таким образом, скользящее окно (sliding window) постоянно сдвигается вперёд секунда за секундой, удаляя временные метки старых запросов, которые выходят за пределы окна.
Алгоритм также обрабатывает краевые случаи (edge cases). Например, если в какой-то момент приходит 8 запросов, а лимит составляет 5 запросов за 5 секунд, лишние запросы будут отклонены. На следующей секунде сервер снова сможет принимать запросы, если после удаления устаревших временных меток появится свободное место в окне.
На практике через окно может проходить гораздо больше запросов. Например, можно задать окно 10 секунд с лимитом 1000 запросов. Такой подход позволяет обрабатывать всплески (bursts) запросов и при этом продолжать работу без остановки.
Мне потребовалось некоторое время, чтобы разобраться в этом алгоритме, но в итоге стало понятно.
Следующий и последний алгоритм для rate limiting — это Sliding Window Counter.
👉 @BackendPortal
Как это работает?
Алгоритм сохраняет временные метки запросов и постоянно проверяет их, удаляя те, которые вышли за пределы заданного временного окна.
Например, представим окно 5 секунд, и разрешено не более 5 запросов за 5 секунд.
Сервер принимает запросы в текущем окне. Если количество запросов меньше или равно 5, сервер их обрабатывает.
Когда мы переходим к 6-й секунде, удаляется временная метка запроса, который был получен на 1-й секунде. После этого сервер может принять новый запрос, полученный на 6-й секунде.
Таким образом, скользящее окно (sliding window) постоянно сдвигается вперёд секунда за секундой, удаляя временные метки старых запросов, которые выходят за пределы окна.
Алгоритм также обрабатывает краевые случаи (edge cases). Например, если в какой-то момент приходит 8 запросов, а лимит составляет 5 запросов за 5 секунд, лишние запросы будут отклонены. На следующей секунде сервер снова сможет принимать запросы, если после удаления устаревших временных меток появится свободное место в окне.
На практике через окно может проходить гораздо больше запросов. Например, можно задать окно 10 секунд с лимитом 1000 запросов. Такой подход позволяет обрабатывать всплески (bursts) запросов и при этом продолжать работу без остановки.
Мне потребовалось некоторое время, чтобы разобраться в этом алгоритме, но в итоге стало понятно.
Следующий и последний алгоритм для rate limiting — это Sliding Window Counter.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
Бэкенд-разработчики, это для вас:
Сценарий:
У вашей e-commerce платформы миллионы заказов. Команда маркетинга хочет видеть все завершённые заказы за последние 24 часа на дашборде.
Вопрос:
Почему такой запрос может работать медленно, и какие стратегии могут улучшить производительность?
👉 @BackendPortal
Сценарий:
У вашей e-commerce платформы миллионы заказов. Команда маркетинга хочет видеть все завершённые заказы за последние 24 часа на дашборде.
SELECT o.id, o.user_id, o.total, o.status
FROM orders o
WHERE o.status = 'completed'
AND o.created_at >= NOW() - INTERVAL '1 day';
Вопрос:
Почему такой запрос может работать медленно, и какие стратегии могут улучшить производительность?
Please open Telegram to view this post
VIEW IN TELEGRAM
Каждая масштабируемая система начинается с одного важного компонента: балансировщика нагрузки (Load Balancer).
Без него ваш backend рано или поздно начнёт падать под нагрузкой.
Вот как на самом деле работают балансировщики нагрузки.
1. Один сервер
Представим, что в системе есть один backend-сервер.
Весь трафик идёт на одну машину.
Users → Server
Когда трафик растёт:
- загрузка CPU увеличивается
- память заполняется
- latency растёт
В итоге сервер падает.
2. Решение — горизонтальное масштабирование
Вместо одного сервера запускается несколько серверов.
- Server 1
- Server 2
- Server 3
- Server 4
Но теперь нужен способ распределять запросы между ними.
Именно для этого используется Load Balancer.
3. Новая архитектура
Теперь схема выглядит так:
Users → Load Balancer → Multiple Servers
Балансировщик решает, какой сервер будет обрабатывать каждый запрос.
4. Популярные алгоритмы балансировки
Round Robin
Запросы распределяются по очереди.
Req1 → Server1
Req2 → Server2
Req3 → Server3
Простой и очень распространённый метод.
Least Connections
Трафик отправляется на сервер с наименьшим количеством активных соединений.
Полезно, когда время обработки запросов сильно различается.
IP Hash
Запросы от одного IP-адреса пользователя направляются на один и тот же сервер.
Часто используется, когда нужна session stickiness.
5. Дополнительные функции балансировщиков
Балансировщики также обеспечивают:
- health checks
- failover
- SSL termination
- routing трафика
Если сервер становится нездоровым, он автоматически исключается из пула.
Пользователи этого даже не замечают.
6. Популярные балансировщики в продакшене
- Nginx
- HAProxy
- AWS Elastic Load Balancing (ELB / ALB)
- Cloudflare
Балансировщик нагрузки — это первый шаг к масштабированию backend-системы.
👉 @BackendPortal
Без него ваш backend рано или поздно начнёт падать под нагрузкой.
Вот как на самом деле работают балансировщики нагрузки.
1. Один сервер
Представим, что в системе есть один backend-сервер.
Весь трафик идёт на одну машину.
Users → Server
Когда трафик растёт:
- загрузка CPU увеличивается
- память заполняется
- latency растёт
В итоге сервер падает.
2. Решение — горизонтальное масштабирование
Вместо одного сервера запускается несколько серверов.
- Server 1
- Server 2
- Server 3
- Server 4
Но теперь нужен способ распределять запросы между ними.
Именно для этого используется Load Balancer.
3. Новая архитектура
Теперь схема выглядит так:
Users → Load Balancer → Multiple Servers
Балансировщик решает, какой сервер будет обрабатывать каждый запрос.
4. Популярные алгоритмы балансировки
Round Robin
Запросы распределяются по очереди.
Req1 → Server1
Req2 → Server2
Req3 → Server3
Простой и очень распространённый метод.
Least Connections
Трафик отправляется на сервер с наименьшим количеством активных соединений.
Полезно, когда время обработки запросов сильно различается.
IP Hash
Запросы от одного IP-адреса пользователя направляются на один и тот же сервер.
Часто используется, когда нужна session stickiness.
5. Дополнительные функции балансировщиков
Балансировщики также обеспечивают:
- health checks
- failover
- SSL termination
- routing трафика
Если сервер становится нездоровым, он автоматически исключается из пула.
Пользователи этого даже не замечают.
6. Популярные балансировщики в продакшене
- Nginx
- HAProxy
- AWS Elastic Load Balancing (ELB / ALB)
- Cloudflare
Балансировщик нагрузки — это первый шаг к масштабированию backend-системы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤3👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Как работает Depth-First Search (DFS):
1. Начинаем со стека: помещаем исходную вершину в стек и помечаем её как посещённую.
2. Извлекаем верхнюю вершину: берём элемент с вершины стека — это текущая вершина для обхода.
3. Обрабатываем вершину: выполняем нужное действие — выводим, проверяем условие, сохраняем путь и т.д.
4. Добавляем непосещённых соседей: просматриваем всех соседей текущей вершины. Для каждого непосещённого — помечаем как посещённый и кладём в стек.
5. Повторяем, пока стек не пуст: возвращаемся к шагу 2. На каждой итерации уходим глубже по одному из путей перед возвратом назад.
6. Бэктрекинг происходит автоматически: если у вершины нет непосещённых соседей, ничего не добавляется в стек, и следующий
👉 @BackendPortal
1. Начинаем со стека: помещаем исходную вершину в стек и помечаем её как посещённую.
2. Извлекаем верхнюю вершину: берём элемент с вершины стека — это текущая вершина для обхода.
3. Обрабатываем вершину: выполняем нужное действие — выводим, проверяем условие, сохраняем путь и т.д.
4. Добавляем непосещённых соседей: просматриваем всех соседей текущей вершины. Для каждого непосещённого — помечаем как посещённый и кладём в стек.
5. Повторяем, пока стек не пуст: возвращаемся к шагу 2. На каждой итерации уходим глубже по одному из путей перед возвратом назад.
6. Бэктрекинг происходит автоматически: если у вершины нет непосещённых соседей, ничего не добавляется в стек, и следующий
pop возвращает нас назад по пути.Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Хотите разобраться с разработкой веб-приложений на Go?
Let's Go — это понятное и лаконичное руководство, которое охватывает всё необходимое: лучшие практики, структуру проекта и практические паттерны кода — включая управление зависимостями, аутентификацию, работу с базами данных, тестирование и многое другое.
👉 @BackendPortal
Let's Go — это понятное и лаконичное руководство, которое охватывает всё необходимое: лучшие практики, структуру проекта и практические паттерны кода — включая управление зависимостями, аутентификацию, работу с базами данных, тестирование и многое другое.
Please open Telegram to view this post
VIEW IN TELEGRAM
lets-go.alexedwards.net
Let’s Go! Learn to build web apps with Go
A clear and concise guide to practical code patterns, project organization, best practices and more.
❤3
Решение медленных запросов часто сводится к добавлению ещё одного индекса. Но переиндексация — вполне реальная проблема, и есть менее известная фича в Postgres получше: CREATE STATISTICS 💡
Я часто ловил себя на том, что пытаюсь починить медленный запрос или плохой execution plan, добавляя ещё один, более специфичный индекс. В большинстве случаев это работало, но… чёрт, это было дорого. Не только по дисковому пространству, но и по стоимости обновления индекса на пути записи (write path).
Малоизвестная возможность в Postgres — это расширенная статистика (extended statistics). Это то, о чём должен знать каждый, кто работает с PG. И я сам слишком долго был по другую сторону — жаль, что не узнал об этом раньше🫣
PostgreSQL уже из коробки имеет немало информации о ваших таблицах. Однако эти данные в основном по отдельным колонкам (есть исключения) и не отражают взаимосвязи между двумя и более колонками.
CREATE STATISTICS (или extended statistics) позволяет PG собирать дополнительную многоколоночную статистику, чтобы учитывать зависимости между колонками, понимать вероятные, маловероятные и невозможные комбинации значений, а также улучшать оценку количества строк (row estimates). Причём улучшения могут быть больше чем на порядок
Это важно, потому что в реальных данных столбцы обычно не независимы друг от друга. Как кофе без кружки — это просто чёрная вода на столе.
Самое приятное — это почти ничего не стоит. Практически не требует памяти или дискового пространства и намного легче поддерживается в актуальном состоянии при изменениях данных.
И использовать это очень просто:
Требование по хранению — около 2 KiB. Аналогичный индекс занял бы ~30 MiB для того же набора данных. И execution plans при этом, как правило, получаются лучше.
Полный разбор — в этом блоге, там же есть бенчмарк (с сгенерированными execution plan’ами и отчётами) на GitHub.👇
- Benchmark code + reports
- Blog post
👉 @BackendPortal
Я часто ловил себя на том, что пытаюсь починить медленный запрос или плохой execution plan, добавляя ещё один, более специфичный индекс. В большинстве случаев это работало, но… чёрт, это было дорого. Не только по дисковому пространству, но и по стоимости обновления индекса на пути записи (write path).
Малоизвестная возможность в Postgres — это расширенная статистика (extended statistics). Это то, о чём должен знать каждый, кто работает с PG. И я сам слишком долго был по другую сторону — жаль, что не узнал об этом раньше
PostgreSQL уже из коробки имеет немало информации о ваших таблицах. Однако эти данные в основном по отдельным колонкам (есть исключения) и не отражают взаимосвязи между двумя и более колонками.
CREATE STATISTICS (или extended statistics) позволяет PG собирать дополнительную многоколоночную статистику, чтобы учитывать зависимости между колонками, понимать вероятные, маловероятные и невозможные комбинации значений, а также улучшать оценку количества строк (row estimates). Причём улучшения могут быть больше чем на порядок
Это важно, потому что в реальных данных столбцы обычно не независимы друг от друга. Как кофе без кружки — это просто чёрная вода на столе.
Самое приятное — это почти ничего не стоит. Практически не требует памяти или дискового пространства и намного легче поддерживается в актуальном состоянии при изменениях данных.
И использовать это очень просто:
CREATE STATISTICS my_stats (mcv, dependencies)
ON region, plan_tier, billing_status
FROM tenants;
Требование по хранению — около 2 KiB. Аналогичный индекс занял бы ~30 MiB для того же набора данных. И execution plans при этом, как правило, получаются лучше.
Полный разбор — в этом блоге, там же есть бенчмарк (с сгенерированными execution plan’ами и отчётами) на GitHub.
- Benchmark code + reports
- Blog post
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6❤2
MWS Cloud Platform приглашает на сеньорский митап
Что обсудим:
→ Почему vhost-user обходит virtio-net
→ Когда писать свой балансировщик вместо HAProxy
→ Почему нельзя выбрать один язык для платформы
Поспорим на дебатах Go vs Kotlin — все желающие могут присоединиться и задавать вопросы из зала.
📅 9 апреля, 18:00
📍 Место Санкт-Петербург, Конногвардейский бульвар, 4, Mishka Bar
Для кого: сеньоров-разработчиков, сетевых инженеров и архитекторов облачных платформ
Сложность докладов: 8/10
Места ограничены, регистрация обязательна. 👉
Что обсудим:
→ Почему vhost-user обходит virtio-net
→ Когда писать свой балансировщик вместо HAProxy
→ Почему нельзя выбрать один язык для платформы
Поспорим на дебатах Go vs Kotlin — все желающие могут присоединиться и задавать вопросы из зала.
📅 9 апреля, 18:00
📍 Место Санкт-Петербург, Конногвардейский бульвар, 4, Mishka Bar
Для кого: сеньоров-разработчиков, сетевых инженеров и архитекторов облачных платформ
Сложность докладов: 8/10
Места ограничены, регистрация обязательна. 👉
❤1
Что если ваш репозиторий был бы AI-агентом?
GitAgent делает это реальностью.
• Git-native стандарт для AI-агентов
• Ваш репозиторий = память, навыки и идентичность
• Работает с OpenAI, Claude, CrewAI и другими
• Версионируемые, проверяемые и воспроизводимые агенты
• Запуск агентов напрямую из GitHub
100% опенсорс
👉 @BackendPortal
GitAgent делает это реальностью.
• Git-native стандарт для AI-агентов
• Ваш репозиторий = память, навыки и идентичность
• Работает с OpenAI, Claude, CrewAI и другими
• Версионируемые, проверяемые и воспроизводимые агенты
• Запуск агентов напрямую из GitHub
100% опенсорс
Please open Telegram to view this post
VIEW IN TELEGRAM
Как разработчик, задумывался ли ты когда-нибудь:
Ты вводишь имя пользователя в Gmail — и UI мгновенно показывает: «Username already taken»…
При том что пользователей по всему миру — миллионы.
Как эта проверка выполняется так быстро?
Я сказал «миллионы», но на самом деле пользователей Gmail около ~1.8 млрд по всему миру.
Меняет ли это что-то в архитектуре?
Во многих ответах упоминается Bloom Filter.
Но как разработчик,
знаешь ли ты, что такое Bloom Filter?
Bloom filter — это структура данных, состоящая из:
* битового массива (просто 0 и 1)
* нескольких хеш-функций
И всё. Ничего больше.
Посмотрим, как это работает:
Добавляем элемент ("john")
Шаг 1: прогоняем через хеш-функции
h1("john") → 2
h2("john") → 5
h3("john") → 8
Шаг 2: выставляем соответствующие индексы в 1
bitArray = [0,1,0,0,1,0,0,1,0,0]
2 5 8
Теперь проверим элемент ("Raj")
Шаг 1: снова хешируем
h1("Raj") → 2
h2("Raj") → 4
h3("Raj") → 9
Шаг 2: проверяем биты
индекс 2 → 1
индекс 4 → 0
Если хотя бы один индекс = 0 → возвращаем FALSE (точно отсутствует)
Теперь проверим другой ("Sumit")
h1("Sumit") → 2
h2("Sumit") → 5
h3("Sumit") → 8
Проверка битов:
2 → 1
5 → 1
8 → 1
Все 1 → возвращаем TRUE (возможно присутствует, нужно проверить в БД)
Почему «возможно»?
Разные входные данные могут отображаться в одни и те же индексы:
john → 2,5,8
Sumit → 2,5,8 (коллизия)
То есть:
ты не добавлял "Sumit",
но биты уже равны 1 (ложноположительное срабатывание)
👉 @BackendPortal
Ты вводишь имя пользователя в Gmail — и UI мгновенно показывает: «Username already taken»…
При том что пользователей по всему миру — миллионы.
Как эта проверка выполняется так быстро?
Я сказал «миллионы», но на самом деле пользователей Gmail около ~1.8 млрд по всему миру.
Меняет ли это что-то в архитектуре?
Во многих ответах упоминается Bloom Filter.
Но как разработчик,
знаешь ли ты, что такое Bloom Filter?
Bloom filter — это структура данных, состоящая из:
* битового массива (просто 0 и 1)
* нескольких хеш-функций
И всё. Ничего больше.
Посмотрим, как это работает:
Добавляем элемент ("john")
Шаг 1: прогоняем через хеш-функции
h1("john") → 2
h2("john") → 5
h3("john") → 8
Шаг 2: выставляем соответствующие индексы в 1
bitArray = [0,1,0,0,1,0,0,1,0,0]
2 5 8
Теперь проверим элемент ("Raj")
Шаг 1: снова хешируем
h1("Raj") → 2
h2("Raj") → 4
h3("Raj") → 9
Шаг 2: проверяем биты
индекс 2 → 1
индекс 4 → 0
Если хотя бы один индекс = 0 → возвращаем FALSE (точно отсутствует)
Теперь проверим другой ("Sumit")
h1("Sumit") → 2
h2("Sumit") → 5
h3("Sumit") → 8
Проверка битов:
2 → 1
5 → 1
8 → 1
Все 1 → возвращаем TRUE (возможно присутствует, нужно проверить в БД)
Почему «возможно»?
Разные входные данные могут отображаться в одни и те же индексы:
john → 2,5,8
Sumit → 2,5,8 (коллизия)
То есть:
ты не добавлял "Sumit",
но биты уже равны 1 (ложноположительное срабатывание)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🤔1
Хочешь узнать про тренды инженерной культуры и разработки в российских ИТ-компаниях? Тогда присоединяйся к ИТ-вечеру в стиле «Русское техно» от МТС Web Services. 🙌
Двери особняка в парке Сокольники в Москве распахнутся 26 марта, чтобы собрать вместе бэкенд- и ML-разработчиков, которые строят современные ИТ-решения.
Участников ждут актуальные практики, мастер-классы, общение, игры и атмосфера вечеринки.
Ты узнаешь:
- какие инженерные культуры существуют у сильных ИТ-игроков на российском рынке, и как на них повлияло развитие ИИ;
- как компании внедряют ИИ в процесс разработки;
- как построить архитектуру для ИИ-агентов.
Попробуешь на практике:
- создать игру с помощью вайб-кодинга с MWS DevTools Agent;
- создать ИИ-агента.
Когда: 26 марта в 18:00
Москва + онлайн
👉 Количество участников ограничено, успей зарегистрироваться по ссылке.
Двери особняка в парке Сокольники в Москве распахнутся 26 марта, чтобы собрать вместе бэкенд- и ML-разработчиков, которые строят современные ИТ-решения.
Участников ждут актуальные практики, мастер-классы, общение, игры и атмосфера вечеринки.
Ты узнаешь:
- какие инженерные культуры существуют у сильных ИТ-игроков на российском рынке, и как на них повлияло развитие ИИ;
- как компании внедряют ИИ в процесс разработки;
- как построить архитектуру для ИИ-агентов.
Попробуешь на практике:
- создать игру с помощью вайб-кодинга с MWS DevTools Agent;
- создать ИИ-агента.
Когда: 26 марта в 18:00
Москва + онлайн
👉 Количество участников ограничено, успей зарегистрироваться по ссылке.
🤔1
Один из способов не утонуть в сложности при проектировании системы — использовать определённую структуру / ментальную модель. Вот простая модель, которой я пользуюсь…
Представь любую систему как состоящую из двух отдельных путей: read path и write path. Твоя база данных или слой хранения находится в центре, а у каждого пути — свой набор проблем и свой инструментарий для их решения.
Write path — это про надёжность (durability) и пропускную способность (throughput). Как правило, ты выбираешь из одного и того же набора инструментов: message queue для сглаживания пиков нагрузки, write-ahead logging для обеспечения надёжности, batching для снижения I/O и асинхронная обработка, чтобы не перегружать критический путь.
Read path — это про задержки (latency) и масштабируемость. И здесь тоже есть стандартный набор: кэширование на разных уровнях (CDN, уровень приложения, уровень запросов), read-реплики для разгрузки primary, денормализация или предвычисление тяжёлых запросов, а также пагинация или cursor-based обход, чтобы избежать полного сканирования.
Когда начинаешь воспринимать это как две отдельные задачи, ты перестаёшь «проектировать систему» целиком и начинаешь отвечать на два более простых вопроса: что нужно write path? что нужно read path? А затем связываешь их через слой хранения.
Этот «фреймворк» (если его так можно назвать) полезен не только в обсуждениях, но и помогает лучше понимать продакшн-системы — особенно когда ты разбираешься в существующей архитектуре, оптимизируешь текущий флоу, дебажишь всплески latency или планируешь масштабирование.
Надеюсь, это поможет.
👉 @BackendPortal
Представь любую систему как состоящую из двух отдельных путей: read path и write path. Твоя база данных или слой хранения находится в центре, а у каждого пути — свой набор проблем и свой инструментарий для их решения.
Write path — это про надёжность (durability) и пропускную способность (throughput). Как правило, ты выбираешь из одного и того же набора инструментов: message queue для сглаживания пиков нагрузки, write-ahead logging для обеспечения надёжности, batching для снижения I/O и асинхронная обработка, чтобы не перегружать критический путь.
Read path — это про задержки (latency) и масштабируемость. И здесь тоже есть стандартный набор: кэширование на разных уровнях (CDN, уровень приложения, уровень запросов), read-реплики для разгрузки primary, денормализация или предвычисление тяжёлых запросов, а также пагинация или cursor-based обход, чтобы избежать полного сканирования.
Когда начинаешь воспринимать это как две отдельные задачи, ты перестаёшь «проектировать систему» целиком и начинаешь отвечать на два более простых вопроса: что нужно write path? что нужно read path? А затем связываешь их через слой хранения.
Этот «фреймворк» (если его так можно назвать) полезен не только в обсуждениях, но и помогает лучше понимать продакшн-системы — особенно когда ты разбираешься в существующей архитектуре, оптимизируешь текущий флоу, дебажишь всплески latency или планируешь масштабирование.
Надеюсь, это поможет.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍2
URI vs URN vs URL — в чём разница?
Если представить библиотеку, книгу можно идентифицировать тремя способами:
- Адрес библиотеки и расположение книги на полке (URL)
- ISBN книги (URN)
- Любым из этих способов (URI)
Соответственно, есть три типа идентификаторов:
URI (Uniform Resource Identifier) — это общее, родительское понятие. Любая строка, которая идентифицирует ресурс. И URL, и URN являются частными случаями URI.
URL (Uniform Resource Locator) — указывает, как получить доступ к ресурсу.
Например: [https://linkedin.com/in/yourprofile]
Это аналог физического адреса — он говорит, куда именно идти.
URN (Uniform Resource Name) — это уникальное имя ресурса, которое остаётся неизменным, даже если ресурс перемещён или недоступен.
Пример: urn:isbn:0-486-27557-4
Можно сравнить с номером социального страхования — он идентифицирует объект, но не говорит, где его найти.
👉 @BackendPortal
Если представить библиотеку, книгу можно идентифицировать тремя способами:
- Адрес библиотеки и расположение книги на полке (URL)
- ISBN книги (URN)
- Любым из этих способов (URI)
Соответственно, есть три типа идентификаторов:
URI (Uniform Resource Identifier) — это общее, родительское понятие. Любая строка, которая идентифицирует ресурс. И URL, и URN являются частными случаями URI.
URL (Uniform Resource Locator) — указывает, как получить доступ к ресурсу.
Например: [https://linkedin.com/in/yourprofile]
Это аналог физического адреса — он говорит, куда именно идти.
URN (Uniform Resource Name) — это уникальное имя ресурса, которое остаётся неизменным, даже если ресурс перемещён или недоступен.
Пример: urn:isbn:0-486-27557-4
Можно сравнить с номером социального страхования — он идентифицирует объект, но не говорит, где его найти.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍2
Писать код сейчас легко, а вот тестировать — сложно.
Давайте посмотрим, где именно находятся разные виды тестов и какую роль они играют.⬇️ ⬇️ ⬇️
Давайте посмотрим, где именно находятся разные виды тестов и какую роль они играют.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍1
Проблема: HTTP-статусы в коде не являются типобезопасными и требуют либо постоянно заглядывать в справочник, либо держать всё в голове.
Решение: http-status-codes
Теперь у меня есть автодополнение и строго типизированные статус-коды, которые легко читать позже. И больше не нужно переживать из-за опечаток или использования некорректных кодов.
👉 @BackendPortal
Решение: http-status-codes
Теперь у меня есть автодополнение и строго типизированные статус-коды, которые легко читать позже. И больше не нужно переживать из-за опечаток или использования некорректных кодов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5😁1
30 вопросов по Docker, которые задают на собеседованиях в DevOps.
Это реальные сценарии из практики, которые часто встречаются на интервью — с упором на отладку, проблемы в продакшене и best practices.
👉 @BackendPortal
Это реальные сценарии из практики, которые часто встречаются на интервью — с упором на отладку, проблемы в продакшене и best practices.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3