Common Questions Flashcards

1
Q
  1. В чем суть ООП и каковы его основные принципы.
A

Объектно-ориентированное программирование (ООП) — это подход, при котором программа рассматривается как набор объектов, взаимодействующих друг с другом. Основные принципы: инкапсуляция, наследование, абстракция, полиморфизм.
Абстрагирование — это способ выделить набор наиболее важных атрибутов и методов и исключить незначимые.
Инкапсуляция – каждый объект является независимой структурой. Все, что ему нужно для работы, уже есть у него внутри. Если он пользуется какой-то переменной, она будет описана в теле объекта, а не снаружи в коде. Это делает объекты более гибкими. Даже если внешний код перепишут, логика работы не изменится.
Инкапсуляция помогает с легкостью управлять кодом. Для обращения к объекту не нужно понимать, как работают его методы. Внутреннее устройство одного объекта закрыто от других: извне «видны» только значения атрибутов и результаты выполнения методов.
Наследование
Можно создавать классы и объекты, которые похожи друг на друга, но немного отличаются — имеют дополнительные атрибуты и методы. Более общее понятие в таком случае становится «родителем», а более специфичное и подробное — «наследником».
Полиморфизм
Одинаковые методы разных объектов могут выполнять задачи разными способами. Например, у «человека» есть метод «работать». У «программиста» реализация этого метода будет означать написание кода, а у «директора» — рассмотрение управленческих вопросов. Но глобально и то, и другое будет работой.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q
  1. В чем суть полиморфизма.
A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q
  1. Принцип SOLID.
A

SOLID — это набор принципов объектно-ориентированного программирования, которые помогают создавать более гибкие, понятные и сопровождаемые системы.
1. Принцип единственной ответственности (Single Responsibility Principle, SRP):
o Суть: Каждый класс должен отвечать за что-то одно.
o Простыми словами: У каждого класса должна быть только одна причина для изменения.
o Пример: Если у нас есть класс, который отвечает за работу с пользователями (User), то он не должен также заниматься отправкой email. Для этого должен быть отдельный класс.
2. Принцип открытости/закрытости (Open/Closed Principle, OCP):
o Суть: Программные сущности должны быть открыты для расширения, но закрыты для изменения.
o Простыми словами: Можно добавлять новое поведение в систему, но нельзя изменять существующий код.
o Пример: Если нужно добавить новый тип фигуры в программу, которая считает площади фигур, не нужно менять существующие классы. Вместо этого добавляется новый класс для новой фигуры.
3. Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP):
o Суть: Объекты наследуемых классов должны быть взаимозаменяемы с объектами базового класса.
o Простыми словами: Дочерний класс должен дополнять, а не изменять поведение базового класса.
o Пример: Если у вас есть класс “Птица” с методом “летать”, то класс “Пингвин” не должен наследоваться от “Птица”, так как пингвины не летают.
4. Принцип разделения интерфейса (Interface Segregation Principle, ISP):
o Суть: Клиенты не должны зависеть от интерфейсов, которые они не используют.
o Простыми словами: Лучше иметь несколько специфических интерфейсов, чем один общий.
o Пример: Вместо одного большого интерфейса, содержащего методы для печати, сканирования и копирования, лучше создать отдельные интерфейсы для каждого действия.
5. Принцип инверсии зависимостей (Dependency Inversion Principle, DIP):
o Суть: Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба типа модулей должны зависеть от абстракций.
o Простыми словами: Зависимости должны быть направлены на абстракции, а не на конкретные реализации.
o Пример: Вместо того чтобы класс использовал конкретный объект базы данных, он должен работать с интерфейсом базы данных. Это позволяет легко заменить одну базу данных на другую.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q
  1. Что такое Dependency Injection и зачем он нужен.
A

Dependency Injection (инъекция зависимостей) — это техника, используемая в программировании для передачи зависимостей объекта извне, а не создавать их внутри объекта. Это помогает сделать код более гибким и тестируемым.
Зачем это нужно?
1. Повышение тестируемости:
o При использовании инъекции зависимостей можно легко заменить реальные зависимости (например, базу данных) на фиктивные (mock-объекты) во время тестирования.
2. Ослабление связи между компонентами:
o Объекты не создают свои зависимости самостоятельно, а получают их извне. Это снижает связность кода, что упрощает его изменение и поддержку.
3. Улучшение гибкости и расширяемости:
o При необходимости изменения зависимости (например, смена типа базы данных), можно просто заменить одну реализацию на другую без изменения самого объекта.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q
  1. DI Lifetime
