Backend
3.95K subscribers
36 photos
712 links
Комьюнити Backend программистов.
Python, Java, Golang, PHP, C#, C/C++, DevOps

Сайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp
Download Telegram
🤔 Как "под капотом" работает аннотация @Transactional?

Аннотация @Transactional в Spring использует прокси для перехвата методов и управления транзакциями. Перед выполнением метода создаётся или используется существующая транзакция, а после выполнения транзакция коммитится или откатывается в случае исключения.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Проблема N+1 и её решение?

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

🚩Как проявляется?

Представим, что у нас есть две сущности: User и связанные с ним Posts. Приложение запрашивает список всех пользователей, а затем для каждого пользователя делает отдельный запрос, чтобы получить связанные с ним посты. Вместо одного запроса к базе данных выполняется: Один запрос для получения всех пользователей. N запросов для получения постов каждого пользователя.
Итог: N+1 запросов.
Это неэффективно, так как количество запросов растёт линейно с увеличением количества данных, что приводит к большим задержкам.

🚩Причины возникновения
🟠Неправильная настройка ORM (например, использование ленивой загрузки (`lazy loading`)).
🟠Невнимательность при проектировании архитектуры приложения.
🟠Недостаток оптимизации при составлении SQL-запросов.

🚩Подходы к решению проблемы

🟠Жадная загрузка (Eager Loading)
Вместо выполнения N отдельных запросов для связанных данных, ORM можно настроить так, чтобы они загружались вместе с основным запросом. Например: В Hibernate это можно сделать с помощью fetch join. В Django ORM используется метод select_related() или prefetch_related().

🟠Оптимизация SQL-запросов вручную
Иногда автоматическая оптимизация ORM не работает идеально. В таких случаях можно написать кастомные SQL-запросы, используя соединения (JOIN) для получения всех необходимых данных в одном запросе.

🟠Кэширование
Если данные редко меняются, можно использовать кэш (например, Redis или Memcached), чтобы минимизировать количество обращений к базе данных.

🟠Анализ запросов
Использование инструментов мониторинга запросов (например, SQLAlchemy профайлеры или Django Debug Toolbar) позволяет вовремя выявить проблему N+1 и устранить её.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Расскажи про уровни изоляции?

Уровни изоляции транзакций:
READ UNCOMMITTED — видны незавершённые изменения.
READ COMMITTED — видны только зафиксированные изменения.
REPEATABLE READ — предотвращает изменения данных, прочитанных транзакцией.
SERIALIZABLE — полная изоляция, все транзакции выполняются последовательно.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Утечка памяти в Java: примеры и объяснение?

В Java происходит, когда объекты, которые больше не нужны, продолжают ссылаться в памяти, и сборщик мусора (Garbage Collector, GC) не может их освободить. Это может привести к росту потребления памяти и в конечном итоге к ошибке OutOfMemoryError.

🚩Примеры утечек памяти в Java

🟠Долгоживущие коллекции
Если объекты добавляются в коллекцию (например, List, Map) и никогда не удаляются, они могут остаться в памяти, даже если больше не используются.
public class MemoryLeakExample {
private static List<Object> list = new ArrayList<>();

public void addToList() {
list.add(new Object()); // Объекты накапливаются, даже если они больше не нужны.
}
}


🟠Ошибки в обработке слушателей (Listeners)
Часто утечка происходит, когда объекты, подписанные на события, не отписываются, даже если больше не используются.
class EventSource {
private List<EventListener> listeners = new ArrayList<>();

public void addListener(EventListener listener) {
listeners.add(listener);
}
}

class LeakingClass {
public LeakingClass(EventSource source) {
source.addListener(new EventListener() {
@Override
public void onEvent() {
// Обработка события
}
});
}
}


🟠Слабые ссылки, которые не используются правильно
Неправильное использование объектов с сильными ссылками, которые хранят данные временно, но остаются доступными слишком долго.
class Cache {
private Map<Key, Value> cache = new HashMap<>();

public void put(Key key, Value value) {
cache.put(key, value); // Объекты накапливаются и не очищаются.
}
}


