BackendQuiz - задачи с собеседований по бэкенду
الذهاب إلى القناة على Telegram
Задачки на алгоритмы, на понимание HTTP и сетевого стека вцелом, так же базы данных и хранилища. Подойдет как для начинающих так и для опытных. Языки и технологии: Java, PHP, Ruby, Javascript, SQL Контакт: @cyberJohnny
إظهار المزيد1 724
المشتركون
لا توجد بيانات24 ساعات
لا توجد بيانات7 أيام
-430 أيام
أرشيف المشاركات
🤔 Что такое виртуальное окружение?
Это изолированная среда для выполнения программного кода, которая позволяет создавать независимые друг от друга пространства для различных проектов. В каждом таком окружении могут быть установлены специфические для проекта зависимости (библиотеки, пакеты), которые не будут пересекаться с зависимостями других проектов.
🚩Зачем нужно
🟠Изоляция зависимостей
В разных проектах могут использоваться различные версии одних и тех же библиотек. Виртуальные окружения позволяют избежать конфликтов версий, создавая изолированные пространства для каждого проекта.
🟠Упрощение управления зависимостями
Легко установить, обновить или удалить зависимости без риска повлиять на другие проекты. Это особенно полезно при работе над проектами с долгим жизненным циклом, где могут возникать проблемы совместимости.
🟠Повышение безопасности
Изоляция окружения помогает ограничить доступ к критически важным системным ресурсам и защищает основную систему от потенциально вредоносного кода.
🟠Удобство разработки и тестирования
Виртуальные окружения позволяют разработчикам легко переключаться между проектами и их зависимостями, что упрощает процесс тестирования и отладки.
🟠Совместимость и переносимость
Проекты с виртуальными окружениями легче перенести на другие системы или передать другим разработчикам. Достаточно скопировать окружение вместе с проектом, чтобы получить полностью функционирующую копию.
🚩Как используется
🟠venv
Встроенный модуль в Python, позволяющий создавать легковесные виртуальные окружения.
🟠virtualenv
Более функциональный инструмент, особенно полезный для старых версий Python.
🟠conda
Инструмент, который управляет как пакетами, так и виртуальными окружениями, поддерживающий не только Python, но и другие языки программирования.
1⃣Создание окружения
Команда для создания нового окружения (например, python -m venv env для venv).
2⃣Активация окружения
Команда для активации окружения (например, source env/bin/activate на Unix-подобных системах или .\env\Scripts\activate на Windows).
3⃣Установка зависимостей
Использование менеджера пакетов (например, pip) для установки необходимых библиотек.
4⃣Деактивация окружения
Команда для выхода из окружения (например, deactivate).
Ставь 👍 и 📚
@backendquiz
🤔 Какие есть уровни изоляции транзакций ?
Уровни изоляции транзакций определяют степень видимости изменений, сделанных одной транзакцией, для других параллельно выполняющихся транзакций. Они помогают контролировать влияние транзакций друг на друга и управляют различными типами аномалий, такими как "грязное" чтение, неповторяющееся чтение и фантомные чтения. В стандарте SQL-92 определены четыре уровня изоляции транзакций:
🚩Read Uncommitted (Чтение неподтвержденных данных)
Транзакция может видеть изменения, сделанные другими транзакциями, даже если эти изменения еще не были зафиксированы (не подтверждены).
🟠Грязное чтение (Dirty Read)
Транзакция может прочитать данные, которые были изменены другой транзакцией, но не были зафиксированы.
🟠Неповторяющееся чтение (Non-repeatable Read)
Транзакция может видеть разные значения данных при повторном чтении, если другая транзакция изменила эти данные и зафиксировала изменения.
🟠Фантомные чтения (Phantom Read)
Транзакция может видеть новые строки, добавленные другой транзакцией, при повторном выполнении запроса.
🚩Read Committed (Чтение подтвержденных данных)
Транзакция может видеть только изменения, которые были зафиксированы другими транзакциями. Неподтвержденные изменения не видны.
🟠Неповторяющееся чтение (Non-repeatable Read)
Транзакция может видеть разные значения данных при повторном чтении, если другая транзакция изменила и зафиксировала эти данные.
🟠Фантомные чтения (Phantom Read)
Транзакция может видеть новые строки, добавленные другой транзакцией, при повторном выполнении запроса.
🚩Repeatable Read (Повторяемое чтение)
Транзакция гарантирует, что если она прочитала данные в начале транзакции, эти данные останутся неизменными до конца транзакции. Транзакция не видит изменения данных, сделанные другими транзакциями после начала текущей транзакции.
Фантомные чтения (Phantom Read): Транзакция может видеть новые строки, добавленные другой транзакцией, при повторном выполнении запроса.
🚩Serializable (Сериализуемость)
Транзакция выполняется так, как если бы она была единственной, работающей в системе. Другие транзакции не могут добавлять, изменять или удалять данные, пока текущая транзакция не завершится. Это самый строгий уровень изоляции. Все аномалии (грязное чтение, неповторяющееся чтение, фантомные чтения) предотвращаются.
-- Установка уровня изоляции
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Пример на Java (использование JDBC)
connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Ставь 👍 и 📚
@backendquiz
🤔 Что такое MVVM?
Это архитектурный шаблон, который разделяет приложение на три части: Model (данные и логика), View (интерфейс) и ViewModel (связь между Model и View).
🚩Пример
Model
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
ViewModel
public class UserViewModel : INotifyPropertyChanged
{
private ObservableCollection _users;
public ObservableCollection Users
{
get { return _users; }
set
{
_users = value;
OnPropertyChanged(nameof(Users));
}
}
public UserViewModel()
{
Users = new ObservableCollection
{
new User { Name = "John Doe", Age = 30 },
new User { Name = "Jane Doe", Age = 25 }
};
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
View (XAML)
Код за View (Code-behind)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new UserViewModel();
}
}
Ставь 👍 и 📚
@backendquiz
🤔 Какие существуют нормальные формы в SQL?
Это процесс организации данных для минимизации избыточности и избегания аномалий при внесении данных. Нормальные формы (NF) — это набор правил, которые помогают в нормализации баз данных.
🟠Первая нормальная форма (1NF)
Таблица находится в 1NF, если: Все столбцы содержат атомарные значения, то есть каждое значение в столбце неделимо. Все строки уникальны, нет повторяющихся строк.
Пример: Если у вас есть таблица с заказами, и каждый заказ может содержать несколько продуктов, вместо хранения всех продуктов в одном столбце, нужно разбить их на отдельные строки.
🟠Вторая нормальная форма (2NF)
Таблица находится во 2NF, если: Она находится в 1NF. Все неключевые столбцы полностью зависят от всего первичного ключа, а не от его части.
Пример
Если в таблице "Заказы" у вас есть составной ключ (OrderID, ProductID), то столбцы, зависящие только от OrderID (например, OrderDate), должны быть вынесены в отдельную таблицу.
🟠Третья нормальная форма (3NF)
Таблица находится в 3NF, если: Она находится во 2NF. Все неключевые столбцы зависят только от первичного ключа, а не от других неключевых столбцов.
Пример
Если в таблице "Сотрудники" у вас есть столбцы EmployeeID, DepartmentID и DepartmentName, нужно вынести DepartmentName в отдельную таблицу "Департаменты", чтобы избежать зависимости между неключевыми столбцами.
🟠Бойс-Кодд нормальная форма (BCNF)
Таблица находится в BCNF, если: Она находится в 3NF. Для каждой функциональной зависимости X -> Y, X является суперключом.
Пример:
Если в таблице "Курс" есть зависимости (Professor, Course) -> Room и Room -> Capacity, необходимо реструктурировать таблицу так, чтобы не было зависимостей, где детерминанты не являются суперключами.
🟠Четвертая нормальная форма (4NF)
Таблица находится в 4NF, если: Она находится в BCNF. В ней нет многозначных зависимостей (Multivalued Dependencies).
Пример:
Если студент может записаться на несколько курсов и участвовать в нескольких клубах, то эти зависимости должны быть вынесены в отдельные таблицы.
🟠Пятая нормальная форма (5NF)
Таблица находится в 5NF, если: Она находится в 4NF. В ней нет соединительных зависимостей (Join Dependencies), которые нельзя разделить без потери данных.
Пример:
Если у вас есть сложные зависимости между несколькими таблицами, то нужно убедиться, что все соединения этих таблиц могут быть разложены обратно без потери информации.
🟠Доменино-ключевая нормальная форма (DKNF)
Таблица находится в DKNF, если: Все ограничения и зависимости выражаются только через домены и ключи таблицы, и отсутствуют аномалии при вставке, обновлении или удалении данных.
Ставь 👍 и 📚
@backendquiz
🤔 Расскажи про https
HTTPS (HyperText Transfer Protocol Secure) — это расширение протокола HTTP, используемое для безопасного обмена данными между веб-браузером и веб-сервером. HTTPS обеспечивает конфиденциальность, целостность и аутентичность передаваемых данных, используя шифрование, аутентификацию и проверку целостности.
🚩Основные аспекты HTTPS
🟠Шифрование: HTTPS использует шифрование для защиты данных, передаваемых между клиентом и сервером. Шифрование делает данные нечитаемыми для посторонних, предотвращая их перехват и кражу. Это достигается с помощью протоколов SSL (Secure Sockets Layer) и его преемника TLS (Transport Layer Security).
🟠Аутентификация: Аутентификация подтверждает, что клиент и сервер являются теми, за кого они себя выдают. Это предотвращает атаки типа "человек посередине" (man-in-the-middle attacks). Аутентификация осуществляется с помощью цифровых сертификатов, которые выдаются доверенными центрами сертификации (Certificate Authorities, CA).
🟠Целостность данных: Целостность данных гарантирует, что данные не были изменены во время передачи. Это достигается с помощью хеш-функций и контрольных сумм, которые проверяются на каждой стороне соединения.
🚩Как работает HTTPS
🟠Инициация соединения: Клиент (например, веб-браузер) инициирует соединение с сервером, отправляя HTTPS-запрос.
🟠Обмен сертификатами: Сервер отправляет клиенту свой цифровой сертификат. Сертификат содержит публичный ключ сервера и информацию о центре сертификации.
🟠Проверка сертификата: Клиент проверяет подлинность сертификата, используя список доверенных центров сертификации. Если сертификат действителен, клиент продолжает установку защищённого соединения.
🟠Установка сеансового ключа: Клиент и сервер договариваются о сеансовом ключе, используя асимметричное шифрование. Этот ключ будет использоваться для шифрования данных в течение сеанса.
🟠Шифрование данных: Данные передаются между клиентом и сервером в зашифрованном виде, что обеспечивает их конфиденциальность и целостность.
🚩Преимущества HTTPS
🟠Безопасность: HTTPS защищает данные от перехвата и подделки, что особенно важно для передачи конфиденциальной информации, такой как пароли и номера кредитных карт.
🟠Доверие пользователей: Наличие HTTPS повышает доверие пользователей к веб-сайту, так как современные браузеры отмечают сайты с HTTPS как безопасные.
🟠SEO (Поисковая оптимизация): Поисковые системы, такие как Google, отдают предпочтение сайтам с HTTPS и могут ранжировать их выше в результатах поиска.
🟠Соответствие стандартам: Многие нормативные акты и стандарты требуют использования HTTPS для защиты данных, например, GDPR в Европейском Союзе.
🚩Как настроить HTTPS
🟠Получение сертификата: Приобретите SSL/TLS сертификат у доверенного центра сертификации (CA) или используйте бесплатные сертификаты, такие как Let's Encrypt.
🟠Установка сертификата: Установите полученный сертификат на веб-сервер. Процесс установки зависит от используемого веб-сервера (например, Apache, Nginx, IIS).
🟠Настройка перенаправлений:Настройте сервер так, чтобы все HTTP-запросы перенаправлялись на HTTPS.
🟠Обновление ссылок и ресурсов: Убедитесь, что все ссылки и ресурсы на сайте используют HTTPS, чтобы избежать смешанного контента (mixed content), когда части страницы загружаются по HTTP.
Ставь 👍 и 📚
@backendquiz
🤔 В чём смысл инкапсуляции?
Один из основных принципов объектно-ориентированного программирования (ООП), наряду с наследованием и полиморфизмом. Смысл инкапсуляции заключается в объединении данных и методов, работающих с этими данными, в одном объекте, а также в ограничении доступа к этим данным из внешнего мира.
🚩Основные аспекты инкапсуляции
🟠Сокрытие данных
В инкапсуляции данные (свойства) объекта скрываются от внешнего доступа и защищаются от некорректных изменений. Это достигается путем использования модификаторов доступа (например, private, protected, public).
🟠Контролируемый доступ
Вместо прямого доступа к данным, предоставляются методы (геттеры и сеттеры) для чтения и изменения значений свойств. Это позволяет контролировать, каким образом данные могут быть изменены или получены.
🟠Защита целостности данных
Инкапсуляция помогает защитить внутреннее состояние объекта от некорректных или неожиданных изменений, обеспечивая целостность данных и уменьшая вероятность ошибок.
🚩Примеры инкапсуляции
На Java
public class Person {
private String name;
private int age;
// Конструктор
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Геттер для имени
public String getName() {
return name;
}
// Сеттер для имени
public void setName(String name) {
this.name = name;
}
// Геттер для возраста
public int getAge() {
return age;
}
// Сеттер для возраста
public void setAge(int age) {
if (age > 0) {
this.age = age;
} else {
System.out.println("Возраст должен быть положительным числом.");
}
}
}
На Python
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
# Геттер для имени
@property
def name(self):
return self._name
# Сеттер для имени
@name.setter
def name(self, name):
self._name = name
# Геттер для возраста
@property
def age(self):
return self._age
# Сеттер для возраста
@age.setter
def age(self, age):
if age > 0:
self._age = age
else:
print("Возраст должен быть положительным числом.")
# Пример использования
person = Person("John", 30)
print(person.name) # John
person.age = -5 # Возраст должен быть положительным числом.
print(person.age) # 30
Ставь 👍 и 📚
@backendquiz
🤔 Что такое Agile?
Это подход к разработке программного обеспечения, который фокусируется на гибкости, сотрудничестве и быстрой адаптации к изменениям. Agile основывается на следующих принципах и ценностях:
🚩Основные принципы
🟠Индивидуумы и взаимодействия важнее процессов и инструментов
Акцент на командную работу и эффективное общение.
🟠Работающее программное обеспечение важнее исчерпывающей документации
Быстрая поставка работающих продуктов с минимально необходимой документацией.
🟠Сотрудничество с заказчиком важнее согласования условий контракта
Постоянное взаимодействие с заказчиком для удовлетворения его потребностей.
🟠Готовность к изменениям важнее следования первоначальному плану
Гибкость в адаптации к изменениям требований и условий.
🚩Основные методологии
🟠Scrum
Итеративный процесс с фиксированными временными промежутками, называемыми спринтами. Роли: Product Owner, Scrum Master, Команда разработки. Артефакты: Product Backlog, Sprint Backlog, Инкремент. Встречи: Планирование спринта, Ежедневные стендап-совещания, Обзор спринта, Ретроспектива.
🟠Kanban
Визуализация процесса работы с помощью доски Kanban. Ограничение незавершенной работы (Work In Progress, WIP). Постоянное улучшение и адаптация.
🟠Extreme Programming (XP)
Практики: Парное программирование, Частые релизы, Непрерывная интеграция, Тестирование.
🟠Lean
Сокращение избыточности и увеличение ценности для клиента.- Принципы: Устранение потерь, Увеличение потока, Улучшение качества.
🚩Плюсы
➕Быстрая адаптация к изменениям
Возможность быстро реагировать на изменения требований или условий рынка.
➕Улучшенное качество продукта
Постоянное тестирование и интеграция.
➕Повышенная вовлеченность команды
Активное участие всех членов команды в процессе разработки.
➕Удовлетворенность клиентов
Постоянное взаимодействие с заказчиками и предоставление им ценности на каждом этапе разработки.
Ставь 👍 и 📚
@backendquiz
🤔 Что такое индексы?
Индексы в базе данных - это структуры, которые улучшают скорость операций поиска данных в таблице базы данных. Они работают по принципу, аналогичному указателю в книге, который позволяет быстро находить нужную информацию. Индексы создаются на одном или нескольких столбцах таблицы и позволяют значительно ускорить выполнение запросов, особенно при работе с большими объемами данных.
🚩Зачем нужны индексы
🟠Ускорение поиска данных
Основная функция индексов - это сокращение времени, необходимого для поиска записей в таблице. Без индексов база данных должна бы была проверять каждую запись, чтобы найти нужные данные.
🟠Улучшение производительности запросов
Индексы могут значительно повысить производительность запросов SELECT, особенно тех, которые часто выполняются.
🟠Сортировка данных
Индексы могут использоваться для ускорения операций сортировки, так как данные в индексе могут быть отсортированы.
🟠Уникальность
Индексы также используются для обеспечения уникальности значений в столбцах. Например, уникальный индекс гарантирует, что в столбце не будет повторяющихся значений.
🚩Как используются индексы
🟠Создание индексов
Индексы создаются с помощью SQL-запросов, таких как CREATE INDEX. Можно создавать индексы на один столбец или на несколько столбцов (составные индексы).
🟠Типы индексов
Существует несколько типов индексов, включая B-дерево, хеш-индексы, битмап-индексы и другие. Каждый тип имеет свои особенности и применяется в зависимости от конкретных задач.
🟠Использование индексов в запросах
При выполнении запросов база данных автоматически использует индексы для оптимизации поиска данных. Это не требует дополнительных действий со стороны пользователя.
🟠Обслуживание индексов
Важно понимать, что индексы требуют дополнительного пространства на диске и могут замедлять операции вставки, обновления и удаления данных, так как индексы нужно поддерживать в актуальном состоянии. Поэтому следует тщательно продумывать, какие индексы необходимы.
Ставь 👍 и 📚
@backendquiz
🤔 Для чего подходят асинхронные операции?
Асинхронные операции позволяют программам выполнять задачи в фоновом режиме, не блокируя основной поток выполнения. Это улучшает производительность и отзывчивость приложений.
🚩Методы
🟠Сетевое взаимодействие
HTTP-запросы: Асинхронные HTTP-запросы позволяют приложениям запрашивать данные у веб-серверов без блокировки пользовательского интерфейса. Например, загрузка данных из API, отправка форм и файлов. WebSockets: Поддержка двустороннего взаимодействия между клиентом и сервером в реальном времени. Это используется в чатах, онлайн-играх и других приложениях, где требуется мгновенная передача данных. API-вызовы: Асинхронные вызовы к внешним API позволяют продолжать выполнение других операций, не дожидаясь ответа от сервера.
🟠Ввод/вывод (I/O)
Файловые операции: Асинхронное чтение и запись файлов позволяет обрабатывать большие объемы данных без блокировки основного потока выполнения. Работа с базами данных: Асинхронные запросы к базам данных уменьшают время ожидания и улучшают масштабируемость приложения.
🟠Фоновые задачи и планирование
Обработка задач в фоне: Выполнение длительных задач, таких как обработка изображений, видео, данных, без блокировки основного потока. Это позволяет улучшить пользовательский опыт, так как приложение остается отзывчивым. Периодические задания: Планирование и выполнение задач по расписанию, например, обновление данных, резервное копирование, мониторинг системы.
🟠Пользовательские интерфейсы
Асинхронные события: Обработка событий пользовательского интерфейса (например, нажатие кнопок, ввод данных) асинхронно для повышения отзывчивости приложений. Анимации и переходы: Асинхронное выполнение анимаций и переходов улучшает пользовательский опыт за счет плавности и непрерывности интерфейса.
🟠Обработка потоков данных
Стриминг данных: Асинхронная обработка потоков данных в реальном времени, таких как видео, аудио, данные с датчиков. Это позволяет эффективно управлять непрерывными потоками информации. Реактивное программирование: Асинхронное реагирование на изменения данных и событий. Реактивные системы позволяют обрабатывать данные по мере их поступления, что особенно важно в приложениях, работающих с большим количеством данных.
🟠Обработка и анализ данных
Параллельные вычисления: Разделение больших задач на более мелкие части, которые выполняются параллельно. Это улучшает производительность при обработке больших объемов данных или выполнении сложных вычислений. Машинное обучение: Асинхронное обучение моделей и выполнение предсказаний позволяет эффективно использовать вычислительные ресурсы.
🚩Примеры использования
🟠Веб-приложения
Асинхронная обработка пользовательских запросов, выполнение сетевых операций и взаимодействие с базами данных для повышения производительности и отзывчивости.
🟠Мобильные приложения
Асинхронные операции обеспечивают плавную работу интерфейса и эффективное использование ресурсов при выполнении сетевых запросов и операций ввода/вывода.
🟠Игровая индустрия
Асинхронное взаимодействие с серверами, обработка событий пользователя и управление игровыми объектами в реальном времени.
🟠Научные вычисления
Параллельное выполнение вычислительных задач и обработка больших объемов данных для повышения эффективности исследований.
Ставь 👍 и 📚
@backendquiz
🤔 Какие связи с моделями в БД знаешь?
🚩"Один к одному" (One-to-One)
Каждая запись в одной таблице связана с одной и только одной записью в другой таблице.
Пользователь (User) и Паспорт (Passport)
Каждому пользователю соответствует один уникальный паспорт. В реляционных базах данных можно реализовать эту связь с помощью уникального внешнего ключа.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE passports (
id SERIAL PRIMARY KEY,
user_id INTEGER UNIQUE,
passport_number VARCHAR(50),
FOREIGN KEY (user_id) REFERENCES users(id)
);
🚩"Один ко многим" (One-to-Many)
Каждая запись в одной таблице может быть связана с несколькими записями в другой таблице, но каждая запись в другой таблице связана только с одной записью в первой таблице.
Пользователь (User) и Заказы (Orders)
Один пользователь может сделать много заказов, но каждый заказ связан с одним пользователем. Эта связь обычно реализуется с помощью внешнего ключа.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER,
order_date DATE,
FOREIGN KEY (user_id) REFERENCES users(id)
);
🚩"Многие ко многим" (Many-to-Many)
Каждая запись в одной таблице может быть связана с множеством записей в другой таблице, и наоборот.
Студенты (Students) и Курсы (Courses)
Один студент может записаться на множество курсов, и каждый курс может быть записан многими студентами. Эта связь обычно реализуется с помощью промежуточной таблицы (таблицы связи), которая содержит внешние ключи обеих связанных таблиц.
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
course_name VARCHAR(100)
);
CREATE TABLE student_courses (
student_id INTEGER,
course_id INTEGER,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (course_id) REFERENCES courses(id)
);
🚩Варианты связей в нереляционных базах данных (NoSQL)
В нереляционных базах данных связи могут быть организованы иначе, поскольку они часто не поддерживают традиционные реляционные модели.
Вложенные документы
Например, в MongoDB документы могут включать вложенные документы или массивы, что позволяет моделировать отношения "один ко многим" и "многие ко многим" внутри одного документа.
{
"_id": 1,
"name": "John",
"orders": [
{ "order_id": 1, "order_date": "2023-08-01" },
{ "order_id": 2, "order_date": "2023-08-05" }
]
}
Ставь 👍 и 📚
@backendquiz
🤔 Как с помощью одного запроса можно выбрать данные из двух таблиц?
Чтобы выбрать данные из двух таблиц в одном запросе, используется оператор JOIN. Например, INNER JOIN объединяет строки, где есть совпадения в обеих таблицах, а LEFT JOIN возвращает все строки из первой таблицы и соответствующие строки из второй, заполняя NULL там, где данных нет.
🚩Отличия между видами JOIN в SQL
В SQL существует несколько видов операторов JOIN, которые позволяют объединять данные из двух или более таблиц на основе определенных условий. Основные типы JOIN включают INNER JOIN, LEFT JOIN, RIGHT JOIN, и каждый из них имеет свои особенности и использование. Рассмотрим их различия на примере двух таблиц:
Таблица A:
id | name
-----------
1 | Alice
2 | Bob
3 | Charlie
Таблица B:
id | city
-----------
1 | New York
3 | Los Angeles
4 | Chicago
🟠INNER JOIN
INNER JOIN возвращает только те строки, которые имеют совпадения в обеих таблицах. Если нет совпадающих строк, такие строки не включаются в результат.
SELECT A.id, A.name, B.city
FROM A
INNER JOIN B ON A.id = B.id;
Результат:
id | name | city
------------------------
1 | Alice | New York
3 | Charlie | Los Angeles
🟠LEFT JOIN (или LEFT OUTER JOIN)
LEFT JOIN возвращает все строки из левой таблицы (A) и совпадающие строки из правой таблицы (B). Если совпадения не найдено, в результате будут строки из левой таблицы с NULL значениями для столбцов из правой таблицы.
SELECT A.id, A.name, B.city
FROM A
LEFT JOIN B ON A.id = B.id;
Результат:
id | name | city
------------------------
1 | Alice | New York
2 | Bob | NULL
3 | Charlie | Los Angeles
🟠RIGHT JOIN (или RIGHT OUTER JOIN)
RIGHT JOIN возвращает все строки из правой таблицы (B) и совпадающие строки из левой таблицы (A). Если совпадения не найдено, в результате будут строки из правой таблицы с NULL значениями для столбцов из левой таблицы.
SELECT A.id, A.name, B.city
FROM A
RIGHT JOIN B ON A.id = B.id;
Результат:
id | name | city
------------------------
1 | Alice | New York
3 | Charlie | Los Angeles
4 | NULL | Chicago
🟠FULL JOIN (или FULL OUTER JOIN)
FULL JOIN возвращает все строки, когда есть совпадение в одной из таблиц. Это объединение LEFT JOIN и RIGHT JOIN. Если совпадения не найдено, результат будет содержать NULL значения для столбцов из другой таблицы.
SELECT A.id, A.name, B.city
FROM A
FULL JOIN B ON A.id = B.id;
id | name | city
------------------------
1 | Alice | New York
2 | Bob | NULL
3 | Charlie | Los Angeles
4 | NULL | Chicago
Ставь 👍 и 📚
@backendquiz
🤔 Что такое SOAP?
Это протокол для обмена структурированными сообщениями в распределённых вычислительных средах. Он основан на XML и используется для передачи данных между различными приложениями через сеть, часто по протоколу HTTP или SMTP.
🚩Основные характеристики
🟠Протокол на основе XML
SOAP сообщения формируются в формате XML, что обеспечивает независимость от платформы и языка программирования.
🟠Стандартизованное сообщение
SOAP сообщение состоит из обязательных и необязательных элементов:
Envelope: Определяет начало и конец сообщения.
Header: Опциональный элемент, содержащий метаинформацию о сообщении.
Body: Основное содержимое сообщения, включающее данные и команды.
Fault: Опциональный элемент для обработки ошибок.
🟠Транспортные протоколы
Чаще всего используется с HTTP/HTTPS, но может работать и с другими протоколами, такими как SMTP.
🟠Расширяемость
SOAP легко расширяется, позволяя добавлять дополнительные функциональные возможности через заголовки и другие элементы.
🟠Независимость от платформы и языка
SOAP может быть использован в любой среде и на любом языке программирования, что обеспечивает высокую совместимость между различными системами.
Value1
Value2
🚩Плюсы
➕Независимость от платформы и языка
SOAP может взаимодействовать с любыми системами, поддерживающими XML и HTTP/SMTP.
➕Строгое соблюдение стандартов
SOAP основывается на строгих стандартах, что обеспечивает надежность и предсказуемость взаимодействия.
➕Расширяемость
Легко адаптируется для специфических потребностей через расширения и заголовки.
➕Встроенная обработка ошибок
Использует элемент Fault для детальной обработки и передачи ошибок.
➕Поддержка сложных операций
Подходит для сложных операций и распределённых транзакций.
🚩Минусы
➖Сложность
SOAP-сообщения могут быть сложными и громоздкими из-за использования XML.
➖Производительность
Использование XML увеличивает объем передаваемых данных, что может снизить производительность.
➖Оверхед
Требует дополнительных ресурсов для обработки и передачи XML-сообщений.
Ставь 👍 и 📚
@backendquiz
🤔 В чем разница char и varchar в SQL ?
Это два типа данных в SQL, которые используются для хранения строковых данных. Основные различия между ними касаются способа хранения данных и управления памятью.
🚩`CHAR` (Fixed-length Character Data)
🟠Фиксированная длина
CHAR(n) хранит строки фиксированной длины n. Если строка короче, она дополняется пробелами до указанной длины.
🟠Использование памяти
Использует фиксированное количество памяти, равное указанной длине n, независимо от фактической длины строки.
🟠Производительность
Может быть быстрее в некоторых случаях, так как длина строк фиксирована и известна заранее, что упрощает управление памятью.
🟠Пример использования
Подходит для хранения данных, которые всегда имеют одинаковую длину, например, коды стран, идентификаторы и т.д.
CREATE TABLE example (
fixed_char CHAR(10)
);
🚩`VARCHAR` (Variable-length Character Data)
🟠Переменная длина
VARCHAR(n) хранит строки переменной длины, где n — это максимальная длина строки. Реальная длина строки определяется по количеству символов в ней.
🟠Использование памяти
Использует только столько памяти, сколько необходимо для хранения фактической длины строки, плюс дополнительные байты для хранения информации о длине строки.
🟠Производительность
Может быть менее эффективным в некоторых случаях по сравнению с CHAR, так как длина строки не фиксирована и требует дополнительной обработки для управления памятью.
🟠Пример использования
Подходит для хранения данных, длина которых может варьироваться, например, имена, адреса, описания и т.д.
CREATE TABLE example (
variable_char VARCHAR(50)
);
Ставь 👍 и 📚
@backendquiz
🤔 Что такое rest api?
Это архитектурный стиль для создания веб-сервисов, который использует стандартные HTTP методы и принципы для взаимодействия между клиентом и сервером. REST API предоставляет набор операций для создания, чтения, обновления и удаления ресурсов, представленных в виде URL.
🚩Основные принципы REST API
🟠Клиент-серверная архитектура
Клиент и сервер отделены друг от друга. Клиент запрашивает ресурсы, сервер обрабатывает запросы и возвращает ресурсы или статус операции.
🟠Бесподсессионное взаимодействие (stateless)
Каждое взаимодействие между клиентом и сервером независимое. Сервер не хранит состояние клиента между запросами. Вся необходимая информация для выполнения запроса должна быть предоставлена в каждом запросе.
🟠Кеширование
Ответы сервера могут быть кешированы клиентом или промежуточными звеньями (прокси-серверами) для повышения производительности и снижения нагрузки на сервер.
🟠Единый интерфейс (Uniform Interface)
Универсальный интерфейс упрощает взаимодействие между клиентом и сервером. Основные методы HTTP (GET, POST, PUT, DELETE) используются для выполнения операций с ресурсами.
🟠Многоуровневая система
REST API может быть организован в виде многоуровневой системы, где компоненты выполняют разные задачи (например, балансировка нагрузки, кеширование, защита и т.д.).
🟠Представление ресурсов (Representations)
Ресурсы представляются в виде различных форматов (обычно JSON или XML). Клиент и сервер могут договариваться о формате данных через заголовки HTTP (например, Content-Type и Accept).
🚩Основные методы HTTP в REST API
🟠GET
Извлечение данных с сервера. Например, получение информации о пользователе.
🟠POST
Отправка данных на сервер для создания нового ресурса. Например, создание новой учетной записи пользователя.
🟠PUT
Обновление существующего ресурса на сервере. Например, обновление информации о пользователе.
🟠DELETE
Удаление ресурса с сервера. Например, удаление учетной записи пользователя.
🟠PATCH
Частичное обновление ресурса на сервере. Например, изменение только email пользователя.
🚩Примеры запроса и ответа
Запрос на создание нового пользователя (POST /users)
POST /users HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "John Doe",
"email": "john.doe@example.com"
}
Ответ на успешное создание пользователя
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
}
Ставь 👍 и 📚
@backendquiz
🤔 Принципы разделения ответственности (MVC, MVVM и другие)?
Принципы разделения ответственности (Separation of Concerns, SoC) предполагают разделение логики программы на отдельные части, каждая из которых выполняет строго определённую функцию. Это позволяет сделать код более структурированным, гибким и легче сопровождаемым. Популярные паттерны проектирования, основанные на разделении ответственности, включают MVC, MVP, MVVM и другие. Они применяются в разработке приложений для чёткого разграничения пользовательского интерфейса, бизнес-логики и работы с данными.
🚩MVC (Model-View-Controller)
🟠Model (Модель)
Хранит данные и логику их обработки. Отвечает за взаимодействие с базой данных или другими источниками данных. Уведомляет представление об изменениях данных.
🟠View (Представление)
Отображает данные пользователю. Реагирует на обновления данных от модели. Не содержит логики обработки данных.
🟠Controller (Контроллер)
Обрабатывает пользовательский ввод (например, нажатия кнопок, ввод текста). Вызывает соответствующие методы модели и обновляет представление.
🚩Плюсы и минусы
➕Хорошее разделение обязанностей.
➕Легче тестировать отдельные компоненты.
➖При большом приложении контроллер может стать перегруженным.
🚩MVP (Model-View-Presenter)
🟠Model (Модель)
Работает с данными и бизнес-логикой.
🟠View (Представление)
Интерфейс пользователя. Не содержит логики, только вызывает методы презентера.
🟠Presenter (Презентер)
Посредник между моделью и представлением. Получает данные из модели и передаёт их в представление. Не знает деталей реализации интерфейса (только абстракция).
Плюсы и минусы
➕Более чёткое разделение обязанностей по сравнению с MVC.
➕Упрощённое тестирование.
➖Возможен рост сложности презентера.
🚩MVVM (Model-View-ViewModel)
🟠Model (Модель)
Управляет данными и бизнес-логикой.
🟠View (Представление)
Отображает данные и предоставляет интерфейс для взаимодействия.
🟠ViewModel
Посредник между моделью и представлением. Содержит логику преобразования данных для представления. Часто использует привязку данных (data binding), что позволяет автоматически обновлять UI при изменении данных.
Плюсы и минусы
➕Простота взаимодействия между представлением и данными.
➕Легко тестировать ViewModel.
➖Возможна сложность с реализацией привязки данных.
🚩Flux/Redux
🟠Store (Хранилище)
Централизованное состояние приложения.
🟠View (Представление)
Компоненты, которые отображают состояние.
🟠Actions (Действия)
Описывают, какие изменения должны произойти в состоянии.
🟠Reducers (Редьюсеры)
Функции, описывающие, как изменяется состояние на основе действий.
Плюсы и минусы
➕Прогнозируемость состояния.
➕Централизованное управление состоянием.
➖Дополнительная сложность при реализации.
🚩Чем полезны принципы разделения ответственности
🟠Упрощение тестирования
можно тестировать компоненты независимо друг от друга.
🟠Повышение читаемости
код проще понять и сопровождать.
🟠Повторное использование кода
компоненты можно использовать в других частях приложения.
🟠Гибкость в разработке
команда может работать над разными частями параллельно.
Ставь 👍 и 📚
@backendquiz
🤔 Что такое модульное программирование?
Это подход к разработке программного обеспечения, при котором приложение разбивается на независимые, взаимосвязанные части, называемые модулями. Каждый модуль отвечает за выполнение определенной функции или набора функций, что делает программу более структурированной, управляемой и легко поддерживаемой.
🚩Характеристики
🟠Инкапсуляция
Каждый модуль скрывает свою внутреннюю реализацию и предоставляет четко определенный интерфейс для взаимодействия с другими модулями. Это уменьшает зависимость между модулями и улучшает устойчивость к изменениям.
🟠Разделение ответственности
Принцип единственной ответственности применяется к модулям, что означает, что каждый модуль отвечает за выполнение одной конкретной задачи или группы тесно связанных задач.
🟠Повторное использование
Модули могут быть повторно использованы в других частях программы или в других проектах, что уменьшает дублирование кода и облегчает его поддержку.
🟠Управляемость и масштабируемость
Разделение программы на модули облегчает управление проектом и его масштабирование. Изменения в одном модуле обычно не требуют изменений в других модулях, что ускоряет разработку и тестирование.
🚩Плюсы
➕Упрощенная отладка и тестирование
Так как модули изолированы друг от друга, их можно тестировать и отлаживать независимо. Это облегчает нахождение и исправление ошибок.
➕Повышенная читаемость и поддерживаемость кода
Разделение кода на небольшие, управляемые части улучшает его структуру и упрощает понимание и поддержку.
➕Ускорение разработки
Разные команды могут работать над разными модулями параллельно, что ускоряет процесс разработки.
➕Легкость вносить изменения и улучшения
Изменения в одном модуле не оказывают значительного влияния на другие модули, что облегчает внедрение новых функций и улучшений.
🚩Примеры применения
🟠Функциональные библиотеки
Модули могут быть оформлены как библиотеки функций, которые предоставляют определенные функциональные возможности, например, работа с файлами, обработка строк или взаимодействие с базами данных.
🟠Классы и объекты в ООП
В объектно-ориентированном программировании классы и объекты можно рассматривать как модули, инкапсулирующие данные и методы.
🟠Модули и пакеты в языках программирования
Многие языки программирования поддерживают концепцию модулей и пакетов, например, модули в Python, пакеты в Java и модули в ECMAScript (JavaScript).
На Python
# file: math_operations.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# file: main.py
import math_operations
x = 10
y = 5
print("Addition:", math_operations.add(x, y))
print("Subtraction:", math_operations.subtract(x, y))
На JavaScript
// file: mathOperations.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// file: main.js
import { add, subtract } from './mathOperations.js';
const x = 10;
const y = 5;
console.log('Addition:', add(x, y));
console.log('Subtraction:', subtract(x, y));
Ставь 👍 и 📚
@backendquiz
🤔 Что такое CD (Continuous Delivery / Continuous Deployment)?
Это практика автоматизации и оптимизации процессов доставки приложений и их обновлений в рабочую среду. Она является частью DevOps-подхода и тесно связана с CI (Continuous Integration).
🚩Два основных значения CD
🟠Continuous Delivery (Непрерывная доставка)
Continuous Delivery подразумевает автоматизацию процессов сборки, тестирования и подготовки приложения к выпуску в продакшн. Однако процесс развертывания остаётся ручным, чтобы команда могла контролировать его выполнение. Ключевые особенности:
Автоматическое развертывание приложения в тестовые и предрелизные среды.
Возможность развернуть приложение в продакшн в любой момент с минимальными усилиями.
Финальное решение о развертывании принимает человек.
Цель: Быть готовым к безопасному и быстрому выпуску обновлений в любой момент.
Пример использования:
В интернет-магазине обновление функционала сначала разворачивается в тестовой среде. После успешной проверки QA-командой или бизнес-менеджером приложение вручную переносится в продакшн.
🟠Continuous Deployment (Непрерывное развертывание)
Continuous Deployment идёт дальше Continuous Delivery, автоматически развертывая обновления в продакшн после успешного прохождения всех тестов. Процесс полностью автоматизирован и исключает ручное вмешательство. Ключевые особенности:
Абсолютная автоматизация — каждый подтверждённый код (коммит) автоматически попадает в продакшн.
Постоянный выпуск обновлений, минимизирующий разницу между разработкой и рабочей средой.
Цель: Сократить время доставки функционала и исправлений до продакшна, обеспечивая быстрые релизы.
Пример использования:
В приложении социальной сети любые изменения (например, исправление ошибки или добавление нового поста) автоматически проходят через CI/CD pipeline и попадают в продакшн.
🚩Ключевые элементы CD
🟠CI/CD Pipeline
Автоматизированный процесс, включающий сборку, тестирование, развертывание.
🟠Тестирование
Юнит-тесты.
Интеграционные тесты.
Нагрузочные тесты.
Проверка безопасности.
🟠Оркестрация и управление
Использование инструментов (Jenkins, GitLab CI/CD, CircleCI, GitHub Actions). Контейнеризация (Docker, Kubernetes).
🟠Мониторинг
Автоматическое отслеживание работоспособности приложений (Prometheus, Grafana).
🚩Плюсы
➕Скорость
Ускоряет доставку новых функций и исправлений.
➕Качество
Раннее выявление ошибок благодаря автоматическим тестам.
➕Прозрачность
Процесс развертывания становится понятным для всей команды.
➕Гибкость
Возможность быстро реагировать на изменения требований.
Ставь 👍 и 📚
@backendquiz
🤔 Как обнаружить самые затратные запросы?
Обнаружение самых затратных запросов важно для оптимизации производительности базы данных. Затратные запросы могут потреблять больше ресурсов, чем необходимо, что приводит к увеличению времени выполнения, нагрузке на сервер и замедлению работы системы. Существует несколько подходов и инструментов для выявления таких запросов.
🚩Включение логирования медленных запросов (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;
Ставь 👍 и 📚
@backendquiz
🤔Как определить, что у кода плохая организация?
Плохая организация кода — это один из главных факторов, который делает поддержку и развитие проекта сложными. Определить, что код плохо организован, можно по следующим признакам:
🟠Отсутствие структуры
- Файлы и каталоги разбросаны хаотично.
- Код находится в одном огромном файле без логического разделения.
- Нет четкой модулярности (всё смешано в одном месте).
🟠Дублирование кода
- Один и тот же фрагмент кода повторяется в разных местах вместо вынесения в отдельные функции или классы.
- При внесении изменений приходится исправлять одну и ту же логику в нескольких местах.
🟠Чрезмерная сложность
- Функции или методы слишком длинные и делают слишком много.
- Код трудно читать из-за вложенных конструкций (if, for, while и т. д.).
- Используются сложные алгоритмы там, где можно было бы обойтись более простыми.
🟠Нарушение принципов SOLID
- Один класс выполняет несколько задач (нарушение *Single Responsibility Principle*).
- Сильная зависимость между модулями (нарушение *Dependency Inversion Principle*).
- Проблемы с расширяемостью кода.
🟠Плохие наименования переменных, функций и классов
- Используются непонятные или слишком короткие названия (a, x1, doSomething).
- Название не отражает суть выполняемой операции.
🟠Отсутствие или избыточная документация
- Если документации нет, код сложно понять.
- Если документации слишком много, и она не актуальна, это также мешает.
🟠Сильная связанность (high coupling)
- Компоненты сильно зависят друг от друга, что усложняет тестирование и внесение изменений.
- Модули не могут использоваться независимо.
🟠Отсутствие тестов
- Если код сложно протестировать, это признак плохой организации.
- Нет юнит-тестов или они покрывают только тривиальные случаи.
🟠Отсутствие обработчиков ошибок
- Ошибки не логируются, а просто подавляются (try...catch с пустым catch).
- Ошибки обрабатываются хаотично.
🟠Проблемы с производительностью
- Избыточное потребление памяти или процессорных ресурсов из-за неоптимальных алгоритмов.
- Использование ненужных циклов, повторные вызовы функций.
Ставь 👍 и 📚
@backendquiz
🤔 Почему goto — это зло?
goto считается "злом" в программировании по ряду причин, связанных с читаемостью, поддерживаемостью и структурой кода. Давайте разберем основные причины, почему его избегают.
🟠Сложность чтения и отладки
Когда в коде используются операторы goto, управление программой может перескакивать из одного места в другое, иногда даже обратно. Это делает код трудно читаемым и практически невозможным для быстрого понимания. Отладка кода с goto затруднена, так как выполнение может переходить в неожиданные участки программы, что усложняет поиск ошибок.
🟠Разрушение структурного программирования
Одним из ключевых достижений программирования стало структурное программирование, предложенное в 1960-х годах. Оно основывается на трех базовых конструкциях:
Последовательность (команды выполняются одна за другой),
Разветвление (if-else, switch),
Циклы (for, while, do-while). Использование goto нарушает эту структуру, что приводит к так называемому "спагетти-коду", где невозможно понять, в каком порядке выполняются инструкции.
🟠Альтернативы `goto`
Вместо goto в большинстве случаев можно использовать:
Циклы (for, while, do-while) – для повторяющихся действий.
Рекурсию – если нужна сложная логика выполнения.
Исключения (try-catch) – для обработки ошибок, вместо goto для выхода из глубоко вложенных структур.
Флаги и условные операторы – когда нужно контролировать выход из определенного блока кода.
🟠Когда `goto` все же оправдан?
Несмотря на его репутацию, goto может быть полезен в низкоуровневом программировании, например:
В коде на C для обработки ошибок (например, единый выход из функции в драйверах ОС).
В компиляхторах или интерпретаторах языков программирования.
В ASM-вставках, где goto заменяется на jmp.
Ставь 👍 и 📚
@backendquiz
