Backend Portal | Программирование
16.1K subscribers
1.83K photos
173 videos
46 files
1.52K links
Присоединяйтесь к нашему каналу и погрузитесь в мир Backend-разработки

Связь: @devmangx

РКН: https://clck.ru/3FobxK
Download Telegram
Наткнулся в интернете на интересную мысль:

Первое правило программирования - не делай хуже, чем есть сейчас.

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

В софте этот принцип означает: не стоит менять код, архитектуру или процессы, пока не поймёшь, зачем они сделаны именно так.
Любое изменение, будь то рефакторинг, апдейт или удаление — должно иметь чёткое обоснование - измеримый прирост в производительности, удобстве поддержки или опыте пользователей. Иначе легко внести лишние баги и сломать проект.

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

Да, кодовая база может казаться старой и грязной. И да, возможно, её действительно стоит организовать по-другому. Но с той же вероятностью ты можешь ошибаться.

Тут важно смирение. Всегда помни, что ты знаешь меньше, чем думаешь, кем бы ни был. Мы склонны переоценивать своё понимание системы.

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

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Даже в классическом SDLC инфраструктура форматов данных эволюционирует. Мы привыкли воспринимать Protobuf как монолит: proto-схема, wire format и парсинг — всё едино. Об этом был пост у руководителя разработки Яндекс Лавки Димы Александрова, в котором он поделился инструментом, разделяющим эти слои — YaFF (Yet another Flat Format).

Яндекс выложил его в опенсорс как альтернативный wire-формат для Protobuf с поддержкой zero-copy чтения. Основная идея в том, чтобы оставить привычные .proto-файлы и API, а способ хранения данных менять под задачу. В YaFF есть несколько стратегий упаковки: flat layout для плотных структур, sparse для разреженных, и dynamic, который сам выбирает оптимальный вариант.

Авторы сознательно не пошли по пути FlatBuffers, где нужно поддерживать отдельную схему и синхронизировать изменения. Здесь источником истины остаётся один protobuf-контракт, что делает внедрение относительно дешёвым. Сериализованное представление становится отдельным бэкендом, который можно подбирать под конкретную нагрузку.

Если захотите копнуть глубже, рекомендую статью на Хабре — там подробно разбирают и внутреннее устройство YaFF и примеры использования.
При работе с JSONB знали ли вы, что следующие запросы функционально эквивалентны, но используют разные индексы?
Оба проверяют, что по пути user.city находится значение "Denver", но первый использует извлечение значения по пути и оператор сравнения, а второй — оператор вхождения.

B-tree индекс по выражению, использует операторы сравнения:
data->'user'->>'city' = 'Denver'

GIN-индекс, использует операторы вхождения:
data @> '{"user": {"city": "Denver"}}'


👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Один из самых умных трюков для защиты данных, которые я видел в продакшене?

—> Временной RLS (Temporal RLS)

Row-Level Security — это функция PostgreSQL, позволяющая управлять тем, какие строки может видеть пользователь, прямо на уровне базы данных.

Вместо того чтобы фильтровать данные в коде приложения, RLS переносит контроль доступа в саму БД

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

Пример использования:

Финтех-компании нужно было дать аналитикам доступ к транзакциям, но с задержкой в 24 часа, чтобы снизить риск мошенничества и инсайдерской торговли

Вместо написания логики в приложении или BI-инструменте, они полностью реализовали это на уровне базы данных.

Как?

1. Включили RLS на таблице

2. Определили политику фильтрации строк

3. Включили принудительное применение RLS для всех обращений (необязательно, но рекомендуется)

Даже если кто-то подключится к базе напрямую через psql, BI-инструмент или SQL-клиент — он увидит только строки, старше 24 часов. Без исключений.

Безопасность обеспечивается у источника

Политики версионируются вместе со схемой

Код приложения не участвует

Вывод:

RLS — это не только про фильтрацию арендаторов. С его помощью можно строить умные правила: задержка по времени, доступ по пользователям, мягкое удаление — и всё это реализуется самой БД

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
CPU, GPU, TPU, NPU и LPU: в чём разница

Сегодня для AI-нагрузок используются пять основных аппаратных архитектур. Каждая по-своему балансирует между универсальностью, параллелизмом и доступом к памяти.

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

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