🟠Замыкания (Closures)
Использование лямбда-выражений или анонимных классов, которые удерживают ссылки на внешние объекты.
public class MemoryLeak {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
Runnable task = () -> list.add(new Object()); // Лямбда удерживает ссылку на list
task.run();
}
}


🟠Потоки (Threads)
Если поток продолжает работать или удерживает ссылки на объекты, которые больше не нужны, это может привести к утечке.
class LeakingThread {
public void startThread() {
Thread thread = new Thread(() -> {
while (true) {
// Бесконечный цикл, который не позволяет завершить поток
}
});
thread.start();
}
}

🟠Закрытие ресурсов
Незакрытые соединения или потоки ввода/вывода могут удерживать ссылки на системные ресурсы.
public void readFile() {
FileInputStream fis = new FileInputStream("file.txt");
// Поток не закрыт
}


🚩Как избежать утечек памяти?

🟠Регулярно анализировать код
Использовать профилировщики памяти, такие как VisualVM, YourKit, или JProfiler. Искать "утекшие" объекты, которые удерживаются ссылками, но больше не нужны.

🟠Использовать слабые ссылки
Применять WeakReference или WeakHashMap для временных данных.

🟠Управлять жизненным циклом объектов
Удалять ненужные объекты из коллекций. Освобождать ресурсы, такие как потоки или соединения.

🟠Отписываться от событий
Удалять слушателей (listeners), когда они больше не нужны.

🟠Правильно закрывать ресурсы
Использовать try-with-resources для работы с потоками и соединениями.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
🤔 Как ты можешь описать абстракцию?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Почему возрастает интерес к функциональному программированию (FP)?

Интерес к функциональному программированию (Functional Programming) растёт из-за изменений в требованиях к разработке современных приложений, таких как потребность в масштабируемости, управлении сложностью и обработке больших данных. Функциональное программирование предлагает преимущества, которые позволяют решать эти задачи более эффективно.

🚩Основные причины роста интереса к FP

🟠Эффективная обработка многопоточности и параллелизма
Функциональное программирование делает акцент на чистых функциях, которые не имеют побочных эффектов. Это упрощает разработку многопоточных приложений, поскольку отсутствует необходимость синхронизации общего состояния. Языки, такие как Scala, Clojure, и Haskell, предоставляют мощные инструменты для работы с параллелизмом и потоками данных, что важно в эпоху многоядерных процессоров.

🟠Масштабируемость и управление состоянием
Современные распределённые системы требуют минимизации работы с изменяемым состоянием. FP, с его подходом к неизменяемым данным, позволяет избегать проблем, связанных с изменяемостью, таких как гонки данных или сложные состояния.

🟠Обработка больших данных
Фреймворки, такие как Apache Spark и Apache Flink, используют концепции функционального программирования (например, операции над коллекциями, как map, filter, reduce) для работы с большими данными. Это делает FP особенно полезным для обработки потоков данных и анализа больших объёмов информации.

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

