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
🤔 Почему возрастает интерес к функциональному программированию (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
🤔 Что такое замыкание и для чего оно полезно?

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

🚩Как это работает?

Когда функция определена внутри другой функции, внутренняя функция имеет доступ ко всем переменным внешней функции благодаря лексическому окружению. Даже после завершения работы внешней функции, это окружение остаётся "живым" для внутренней функции, и она может использовать и изменять эти переменные.

🚩Основные характеристики замыканий

🟠Захват переменных внешней функции
Внутренняя функция "запоминает" переменные, которые существовали во внешней функции в момент её создания.

🟠Доступ к закрытым данным
Замыкания позволяют скрывать данные и предоставлять к ним доступ только через определённые функции.

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

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

🚩Для чего замыкания полезны?

🟠Инкапсуляция данных
Замыкания позволяют скрывать переменные и предоставлять доступ к ним только через определённые функции. Это помогает защитить данные от случайного изменения и улучшает безопасность кода.

🟠Сохранение состояния между вызовами
Замыкания могут "запоминать" значение переменных между вызовами функции. Например, можно создать счётчик, который хранит своё состояние.

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

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

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

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

🟠Счётчик
Создание функции, которая инкрементирует и возвращает число при каждом вызове. Переменная-счётчик хранится в замыкании и остаётся доступной для внутренней функции.

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

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

🟠Мемоизация
Хранение результатов вычислений в замыкании для оптимизации производительности.

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

Scrum — это методология Agile с фиксированными спринтами и определёнными ролями (Scrum Master, Product Owner). Kanban — это гибкий подход, где работа организована на доске с карточками, и нет строгих временных рамок. Scrum ориентирован на итерации, а Kanban — на постоянный поток задач.

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

Индекс массива часто начинается с нуля по историческим и практическим причинам, связанным с архитектурой компьютеров и принципами работы с памятью. Это поведение стало стандартом в большинстве языков программирования (например, C, C++, Java, Python).

🚩Основные причины

🟠Простота адресации в памяти
Массивы хранятся в памяти как последовательные ячейки, и для доступа к элементу массива используется смещение от начального адреса.
Если массив начинается с индекса 0, то адрес элемента вычисляется по формуле:
\text{Адрес элемента} = \text{Базовый адрес} + (\text{индекс} \times \text{размер элемента})

Например, для первого элемента массива (индекс 0):
\text{Адрес} = \text{Базовый адрес} + (0 \times \text{размер элемента}) = \text{Базовый адрес}


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

🟠Историческое наследие
Индексация с нуля пришла из языка C и более ранних языков, таких как Assembly. Язык C, созданный в 1970-х годах, получил широкое распространение, и многие современные языки программирования унаследовали его подход. Например, в C указатель на массив указывает на первый элемент (index 0), а доступ к элементам происходит через арифметику указателей.

🟠Удобство работы с указателями
В языках низкого уровня (например, C) массив и указатель на его начало практически эквивалентны. Индексация с нуля позволяет упростить арифметику указателей: Если ptr — указатель на начало массива, то ptr + i указывает на i-й элемент массива, где i = 0 указывает на первый элемент.

🟠Математическая логика
В математике и теории множеств индексы и последовательности часто начинаются с 0. Например: Вектор длиной n имеет n элементов, и их индексы обычно лежат в диапазоне [0, n-1].

🚩Почему не с единицы?

Хотя индексация с 1 может быть интуитивно понятной для некоторых людей (особенно не программистов), она требует дополнительных вычислений при адресации. Для индекса 1 формула смещения будет
\text{Адрес элемента} = \text{Базовый адрес} + ((\text{индекс} - 1) \times \text{размер элемента})


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

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

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

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

🚩Почему управление версиями API важно?

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

🚩Подходы к управлению версиями API

🟠Версионирование через URL (URI-based Versioning)
Версия API указывается как часть URL.
https://api.example.com/v1/users
https://api.example.com/v2/users

Плюсы и минусы
Простота и очевидность для клиентов API.
Разные версии могут существовать параллельно.
Может привести к дублированию кода на сервере.
URL становятся менее "чистыми".

🟠Версионирование через заголовки (Header Versioning)
Версия передаётся в HTTP-заголовке запроса.
GET /users  
Accept: application/vnd.example.v1+json

Плюсы и минусы
URL остаются чистыми.
Позволяет более гибко управлять форматами ответов.
Требует явного указания заголовков.
Может быть менее очевидным для клиентов.

🟠Версионирование через параметр запроса (Query Parameter Versioning)
Версия указывается в качестве параметра запроса.
https://api.example.com/users?version=1
https://api.example.com/users?version=2


Плюсы и минусы
Простота реализации.
Легко управлять параметрами запроса.
Может запутать клиентов, если параметры запроса используются для других целей.
Не является общепринятым стандартом.

🟠Версионирование через медиатип (Media Type Versioning)
Версия API определяется через тип содержимого (Content-Type) или заголовок Accept.
GET /users  
Accept: application/json; version=1


Плюсы и минусы
Хорошая интеграция с REST API.
Поддерживает эволюцию API без изменения URL.
Сложнее реализовать и понимать клиентам.

🚩Как выбирать подход к версионированию?

🟠URL-версионирование
Подходит для большинства API, когда изменения значительны и нужны отдельные версии.
🟠Заголовки или медиатипы
Подходят для больших корпоративных систем или случаев, когда нужно сохранить чистый URL.
🟠Query-параметры
Подойдут для небольших проектов или временного тестирования новых версий.

🚩Стратегии управления версиями API

🟠Семантическое версионирование (Semantic Versioning)
Следует правилам MAJOR.MINOR.PATCH (например, v1.2.3):
MAJOR: Несовместимые изменения, ломающие существующий код.
MINOR: Добавление новой функциональности, совместимое с предыдущими версиями.
PATCH: Исправления ошибок и мелкие изменения.

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

🟠Документация и коммуникация
Обновления версий API должны сопровождаться подробной документацией. Информируйте пользователей о предстоящих изменениях и сроках вывода старых версий.

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

🚩Рекомендации для управления версиями API
Всегда начинайте с v1 в URL или заголовках. Документируйте все изменения при выпуске новой версии. Устанавливайте сроки поддержки устаревших версий. Используйте семантическое версионирование для отслеживания изменений. Оповещайте пользователей API о планируемых обновлениях заранее. Тестируйте старые и новые версии API на совместимость.

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