A

В контексте инъекции зависимостей (Dependency Injection), lifetime (время жизни) зависимостей определяет, как долго объект (зависимость) существует в приложении. Разные фреймворки и контейнеры внедрения зависимостей могут поддерживать различные лайфтаймы. Вот основные типы времени жизни зависимостей:
1. Transient (Кратковременный):
o Описание: Объект создается каждый раз при запросе зависимости.
o Пример: Если класс UserService зависит от класса Logger, то каждый раз при создании нового объекта UserService будет создаваться новый объект Logger.
o Использование: Когда зависимость легковесная и не требует значительных ресурсов для создания. Подходит для объектов, которые не должны разделять состояние.
2. Scoped (Область видимости):
o Описание: Объект создается один раз на каждый запрос (или сессию).
o Пример: В веб-приложениях объект может создаваться один раз на каждый HTTP-запрос.
o Использование: Когда необходимо разделить состояние между объектами в пределах одного запроса или сессии, но не между различными запросами.
3. Singleton (Одиночка):
o Описание: Объект создается один раз и используется на протяжении всего времени жизни приложения.
o Пример: Если класс Configuration содержит настройки приложения, то он может быть создан один раз при старте приложения и использоваться везде.
o Использование: Для зависимостей, которые требуют значительных ресурсов для создания или содержат состояние, которое должно быть разделено между всеми частями приложения.
4. Per-Thread (На поток):
o Описание: Объект создается один раз на поток.
o Пример: В многопоточных приложениях, где нужно иметь отдельные экземпляры зависимости для каждого потока.
o Использование: Когда нужно, чтобы каждый поток имел свою версию зависимости, часто используется в многопоточном программировании.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q
  1. Принципы KISS, YAGNI, DRY.
A

KISS (Keep It Simple, Stupid)
Пояснение:
* Суть: Принцип KISS призывает к тому, чтобы системы, коды и процессы оставались максимально простыми и понятными.
* Почему это важно: Чем проще код, тем легче его читать, понимать, сопровождать и изменять. Сложные решения увеличивают вероятность ошибок и делают поддержку кода трудоемкой.
* Пример: Вместо написания сложного алгоритма, который трудно понять, следует использовать более простое и очевидное решение, даже если оно менее эффективно.
YAGNI (You Aren’t Gonna Need It)
Пояснение:
* Суть: Принцип YAGNI утверждает, что не следует добавлять функциональность до тех пор, пока она действительно не понадобится.
* Почему это важно: Добавление ненужного функционала увеличивает сложность кода, делает его труднее тестируемым и сопровождаемым, а также может привести к техническому долгу.
* Пример: Не стоит заранее добавлять методы или классы, которые могут понадобиться в будущем. Если нет конкретной необходимости здесь и сейчас, лучше отложить их создание до того момента, когда это действительно будет нужно.
DRY (Don’t Repeat Yourself)
Пояснение:
* Суть: Принцип DRY говорит о том, что повторение кода следует избегать. Каждый фрагмент информации должен быть представлен в системе единожды.
* Почему это важно: Повторяющийся код усложняет его поддержку и тестирование. Если в одном месте потребуется изменение, нужно будет найти и изменить все повторяющиеся фрагменты, что увеличивает риск ошибок.
* Пример: Вместо того чтобы копировать и вставлять одинаковый код в разных частях программы, следует вынести этот код в отдельный метод или класс и использовать его повторно.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q
  1. Какие существуют паттерны, какие паттерны применял. В чем их суть и польза.
A

Паттерн Strategy (Стратегия) — это поведенческий паттерн проектирования, который позволяет определять семейство алгоритмов, инкапсулировать каждый из них и делать их взаимозаменяемыми. Паттерн Strategy позволяет изменять алгоритмы независимо от клиентов, которые их используют.

Основная идея
Паттерн Strategy предлагает вынести изменяющиеся алгоритмы и бизнес-логику из основного класса и инкапсулировать их в отдельные классы, которые реализуют общий интерфейс. Это позволяет динамически изменять поведение объекта, не изменяя его код.

