Backend Portal | Программирование
17.4K subscribers
1.45K photos
136 videos
40 files
1.28K links
Присоединяйтесь к нашему каналу и погрузитесь в мир Backend-разработки

Связь: @devmangx

РКН: https://clck.ru/3FobxK
Download Telegram
Проверяет наличие электронной почты без отправки письма.

https://github.com/reacherhq/check-if-email-exists/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2
Поздравляем, вы на 1 шаг ближе к работе мечты 🥳

Осталось только прочитать этот пост, подписаться на канал и откликнуться на вакансию 😉

Avito Career — место, где Авито делится актуальными вакансиями и стажировками для бэкенд-разработчиков.

Подписывайтесь, чтобы найти ту самую работу
3🤔2
Практический Docker Roadmap

Она включает более 50 практических заданий, дополненных десятками визуальных разборов и несколькими теоретическими глубокими погружениями. На данный момент вы можете изучить:

- Как запускать разные типы контейнеров (веб-приложения, CLI-утилиты, базы данных и т.д.)
- Как перечислять, инспектировать и управлять локальными контейнерами
- Как выполнять команды внутри контейнеров и отлаживать простые проблемы
- Как обновлять контейнерные образы для stateless и stateful приложений
- Как собирать контейнерные образы как профи
...и несколько других тем

https://labs.iximiuz.com/roadmaps/docker

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
SELECT FOR UPDATE в Postgres фактически делает запись

В heap-странице Postgres у каждого tuple есть заголовок header с метаданными.

Когда транзакция выполняет SELECT FOR UPDATE, у найденных tuple (по предикату) обновляется header: они помечаются как залоченные, а атрибут xmax фиксирует XID транзакции, которая поставила лок.

Конкретно выставляются два бита в infomask заголовка: HEAP_XMAX_EXCL_LOCK и HEAP_XMAX_LOCK_ONLY.

Из-за этого страница становится dirty и это также попадает в WAL, который потом может уехать на standby-реплику.

Позже dirty-страница может быть сброшена на диск background writer-ом.

На commit эти биты очищаются.

Забавно, что операция чтения может породить приличный объём write I/O.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Хорошие новости для пользователей Postgres под конец года. Команда TimescaleDB выпустила и открыла исходники расширения pg_textsearch.

В Postgres уже есть встроенный полнотекстовый поиск, а это расширение делает его более современным и продвинутым за счёт добавления ранжирования BM25.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему JSON жрёт ваш CPU

Ваш API тормозит. Вы грешите на базу. Потом на сеть. А реальным бутылочным горлышком может быть язык, на котором вы общаетесь.

JSON — это не формат данных. Это текстовая строка.

Каждый раз, когда вы отправляете {"id": 12345}, сервер платит скрытый налог на парсинг. Даже с современными SIMD-оптимизированными парсерами текст упирается в архитектурные ограничения, которых нет у бинарных форматов.

Разбор по инженерке:

1. Стоимость для CPU (машина состояний против арифметики)

JSON (текст):
Чтобы прочитать число 12345, CPU получает поток байт. Даже самые быстрые парсеры вроде simdjson вынуждены работать как машина состояний:

- искать структурные разделители (: и ,)
- проверять escape-последовательности ()
- конвертировать число: проход по ASCII-символам, вычитание '0', умножение на степени 10 и суммирование

Всё это — ветвления, промахи предсказателя и обращения к памяти.

-» Protobuf (бинарь):
Передаёт либо Varint (для маленьких чисел), либо фиксированную ширину (для больших).

Fixed-width (например, fixed32) — это просто memcpy. Парсинга нет вообще.

-» Varint — чтение байт по одному с проверкой старшего бита (MSB), продолжается ли число.

Итог: декодирование сводится к нескольким битовым сдвигам и маскам. Для числовых нагрузок это гарантированно быстрее любого текстового парсинга.

2. Стоимость по пропускной способности (энтропия против избыточности)

JSON:
[{"status": "active"}, {"status": "active"}]


Ключ "status" передаётся снова и снова.

Контраргумент: но gzip же всё сжимает.

Ответ: gzip уменьшает трафик, но увеличивает нагрузку на CPU. Сервер делает Serialize JSON → Compress → Send. Клиент — Decompress → Parse JSON. Вы тратите CPU на сжатие избыточного текста, которого вообще не должно было быть.

--» Protobuf:
Отделяет схему от данных.
В wire-формате строка "status" заменяется ID поля, например 1: [Tag: 1][Value: "active"]. Размер сообщения меньше ещё до компрессии, а значит экономятся CPU-циклы с обеих сторон.

3. Стоимость надёжности

JSON — это схема-при-чтении.
Получатель получает blob и надеется, что id — это число. В коде появляются проверки вида if typeof(id) !== 'number или подключаются валидаторы вроде Zod или Pydantic, которые добавляют ещё один слой runtime-нагрузки.

