p50, p95 и p99.
Сколько тут этих p и что они значат?
Коротко: p = percentile (процентиль).
Он показывает распределение производительности, а не среднее значение.
Сколько вообще бывает этих p?
Процентили есть от p0 до p100, но на практике обычно смотрят на:
• p50 -> медиана
• p90 -> первые “подтупливания”
• p95 -> базовая линия для SLA
• p99 -> tail latency (хвостовая задержка)
• p99.9 -> системы с ультра-надежностью (Google и Amazon следят за p99.9)
Представь 100 пользователей, которые бьют в твой API.
p50 = 120ms -> 50 пользователей уложились в 120ms или быстрее, 50 были медленнее.
p95 = 800ms -> 95 пользователей уложились в 800ms или быстрее, 5 были медленнее.
p99 = 2.5s -> 99 пользователей уложились в 2.5s или быстрее, 1 был медленнее (вот тут и живет фрустрация).
Почему трекать процентили, а не среднее?
Потому что средняя задержка умеет прятать боль.
Пример:
100ms
110ms
120ms
130ms
5000ms
Среднее ≈ 1,092ms❌
p50 = 120ms
p95 = 5000ms✅
Зная p50, p95 и p99, ты можешь:
• заметить всплески задержек до того, как все упадет
• понять реальный UX пользователей
• найти проблемы со скейлингом и контеншеном
• безопаснее настроить ретраи, таймауты и backpressure
• задать адекватные SLA
• не допустить системы “быстро, но ненадежно”
⚙ Backend Ready | #урок
Сколько тут этих p и что они значат?
Коротко: p = percentile (процентиль).
Он показывает распределение производительности, а не среднее значение.
Сколько вообще бывает этих p?
Процентили есть от p0 до p100, но на практике обычно смотрят на:
• p50 -> медиана
• p90 -> первые “подтупливания”
• p95 -> базовая линия для SLA
• p99 -> tail latency (хвостовая задержка)
• p99.9 -> системы с ультра-надежностью (Google и Amazon следят за p99.9)
Представь 100 пользователей, которые бьют в твой API.
p50 = 120ms -> 50 пользователей уложились в 120ms или быстрее, 50 были медленнее.
p95 = 800ms -> 95 пользователей уложились в 800ms или быстрее, 5 были медленнее.
p99 = 2.5s -> 99 пользователей уложились в 2.5s или быстрее, 1 был медленнее (вот тут и живет фрустрация).
Почему трекать процентили, а не среднее?
Потому что средняя задержка умеет прятать боль.
Пример:
100ms
110ms
120ms
130ms
5000ms
Среднее ≈ 1,092ms
p50 = 120ms
p95 = 5000ms
Зная p50, p95 и p99, ты можешь:
• заметить всплески задержек до того, как все упадет
• понять реальный UX пользователей
• найти проблемы со скейлингом и контеншеном
• безопаснее настроить ретраи, таймауты и backpressure
• задать адекватные SLA
• не допустить системы “быстро, но ненадежно”
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
🤔 Какая разница у протоколов http и https ?
Основное различие между протоколами HTTP (HyperText Transfer Protocol) и HTTPS (HyperText Transfer Protocol Secure) заключается в уровне безопасности, который они обеспечивают при передаче данных между клиентом (например, веб-браузером) и сервером.
🚩Основные различия
🟠Шифрование
HTTP: Данные передаются в открытом виде, что делает их уязвимыми для перехвата и чтения злоумышленниками.
HTTPS: Данные передаются в зашифрованном виде с использованием SSL/TLS (Secure Sockets Layer/Transport Layer Security). Это обеспечивает защиту данных от перехвата и несанкционированного доступа.
🟠Аутентификация
HTTP: Отсутствует механизм аутентификации, что затрудняет проверку подлинности веб-сайта.
HTTPS: Использует сертификаты SSL/TLS, которые удостоверяют подлинность веб-сайта, подтверждая, что соединение установлено с тем сервером, с которым намеревался связаться пользователь.
🟠Интегритет данных
HTTP: Данные могут быть изменены или повреждены во время передачи, и это не будет обнаружено.
HTTPS: Гарантирует целостность данных, так как любые изменения данных при передаче будут обнаружены, и соединение будет разорвано.
🟠Порт
HTTP: Использует порт 80 по умолчанию.
HTTPS: Использует порт 443 по умолчанию.
🚩Плюсы
➕Безопасность
Обеспечивает защиту конфиденциальной информации, такой как логины, пароли, номера кредитных карт.
➕Доверие пользователей
Пользователи склонны больше доверять веб-сайтам, использующим HTTPS, так как это указывает на то, что сайт заботится о безопасности данных.
➕SEO
Поисковые системы, такие как Google, предпочитают сайты, использующие HTTPS, и ранжируют их выше по сравнению с сайтами, использующими HTTP.
⚙ Backend Ready | #урок
Основное различие между протоколами HTTP (HyperText Transfer Protocol) и HTTPS (HyperText Transfer Protocol Secure) заключается в уровне безопасности, который они обеспечивают при передаче данных между клиентом (например, веб-браузером) и сервером.
🚩Основные различия
🟠Шифрование
HTTP: Данные передаются в открытом виде, что делает их уязвимыми для перехвата и чтения злоумышленниками.
HTTPS: Данные передаются в зашифрованном виде с использованием SSL/TLS (Secure Sockets Layer/Transport Layer Security). Это обеспечивает защиту данных от перехвата и несанкционированного доступа.
🟠Аутентификация
HTTP: Отсутствует механизм аутентификации, что затрудняет проверку подлинности веб-сайта.
HTTPS: Использует сертификаты SSL/TLS, которые удостоверяют подлинность веб-сайта, подтверждая, что соединение установлено с тем сервером, с которым намеревался связаться пользователь.
🟠Интегритет данных
HTTP: Данные могут быть изменены или повреждены во время передачи, и это не будет обнаружено.
HTTPS: Гарантирует целостность данных, так как любые изменения данных при передаче будут обнаружены, и соединение будет разорвано.
🟠Порт
HTTP: Использует порт 80 по умолчанию.
HTTPS: Использует порт 443 по умолчанию.
🚩Плюсы
➕Безопасность
Обеспечивает защиту конфиденциальной информации, такой как логины, пароли, номера кредитных карт.
➕Доверие пользователей
Пользователи склонны больше доверять веб-сайтам, использующим HTTPS, так как это указывает на то, что сайт заботится о безопасности данных.
➕SEO
Поисковые системы, такие как Google, предпочитают сайты, использующие HTTPS, и ранжируют их выше по сравнению с сайтами, использующими HTTP.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
🤔 Что знаешь о принципах программирования KISS?
Это принцип проектирования и разработки, который предполагает, что системы и решения должны быть максимально простыми и избегать ненужной сложности. Этот принцип особенно важен в программировании и инженерии, так как помогает создавать более понятные, поддерживаемые и надежные системы.
🚩Аспекты
🟠Простота
Системы должны быть простыми в понимании и использовании. Чем проще система, тем меньше вероятность возникновения ошибок. Простота достигается за счет минимизации количества компонентов и взаимодействий между ними.
🟠Ясность
Код должен быть понятным и легко читаемым. Это облегчает его поддержку и модификацию. Использование понятных имен переменных, функций и классов, а также понятная структура кода способствуют ясности.
🟠Избегание избыточности
Компоненты или функциональность следует избегать. Если какой-то элемент системы не добавляет реальной ценности, его следует убрать. Это включает в себя как аппаратное, так и программное обеспечение.
🟠Модульность
Системы должны быть разбиты на небольшие, независимые модули, каждый из которых выполняет свою четко определенную задачу. Модульность помогает в тестировании, повторном использовании и поддержке кода.
🚩Примеры применения
🟠Программирование
При разработке функций или методов следует избегать создания слишком сложных алгоритмов, если можно использовать более простые и понятные решения. Использование стандартных библиотек и инструментов вместо написания собственного кода с нуля, когда это возможно.
🟠Проектирование систем
В системной архитектуре следует избегать излишнего усложнения связей между компонентами системы. Использование простых и проверенных шаблонов проектирования вместо сложных и экспериментальных решений.
🟠Документация
Документация должна быть простой и понятной, избегая излишне технических или сложных объяснений. Хорошо структурированная и лаконичная документация помогает пользователям и разработчикам быстрее понять систему.
🚩Плюсы
➕Легкость понимания и поддержки
Простые системы легче понимать и поддерживать, что снижает затраты на обучение и поддержку.
➕Снижение количества ошибок
Чем проще система, тем меньше вероятность возникновения ошибок и проблем при её использовании.
➕Повышение производительности
Простые решения часто требуют меньше ресурсов и могут работать быстрее и эффективнее.
➕Улучшение масштабируемости
Простые и модульные системы легче масштабировать и расширять по мере необходимости.
⚙ Backend Ready | #урок
Это принцип проектирования и разработки, который предполагает, что системы и решения должны быть максимально простыми и избегать ненужной сложности. Этот принцип особенно важен в программировании и инженерии, так как помогает создавать более понятные, поддерживаемые и надежные системы.
🚩Аспекты
🟠Простота
Системы должны быть простыми в понимании и использовании. Чем проще система, тем меньше вероятность возникновения ошибок. Простота достигается за счет минимизации количества компонентов и взаимодействий между ними.
🟠Ясность
Код должен быть понятным и легко читаемым. Это облегчает его поддержку и модификацию. Использование понятных имен переменных, функций и классов, а также понятная структура кода способствуют ясности.
🟠Избегание избыточности
Компоненты или функциональность следует избегать. Если какой-то элемент системы не добавляет реальной ценности, его следует убрать. Это включает в себя как аппаратное, так и программное обеспечение.
🟠Модульность
Системы должны быть разбиты на небольшие, независимые модули, каждый из которых выполняет свою четко определенную задачу. Модульность помогает в тестировании, повторном использовании и поддержке кода.
🚩Примеры применения
🟠Программирование
При разработке функций или методов следует избегать создания слишком сложных алгоритмов, если можно использовать более простые и понятные решения. Использование стандартных библиотек и инструментов вместо написания собственного кода с нуля, когда это возможно.
🟠Проектирование систем
В системной архитектуре следует избегать излишнего усложнения связей между компонентами системы. Использование простых и проверенных шаблонов проектирования вместо сложных и экспериментальных решений.
🟠Документация
Документация должна быть простой и понятной, избегая излишне технических или сложных объяснений. Хорошо структурированная и лаконичная документация помогает пользователям и разработчикам быстрее понять систему.
🚩Плюсы
➕Легкость понимания и поддержки
Простые системы легче понимать и поддерживать, что снижает затраты на обучение и поддержку.
➕Снижение количества ошибок
Чем проще система, тем меньше вероятность возникновения ошибок и проблем при её использовании.
➕Повышение производительности
Простые решения часто требуют меньше ресурсов и могут работать быстрее и эффективнее.
➕Улучшение масштабируемости
Простые и модульные системы легче масштабировать и расширять по мере необходимости.
Please open Telegram to view this post
VIEW IN TELEGRAM
Похоже, компании реально переосмысляют весь SDLC вокруг агентов и пытаются прийти к миру, где инженеры, возможно, вообще не будут писать ни одной строчки кода руками.
Я тут общался с одним инженерным лидом, и по ощущениям многие уже готовятся к полностью agentic SDLC. В репозиториях начинают появляться файлы под Claude и прочие agent-штуки, под внутренние инструменты пилят MCP, и в целом многое меняется. Код-ревью тоже автоматизируют, и это только один из пунктов.
Вот такие времена :)
⚙ Backend Ready | #урок
Я тут общался с одним инженерным лидом, и по ощущениям многие уже готовятся к полностью agentic SDLC. В репозиториях начинают появляться файлы под Claude и прочие agent-штуки, под внутренние инструменты пилят MCP, и в целом многое меняется. Код-ревью тоже автоматизируют, и это только один из пунктов.
Вот такие времена :)
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое SOLID?
Это акроним, представляющий пять основных принципов объектно-ориентированного программирования и дизайна, которые помогают разработчикам создавать более понятный, гибкий и поддерживаемый код. Эти принципы были предложены Робертом Мартином (известным также как Uncle Bob) и являются основополагающими в области программной инженерии.
🟠Single Responsibility Principle (Принцип единственной ответственности)
Этот принцип гласит, что у каждого класса должна быть только одна причина для изменения, то есть класс должен иметь только одну ответственность или задачу. Это помогает уменьшить сложность и повысить читаемость кода, делая его более управляемым и легким для поддержки. Когда класс выполняет лишь одну задачу, его легче тестировать и изменять без влияния на другие части системы.
🟠Open/Closed Principle (Принцип открытости/закрытости)
Программные сущности (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для модификации. Это означает, что поведение классов должно быть расширяемым без изменения их исходного кода. Для реализации этого принципа часто используются абстракции и интерфейсы, которые позволяют добавлять новые функции через наследование и полиморфизм, не нарушая существующий код.
🟠Liskov Substitution Principle (Принцип подстановки Барбары Лисков)
Объекты подклассов должны быть заменяемы объектами суперклассов без нарушения правильности программы. Это означает, что если у нас есть базовый класс и его подкласс, то мы должны иметь возможность заменить экземпляры базового класса экземплярами подкласса без изменения желаемого поведения программы. Этот принцип поддерживает полиморфизм и гарантирует, что производные классы могут корректно взаимодействовать с остальным кодом.
🟠Interface Segregation Principle (Принцип разделения интерфейсов)
Клиенты не должны зависеть от интерфейсов, которые они не используют. Этот принцип направлен на создание узкоспециализированных интерфейсов, которые являются специфичными для отдельных клиентов. Таким образом, классы, реализующие эти интерфейсы, не будут обязаны реализовывать методы, которые им не нужны. Это уменьшает сложность и улучшает управляемость кода, а также способствует гибкости и повторному использованию интерфейсов.
🟠Dependency Inversion Principle (Принцип инверсии зависимостей)
Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба типа модулей должны зависеть от абстракций. Этот принцип направлен на уменьшение зависимости высокоуровневого кода от низкоуровневых деталей, что позволяет легче изменять и тестировать систему. Реализация этого принципа часто включает использование инверсии управления (IoC) и внедрения зависимостей (DI), что способствует созданию более гибких и модульных архитектур.
⚙ Backend Ready | #урок
Это акроним, представляющий пять основных принципов объектно-ориентированного программирования и дизайна, которые помогают разработчикам создавать более понятный, гибкий и поддерживаемый код. Эти принципы были предложены Робертом Мартином (известным также как Uncle Bob) и являются основополагающими в области программной инженерии.
🟠Single Responsibility Principle (Принцип единственной ответственности)
Этот принцип гласит, что у каждого класса должна быть только одна причина для изменения, то есть класс должен иметь только одну ответственность или задачу. Это помогает уменьшить сложность и повысить читаемость кода, делая его более управляемым и легким для поддержки. Когда класс выполняет лишь одну задачу, его легче тестировать и изменять без влияния на другие части системы.
🟠Open/Closed Principle (Принцип открытости/закрытости)
Программные сущности (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для модификации. Это означает, что поведение классов должно быть расширяемым без изменения их исходного кода. Для реализации этого принципа часто используются абстракции и интерфейсы, которые позволяют добавлять новые функции через наследование и полиморфизм, не нарушая существующий код.
🟠Liskov Substitution Principle (Принцип подстановки Барбары Лисков)
Объекты подклассов должны быть заменяемы объектами суперклассов без нарушения правильности программы. Это означает, что если у нас есть базовый класс и его подкласс, то мы должны иметь возможность заменить экземпляры базового класса экземплярами подкласса без изменения желаемого поведения программы. Этот принцип поддерживает полиморфизм и гарантирует, что производные классы могут корректно взаимодействовать с остальным кодом.
🟠Interface Segregation Principle (Принцип разделения интерфейсов)
Клиенты не должны зависеть от интерфейсов, которые они не используют. Этот принцип направлен на создание узкоспециализированных интерфейсов, которые являются специфичными для отдельных клиентов. Таким образом, классы, реализующие эти интерфейсы, не будут обязаны реализовывать методы, которые им не нужны. Это уменьшает сложность и улучшает управляемость кода, а также способствует гибкости и повторному использованию интерфейсов.
🟠Dependency Inversion Principle (Принцип инверсии зависимостей)
Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба типа модулей должны зависеть от абстракций. Этот принцип направлен на уменьшение зависимости высокоуровневого кода от низкоуровневых деталей, что позволяет легче изменять и тестировать систему. Реализация этого принципа часто включает использование инверсии управления (IoC) и внедрения зависимостей (DI), что способствует созданию более гибких и модульных архитектур.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1😁1
🤔 Что в твоем понимании значит правильный код?
Это код, который не только выполняет поставленные задачи, но и соответствует ряду критериев, обеспечивающих его качество, читаемость, сопровождение и эффективность.
🚩Характеристики
🟠Читаемость
Переменные, функции, классы и другие сущности должны иметь понятные и описательные имена, которые отражают их назначение. Следование стандартам кодирования и стиля, включая правильное форматирование, отступы и использование комментариев. Использование комментариев для объяснения сложных или неочевидных частей кода, но не для очевидных вещей, которые можно понять из названий переменных и функций.
🟠Сопровождаемость
Код должен быть разбит на модули, функции или классы с чётко определёнными задачами. Это упрощает его понимание, тестирование и изменение. Избегание дублирования кода через применение принципа DRY (Don't Repeat Yourself). Код должен быть легко тестируемым. Написание автоматических тестов для проверки корректности работы помогает предотвратить ошибки.
🟠Эффективность
Код должен быть оптимизирован для выполнения задач с минимальными затратами ресурсов, таких как время выполнения и использование памяти. Использование эффективных алгоритмов и структур данных для обеспечения хорошей производительности, особенно на больших объемах данных.
🟠Надежность
Код должен корректно обрабатывать ошибки и исключительные ситуации, предотвращая неожиданные сбои. Проверка входных данных для предотвращения некорректного поведения программы.
🟠Документированность
Написание документации, описывающей основные компоненты системы, их взаимодействие и использование. Хорошо документированный код облегчает его понимание для других разработчиков.
🟠Применение принципов и паттернов проектирования
Применение принципов SOLID для создания устойчивого, гибкого и масштабируемого кода. Использование проверенных решений для общих задач проектирования.
🚩Примеры
Читаемость и сопровождаемость
Тестируемость
⚙ Backend Ready | #урок
Это код, который не только выполняет поставленные задачи, но и соответствует ряду критериев, обеспечивающих его качество, читаемость, сопровождение и эффективность.
🚩Характеристики
🟠Читаемость
Переменные, функции, классы и другие сущности должны иметь понятные и описательные имена, которые отражают их назначение. Следование стандартам кодирования и стиля, включая правильное форматирование, отступы и использование комментариев. Использование комментариев для объяснения сложных или неочевидных частей кода, но не для очевидных вещей, которые можно понять из названий переменных и функций.
🟠Сопровождаемость
Код должен быть разбит на модули, функции или классы с чётко определёнными задачами. Это упрощает его понимание, тестирование и изменение. Избегание дублирования кода через применение принципа DRY (Don't Repeat Yourself). Код должен быть легко тестируемым. Написание автоматических тестов для проверки корректности работы помогает предотвратить ошибки.
🟠Эффективность
Код должен быть оптимизирован для выполнения задач с минимальными затратами ресурсов, таких как время выполнения и использование памяти. Использование эффективных алгоритмов и структур данных для обеспечения хорошей производительности, особенно на больших объемах данных.
🟠Надежность
Код должен корректно обрабатывать ошибки и исключительные ситуации, предотвращая неожиданные сбои. Проверка входных данных для предотвращения некорректного поведения программы.
🟠Документированность
Написание документации, описывающей основные компоненты системы, их взаимодействие и использование. Хорошо документированный код облегчает его понимание для других разработчиков.
🟠Применение принципов и паттернов проектирования
Применение принципов SOLID для создания устойчивого, гибкого и масштабируемого кода. Использование проверенных решений для общих задач проектирования.
🚩Примеры
Читаемость и сопровождаемость
def calculate_area(radius):
"""Calculate the area of a circle given its radius."""
import math
if radius < 0:
raise ValueError("Radius cannot be negative")
return math.pi * radius ** 2
Тестируемость
def add(a, b):
"""Add two numbers and return the result."""
return a + b
# Unit test for the add function
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
test_add()
Please open Telegram to view this post
VIEW IN TELEGRAM
Видел интересное видео от CTO Zerodha про то, как они масштабировали Postgres с 7+ млн таблиц.
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:
- синхронщина? не масштабируется, значит выкидываем.
- все в async. тяжелую генерацию отчетов ставим в очередь.
- независимый middleware, которому все равно на базу и на приложение.
- собрали “DungBeetle” на Go: обобщенные, независимые от СУБД HTTP API, чтобы тянуть отчеты из любой базы.
- результаты сливаем в отдельную Results DB, а приложение читает уже оттуда.
Вот так выглядит настоящий масштаб.
Смотреть видео
⚙ Backend Ready | #урок
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:
- синхронщина? не масштабируется, значит выкидываем.
- все в async. тяжелую генерацию отчетов ставим в очередь.
- независимый middleware, которому все равно на базу и на приложение.
- собрали “DungBeetle” на Go: обобщенные, независимые от СУБД HTTP API, чтобы тянуть отчеты из любой базы.
- результаты сливаем в отдельную Results DB, а приложение читает уже оттуда.
Вот так выглядит настоящий масштаб.
Смотреть видео
Please open Telegram to view this post
VIEW IN TELEGRAM
Python 3.14 стал до 30 % быстрее благодаря новому интерпретатору с tail call — ускорение без изменений в коде, просто обновите версию.
Команда CPython продолжает ускорять Python. Так, релиз 3.14 уже включает одну из самых заметных внутренних реформ — новый байт-кодовый интерпретатор.
Читать статью
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤1👍1
🤔 Как можно заблокировать конкретные поля в Postgres?
В PostgreSQL можно использовать различные методы для блокировки конкретных полей или строк таблицы, чтобы предотвратить их изменение или обеспечить управление конкурентным доступом к данным. Наиболее распространенные способы включают использование транзакционных блокировок и политик доступа.
🟠Использование блокировок уровня строки (Row-Level Locks)
PostgreSQL поддерживает блокировки уровня строки с помощью команд
🟠Использование политик доступа (Row-Level Security Policies)
Политики безопасности на уровне строк позволяют определить, кто и при каких условиях может видеть или изменять данные в таблице. Это обеспечивается с помощью функций и политик безопасности.
🟠Использование триггеров (Triggers)
Триггеры позволяют автоматически выполнять определенные действия перед или после операции
🟠Ограничения на уровне столбца (Column-Level Constraints)
Ограничения на уровне столбца могут использоваться для ограничения возможных значений или для создания выражений, которые должны быть выполнены для выполнения изменения.
⚙ Backend Ready | #урок
В PostgreSQL можно использовать различные методы для блокировки конкретных полей или строк таблицы, чтобы предотвратить их изменение или обеспечить управление конкурентным доступом к данным. Наиболее распространенные способы включают использование транзакционных блокировок и политик доступа.
🟠Использование блокировок уровня строки (Row-Level Locks)
PostgreSQL поддерживает блокировки уровня строки с помощью команд
SELECT FOR UPDATE и SELECT FOR SHARE. Эти команды позволяют заблокировать конкретные строки для изменения другими транзакциями, пока текущая транзакция не завершится.SELECT FOR UPDATE:BEGIN; -- Начало транзакции
-- Выбираем и блокируем строки для обновления
SELECT * FROM my_table WHERE id = 1 FOR UPDATE;
-- Выполняем необходимые операции
UPDATE my_table SET field = 'new_value' WHERE id = 1;
COMMIT; -- Завершение транзакции
SELECT FOR SHARE:BEGIN; -- Начало транзакции
-- Выбираем и блокируем строки для чтения
SELECT * FROM my_table WHERE id = 1 FOR SHARE;
-- Выполняем необходимые операции
-- Изменение данных будет заблокировано для других транзакций
-- Однако, можно выполнять SELECT
COMMIT; -- Завершение транзакции
🟠Использование политик доступа (Row-Level Security Policies)
Политики безопасности на уровне строк позволяют определить, кто и при каких условиях может видеть или изменять данные в таблице. Это обеспечивается с помощью функций и политик безопасности.
-- Включаем безопасность на уровне строк для таблицы
ALTER TABLE my_table ENABLE ROW LEVEL SECURITY;
-- Создаем роль, которая будет иметь доступ
CREATE ROLE limited_role;
-- Создаем политику, которая позволяет только чтение данных
CREATE POLICY read_only_policy ON my_table
FOR SELECT
USING (true); -- Условие для выполнения SELECT
-- Применяем политику для роли limited_role
GRANT SELECT ON my_table TO limited_role;
🟠Использование триггеров (Triggers)
Триггеры позволяют автоматически выполнять определенные действия перед или после операции
INSERT, UPDATE, DELETE. Можно создать триггер, который будет блокировать изменение конкретных полей.CREATE OR REPLACE FUNCTION prevent_update()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.field IS DISTINCT FROM OLD.field THEN
RAISE EXCEPTION 'Field "field" cannot be updated';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Применяем триггер к таблице
CREATE TRIGGER prevent_update_trigger
BEFORE UPDATE ON my_table
FOR EACH ROW
EXECUTE FUNCTION prevent_update();
🟠Ограничения на уровне столбца (Column-Level Constraints)
Ограничения на уровне столбца могут использоваться для ограничения возможных значений или для создания выражений, которые должны быть выполнены для выполнения изменения.
ALTER TABLE my_table
ADD CONSTRAINT field_check CHECK (field IS NOT NULL);
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1🔥1😁1
Axios против Fetch: выбираем инструмент для запросов в 2026 году 📡
Несмотря на то что в Node.js давно завезли нативный
Разница в подходе: 🛠️
— Fetch: Это низкоуровневый API. Чтобы получить JSON, тебе нужно сделать два шага: сначала дождаться ответа, а потом вызвать
— Axios: Это обертка, которая делает всю грязную работу за тебя. Он автоматически парсит JSON и возвращает готовый объект в
Почему Axios всё еще круче? 🚀
— Интерцепторы (Interceptors): Можно создать функцию, которая будет автоматически добавлять токен авторизации к каждому запросу или логировать время ответа. С
— Таймауты: В Axios таймаут задается одной строкой в конфиге. В
— Обработка ошибок: Axios считает ошибкой любой статус, кроме 2xx.
Пример интерцептора в Axios:
Когда использовать Fetch? 🏗️
— Если ты пишешь легкую библиотеку и не хочешь лишних зависимостей.
— Если ты работаешь в Edge-окружениях (например, Vercel Edge Functions), где важен размер бандла.
— Если тебе просто нужно сделать один запрос и ты не хочешь тянуть NPM-пакет.
Методы и фишки: 📝
— axios.all([]) — удобный аналог
— Base URL — возможность задать корень API один раз и дальше писать только пути. 🧩
— XSRF Protection — встроенная защита от подделки межсайтовых запросов.
> Итог:
---
### **Пакет
Разработка на Node.js без этого пакета — это страдание. Отредактировал файл -> Перешел в консоль ->
Шаг 1 — установка и запуск:
Обычно его ставят как
Зачем это нужно? 🚀
— Скорость разработки: Ты видишь результат своих правок через секунду. 🏎️
— Гибкость: Можно настроить, какие файлы игнорировать (например, тесты или логи), чтобы сервер не перезагружался зря.
— Поддержка любого языка: Через
Крутые фишки: 📝
— nodemon.json — файл настроек, где можно прописать расширения (
— Ручной рестарт: Если что-то зависло, просто введи
— Запуск команд: Можно настроить выполнение линтера или тестов перед каждым перезапуском.
> Важный нюанс: В Node.js 18+ появился встроенный флаг
⚙ Backend Ready | #урок
Несмотря на то что в Node.js давно завезли нативный
fetch, библиотека Axios всё еще остается стандартом в индустрии. Почему разработчики не спешат переходить на «встроенное» решение? Разница в подходе: 🛠️
— Fetch: Это низкоуровневый API. Чтобы получить JSON, тебе нужно сделать два шага: сначала дождаться ответа, а потом вызвать
.json().— Axios: Это обертка, которая делает всю грязную работу за тебя. Он автоматически парсит JSON и возвращает готовый объект в
response.data.Почему Axios всё еще круче? 🚀
— Интерцепторы (Interceptors): Можно создать функцию, которая будет автоматически добавлять токен авторизации к каждому запросу или логировать время ответа. С
fetch тебе придется писать обертку руками. 🔍— Таймауты: В Axios таймаут задается одной строкой в конфиге. В
fetch для этого нужно создавать AbortController (как мы учили в прошлых постах). ⏱️— Обработка ошибок: Axios считает ошибкой любой статус, кроме 2xx.
fetch же не выдаст ошибку, даже если сервер вернул 404 или 500 — тебе нужно вручную проверять свойство res.ok.Пример интерцептора в Axios:
const axios = require('axios');
const api = axios.create({ baseURL: 'https://api.example.com' });
api.interceptors.request.use(config => {
config.headers.Authorization = 'Bearer SECRET_TOKEN';
return config;
});
const data = await api.get('/users'); // Токен подставится сам!
Когда использовать Fetch? 🏗️
— Если ты пишешь легкую библиотеку и не хочешь лишних зависимостей.
— Если ты работаешь в Edge-окружениях (например, Vercel Edge Functions), где важен размер бандла.
— Если тебе просто нужно сделать один запрос и ты не хочешь тянуть NPM-пакет.
Методы и фишки: 📝
— axios.all([]) — удобный аналог
Promise.all для параллельных запросов.— Base URL — возможность задать корень API один раз и дальше писать только пути. 🧩
— XSRF Protection — встроенная защита от подделки межсайтовых запросов.
> Итог:
fetch — это база, которую нужно знать. Но если ты строишь серьезное приложение с кучей запросов, сложной авторизацией и логированием — Axios сэкономит тебе часы времени и сотни строчек кода. ✅---
### **Пакет
nodemon — забываем про ручной перезапуск сервера 🔄**Разработка на Node.js без этого пакета — это страдание. Отредактировал файл -> Перешел в консоль ->
Ctrl+C -> Вверх -> Enter. И так 500 раз в день. Nodemon делает это за тебя: он следит за файлами в папке и перезапускает процесс мгновенно после сохранения.Шаг 1 — установка и запуск:
Обычно его ставят как
devDependency, чтобы он не улетал на боевой сервер.npm install --save-dev nodemon
// package.json
"scripts": {
"dev": "nodemon index.js"
}
npm run dev
Зачем это нужно? 🚀
— Скорость разработки: Ты видишь результат своих правок через секунду. 🏎️
— Гибкость: Можно настроить, какие файлы игнорировать (например, тесты или логи), чтобы сервер не перезагружался зря.
— Поддержка любого языка: Через
nodemon можно запускать даже Python или Ruby скрипты, если тебе нужен авто-рестарт.Крутые фишки: 📝
— nodemon.json — файл настроек, где можно прописать расширения (
.js, .json, .graphql) и папки для слежки. ⚙️— Ручной рестарт: Если что-то зависло, просто введи
rs в терминале, и nodemon перезапустит сервер без выхода из программы.— Запуск команд: Можно настроить выполнение линтера или тестов перед каждым перезапуском.
> Важный нюанс: В Node.js 18+ появился встроенный флаг
--watch. Можно запускать так: node --watch index.js. Это работает быстрее и не требует установки пакетов. Но nodemon всё еще популярен из-за более гибких настроек и удобного лога в консоли. ✅Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🔥1
Python Ready — авторский канал, где Python перестаёт быть только теорией и становится рабочим инструментом. Мини-проекты, боты, советы, разборы задач, гайды и шпаргалки для каждого программиста.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Хочешь посмотреть, как Java эволюционировала, фича за фичей?
brunoborges сделал офигенный сайт, где изменения языка Java показаны рядом, в формате side-by-side. Идеально для студентов и для тех, кто модернизирует легаси-приложения.
Зацени:
https://javaevolved.github.io
⚙ Backend Ready | #урок
brunoborges сделал офигенный сайт, где изменения языка Java показаны рядом, в формате side-by-side. Идеально для студентов и для тех, кто модернизирует легаси-приложения.
Зацени:
https://javaevolved.github.io
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Один умный человек, написал эссе про алгоритм BM25, который лежит в основе Elasticsearch, Apache Solr и Apache Lucene.
Зачем? Просто потому что ему было нечем заняться, он нырнул в кроличью нору информационного поиска: пытался понять, почему и где TF-IDF в итоге упирается в свои пределы, как на самом деле устроен BM25 под капотом, и почему системы вроде Elasticsearch, Solr и Lucene сделали его своей дефолтной функцией ранжирования.
В эссе узнаете, почему BM25 так хорошо работает, как каждая часть формулы влияет на ранжирование, и какое место он занимает в современном retrieval-стеке.
Этот текст должен дать тебе нормальную ментальную модель, чтобы понимать BM25 и также IDF из популярного TF-IDF. Зацени.
⚙ Backend Ready | #урок
Зачем? Просто потому что ему было нечем заняться, он нырнул в кроличью нору информационного поиска: пытался понять, почему и где TF-IDF в итоге упирается в свои пределы, как на самом деле устроен BM25 под капотом, и почему системы вроде Elasticsearch, Solr и Lucene сделали его своей дефолтной функцией ранжирования.
В эссе узнаете, почему BM25 так хорошо работает, как каждая часть формулы влияет на ранжирование, и какое место он занимает в современном retrieval-стеке.
Этот текст должен дать тебе нормальную ментальную модель, чтобы понимать BM25 и также IDF из популярного TF-IDF. Зацени.
Please open Telegram to view this post
VIEW IN TELEGRAM
Fastify — когда Express становится слишком медленным 🏎️
Express — это классика, но он был создан в те времена, когда Node.js только зарождался. Fastify — это современный фреймворк, созданный с фокусом на максимальную производительность и минимальные накладные расходы. Он буквально «летает» за счет оптимизации JSON-схем и встроенной системы плагинов.
Шаг 1 — создаем первый роут:
Синтаксис похож на Express, но сразу предлагает использовать
Зачем это нужно? 🚀
— Сверхскорость: Fastify считается одним из самых быстрых фреймворков для Node.js. Он тратит меньше ресурсов процессора на каждый запрос.
— Валидация «из коробки»: Fastify использует JSON Schema для проверки входных данных. Это не только делает API безопасным, но и ускоряет сериализацию ответов в 2 раза. 🛡️
— Экосистема плагинов: Вместо хаотичного мидлвара, как в Express, здесь строгая и понятная иерархия плагинов.
Крутые фишки: 📝
— Hooks: Ты можешь вклиниться в любой момент жизненного цикла запроса (
— Типизация: Отличная поддержка TypeScript прямо из коробки. 🧩
— Декораторы: Позволяют легко добавлять новые методы в объекты
— Логирование: Встроенный сверхбыстрый логгер Pino (о котором мы писали раньше).
Пример с валидацией:
> Важный нюанс: Если ты начинаешь новый проект в 2026 году — выбирай Fastify. Express всё еще жив, но Fastify предлагает более современную архитектуру и лучшую производительность для микросервисов. ✅
---
### **Пакет
В любом серьезном бэкенде есть задачи, которые должны выполняться сами по себе: рассылка писем по утрам, чистка старых логов или бэкап базы данных в полночь. Пакет
Шаг 1 — настраиваем «будильник»:
Зачем это нужно? 🚀
— Автоматизация: Тебе не нужно помнить о рутинных задачах — сервер сделает всё сам.
— Гибкость: Можно настроить запуск раз в секунду, раз в месяц или только по рабочим дням в 9 утра. 📅
— Надежность: Задачи работают в фоне и не мешают пользователям пользоваться сайтом.
Как читать синтаксис (5 звезд): 📝
—
—
—
—
Крутые фишки: 📝
— Поддержка часовых поясов: Твой сервер может стоять в США, но выполнять задачи по времени твоего города.
— Управление: Задачи можно динамически создавать, останавливать (
— async/await: Внутри задачи можно спокойно использовать асинхронный код для запросов к БД или API.
> Важный нюанс: Если у тебя один сервер —
⚙ Backend Ready | #урок
Express — это классика, но он был создан в те времена, когда Node.js только зарождался. Fastify — это современный фреймворк, созданный с фокусом на максимальную производительность и минимальные накладные расходы. Он буквально «летает» за счет оптимизации JSON-схем и встроенной системы плагинов.
Шаг 1 — создаем первый роут:
Синтаксис похож на Express, но сразу предлагает использовать
async/await.npm install fastify
const fastify = require('fastify')({ logger: true });
fastify.get('/ping', async (request, reply) => {
return { status: 'pong' }; // JSON парсится автоматически
});
fastify.listen({ port: 3000 }, (err) => {
if (err) throw err;
console.log('Fastify запущен!');
});
Зачем это нужно? 🚀
— Сверхскорость: Fastify считается одним из самых быстрых фреймворков для Node.js. Он тратит меньше ресурсов процессора на каждый запрос.
— Валидация «из коробки»: Fastify использует JSON Schema для проверки входных данных. Это не только делает API безопасным, но и ускоряет сериализацию ответов в 2 раза. 🛡️
— Экосистема плагинов: Вместо хаотичного мидлвара, как в Express, здесь строгая и понятная иерархия плагинов.
Крутые фишки: 📝
— Hooks: Ты можешь вклиниться в любой момент жизненного цикла запроса (
onRequest, preHandler и т.д.).— Типизация: Отличная поддержка TypeScript прямо из коробки. 🧩
— Декораторы: Позволяют легко добавлять новые методы в объекты
request и reply без костылей.— Логирование: Встроенный сверхбыстрый логгер Pino (о котором мы писали раньше).
Пример с валидацией:
const schema = {
params: {
type: 'object',
properties: { id: { type: 'number' } }
}
};
fastify.get('/user/:id', { schema }, async (req, res) => {
return { userId: req.params.id };
});
> Важный нюанс: Если ты начинаешь новый проект в 2026 году — выбирай Fastify. Express всё еще жив, но Fastify предлагает более современную архитектуру и лучшую производительность для микросервисов. ✅
---
### **Пакет
cron — планируем задачи по расписанию ⏰**В любом серьезном бэкенде есть задачи, которые должны выполняться сами по себе: рассылка писем по утрам, чистка старых логов или бэкап базы данных в полночь. Пакет
cron позволяет настроить выполнение функций по расписанию с помощью стандартного синтаксиса crontab.Шаг 1 — настраиваем «будильник»:
npm install cron
const { CronJob } = require('cron');
const job = new CronJob(
'0 0 * * *', // Каждый день в полночь
function() {
console.log('Время делать бэкап базы данных! 💾');
},
null, // Коллбэк при остановке
true, // Запустить сразу
'Europe/Moscow' // Часовой пояс
);
Зачем это нужно? 🚀
— Автоматизация: Тебе не нужно помнить о рутинных задачах — сервер сделает всё сам.
— Гибкость: Можно настроить запуск раз в секунду, раз в месяц или только по рабочим дням в 9 утра. 📅
— Надежность: Задачи работают в фоне и не мешают пользователям пользоваться сайтом.
Как читать синтаксис (5 звезд): 📝
—
* * * * * * (секунды, минуты, часы, день месяца, месяц, день недели).—
0 */2 * * * — каждые два часа.—
0 9 * * 1-5 — в 9:00 с понедельника по пятницу. 👔—
30 18 * * * — каждый день в 18:30.Крутые фишки: 📝
— Поддержка часовых поясов: Твой сервер может стоять в США, но выполнять задачи по времени твоего города.
— Управление: Задачи можно динамически создавать, останавливать (
job.stop()) и запускать заново в коде. ⚙️— async/await: Внутри задачи можно спокойно использовать асинхронный код для запросов к БД или API.
> Важный нюанс: Если у тебя один сервер —
cron идеален. Если же у тебя кластер из 10 серверов, обычный cron запустится на каждом из них одновременно. В таких случаях лучше использовать распределенные очереди задач, например BullMQ или Agenda. ✅Please open Telegram to view this post
VIEW IN TELEGRAM
BullMQ — мощные очереди задач для тех, кто вырос из обычного Cron 🐂
Когда твой проект растет, простых задач «по расписанию» становится мало. Что, если нужно отправить 10 000 писем, но API почтового сервиса тормозит? Или нужно обработать тяжелое видео, не заставляя пользователя ждать ответа? Здесь на сцену выходит BullMQ — стандарт для очередей задач в Node.js, работающий на базе Redis.
Шаг 1 — создаем очередь и воркер:
Одна часть приложения (продюсер) кидает задачу в очередь, а другая (воркер) — выполняет её, когда освободится.
Зачем это нужно? 🚀
— Фоновая обработка: Пользователь нажимает «Загрузить», и мы сразу говорим ему «Ок, скоро всё будет», а само видео обрабатывается в фоне. 🎬
— Устойчивость к сбоям: Если воркер упадет или сервер перезагрузится, задача не пропадет. Она останется в Redis и будет выполнена позже.
— Rate Limiting: Можно ограничить выполнение задач (например, не больше 5 запросов в секунду к стороннему API), чтобы не получить бан. 🛡️
— Повторы (Retries): Если задача упала с ошибкой (например, сеть мигнула), BullMQ может автоматически попробовать еще раз через 5, 10 или 60 минут.
Крутые фишки: 📝
— Priorities: Можно сделать так, чтобы задачи от Premium-пользователей всегда шли в начало очереди. ✨
— Delayed Jobs: Выполни задачу не сейчас, а ровно через 2 часа.
— Parent/Child Jobs: Создавай сложные цепочки — выполни задачу А, и только если она успешна, запускай задачи Б и В.
— Панель управления: Есть готовые админки (например, BullBoard), где можно в реальном времени смотреть, сколько задач в очереди, сколько упало и почему. 📊
Почему Redis? 🤔
Redis работает в оперативной памяти, поэтому обмен задачами происходит мгновенно. Это намного быстрее, чем хранить очередь в обычной реляционной базе вроде PostgreSQL.
> Важный нюанс: BullMQ — это профессиональный инструмент. Если тебе просто нужно раз в день чистить логи, обычного
⚙ Backend Ready | #урок
Когда твой проект растет, простых задач «по расписанию» становится мало. Что, если нужно отправить 10 000 писем, но API почтового сервиса тормозит? Или нужно обработать тяжелое видео, не заставляя пользователя ждать ответа? Здесь на сцену выходит BullMQ — стандарт для очередей задач в Node.js, работающий на базе Redis.
Шаг 1 — создаем очередь и воркер:
Одна часть приложения (продюсер) кидает задачу в очередь, а другая (воркер) — выполняет её, когда освободится.
npm install bullmq ioredis
const { Queue, Worker } = require('bullmq');
// 1. Создаем очередь
const videoQueue = new Queue('video-processing');
// 2. Добавляем задачу (например, из контроллера)
await videoQueue.add('compress', { videoId: 42, format: 'mp4' });
// 3. Воркер в отдельном процессе подхватывает задачу
const worker = new Worker('video-processing', async job => {
console.log(`Обработка видео ${job.data.videoId}...`);
// Тут логика сжатия
return 'Done';
});
Зачем это нужно? 🚀
— Фоновая обработка: Пользователь нажимает «Загрузить», и мы сразу говорим ему «Ок, скоро всё будет», а само видео обрабатывается в фоне. 🎬
— Устойчивость к сбоям: Если воркер упадет или сервер перезагрузится, задача не пропадет. Она останется в Redis и будет выполнена позже.
— Rate Limiting: Можно ограничить выполнение задач (например, не больше 5 запросов в секунду к стороннему API), чтобы не получить бан. 🛡️
— Повторы (Retries): Если задача упала с ошибкой (например, сеть мигнула), BullMQ может автоматически попробовать еще раз через 5, 10 или 60 минут.
Крутые фишки: 📝
— Priorities: Можно сделать так, чтобы задачи от Premium-пользователей всегда шли в начало очереди. ✨
— Delayed Jobs: Выполни задачу не сейчас, а ровно через 2 часа.
— Parent/Child Jobs: Создавай сложные цепочки — выполни задачу А, и только если она успешна, запускай задачи Б и В.
— Панель управления: Есть готовые админки (например, BullBoard), где можно в реальном времени смотреть, сколько задач в очереди, сколько упало и почему. 📊
Почему Redis? 🤔
Redis работает в оперативной памяти, поэтому обмен задачами происходит мгновенно. Это намного быстрее, чем хранить очередь в обычной реляционной базе вроде PostgreSQL.
> Важный нюанс: BullMQ — это профессиональный инструмент. Если тебе просто нужно раз в день чистить логи, обычного
node-cron хватит. Но если от выполнения задачи зависят деньги или лояльность юзера — используй очереди. ✅Please open Telegram to view this post
VIEW IN TELEGRAM
🔌 Модуль
Когда мы делаем HTTP-запрос, Node.js сам разрешает домены, но иногда приложению нужно делать это вручную: проверить существование домена, получить его IP или узнать MX-записи почтового сервера.
dns — резолвинг и проверка сети**
—
—
—
—
— dns.resolve() — отправляет реальный запрос к DNS-серверам в сети. Позволяет узнать IP-адреса, привязанные к домену.
— dns.lookup() — использует настройки операционной системы (например, файл
— dns.reverse() — выполняет обратное преобразование: вы передаете IP-адрес, а модуль пытается найти имя хоста, которое ему соответствует.
— dns.resolveMx() — возвращает записи почтового обмена. Идеально для проверки, существует ли почтовый сервер у домена перед отправкой письма.
— dns.getServers() — показывает список IP-адресов DNS-серверов, которые в данный момент использует твоя система для резолвинга.
⚙ Backend Ready | #урок
dns — работаем с доменными именами напрямуюКогда мы делаем HTTP-запрос, Node.js сам разрешает домены, но иногда приложению нужно делать это вручную: проверить существование домена, получить его IP или узнать MX-записи почтового сервера.
dns — резолвинг и проверка сети**
—
dns.resolve()—
dns.lookup()—
dns.reverse()—
dns.getServers()— dns.resolve() — отправляет реальный запрос к DNS-серверам в сети. Позволяет узнать IP-адреса, привязанные к домену.
const dns = require('dns');
dns.resolve('google.com', (err, addresses) => {
console.log('IP адреса:', addresses);
});
// Результат: IP адреса: ['142.250.185.142', ...]
— dns.lookup() — использует настройки операционной системы (например, файл
hosts). Это быстрее, но не всегда дает актуальные данные из интернета.dns.lookup('localhost', (err, address) => {
console.log('Адрес:', address);
});
// Результат: Адрес: 127.0.0.1
— dns.reverse() — выполняет обратное преобразование: вы передаете IP-адрес, а модуль пытается найти имя хоста, которое ему соответствует.
— dns.resolveMx() — возвращает записи почтового обмена. Идеально для проверки, существует ли почтовый сервер у домена перед отправкой письма.
dns.resolveMx('github.com', (err, addresses) => {
console.log(addresses);
});
— dns.getServers() — показывает список IP-адресов DNS-серверов, которые в данный момент использует твоя система для резолвинга.
Please open Telegram to view this post
VIEW IN TELEGRAM