Преимущества паттерна Strategy

Замена алгоритмов на лету: Позволяет динамически изменять алгоритмы, не меняя код клиента.

Принцип открытости/закрытости: Позволяет добавлять новые алгоритмы без изменения существующего кода.

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

Недостатки паттерна Strategy

Усложнение кода: Добавление новых классов для каждой стратегии может усложнить код и сделать его менее удобным для чтения.

Выбор стратегии: Клиент должен знать, какие стратегии существуют, и уметь выбирать между ними.

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

Сортировка: Различные алгоритмы сортировки (быстрая сортировка, сортировка слиянием, сортировка пузырьком) могут быть реализованы как стратегии.

Кеширование: Различные стратегии кеширования (кеширование в памяти, кеширование на диске, распределенное кеширование).

Шифрование: Различные алгоритмы шифрования (AES, RSA, Blowfish) могут быть реализованы как стратегии.

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

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

Основная идея

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

Применимость

Паттерн Facade используется, когда:

Нужно предоставить простой интерфейс для сложной подсистемы.

Существует множество зависимых классов или сложных взаимодействий между ними.

Нужно уменьшить количество зависимостей между клиентами и подсистемой.

Преимущества паттерна Facade

Упрощение интерфейса: Фасад предоставляет упрощенный интерфейс для взаимодействия с подсистемой, скрывая ее сложность.

Снижение зависимости: Клиенты зависят только от фасада, а не от множества классов подсистемы.

Разделение кода: Позволяет разделить систему на подсистемы, каждая из которых может быть проще и независимой.

Недостатки паттерна Facade

Ограниченная функциональность: Фасад может не предоставить всю функциональность подсистемы, ограничивая возможности клиента.

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

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

Основная идея

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

Преимущества паттерна Abstract Factory

Изоляция конкретных классов: Клиентский код работает с абстрактными интерфейсами и не зависит от конкретных классов продуктов.

Легкость замены семейств продуктов: Можно легко заменить одно семейство продуктов на другое, изменив используемую фабрику.

Согласованность продуктов: Гарантируется, что созданные продукты будут совместимы друг с другом.

Недостатки паттерна Abstract Factory

Сложность в добавлении новых продуктов: Если необходимо добавить новый тип продукта, нужно изменить интерфейс абстрактной фабрики и все конкретные фабрики.

Большое количество классов: Добавление новых фабрик и продуктов может привести к увеличению количества классов, что усложняет структуру кода.

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

GUI библиотеки: Создание компонентов пользовательского интерфейса для различных платформ (Windows, MacOS, Linux).

Подключение к базам данных: Создание объектов подключения, команд и чтения данных для различных СУБД (SQL Server, MySQL, PostgreSQL).

Системы обработки документов: Создание различных форматов документов (PDF, DOCX, HTML).

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
  1. Отличие Abstract Factory от Factory Method.
A

Abstract Factory – это объект, а Factory Method – это метод. Соответственно, метод можно переопределить в производном классе, чтобы он возвращал что-то другое (например, другую реализацию интерфейса)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q
  1. Отличие Adapter от Proxy.
A

Ключевые отличия:
1. Назначение:
o Adapter: Преобразует интерфейс одного класса в интерфейс другого. Цель — обеспечить совместимость между несовместимыми интерфейсами.
o Proxy: Контролирует доступ к объекту, предоставляя дополнительные операции перед или после вызова реального объекта. Цель — управление доступом к объекту.
2. Использование:
o Adapter: Используется, когда нужно интегрировать старую систему с новой или когда интерфейсы не совпадают.
o Proxy: Используется, когда нужно добавлять функциональность, такую как кэширование, логирование, контроль доступа, без изменения реального объекта.
3. Типы Proxy:
o Remote Proxy: Представляет объект, находящийся в другом адресном пространстве.
o Virtual Proxy: Контролирует доступ к ресурсу, создание которого дорого стоит.
o Protection Proxy: Контролирует доступ к ресурсу на основе прав доступа.
o Smart Proxy: Добавляет дополнительное поведение к реальному объекту.
В итоге, Adapter и Proxy решают разные задачи: Adapter обеспечивает совместимость интерфейсов, а Proxy контролирует доступ и добавляет функциональность к объекту.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
  1. Какие существую антипаттерны. Почему их следует избегать.