TPU ещё сильнее специализированы под AI. Их основа — массивы MAC-блоков, через которые веса, активации и промежуточные результаты передаются без постоянного обращения к памяти. Выполнением управляет компилятор, а сама архитектура изначально создавалась Google для нейросетевых задач.

NPU оптимизированы для энергоэффективного инференса на устройствах. Они используют MAC-массивы и встроенную SRAM, но работают с низкопотребляющей системной памятью вместо HBM. Такие процессоры устанавливают в смартфоны, ноутбуки, носимые устройства и IoT-системы. К этому типу относятся Apple Neural Engine и NPU от Intel.

LPU — архитектура Groq, созданная для обработки языковых моделей. Она исключает внешнюю память из критического пути: веса хранятся во встроенной SRAM, а выполнение полностью планируется компилятором. Это устраняет промахи кеша и накладные расходы на планирование во время работы.

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

Эволюция AI-железа движется от универсальных CPU к всё более специализированным архитектурам. На каждом этапе часть гибкости обменивается на производительность и энергоэффективность.

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

Та же проблема возникает и на программном уровне. Во время инференса LLM один GPU может ежедневно создавать терабайты KV-кеша, большая часть которого затем удаляется и пересчитывается. Это одна из причин высокой стоимости агентных нагрузок.


👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Лето — неплохое время, чтобы навести порядок в базе данных. Например, проверить, не накопились ли в PostgreSQL бесполезные индексы.

pg_stat_user_indexes — системное представление PostgreSQL со статистикой использования индексов.

Со временем приложение меняется, вместе с ним меняются запросы, а старые индексы продолжают оставаться в базе. Некоторые из них больше не используются, другие срабатывают крайне редко. При этом каждый индекс создаёт дополнительную нагрузку при INSERT, UPDATE и DELETE.

В системах с большим количеством операций записи иногда выгодно удалить даже редко используемый индекс, если затраты на его обслуживание превышают пользу.
Посмотреть статистику можно так:
SELECT * FROM pg_stat_user_indexes;


Основные поля:
idx_scan — количество сканирований индекса с момента последнего сброса статистики. 0 означает, что индекс не использовался.
last_idx_scan — время последнего сканирования. NULL означает, что индекс ни разу не использовался после сброса статистики.
idx_tup_read — общее количество записей индекса, возвращённых при сканировании.
idx_tup_fetch — количество актуальных строк таблицы, реально полученных через индекс.

В первую очередь стоит обратить внимание на крупные индексы с idx_scan = 0: они создают нагрузку при записи, но не приносят пользы запросам.

Однако удалять их сразу не стоит. Если недавно выполнялся pg_stat_reset(), статистика может охватывать слишком короткий период. Лучше дождаться полного типичного цикла нагрузки.

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

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

Для безопасного удаления лучше использовать:
DROP INDEX CONCURRENTLY index_name;


Так PostgreSQL удалит индекс без блокировки таблицы через ACCESS EXCLUSIVE.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
PostgreSQL 19 сможет динамически подстраиваться под всплески нагрузки.

Вместо фиксированного пула I/O-воркеров, рассчитанного на условный «средний день», система будет масштабировать его по ситуации:

нагрузка растёт → очередь I/O увеличивается → PostgreSQL это замечает → запускает дополнительных воркеров → очередь разгружается → после снижения нагрузки лишние воркеры завершают работу.

Без ручного вмешательства и постоянного выделения ресурсов с запасом.

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

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Вышла новая статья о сборщике мусора Green Tea в Go.

Пейволл уже сняли, так что материал теперь можно прочитать бесплатно.

https://theconsensus.dev/p/2026/07/19/observing-gos-garbage-collector-old-and-new.html

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
PostgreSQL 19 теперь умеет показывать активность асинхронного ввода-вывода прямо в EXPLAIN.

Это упрощает понимание:
→ где именно используется асинхронный I/O;
→ какие части плана обращаются к хранилищу;
→ получает ли запрос преимущество от асинхронного чтения.

Меньше догадок и больше прозрачности в том, что PostgreSQL делает под капотом плана выполнения запроса.
В PostgreSQL 18 появился асинхронный I/O.

А в PostgreSQL 19 стало проще увидеть, как он работает.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Один из лучших инструментов для создания диаграмм в разработке — и при этом бесплатный и совместимый с GitHub.

Подходит для UML-диаграмм, блок-схем и описания процессов.

Готовые схемы можно экспортировать в изображения, PDF, HTML и другие форматы.