Protobuf — это схема при записи.
Контракт enforced на границе сериализации. Он не ловит логические ошибки, но гарантирует сохранность типов. Обычно не нужны тяжёлые runtime-валидаторы, чтобы проверить, что Integer — это Integer.

Можно сказать:

JSON отлично подходит для публичных API — его легко дебажить и читать. Но для высоконагруженных микросервисов JSON — это налог.

Переход на gRPC/Protobuf — не сверхчудо. Это просто перенос сложности из парсинг текста в генерацию кода

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
12
Postgres CTE

-» небольшие, читаемые блоки SQL
-» можно тестировать запрос по частям
-» переиспользовать фрагменты SQL в других запросах

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
2
В небольшом приложении один HTTP-запрос обычно делает всё.

Например, пользователь регистрируется.

Бэкенд сохраняет пользователя, отправляет welcome-письмо, пишет метрики и только потом отвечает. Работает, но пользователь ждёт дольше, а если что-то ломается посередине, может упасть вся операция.

Проблема в том, что в одном потоке смешиваются критичные и второстепенные задачи.

Создать пользователя -» критично. Отправить welcome-письмо -» нет. Когда всё идёт в одном флоу, у всего одинаковый вес, и приложение начинает тормозить.

В более крупных системах это решают через Message Queue.

Бэкенд выступает как producer -» сохраняет пользователя и кладёт сообщение в очередь с отложенной задачей, например «отправить welcome-email». На этом запрос заканчивается и быстро отдаёт ответ.

Позже один или несколько воркеров забирают сообщение из очереди и выполняют задачу. Если отправка письма упала, её можно ретраить, не затрагивая пользователя.

Так создание пользователя и отправка письма перестают зависеть друг от друга.

Обратная сторона -» в системе появляется больше компонентов и растёт сложность.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Обобщённые инвертированные индексы (GIN) - мощный инструмент в Postgres.

Они хороши тем, что переворачивают привычную модель индексации.

Вместо логики вида: строка с ID 2 содержит значение "become a database expert", индекс хранит обратное соответствие: токен "database" указывает на строки с ID 1, 2 и 3, а "expert" — на строку с ID 2.

GIN-индексу на вход подаётся набор значений для каждой строки, которую нужно проиндексировать. Каждое уникальное значение становится ключом в индексе и сопоставляется с набором CTID (идентификаторов кортежей строк), в которых это значение встречается.

У такого подхода есть несколько сценариев применения, и один из самых популярных - полнотекстовый поиск. В MySQL для этого есть отдельный тип индекса FULLTEXT, а в Postgres похожая функциональность строится на более универсальных GIN-индексах.

Как это выглядит на практике:

(a) Добавляем колонку tsvector в таблицу:

CREATE TABLE post (
author TEXT,
publish_date DATE,
content TEXT NOT NULL,
search_vector tsvector
);


(b) Заполняем её лексемами (нормализованными словами):

UPDATE post
SET search_vector =
to_tsvector('english', content);


(c) Создаём GIN-индекс по лексемам:

CREATE INDEX post_search_idx
ON post USING GIN(search_vector);


(d) И выполняем запросы:

SELECT * FROM post
WHERE search_vector @@
to_tsquery('english', 'database & expert');


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

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
2
В софте очень часто работают так: система хранит текущее состояние.

Например:
» у пользователя такой баланс
» заказ сейчас в таком статусе
» подписка активна

Event Sourcing предлагает другой подход.

Идея простая:
хранить не финальное состояние, а всю историю изменений.

То есть вместо того, чтобы сохранять

balance = 100


ты сохраняешь события:

deposit +200
purchase -50
adjustment -50


А текущий баланс считается путём воспроизведения этих событий.

По сути, как бухгалтерская книга.

Что такое событие в этом контексте?

Событие это факт, который уже произошёл и не меняется.

Например:
» PaymentReceived
» OrderConfirmed
» SubscriptionCancelled

События:
» не редактируются
» не удаляются
» только добавляются

Фактически база данных становится append-only.

Зачем вообще так усложнять?

Потому что это даёт мощные возможности из коробки:

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

Никаких дополнительных логов не нужно. История уже есть.

Но важно понимать: у этого подхода есть серьёзные trade-off-ы.

Event Sourcing усложняет всё остальное:

» чтобы читать текущее состояние, нужны проекции
» ментальная модель сложнее
» миграции событий - проблема и требуют аккуратности

Это сила в обмен на сложность.

Где Event Sourcing реально уместен?

Он хорошо заходит, когда:
» домен сложный
» нужна жёсткая аудитируемость
» события важнее состояния
» бизнес постоянно спрашивает «как мы к этому пришли»

Платежи, финансы, бухгалтерия, compliance — классические кандидаты.

Где его лучше не использовать?

» простые CRUD-системы
» тривиальная бизнес-логика
» команды без опыта работы с паттерном
» случаи, когда нужен только текущий стейт