A
  1. Spaghetti Code (Спагетти-код)
    Описание: Код, в котором отсутствует структура и порядок, что делает его трудным для понимания и сопровождения.
    Проблемы: Трудности в чтении, понимании и изменении кода. Увеличивается вероятность ошибок.
  2. God Object (Объект-бог)
    Описание: Класс, который знает слишком много или делает слишком много. Он нарушает принцип единственной ответственности (SRP).
    Проблемы: Трудности в сопровождении и тестировании, высокая связанность, низкая модульность.
  3. Golden Hammer (Золотой молоток)
    Описание: Использование одного и того же инструмента или технологии для решения всех задач, независимо от того, подходит ли этот инструмент для конкретной задачи.
    Проблемы: Неправильное использование инструментов, снижение эффективности.
  4. Premature Optimization (Преждевременная оптимизация)
    Описание: Оптимизация кода до того, как станет понятно, что именно требует оптимизации. Это может усложнить код и уменьшить его читаемость.
    Проблемы: Усложнение кода, меньшая гибкость.
  5. Magic Numbers (Магические числа)
    Описание: Использование числовых значений непосредственно в коде, вместо использования именованных констант или перечислений.
    Проблемы: Непонимание значения чисел, трудности в изменении.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
  1. Какие существуют типы тестов.
A

По цели тестирования:
1. Функциональное тестирование — проверка того, как приложение выполняет свои функции согласно требованиям.
o Модульное тестирование (Unit Testing) — тестирование отдельных модулей или компонентов системы.
o Интеграционное тестирование (Integration Testing) — проверка взаимодействия между модулями.
o Системное тестирование (System Testing) — тестирование всей системы как единого целого.
o Приемочное тестирование (Acceptance Testing) — проверка соответствия системы требованиям пользователя.
o Регрессионное тестирование (Regression Testing) — проверка того, что изменения в коде не нарушили существующую функциональность.
2. Нефункциональное тестирование — проверка нематериальных аспектов системы.
o Тестирование производительности (Performance Testing) — проверка времени отклика, пропускной способности и других параметров.
 Тестирование нагрузки (Load Testing) — проверка работы системы под ожидаемой нагрузкой.
 Тестирование стрессов (Stress Testing) — проверка системы при экстремальных условиях.
 Тестирование стабильности (Stability Testing) — проверка работы системы в течение длительного времени.
o Тестирование безопасности (Security Testing) — проверка на уязвимости, безопасность данных и защиту от угроз.
o Тестирование удобства использования (Usability Testing) — оценка удобства интерфейса и пользовательского опыта.
o Тестирование совместимости (Compatibility Testing) — проверка работы приложения в различных окружениях, включая операционные системы, браузеры и устройства.
По методу тестирования:
1. Черный ящик (Black-Box Testing) — тестирование без учета внутренней структуры кода. Тестировщик проверяет только входные и выходные данные.
2. Белый ящик (White-Box Testing) — тестирование с учетом внутренней структуры кода. Оценивается работа алгоритмов и логики.
3. Серый ящик (Gray-Box Testing) — комбинация черного и белого ящика. Тестировщик имеет частичное знание о внутренней структуре системы.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
  1. Что такое Mock, Stub.
A

Основные различия:
* Stub: Используется для предоставления предопределенных данных. Он не проверяет, как объект используется, а просто возвращает данные, которые задаются в тесте.
* Mock: Не только предоставляет данные, но и проверяет, как взаимодействие происходит (например, какие методы были вызваны и с какими параметрами).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q
  1. Отличие аутентификации от авторизации.
A

Аутентификация — это процесс проверки подлинности пользователя. Он позволяет системе убедиться, что пользователь действительно тот, за кого себя выдаёт. В ходе аутентификации пользователь предоставляет свои учетные данные (например, логин и пароль, отпечаток пальца, или одноразовый код из SMS), и система проверяет их на соответствие с ранее зарегистрированными данными. Примеры аутентификации:
* Ввод логина и пароля.
* Использование биометрических данных, таких как отпечаток пальца или распознавание лица.
* Двухфакторная аутентификация (например, пароль + код из SMS).
Авторизация — это процесс определения прав и полномочий пользователя, который уже прошел аутентификацию. Он позволяет системе решить, к каким ресурсам или операциям пользователь имеет доступ. Авторизация отвечает на вопрос: “Что пользователь может делать?”. Примеры авторизации:
* Пользователь имеет право просматривать, редактировать или удалять определенные данные.
* Пользователь может доступаться только к определенным разделам системы.
* Пользователь имеет определенные роли, которые определяют его полномочия (например, администратор, редактор, просмотрщик).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q
  1. Какие есть UML диаграммы.