http://app.diagrams.net

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Postgres 19 исправляет AUTOVACUUM

Autovacuum удаляет мёртвые строки и поддерживает таблицы в нормальном состоянии. Теперь PostgreSQL умеет:

→ Запускать несколько autovacuum-воркеров
→ Оценивать таблицы по уровню риска
→ В первую очередь обрабатывать таблицы, которым очистка нужна срочно
→ Выполнять VACUUM для нескольких таблиц параллельно

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Morning Banger: новый выпуск PING от APNIC про загадочное поведение DNS-запросов.

Почти каждый DNS-запрос, который видят APNIC Labs, появляется дважды, а иногда и больше. В обычный день система фиксирует около 150 млн уникальных DNS-меток, но получает примерно 270 млн запросов.
Почему DNS постоянно повторяет одни и те же запросы?

В новом выпуске PING George Michaelson и главный научный сотрудник APNIC Geoff Huston разбирают, что происходит внутри DNS-инфраструктуры и почему дублирование запросов — это не просто лишний трафик, а часть поведения самой системы.

Причины могут быть разными: кэши, прокси, повторные обращения браузеров, особенности DNSSEC и работа recursive resolver’ов. Повторный запрос может показывать, сколько резолверов стоит за пользователем и какие механизмы участвуют в разрешении домена.

Интересный разбор того, как на самом деле работает один из фундаментальных слоёв интернета.
https://blog.apnic.net/2026/07/23/podcast-dns-query-duplication/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Планировщик запросов PostgreSQL использует динамическое программирование, чтобы подобрать наиболее дешёвый порядок JOIN при объединении нескольких таблиц.

Пожалуй, один из тех редких моментов, когда dynamic programming встречается не в задачке с LeetCode, а внутри системы, которой разработчики пользуются каждый день.

https://internals-for-interns.com/posts/postgres-query-planner/

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Rust заменяет C внутри ядра Linux.

Так говорит человек, который поддерживает Linux с 90-х.

Его зовут Грег Кроа-Хартман. Фактически второй человек после Линуса Торвальдса.
Он лично проверял почти все CVE ядра Linux, выпущенные за последнее десятилетие.
Когда-то он не любил Rust.

Однажды друг предложил ему попробовать. Его ответ был: «Что? Нет, C отличный». Друг возразил: «С ним программировать снова становится весело». Грега это не убедило.
Он ошибался.

На Rust Week 2026 в Нидерландах Грег представил предложение, разработанное вместе с контрибьютором ядра Бенно Лоссином, которое потенциально может устранить около 80% CVE, возникающих в ядре каждый год.

Новый тип Rust под названием Untrusted помечает на этапе компиляции любые данные, поступающие из user space или от железа. Работать с такими данными нельзя, пока вы явно их не провалидируете.

Linux генерирует примерно 13 CVE в день. Почти ни одна из них не связана со сложными атаками. В большинстве случаев это одни и те же ошибки C, которые повторяются десятилетиями: непроверенные указатели, забытые unlock, use-after-free — ошибки, которые Rust делает структурно невозможными.

На Open Source Summit India в этом году Грег сказал прямо:
«Ядро движется в сторону Rust. Git движется в сторону Rust. Многие проекты начинают переходить на Rust».
Человек, который когда-то говорил, что C отличный, теперь называет Rust «более приятным для мейнтейнеров» и способом сделать «Linux безопаснее для пользователей».

Rust больше не эксперимент внутри ядра.
Он становится одним из крупнейших изменений в Linux за последние десятилетия.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Facebook настолько не устраивал Git, что в итоге компания создала ему сразу три замены.

Начиналось всё как у многих: один огромный monorepo, в котором лежал код всех команд.
По мере роста кодовой базы Git начал сдавать. Обычный git fetch мог занимать до 30 минут. Инженеры тратили больше времени на ожидание Git, чем на написание кода.

Facebook обратился к мейнтейнерам Git с вопросом, как масштабировать такую систему.
Ответ был простой: разбить репозиторий на несколько поменьше.
Для Facebook это не подходило. Весь смысл был именно в monorepo.

Тогда инженеры обратили внимание на менее популярный Mercurial. Его было проще расширять, а сообщество охотнее принимало изменения. Facebook перенёс туда всю кодовую базу и помог превратить Mercurial в один из лучших вариантов для огромных monorepo.

Но со временем и Mercurial упёрся в ограничения.
Тогда Facebook написал собственную систему контроля версий с нуля — Sapling.