Важное уточнение:

Event Sourcing не равен CQRS.
Их часто используют вместе, но одно не требует другого.

И напоследок главное.

Event Sourcing — это не оптимизация.

Это решение по моделированию.

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

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3🔥1
В SQLite около 155 800 строк кода, а тестовый набор - примерно 92 миллиона строк. Это примерно в 590 раз больше тестов, чем самого кода 🤯

Вот такой уровень тестирования нужен для настоящей продакшен-базы данных. Ниже — какие типы тестов у них есть.

» Тесты на нехватку памяти (OOM)
SQLite не может просто упасть, когда заканчивается память. На встраиваемых устройствах OOM — обычное дело. Они симулируют падения malloc в каждой возможной точке и проверяют, что база корректно это переживает.

» Тесты I/O-ошибок
Диски ломаются. Сеть отваливается. Права могут измениться посреди операции. SQLite подменяет файловую систему на кастомный слой, который может симулировать сбои после N операций, и проверяет, что данные не повреждаются.

» Краш-тесты
Что будет, если питание пропадёт посреди записи? Они симулируют крэш в случайные моменты во время записи, портят несинхронизированные данные, как это делает реальная файловая система, и проверяют, что транзакция либо полностью завершилась, либо чисто откатилась. Никакой порчи данных.

» Fuzz-тестирование
В SQLite кидают кривой SQL, битые файлы базы и случайный мусор. Инструмент dbsqlfuzz прогоняет около 500 миллионов мутаций тестов в день на 16 ядрах.

» 100% покрытие ветвлений
Каждая инструкция ветвления в ядре SQLite проверяется в обе стороны. Не просто «эта строка выполнялась», а «это условие было и true, и false».

Базы данных вообще не прощают ошибок :)

Если хочется копнуть глубже, советую почитать официальную документацию SQLite про их стратегию тестирования. Очень практично и по делу. А если понравился пост - ставь реакцию 👌

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🤯73
Два года назад парень сделал максимально простой демо-пример, который на уровне операционной системы показывает, что происходит, если не использовать пул соединений для Postgres.

С тех пор его рекомендуют даже LLM, и он регулярно получает такой фидбек:
«Впервые наглядно понял, как работает connection pooling».

Это и подтолкнуло поделиться этим видео с вами, друзья 🎷 - смотреть

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Media is too big
VIEW IN TELEGRAM
🎬 Что это? А это второй выпуск нового интерактивного шоу «АйТир Лист» от МойОфис

«АйТир Лист» – это шоу, в котором эксперты оценивают технологии, компании, фреймворки и ИТ-решения по шкале от 1 до 4. Каждый выпуск — это 14 табличек от модератора, жаркие дискуссии и итоговый рейтинг, который поможет зрителям разобраться в актуальных трендах и сделать собственные выводы.

Во втором выпуске мы оценим фичи и идиомы C++.
Гости выпуска:
Данил Черепанов, архитектор Редакторов МойОфис
Антон Полухин, эксперт-разработчик C++ Техплатформы Городских сервисов Яндекса

🎥 Смотрите наш юбилейный второй выпуск там, где вам удобно:
VK | YouTube | RuTube

Реклама
ООО "НОВЫЕ ОБЛАЧНЫЕ ТЕХНОЛОГИИ"
ИНН: 7703807270
erid: 2W5zFG7z16x
🔥2🤔2💊2
This media is not supported in your browser
VIEW IN TELEGRAM
Элегантное разделение ответственности в Apache Kafka даёт кучу возможностей для масштабирования.

Но за это приходится платить компромиссами.

Производитель, потребитель и брокер.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Привыкнув к визуальным редакторам вроде VS Code, каждый раз после SSH-подключения к серверу и необходимости править конфиги через Vim не хочется

На GitHub нашёл проект Fresh. Он переносит привычный графический опыт редакторов прямо в терминал.

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

При этом спокойно открывает файлы размером в несколько гигабайт, а потребление памяти практически незаметно.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2💊1
Сервер для потоковой трансляции видео, написанный на Go.

GitHub: https://github.com/gwuhaolin/livego/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6😁4
Биллинговое решение для хостинг-компаний.

GitHub: https://github.com/Paymenter/Paymenter/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Потоковая передача музыки с YouTube с фоновым воспроизведением и кэшированием.

https://github.com/25huizengek1/ViTune/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍1
Только что открыл для себя Resend Go SDK — пожалуй, самый чистый и удобный способ отправлять письма из Go-приложений.

Простой и понятный API
Строгая типизация, нативная поддержка Go
Встроенная поддержка шаблонов
Массовая отправка писем
Webhooks и трекинг доставляемости

Отлично подходит для транзакционных писем, уведомлений и не только. Больше не нужно возиться с настройками SMTP.

Заценить можно тут ❤️

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
1