A

UML (Unified Modeling Language) — это стандартный язык для моделирования программных систем. UML предлагает несколько типов диаграмм, которые можно разделить на две основные категории: диаграммы структуры и диаграммы поведения.
Диаграммы структуры
1. Диаграмма классов (Class Diagram):
o Отображает классы системы и их взаимосвязи.
o Показывает атрибуты и методы классов, а также отношения между ними (наследование, ассоциации, агрегация, композиция).
2. Диаграмма объектов (Object Diagram):
o Показывает экземпляры классов (объекты) в определенный момент времени.
o Визуализирует конкретное состояние системы.
3. Диаграмма компонентов (Component Diagram):
o Моделирует физическую структуру кода в терминах компонентов.
o Показывает зависимости между компонентами.
4. Диаграмма развёртывания (Deployment Diagram):
o Отображает физическое расположение узлов и артефактов в системе.
o Показывает, на каких машинах и как программные компоненты размещены.
5. Диаграмма пакетов (Package Diagram):
o Группирует элементы модели в пакеты и показывает зависимости между ними.
o Упрощает управление большими системами.
6. Диаграмма профилей (Profile Diagram):
o Расширяет UML для специфических доменов.
o Используется для создания стереотипов, тегированных значений и ограничений.
Диаграммы поведения
1. Диаграмма прецедентов (Use Case Diagram):
o Моделирует функциональные требования к системе.
o Показывает акторов (пользователей или внешние системы) и их взаимодействие с системой через прецеденты (use cases).
2. Диаграмма активности (Activity Diagram):
o Моделирует рабочие процессы и действия внутри системы.
o Показывает последовательность действий и их логические ветвления.
3. Диаграмма состояний (State Machine Diagram):
o Описывает состояния объекта и переходы между ними в ответ на события.
o Используется для моделирования поведения объектов в зависимости от их состояния.
4. Диаграмма последовательности (Sequence Diagram):
o Отображает взаимодействие объектов во времени.
o Показывает последовательность обмена сообщениями между объектами для выполнения конкретного функционала.
5. Диаграмма кооперации (Communication Diagram):
o Фокусируется на структурной организации взаимодействия объектов.
o Показывает, какие объекты взаимодействуют и как они связаны.
6. Диаграмма временных характеристик (Timing Diagram):
o Отображает изменения состояния или значений объектов во времени.
o Используется для анализа временных аспектов взаимодействия объектов.
7. Диаграмма компонентов взаимодействия (Interaction Overview Diagram):
o Комбинирует элементы диаграмм активности и диаграмм последовательности.
o Позволяет моделировать сложные взаимодействия и их контрольный поток.
Каждая из этих диаграмм используется для моделирования различных аспектов системы и помогает в разработке, анализе и документировании сложных программных систем.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q
  1. Как строится RESTful Api.
A