А когда кодовая база выросла настолько, что один инженер уже физически не мог скачать её целиком на ноутбук, появился EdenFS — виртуальная файловая система, которая подгружает файл только в тот момент, когда разработчик реально его открывает.

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

Большинство компаний подстраивают рабочие процессы под доступные инструменты.
Facebook просто создаёт новые инструменты, когда старые перестают справляться.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Задержки это смерть от тысячи мелких порезов.

Так что чините. Начните с базы: один плохой запрос легко добавляет полсекунды, а на тысячах запросов это превращается в катастрофу. Не используйте SELECT *, добавляйте индексы, убивайте N+1 и всегда проверяйте запросы через EXPLAIN.

Дальше посмотрите на сетевые прыжки. Каждый переход через цепочку сервисов добавляет задержку, поэтому мелкие сервисы иногда лучше объединить. Хорошая идея — использовать BFF.

Кэш тоже обязателен. Если данные не меняются, нет смысла тянуть их заново. Сессии, каталоги, конфиги — держите их горячими. Протухший кэш плохо, но отсутствие кэша почти всегда хуже.

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

И не таскайте лишние данные. Убирайте ненужные поля, сжимайте ответы, делайте пагинацию и оптимизируйте картинки.

Скорость это не дополнительная фича, а фундамент нормального UX.

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Fleetbase — опенсорсная модульная ОС для логистики и управления цепочками поставок.

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

В общем, self-hosted логистика для тех, кому обычного CRUD уже недостаточно.

https://github.com/fleetbase/fleetbase

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Несколько алгоритмов, которые я периодически заставляю себя повторять, чтобы не забыть, как они работают:

• Kadane’s → максимальная сумма подмассива
• Rabin–Karp → поиск подстроки с помощью хеширования
• Topological Sort → топологическая сортировка DAG
• Prim’s → минимальное остовное дерево
• Kruskal’s → MST с Union-Find
• Dijkstra’s → кратчайший путь без отрицательных весов
• Bellman–Ford → кратчайший путь с отрицательными весами
• Tarjan’s → компоненты сильной связности
• Backtracking → решение Sudoku

К этим алгоритмам я продолжаю возвращаться даже спустя годы.

А какие алгоритмы вы до сих пор периодически повторяете?

👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Лучшие инженеры не изучают распределённые системы по поверхностным пересказам. Они сразу обращаются к фундаментальным научным статьям. Чтение таких работ помогает понять, почему системы спроектированы именно так, а не просто научиться ими пользоваться.

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

1. The Google File System (2003)

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

Ссылка: https://static.googleusercontent.com/media/research.google.com/en//archive/gfs-sosp2003.pdf

2. Dynamo: Amazon’s Highly Available Key-Value Store (2007)

Почему стоит прочитать: исчерпывающий разбор того, как пожертвовать согласованностью ради высокой доступности — AP в теореме CAP. В статье изложены ключевые паттерны, лежащие в основе масштабируемых NoSQL-хранилищ: консистентное хеширование, векторные часы, gossip-протоколы и настраиваемый кворум для операций чтения и записи.

Ссылка: https://allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf

3. In Search of an Understandable Consensus Algorithm (Raft) (2014)

Почему стоит прочитать: Paxos печально известен тем, насколько сложно его понять и корректно реализовать, тогда как Raft делает концепцию реплицируемых конечных автоматов более доступной. Алгоритм разбивает задачу консенсуса на отдельные подзадачи, которые легко анализировать: выбор лидера, репликацию журнала и обеспечение безопасности.

Ссылка: https://raft.github.io/raft.pdf

4. Spanner: Google’s Globally-Distributed Database (2012)

Почему стоит прочитать: статья показывает, как добиться строгой сериализуемости и внешней согласованности между дата-центрами по всему миру. Секрет — API Google TrueTime, ограничивающий неопределённость времени с помощью синхронизированных GPS-приёмников и атомных часов.

Ссылка: https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf

5. Time, Clocks, and the Ordering of Events in a Distributed System

Почему стоит прочитать: на физическое время нельзя полагаться при работе с независимыми узлами. Лэмпорт вводит логические часы и фундаментальное отношение «произошло до» (happened-before), лежащее в основе упорядочивания событий в современных распределённых сетях.

Ссылка: https://amturing.acm.org/p558-lamport.pdf

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