🟠Популяризация функциональных возможностей в императивных языках
Основные императивные языки программирования (Java, Python, JavaScript, C#) добавляют функциональные возможности, такие как лямбды, стримы и функции высшего порядка. Это делает функциональный стиль более доступным для широкой аудитории разработчиков.

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

🟠Тенденции к модульности и повторному использованию кода
FP способствует созданию более модульного кода. Композиция функций позволяет легко строить новые функциональности из существующих компонентов.

🟠Популярность в веб-разработке и мобильных приложениях
Языки, такие как Elm, ReasonML, и фреймворки, например React (с концепцией функциональных компонентов), активно используют принципы функционального программирования. Это позволяет создавать приложения с минимальным количеством багов и высокой предсказуемостью поведения.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🤔 Что такое столп "наследование"?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Как обнаружить самые затратные запросы?

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

🚩Включение логирования медленных запросов (Slow Query Logging)

Многие системы управления базами данных (СУБД) поддерживают логирование запросов, выполнение которых занимает больше определённого времени.

🟠MySQL
Используйте slow_query_log. Активировать лог:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- Время выполнения в секундах


🟠PostgreSQL
Включите log_min_duration_statement.
SET log_min_duration_statement = 1000; -- Логировать запросы, выполняющиеся более 1 секунды


🚩Использование EXPLAIN или ANALYZE

Эти команды дают подробный план выполнения запросов, показывая, как база данных интерпретирует их.

MySQL
EXPLAIN SELECT * FROM orders WHERE status = 'pending';


PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE status = 'pending';


🚩Использование системных представлений и мониторинга запросов

🟠MySQL
Используйте таблицу performance_schema для анализа запросов.
SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;


🟠PostgreSQL
Используйте расширение pg_stat_statements.
CREATE EXTENSION pg_stat_statements;

Получите информацию
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;


🚩Мониторинг с использованием внешних инструментов

🟠New Relic
Проводит анализ SQL-запросов, показывая самые медленные.
🟠Datadog
Позволяет отслеживать производительность запросов в реальном времени.
🟠SolarWinds DPA (Database Performance Analyzer)
Специализированный инструмент для анализа производительности баз данных.

🚩Оптимизация индексов

🟠MySQL
SELECT * FROM sys.schema_unused_indexes;


🟠PostgreSQL
Проверьте в плане выполнения запросов (EXPLAIN), используются ли индексы.

🚩Нагрузочное тестирование (Load Testing)

Используйте нагрузочные тесты, чтобы выявить запросы, создающие "бутылочные горлышки":
🟠Apache JMeter
Симулирует многопоточную нагрузку на базу данных.
🟠Gatling
Анализирует производительность системы под высокой нагрузкой.

🚩Анализ трассировки запросов

Включите трассировку (например, в MySQL — SHOW PROFILE):
SET profiling = 1;
SELECT * FROM orders WHERE status = 'pending';
SHOW PROFILE FOR QUERY 1;


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 В чём разница между SQL и NoSQL?

SQL (Structured Query Language) — это язык запросов для работы с реляционными базами данных, которые организуют данные в таблицах. NoSQL — это общий термин для баз данных, которые не используют табличную модель и часто оптимизированы для работы с большими объемами распределенных данных. Основные различия включают модели данных, схемы, масштабируемость, и консистентность.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🤔 Принципы Agile-манифеста?

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

🚩4 ценности Agile

🟠Люди и взаимодействие важнее процессов и инструментов
Это подчёркивает, что успех проекта зависит от командной работы и коммуникации, а не от формальностей и процедур.

🟠Работающий продукт важнее исчерпывающей документации
Фокус на создании ценного результата, а не на написании огромного количества документации.

🟠Сотрудничество с заказчиком важнее согласования условий контракта
Постоянное взаимодействие с клиентом помогает лучше понять его потребности и вовремя внести изменения.

🟠Готовность к изменениям важнее следования первоначальному плану
Agile приветствует изменения, даже на поздних этапах разработки, чтобы продукт соответствовал текущим требованиям.

🚩12 принципов Agile-манифеста

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

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

🟠Частая поставка работающего программного обеспечения (раз в несколько недель или месяцев)
Это позволяет заказчику видеть прогресс и получать ценность на протяжении всего проекта.

🟠Плотное ежедневное взаимодействие разработчиков и бизнес-представителей
Это обеспечивает лучшее понимание задач и ускоряет принятие решений.

🟠Строить проекты вокруг мотивированных людей
Доверие, поддержка и автономия способствуют эффективной работе команды.

🟠Наиболее эффективный способ передачи информации — личное общение
Несмотря на технологии, живое взаимодействие остаётся наиболее продуктивным.

🟠Работающее программное обеспечение — основной показатель прогресса
Конечный результат важнее количества завершённых задач.

🟠Гибкие методологии поддерживают устойчивую разработку
Команда должна работать в комфортном ритме, чтобы сохранять продуктивность в долгосрочной перспективе.

🟠Постоянное внимание к техническому совершенству и качеству проектирования
Это снижает технический долг и упрощает внесение изменений.

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

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

🟠Регулярная адаптация к изменениям через осмысление прошедших этапов
Ретроспективы помогают команде улучшать процессы и избегать повторения ошибок.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Из чего состоит ответ на сервере?

Ответ сервера состоит из статусного кода, заголовков и тела. Статусный код сообщает результат обработки запроса (успех, ошибка и т. д.). Заголовки содержат метаданные, а тело передает данные.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Почему синглтон может быть антипаттерном?

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

🚩Проблемы с синглтоном

🟠 Нарушение принципов ООП
Синглтон нарушает принципы единственной ответственности (SRP) и инверсии зависимостей (DIP):
Он выполняет две задачи: управляет своим жизненным циклом (ограничивает создание экземпляров) и предоставляет бизнес-логику.
Жёсткая связь с синглтоном делает код трудно тестируемым и менее гибким.

🟠Скрытая глобальная зависимость
Синглтон фактически является глобальной переменной, поскольку предоставляет универсальный доступ. Это приводит к:
Затруднению отслеживания, где и как используется объект.
Повышенной связности компонентов, что усложняет их модификацию.

🟠Трудности с тестированием
Подменить синглтон в тестах сложно, так как он контролирует свой жизненный цикл. Это затрудняет использование мок-объектов.
Многоразовые тесты могут зависеть от состояния синглтона, что делает тесты нестабильными.

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

🟠Нарушение принципа открытости/закрытости (OCP)
Синглтон делает класс жёстко связанным со своей реализацией, что затрудняет расширение или изменение поведения. Например, нельзя легко заменить синглтон другой реализацией без изменения клиентского кода.

🟠Затруднения при модульном тестировании
Использование синглтона в нескольких местах увеличивает сложность изоляции компонентов. Выстраивать модульные тесты становится трудно, так как синглтон сохраняет состояние между вызовами.

🟠Проблемы в распределённых системах
В распределённых приложениях синглтон не гарантирует, что существует только один экземпляр объекта на всех узлах системы. Это требует дополнительных механизмов синхронизации.

🟠Склонность к неправильному использованию
Синглтон часто используется там, где можно обойтись другими механизмами (например, Dependency Injection). Это приводит к избыточной сложности и трудностям в поддержке.

🚩Примеры ситуаций, где синглтон становится проблемой

🟠Жёсткое связывание логики
Если объект доступа к базе данных реализован как синглтон, его сложно заменить другим объектом для тестирования.

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

🟠Непотокобезопасная реализация
В отсутствии надёжного механизма синхронизации попытки создать объект в многопоточном окружении могут вызвать дублирование.

🚩Как избежать проблем с синглтоном?

🟠Dependency Injection (DI)
Вместо синглтона передавайте зависимости через конструкторы или специальные контейнеры. Это упрощает тестирование и уменьшает связность.
🟠Использование слабых ссылок или провайдеров
Используйте шаблоны, которые позволяют создавать объекты по мере необходимости, избегая их глобальности.
🟠Паттерн "Одиночка с явной передачей"
Позвольте клиентам явно передавать экземпляры через методы, вместо использования глобального доступа.
🟠Сосредоточьтесь на композиции
Разделите логику синглтона на несколько отдельных классов, каждый из которых отвечает за одну задачу.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Расскажи об отличиях MVC от MVP

MVC (Model-View-Controller) и MVP (Model-View-Presenter) — это архитектурные паттерны для разделения логики. В MVC контроллер обрабатывает логику и обновляет представление, а в MVP презентер выполняет аналогичную роль, но взаимодействие с представлением более тесное. MVP чаще используется в мобильной разработке, где логика взаимодействия с представлением более сложная.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2
🤔 Как бороться с адом зависимостей?

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

🚩Причины возникновения ада зависимостей

🟠 Жёсткая связность компонентов
Когда модули напрямую зависят друг от друга, изменения в одном модуле требуют изменения в других.
🟠Циклические зависимости
Два или более модуля зависят друг от друга, создавая замкнутую цепь.
🟠Избыточное использование внешних библиотек
Приводит к сложным цепочкам зависимостей и проблемам совместимости.
🟠Отсутствие слоистости в архитектуре
Все компоненты напрямую взаимодействуют друг с другом.
🟠Смешение ответственности
Модули выполняют множество задач, что усложняет их декомпозицию.

🚩 Стратегии борьбы с адом зависимостей

🟠Используйте Dependency Injection (DI)
Вместо того чтобы модули создавали зависимости самостоятельно, передавайте их извне (например, через конструктор или фабрику). Применение DI-контейнеров (Spring, Guice) позволяет централизованно управлять зависимостями.

🟠Следуйте принципам SOLID
Single Responsibility Principle (SRP): Каждому модулю должна быть отведена одна задача.
Dependency Inversion Principle (DIP): Зависимости должны строиться на абстракциях, а не на конкретных реализациях.

🟠Внедряйте слоистую архитектуру
Разделите проект на слои: UI (пользовательский интерфейс).
Бизнес-логика.
Доступ к данным.
Между слоями используйте чётко определённые интерфейсы.

🟠Используйте модули и изолируйте зависимости
Разделите систему на независимые модули (например, с помощью Gradle или Maven). Каждый модуль должен иметь минимальный набор зависимостей.

🟠Избегайте циклических зависимостей
Циклы между модулями или классами усложняют понимание и поддержку системы.
Решения:
Внедряйте интерфейсы или посредников.
Пересмотрите ответственность модулей.

🟠Контролируйте внешние зависимости
Используйте только необходимые внешние библиотеки. Проверяйте лицензии, совместимость версий и активность сообщества.

🟠Применяйте шаблоны проектирования
Шаблоны проектирования, такие как Фабричный метод, Фасад и Адаптер, могут снизить связность и изолировать зависимости.

🟠Внедряйте автоматизированные тесты
Напишите модульные тесты для критически важных компонентов. Используйте интеграционные тесты для проверки взаимодействия между модулями.

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

🟠Применяйте Dependency Graph
Создание графа зависимостей помогает визуализировать связи между модулями и найти проблемные места.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое столп "наследование"?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31
🤔 Логика предметной области в хранимых процедурах: плюсы и минусы

Это исполняемый код (например, SQL-скрипты), который хранится и выполняется непосредственно в базе данных. Разработка бизнес-логики внутри хранимых процедур является спорной практикой. Она имеет как преимущества, так и недостатки в зависимости от требований системы, архитектуры и команды разработки.

🚩Плюсы

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

Централизация бизнес-логики
Вся логика предметной области сосредоточена в одном месте (в БД), что облегчает контроль доступа и выполнение важных операций. Удобно для многослойных систем, где несколько клиентских приложений используют одну базу данных.

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

Повышение безопасности
Системы могут ограничить доступ к таблицам и предоставить доступ только к хранимым процедурам, что снижает риск несанкционированного доступа. Встроенные механизмы контроля прав доступа (например, в PostgreSQL и Oracle).

Языковые возможности БД
Современные СУБД поддерживают процедурные языки, такие как PL/pgSQL (PostgreSQL), T-SQL (SQL Server) или PL/SQL (Oracle), которые предоставляют функции, циклы и исключения, что позволяет реализовать сложную логику.

Миграция между системами
При необходимости переноса части функциональности между разными приложениями (например, Web-приложением и мобильным клиентом) логика в БД остаётся неизменной.

🚩Минусы

Сложность поддержки и сопровождения
Хранимые процедуры часто сложны для чтения, отладки и тестирования по сравнению с кодом на языке программирования (например, Java, C#, Python). Версионный контроль затруднён, так как БД не всегда удобно интегрируется с системами контроля версий (Git).

Жёсткая зависимость от БД
Логика, написанная в хранимых процедурах, привязывает систему к конкретной СУБД (например, Oracle или SQL Server). Переход на другую БД становится дорогостоящим и трудоёмким.

Отсутствие масштабируемости
Сервер базы данных становится "узким местом" системы. Если бизнес-логика выполняется только на сервере БД, это может привести к перегрузке, особенно при высоком трафике.

Ограниченные возможности тестирования
Инструменты для юнит-тестирования и автоматизированного тестирования хранимых процедур менее развиты, чем для традиционного кода приложений. Тестирование бизнес-логики требует специальной инфраструктуры (например, отдельной тестовой БД).

Смешение слоёв архитектуры
Внедрение логики в БД нарушает принципы многослойной архитектуры, такие как Separation of Concerns (разделение ответственности). Логика бизнес-уровня смешивается с уровнем данных.

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

Зависимость от разработчиков БД
Написание и оптимизация хранимых процедур требуют специфических навыков SQL и понимания особенностей СУБД. Не все разработчики владеют этими навыками.

🚩Когда стоит использовать?

🟠Производительность критична
Если необходимо минимизировать сетевые вызовы и максимально эффективно обрабатывать большие объёмы данных.
🟠Централизация логики
Если бизнес-логика должна быть единой для нескольких клиентов (например, мобильного приложения, веб-сервиса).
🟠Ограничение доступа
Если безопасность и контроль доступа являются приоритетом.
🟠Проекты с жёсткой привязкой к БД
Например, для старых систем или проектов, где миграция на новую архитектуру невозможна.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Что такое статические и динамические типизации?

Это два подхода к определению и проверке типов данных в языках программирования. Они определяют, как язык работает с типами переменных и выражений во время выполнения и компиляции программы.

🚩 Статическая типизация
Означает, что типы переменных определяются во время компиляции и не могут изменяться в процессе выполнения программы. Это свойственно языкам с жёсткой типизацией, например, таким как C, C++, Java, Rust, Kotlin.

🚩Особенности статической типизации
🟠Проверка типов на этапе компиляции
Компилятор проверяет, соответствуют ли типы используемых данных их объявленным типам. Ошибки типов обнаруживаются ещё до запуска программы, что повышает её надёжность.

🟠Явное объявление типов
Разработчику часто нужно указывать тип переменной явно (например, int, float и т.д.). В некоторых языках есть вывод типов (type inference), когда компилятор сам определяет тип переменной, основываясь на её значении.

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

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

🚩Плюсы и минусы
Обнаружение ошибок на ранних этапах разработки
Улучшение производительности
Более предсказуемое поведение
Требуется больше кода для явного объявления типов.
Может усложнить написание кода, особенно в ситуациях, когда типы могут быть разными.

🚩Динамическая типизация
Означает, что типы переменных определяются во время выполнения программы. Это свойственно интерпретируемым языкам программирования, таким как Python, JavaScript, Ruby, PHP.

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

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

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

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

🚩Минусы
Ошибки типов выявляются во время выполнения
Может привести к неожиданным ошибкам (например, если переменная используется с неверным типом).
Низкая производительность

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое индексы?

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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Пример кода, создающего утечку памяти?

Происходит, когда программа выделяет память для объектов, но не освобождает её, даже когда эти объекты больше не нужны. Это особенно критично в языках, где управление памятью ложится на разработчика, например, в C или C++. Однако утечки памяти могут возникать и в языках с автоматической сборкой мусора (GC), таких как Python или Java, если есть "живые" ссылки на ненужные объекты.

🚩Пример утечки памяти в C++

В функции memoryLeakExample() память для переменной ptr выделяется динамически с помощью new. Однако память не освобождается с помощью delete, когда указатель выходит из области видимости. При многократном вызове этой функции программа будет терять память с каждым вызовом, что приведёт к утечке и потенциальному исчерпанию ресурсов.
#include <iostream>

void memoryLeakExample() {
int* ptr = new int(5); // Динамическое выделение памяти
std::cout << "Выделена память по адресу: " << ptr << " со значением: " << *ptr << std::endl;
// Здесь мы забываем освободить память
} // Утечка памяти: указатель ptr выходит из области видимости, а память не освобождается.

int main() {
for (int i = 0; i < 1000000; ++i) {
memoryLeakExample(); // Функция вызывается многократно
}
return 0;
}


🚩Пример утечки памяти в Python
Даже в языках с сборщиком мусора (как в Python), утечки памяти могут происходить из-за сильных ссылок, которые препятствуют сборке мусора.
class LeakyClass:
def __init__(self):
self.data = [0] * 10**6 # Занимаем большой объём памяти

def memory_leak_example():
leaks = [] # Список хранит ссылки на объекты
while True:
leaks.append(LeakyClass()) # Объекты добавляются, но не удаляются

memory_leak_example()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 В чём разница между SQL и NoSQL?

SQL (Structured Query Language) — это язык запросов для работы с реляционными базами данных, которые организуют данные в таблицах. NoSQL — это общий термин для баз данных, которые не используют табличную модель и часто оптимизированы для работы с большими объемами распределенных данных. Основные различия включают модели данных, схемы, масштабируемость, и консистентность.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2