Построение RESTful API включает несколько ключевых шагов и принципов:
1. Определение ресурса:
o RESTful API основан на концепции ресурсов. Ресурсами могут быть сущности вашей системы, такие как пользователи, заказы, продукты и т.д.
o Каждый ресурс должен иметь уникальный идентификатор (URI).
2. Проектирование URI:
o URI должны быть логичными и предсказуемыми.
o Используйте множественное число для обозначения коллекций ресурсов (например, /users для коллекции пользователей и /users/{id} для конкретного пользователя).
3. Использование HTTP-методов:
o GET: для получения данных.
o POST: для создания новых ресурсов.
o PUT: для обновления существующих ресурсов.
o DELETE: для удаления ресурсов.
o PATCH: для частичного обновления ресурсов.
4. Формат данных:
o RESTful API обычно использует JSON для передачи данных из-за его легкости и читаемости.
o Обеспечьте поддержку различных форматов данных через заголовки HTTP (например, Content-Type и Accept).
5. Статусы HTTP-ответов:
o Используйте соответствующие коды статусов HTTP для обозначения результатов операций (например, 200 OK, 201 Created, 204 No Content, 400 Bad Request, 404 Not Found, 500 Internal Server Error).
6. Обработка ошибок:
o Верните информативные сообщения об ошибках с соответствующими кодами статусов.
o Определите структуру ответа для ошибок, чтобы клиенты могли легко понять и обработать их.
7. Безопасность:
o Используйте HTTPS для защиты данных при передаче.
o Реализуйте механизмы аутентификации и авторизации (например, OAuth2, JWT).
o Управляйте доступом к ресурсам на основе ролей и прав.
8. Версионирование:
o Версионирование API помогает управлять изменениями и обеспечивает обратную совместимость.
o Включите версию в URI (например, /v1/users) или используйте заголовки (например, Accept: application/vnd.yourapi.v1+json).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q
  1. Как происходит отправка HTTP запроса и получение результата клиентом? Что просходит в этом процессе? Из чего состоит HTTP запрос?
A

Процесс отправки HTTP-запроса и получения ответа
1. Формирование запроса:
o Клиент создает HTTP-запрос, определяя метод (GET, POST, PUT, DELETE и т.д.), URL, заголовки и, если необходимо, тело запроса.
2. Отправка запроса:
o Запрос отправляется по сети на сервер, используя TCP/IP протоколы.
o Веб-браузеры или другие HTTP-клиенты (например, cURL, Postman) управляют этим процессом на уровне приложений.
3. Обработка запроса сервером:
o Сервер принимает запрос и разбирает его.
o Сервер определяет маршрут и вызывает соответствующий обработчик (контроллер, действие).
o Обработчик выполняет логику, взаимодействует с базой данных или другими сервисами, готовит данные для ответа.
4. Формирование ответа:
o Сервер создает HTTP-ответ, определяя статус-код, заголовки и, если необходимо, тело ответа (например, JSON или HTML).
5. Отправка ответа:
o Ответ отправляется по сети обратно клиенту.
6. Получение ответа клиентом:
o Клиент получает ответ и разбирает его.
o Веб-браузер может отобразить HTML, а другие клиенты могут обработать данные (например, JSON) и выполнить соответствующие действия.
Состав HTTP-запроса
HTTP-запрос состоит из следующих компонентов:
1. Стартовая строка (Request Line):
o Содержит метод запроса, URI и версию протокола.
o Пример: GET /api/users HTTP/1.1
2. Заголовки запроса (Request Headers):
o Пары ключ-значение, которые передают дополнительную информацию о запросе и клиенте.
o Примеры:
Host: example.com
User-Agent: Mozilla/5.0
Content-Type: application/json
Accept: application/json
3. Пустая строка:
o Разделяет заголовки и тело запроса.
4. Тело запроса (Request Body) (если применимо):
o Содержит данные, отправляемые на сервер, например, JSON, XML или форму.
o Используется в методах POST, PUT и PATCH.
Пример HTTP-запроса

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Accept: application/json
Content-Length: 56

{
“name”: “John Doe”,
“email”: “john.doe@example.com”
}
Состав HTTP-ответа
HTTP-ответ состоит из следующих компонентов:
1. Стартовая строка (Status Line):
o Содержит версию протокола, статус-код и статусное сообщение.
o Пример: HTTP/1.1 200 OK
2. Заголовки ответа (Response Headers):
o Пары ключ-значение, которые передают дополнительную информацию о ответе и сервере.
o Примеры:
Content-Type: application/json
Content-Length: 123
Date: Wed, 24 Jul 2024 18:00:00 GMT
3. Пустая строка:
o Разделяет заголовки и тело ответа.
4. Тело ответа (Response Body):
o Содержит данные, отправленные сервером, например, HTML, JSON или бинарные данные.
Пример HTTP-ответа

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 56

{
“id”: 1,
“name”: “John Doe”,
“email”: “john.doe@example.com”
}

17
Q
  1. Что такое ORM и зачем они нужны.
A

Что такое ORM?
ORM (Object-Relational Mapping) — это технология, которая позволяет разработчикам работать с базами данных на уровне объектов, используя объектно-ориентированный подход. ORM автоматически преобразует данные из базы данных в объекты программного кода и обратно, что упрощает взаимодействие между программой и реляционной базой данных.
Зачем нужны ORM?
ORM предлагает несколько преимуществ, которые делают его полезным и широко используемым в разработке программного обеспечения:
1. Удобство работы с данными:
o Разработчики могут работать с данными, используя привычные объекты и коллекции, вместо написания сложных SQL-запросов.
o Это упрощает чтение и сопровождение кода, так как код становится более декларативным и объектно-ориентированным.
2. Сокращение количества кода:
o ORM автоматически генерирует SQL-запросы для создания, чтения, обновления и удаления данных.
o Это уменьшает количество шаблонного кода, который необходимо писать вручную, и снижает вероятность ошибок.
3. Повышение производительности разработки:
o Разработчики могут быстрее создавать и изменять модели данных, не тратя время на ручное написание SQL.
o ORM обеспечивает высокоуровневые API, которые ускоряют разработку и тестирование.
4. Абстракция базы данных:
o ORM абстрагирует специфику конкретной СУБД, позволяя разрабатывать приложения, независимые от используемой базы данных.
o Это облегчает миграцию с одной СУБД на другую.
5. Поддержка сложных отношений и транзакций:
o ORM автоматически управляет связями между объектами (например, один-к-одному, один-ко-многим, многие-ко-многим) и обеспечивает целостность данных.
o ORM поддерживает транзакции, позволяя атомарно выполнять набор операций.

18
Q
  1. Что такое Docker, зачем он нужен и его главные преимущества.
A

Docker — это платформа для разработки, доставки и запуска приложений в изолированных контейнерах. Контейнеры позволяют упаковывать приложение вместе со всеми его зависимостями в единый переносимый блок, который можно запускать в любом окружении, будь то локальный компьютер разработчика, сервер в дата-центре или облачный сервис.
Зачем нужен Docker?
Docker решает несколько ключевых проблем в процессе разработки и деплоя приложений:
1. Проблема совместимости:
o “Работает на моей машине, но не на сервере.” Docker обеспечивает единое окружение для разработки, тестирования и продакшн, что минимизирует проблемы совместимости.
2. Упрощение деплоя:
o Docker позволяет легко развертывать приложения и их зависимости на разных серверах и платформах.
3. Изоляция окружений:
o Каждый контейнер работает в своем собственном изолированном окружении, что позволяет запускать несколько приложений с различными версиями библиотек на одном хосте без конфликтов.
Главные преимущества Docker
1. Портативность:
o Контейнеры Docker могут быть запущены на любом хосте, который поддерживает Docker, будь то локальная машина, сервер или облачная платформа. Это делает приложение переносимым и предсказуемым в разных окружениях.
2. Изоляция:
o Контейнеры изолируют приложение и его зависимости от системы и других приложений. Это обеспечивает более высокую безопасность и предсказуемость поведения приложений.
3. Масштабируемость:
o Docker позволяет легко масштабировать приложения путем запуска множества экземпляров контейнеров и управления ими с помощью оркестрационных инструментов, таких как Kubernetes или Docker Swarm.
4. Ускорение разработки и деплоя:
o Docker упрощает и ускоряет процесс настройки окружения для разработки и тестирования. Это также облегчает процесс CI/CD (Continuous Integration/Continuous Deployment).
5. Эффективность использования ресурсов:
o Контейнеры имеют меньшие накладные расходы по сравнению с виртуальными машинами, так как они разделяют ядро операционной системы и используют ресурсы более эффективно.
6. Версионность и контроль изменений:
o Docker позволяет легко создавать, версионировать и обновлять образы контейнеров, что упрощает управление зависимостями и контроль изменений в приложениях.

19
Q
  1. Что такое CI, CD. В чем отличие.
A

CI/CD (Continuous Integration and Continuous Delivery/Deployment) — это практика и набор процессов, направленных на улучшение качества программного обеспечения и ускорение его выпуска. Эти процессы включают автоматизацию сборки, тестирования и развертывания приложения.
CI (Continuous Integration)
Continuous Integration (непрерывная интеграция) — это практика регулярного слияния изменений кода в главную ветку репозитория. Каждое слияние запускает автоматизированные процессы сборки и тестирования, чтобы убедиться, что изменения не приводят к регрессиям или другим проблемам.
Основные цели CI:
1. Раннее обнаружение ошибок:
o Регулярная интеграция изменений позволяет выявлять и устранять ошибки на ранней стадии разработки.
2. Автоматизация тестирования:
o Все новые коммиты проходят через автоматические тесты, что обеспечивает стабильность кода и предотвращает регрессии.
3. Улучшение качества кода:
o Частые коммиты и автоматизированные проверки улучшают качество кода и облегчают его сопровождение.
4. Повышение командной эффективности:
o Разработчики могут обнаруживать конфликты и ошибки интеграции сразу, что ускоряет процесс разработки и выпуска.
CD (Continuous Delivery / Continuous Deployment)
Continuous Delivery (непрерывная доставка) и Continuous Deployment (непрерывное развертывание) — это практики, направленные на автоматизацию выпуска программного обеспечения после этапа интеграции.
Continuous Delivery (CD):
Непрерывная доставка — это процесс, при котором код, прошедший этапы сборки и тестирования, автоматически готовится к выпуску. Хотя развертывание может требовать ручного запуска, весь процесс до этого этапа полностью автоматизирован.
Основные цели Continuous Delivery:
1. Быстрая и надежная доставка кода:
o Код может быть развернут в любое время с минимальными усилиями, что уменьшает риски и повышает гибкость команды.
2. Автоматизация процессов:
o Сборка, тестирование и подготовка к развертыванию полностью автоматизированы, что снижает количество ошибок и ускоряет процесс выпуска.
3. Стабильные релизы:
o Благодаря автоматизированным тестам и проверкам, релизы становятся более стабильными и качественными.
Continuous Deployment (CD):
Непрерывное развертывание — это расширение непрерывной доставки, при котором каждая успешная сборка автоматически разворачивается в производственной среде без необходимости ручного вмешательства.
Основные цели Continuous Deployment:
1. Полная автоматизация:
o Каждый коммит, прошедший все тесты и проверки, автоматически разворачивается в продакшн, что обеспечивает максимальную скорость выпуска.
2. Минимизация времени вывода на рынок:
o Новые функции и исправления ошибок доставляются пользователям как можно быстрее, что повышает конкурентоспособность продукта.
3. Непрерывное улучшение:
o Постоянные и быстрые релизы позволяют быстро реагировать на фидбек пользователей и постоянно улучшать продукт.
Отличие между Continuous Integration и Continuous Delivery/Deployment
1. Цель:
o CI: Обеспечить стабильность и качество кода путем регулярной интеграции и тестирования.
o CD (Delivery): Подготовить код к выпуску с минимальными усилиями, автоматизируя весь процесс до развертывания.
o CD (Deployment): Автоматически развертывать каждую успешную сборку в производственную среду.
2. Автоматизация:
o CI: Автоматизация сборки и тестирования.
o CD (Delivery): Автоматизация до этапа развертывания.
o CD (Deployment): Полная автоматизация, включая развертывание в продакшн.
3. Ручное вмешательство:
o CI: Требуется для интеграции кода.
o CD (Delivery): Может требоваться для запуска развертывания.
o CD (Deployment): Не требуется, развертывание полностью автоматизировано.

20
Q
  1. Как сохранить большой файл (размер больше чем объем оперативной памяти) на диск.
A

Сохранение большого файла, размер которого превышает объем оперативной памяти, требует специального подхода для обработки данных. Важно избежать загрузки всего файла в память, чтобы предотвратить исчерпание ресурсов системы. Это можно сделать, используя потоковую обработку данных.
Общий подход
1. Чтение данных по частям:
o Вместо чтения всего файла целиком, данные читаются по частям (например, блоками или чанками).
2. Запись данных по частям:
o Прочитанные части данных сразу записываются на диск.

21
Q

Многопоточность против асинхронности

A

Lets start with single-thread execution. Suppose that we have an application which gets data from the database, does some handling of it and then returns it to the user. So when the request comes to the application, our single thread will query the database and while the database is working to retrieve the data our thread will be paused so new requests can’t be handled during this time.

In the multithreaded environment we’ll have many threads which will handle the requests, but all of them will still be paused when the database will work to provide the data.

In the asynchronous environments threads when they reach the awaitable operation can be assigned to do other operation while they wait that awaitable operation to complete. When it’s completed the execution will be resumed