---
title: Computer Science
seo:
  title: "Computer Science — С# Developer"
  description: "Тема «Computer Science» для собеседования С# Developer. Вы набираете google.com в браузере. Расскажите как можно подробнее, что происходит в это время на HTTP-уровне? Как работает HTTPS?"
---

[Все темы С# Developer](/s-developer)

## <strong>Вы набираете google.com в браузере. Расскажите как можно подробнее, что происходит в это время на</strong> <code>HTTP</code><strong>-уровне?</strong> [#q-14bee738d69b810690cdfab6681ec9ac]

Что происходит при наборе [google.com](http://google.com/) в браузере на <code>HTTP</code>-уровне&#58;

{/* prettier-ignore */}
1. <strong>Ввод URL&#58;</strong>

    - <strong>Действие&#58;</strong> Пользователь вводит <code>google&#46;com</code> в адресную строку браузера.

1. <strong>DNS-запрос&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер отправляет запрос DNS-серверу для получения IP-адреса домена <code>google&#46;com</code>.

    - <strong>Ответ&#58;</strong> DNS-сервер возвращает IP-адрес Google, например, <code>142&#46;250&#46;190&#46;14</code>.

1. <strong>Установка TCP-соединения&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер инициирует TCP-соединение с сервером Google на порту 80 (HTTP) или 443 (HTTPS).

    - <strong>Процесс&#58;</strong> Происходит трехстороннее рукопожатие (SYN, SYN-ACK, ACK).

1. <strong>HTTP-запрос&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер отправляет HTTP-запрос на сервер Google.

    - <strong>Пример запроса&#58;</strong>

        ```csharp
        GET / HTTP/1.1
        Host: www.google.com
        User-Agent: [ваш браузер]
        Accept: text/html
        ```

1. <strong>Обработка запроса&#58;</strong>

    - <strong>Описание&#58;</strong> Веб-сервер Google получает запрос и обрабатывает его, определяя, какой контент отправить в ответ.

1. <strong>HTTP-ответ&#58;</strong>

    - <strong>Описание&#58;</strong> Сервер отправляет обратно HTTP-ответ, содержащий запрашиваемую веб-страницу.

    - <strong>Пример ответа&#58;</strong>

        ```http
        HTTP/1.1 200 OK
        Content-Type: text/html
        Content-Length: [длина содержимого]

        [HTML-код веб-страницы]
        ```

1. <strong>Отображение содержимого&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер получает ответ, анализирует HTML-код и рендерит веб-страницу для отображения пользователю.

:::note[Ссылки для изучения]

1. [Что на самом деле происходит, когда пользователь вбивает в браузер адрес google.com](https://habr.com/ru/companies/htmlacademy/articles/254825/)
   :::

---

## <strong>Как работает</strong> <code>HTTPS</code><strong>?</strong> [#q-14bee738d69b81309431d245ed57911d]

Как работает <code>HTTPS</code>&#58;

{/* prettier-ignore */}
1. <strong>Начало соединения&#58;</strong>

    - <strong>Действие&#58;</strong> Пользователь вводит URL с <code>https&#58;&#47;&#47;</code>, браузер инициирует соединение на порту 443.

1. <strong>DNS-запрос&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер выполняет DNS-запрос, чтобы получить IP-адрес сервера.

1. <strong>TLS/SSL рукопожатие&#58;</strong>

    - <strong>Описание&#58;</strong> Устанавливается защищенное соединение через протокол TLS/SSL.

    - <strong>Процесс&#58;</strong>

        - <strong>ClientHello&#58;</strong> Браузер отправляет сообщение <code>ClientHello</code>, содержащее информацию о поддерживаемых версиях TLS, шифрах и других параметрах.

        - <strong>ServerHello&#58;</strong> Сервер отвечает сообщением <code>ServerHello</code>, выбирая версию протокола и шифр.

        - <strong>Сертификат&#58;</strong> Сервер отправляет свой цифровой сертификат для аутентификации.

        - Ключи&#58; стороны вырабатывают секреты трафика по согласованному механизму, например (EC)DHE. В TLS 1.3 RSA-обмен ключами удален; RSA может использоваться для подписи сертификата.

        - <strong>Шифрование&#58;</strong> Обе стороны устанавливают симметричный ключ для шифрования последующих данных.

1. <strong>HTTP-запрос&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер отправляет HTTP-запрос, зашифрованный с использованием симметричного ключа.

    - <strong>Пример запроса&#58;</strong>

        ```csharp
        GET / HTTP/1.1
        Host: www.example.com
        ```

1. <strong>HTTP-ответ&#58;</strong>

    - <strong>Описание&#58;</strong> Сервер отправляет зашифрованный HTTP-ответ.

    - <strong>Пример ответа&#58;</strong>

        ```http
        HTTP/1.1 200 OK
        Content-Type: text/html
        Content-Length: [длина содержимого]

        [зашифрованный HTML-код веб-страницы]
        ```

1. <strong>Декодирование и отображение&#58;</strong>

    - <strong>Описание&#58;</strong> Браузер расшифровывает полученные данные и отображает содержимое веб-страницы пользователю.

:::note[Ссылки для изучения]

1. [Как HTTPS обеспечивает безопасность соединения](https://habr.com/ru/articles/188042/)
   :::

---

## <strong>Как вы понимаете</strong> <code>SOLID</code><strong>?</strong> [#q-14bee738d69b81c58c58d6e1916a2461]

Принципы <code>SOLID</code>&#58;

{/* prettier-ignore */}
1. <code>Single Responsibility Principle</code> <strong>(Принцип единственной ответственности)&#58;</strong>

    - <strong>Описание&#58;</strong> Класс должен иметь только одну причину для изменения, то есть выполнять только одну задачу.

    - <strong>Пример&#58;</strong> Класс, отвечающий только за управление пользователями, не должен заниматься логированием.

1. <code>Open&#47;Closed Principle</code> <strong>(Принцип открытости/закрытости)&#58;</strong>

    - <strong>Описание&#58;</strong> Классы должны быть открыты для расширения, но закрыты для изменения.

    - <strong>Пример&#58;</strong> Добавление новой функциональности через наследование или интерфейсы, не изменяя существующий код.

1. <code>Liskov Substitution Principle</code> <strong>(Принцип подстановки Барбары Лисков)&#58;</strong>

    - <strong>Описание&#58;</strong> Объекты базового класса должны быть заменяемы объектами производных классов без нарушения работы программы.

    - <strong>Пример&#58;</strong> Подклассы должны полностью реализовывать поведение базового класса.

1. <code>Interface Segregation Principle</code> <strong>(Принцип разделения интерфейсов)&#58;</strong>

    - <strong>Описание&#58;</strong> Много специализированных интерфейсов лучше, чем один универсальный.

    - <strong>Пример&#58;</strong> Клиенты не должны зависеть от интерфейсов, которые они не используют.

1. <code>Dependency Inversion Principle</code> <strong>(Принцип инверсии зависимостей)&#58;</strong>

    - <strong>Описание&#58;</strong> Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей, детали должны зависеть от абстракций.

    - <strong>Пример&#58;</strong> Использование интерфейсов или абстрактных классов для определения зависимостей.

:::note[Ссылки для изучения]

1. [Простое объяснение принципов SOLID](https://habr.com/ru/companies/vk/articles/412699/)
   :::

---

## <strong>Какие протоколы сериализации вы знаете и где они применяются?</strong> [#q-14bee738d69b817aaf44fa697e7f25ea]

Протоколы сериализации&#58;

{/* prettier-ignore */}
1. <code>JSON</code> <strong>(JavaScript Object Notation)&#58;</strong>

    - <strong>Описание&#58;</strong> Текстовый формат обмена данными, легко читаемый человеком.

    - <strong>Применение&#58;</strong> Веб-сервисы, REST API, конфигурационные файлы.

    - <strong>Пример&#58;</strong>

        ```json
        {"name": "John", "age": 30}
        ```

1. <code>XML</code> <strong>(Extensible Markup Language)&#58;</strong>

    - <strong>Описание&#58;</strong> Текстовый формат, использующий теги для описания структуры данных.

    - <strong>Применение&#58;</strong> Веб-сервисы (SOAP), конфигурационные файлы, документы.

    - <strong>Пример&#58;</strong>

        ```xml
        <person><name>John</name><age>30</age></person>
        ```

1. <code>Protocol Buffers</code> <strong>(Protobuf)&#58;</strong>

    - <strong>Описание&#58;</strong> Бинарный формат сериализации данных, разработанный Google.

    - <strong>Применение&#58;</strong> Внутренние системы, межсервисное взаимодействие, RPC.

    - <strong>Пример&#58;</strong>

        ```csharp
        message Person {
          string name = 1;
          int32 age = 2;
        }
        ```

1. <code>Avro</code><strong>&#58;</strong>

    - <strong>Описание&#58;</strong> Бинарный формат сериализации данных, разработанный Apache.

    - <strong>Применение&#58;</strong> Обработка больших данных, Hadoop, Kafka.

    - <strong>Пример&#58;</strong>

        ```json
        {"type": "record", "name": "Person", "fields": [{"name": "name", "type": "string"}, {"name": "age", "type": "int"}]}
        ```

1. <code>MessagePack</code><strong>&#58;</strong>

    - <strong>Описание&#58;</strong> Бинарный формат сериализации данных, компактный и быстрый.

    - <strong>Применение&#58;</strong> Веб-сервисы, межсервисное взаимодействие.

    - <strong>Пример&#58;</strong> Бинарный эквивалент JSON-структуры.

1. <code>Thrift</code><strong>&#58;</strong>

    - <strong>Описание&#58;</strong> Протокол сериализации и межъязыковая служба RPC, разработанный Facebook.

    - <strong>Применение&#58;</strong> Межъязыковое взаимодействие, микросервисы.

    - <strong>Пример&#58;</strong>

        ```csharp
        struct Person {
          1: string name,
          2: i32 age
        }
        ```

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

:::note[Ссылки для изучения]

1. [Сериализация данных в JSON](https://ru.hexlet.io/courses/go-web-development/lessons/data-serialization/theory_unit)
   :::

---

## <strong>Что такое в вашем понимании чистая функция? Какие у нее преимущества?</strong> [#q-14bee738d69b810d8a71d640f27fde57]

<strong>Чистая функция -</strong> функция, которая всегда возвращает один и тот
же результат для одних и тех же входных данных и не имеет побочных эффектов (не
изменяет внешнее состояние).

#### Преимущества&#58;

{/* prettier-ignore */}
1. <strong>Предсказуемость&#58;</strong>

    - <strong>Описание&#58;</strong> Легко предсказать результат вызова функции с определенными аргументами.

    - <strong>Пример&#58;</strong> <code>int Add&#40;int a&#44; int b&#41; &#123; return a &#43; b&#59; &#125;</code> всегда возвращает одно и то же значение для одинаковых входных данных.

1. <strong>Тестируемость&#58;</strong>

    - <strong>Описание&#58;</strong> Легко тестировать, так как нет зависимости от внешнего состояния или контекста.

    - <strong>Пример&#58;</strong> Юнит-тесты могут проверять функцию на различных входных данных.

1. <strong>Мемоизация&#58;</strong>

    - <strong>Описание&#58;</strong> Результаты чистых функций можно кэшировать для повышения производительности.

    - <strong>Пример&#58;</strong> Мемоизация позволяет избежать повторных вычислений для одинаковых входных данных.

1. <strong>Параллелизм&#58;</strong>

    - <strong>Описание&#58;</strong> Чистые функции безопасно выполнять параллельно, так как они не изменяют состояние.

    - <strong>Пример&#58;</strong> Можно запускать в разных потоках без риска взаимного влияния.

1. <strong>Отсутствие побочных эффектов&#58;</strong>

    - <strong>Описание&#58;</strong> Не изменяют состояние программы, не зависят от внешнего состояния.

    - <strong>Пример&#58;</strong> Не изменяют глобальные переменные, не выполняют операции ввода-вывода.

:::note[Ссылки для изучения]

1. [Рефакторинг в чистые функции](https://learn.microsoft.com/ru-ru/dotnet/standard/linq/refactor-pure-functions)
   :::

---

## <strong>Что такое</strong> <code>dependency injection</code> <strong>и зачем оно нужно?</strong> [#q-14bee738d69b81ed9d43d99cbede2f02]

<code>Dependency Injection</code> <strong>-</strong> это дизайн-паттерн, который
позволяет передавать зависимости объекта извне вместо создания их внутри
объекта.

#### Зачем нужно&#58;

{/* prettier-ignore */}
1. <strong>Ослабление связности&#58;</strong>

    - <strong>Описание&#58;</strong> Классы не создают свои зависимости напрямую, что уменьшает связность кода и упрощает его изменение.

    - <strong>Пример&#58;</strong> Зависимости передаются через конструктор, метод или свойства.

1. <strong>Упрощение тестирования&#58;</strong>

    - <strong>Описание&#58;</strong> Легче тестировать классы, так как можно подменять реальные зависимости тестовыми объектами (моками).

    - <strong>Пример&#58;</strong> Использование фреймворков для мокирования при написании юнит-тестов.

1. <strong>Улучшение читаемости и поддержки кода&#58;</strong>

    - <strong>Описание&#58;</strong> Код становится более понятным и легко поддерживаемым, так как зависимости явно указаны.

    - <strong>Пример&#58;</strong> Конструктор класса показывает все необходимые зависимости.

1. <strong>Повышение переиспользуемости&#58;</strong>

    - <strong>Описание&#58;</strong> Компоненты можно легко переиспользовать в других контекстах, так как они не зависят от конкретных реализаций своих зависимостей.

    - <strong>Пример&#58;</strong> Классы можно использовать с разными реализациями интерфейсов.

#### Пример&#58;

```csharp
public interface ILogger
{
    void Log(string message);
}

public class FileLogger : ILogger
{
    public void Log(string message)
    {
        // Логирование в файл
    }
}

public class UserService
{
    private readonly ILogger _logger;

    // Внедрение зависимости через конструктор
    public UserService(ILogger logger)
    {
        _logger = logger;
    }

    public void CreateUser(string name)
    {
        // Логика создания пользователя
        _logger.Log("User created: " + name);
    }
}

// Конфигурация DI
ILogger logger = new FileLogger();
UserService userService = new UserService(logger);
```

:::note[Ссылки для изучения]

1. [Dependency injection в ASP.NET](https://metanit.com/sharp/aspnet5/6.1.php)
   :::

---

## <strong>Что такое</strong> <code>cohesion</code> <strong>и</strong> <code>coupling</code> <strong>(связанность и связность)?</strong> [#q-14bee738d69b81bca420f0668430a2a7]

<code>Cohesion</code> <strong>(Связность) -</strong> это мера того, насколько
сильно связаны и сфокусированы друг на друге элементы внутри одного модуля или
класса.

<strong>Высокая связность&#58;</strong>

- <strong>Описание&#58;</strong> Все методы и данные внутри модуля тесно связаны
  и работают на достижение одной цели.

- <strong>Преимущества&#58;</strong> Легкость в понимании, тестировании и
  поддержке.

<code>Coupling</code> <strong>(Связанность) -</strong> это мера зависимости
одного модуля от другого.

<strong>Низкая связанность&#58;</strong>

- <strong>Описание&#58;</strong> Модули минимально зависят друг от друга,
  изменения в одном модуле не сильно влияют на другие.

- <strong>Преимущества&#58;</strong> Повышенная модульность, легкость в
  изменении и переиспользовании.

#### Пример&#58;

<strong>Высокая связность&#58;</strong>

```csharp
public class UserService
{
    private readonly UserRepository _userRepository;

    public UserService(UserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(string name)
    {
        _userRepository.Add(new User(name));
    }
}
```

<strong>Низкая связанность&#58;</strong>

```csharp
public class UserService
{
    private readonly IUserRepository _userRepository;

    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(string name)
    {
        _userRepository.Add(new User(name));
    }
}
```

:::note[Ссылки для изучения]

1. [Отличия между cohesion и coupling](https://habr.com/ru/articles/568216/)
   :::

---

## <strong>Что такое</strong> <code>IaaS</code><strong>,</strong> <code>PaaS</code><strong>,</strong> <code>SaaS</code> <strong>и каковы различия между ними?</strong> [#q-14bee738d69b814885b6ca04630be9ba]

<code>IaaS</code> <strong>(Infrastructure as a Service)&#58;</strong>

<strong>Определение&#58;</strong> Предоставление виртуализированной
вычислительной инфраструктуры через интернет.

<strong>Пример&#58;</strong> Amazon Web Services (AWS), Microsoft Azure, Google
Cloud Platform (GCP).

<strong>Особенности&#58;</strong>

- Пользователь управляет операционными системами, приложениями, хранилищем и сетевыми компонентами.

- Провайдер управляет серверами, виртуализацией, хранилищем и сетью.

<code>PaaS</code> <strong>(Platform as a Service)&#58;</strong>

<strong>Определение&#58;</strong> Предоставление платформы, позволяющей
разрабатывать, тестировать и развертывать приложения.

<strong>Пример&#58;</strong> Google App Engine, Microsoft Azure App Services,
Heroku.

<strong>Особенности&#58;</strong>

- Пользователь управляет приложениями и данными.

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

<code>SaaS</code> <strong>(Software as a Service)&#58;</strong>

<strong>Определение&#58;</strong> Предоставление готового программного
обеспечения через интернет.

<strong>Пример&#58;</strong> Google Workspace, Microsoft Office 365, Salesforce.

<strong>Особенности&#58;</strong>

- Пользователь использует готовое приложение.

- Провайдер управляет всем&#58; приложением, данными, серверами, хранилищем и сетью.

#### Различия&#58;

{/* prettier-ignore */}
- <strong>Управление&#58;</strong>

    - <strong>IaaS&#58;</strong> Максимальный контроль над инфраструктурой.

    - <strong>PaaS&#58;</strong> Контроль над приложениями и данными.

    - <strong>SaaS&#58;</strong> Минимальный контроль, используется готовое ПО.

- <strong>Применение&#58;</strong>

    - <strong>IaaS&#58;</strong> Гибкость и контроль для IT-инфраструктуры.

    - <strong>PaaS&#58;</strong> Упрощение разработки и развертывания приложений.

    - <strong>SaaS&#58;</strong> Доступ к приложениям без необходимости управления инфраструктурой.

:::note[Ссылки для изучения]

1. [Разница между IaaS, PaaS, SaaS](https://cloud.vk.com/blog/raznica-mezhdu-iaas-paas-saas-statya-ob-oblakah-v-internete)
   :::

---

## <strong>Какие способы отладки программы вы используете?</strong> [#q-14bee738d69b81559834f54141d8bc06]

Способы отладки программы&#58;

{/* prettier-ignore */}
1. <strong>Логирование&#58;</strong>

    - <strong>Описание&#58;</strong> Запись событий и данных выполнения программы в лог-файлы.

    - <strong>Инструменты&#58;</strong> Log4j, NLog, Serilog.

    - <strong>Преимущества&#58;</strong> Позволяет анализировать поведение программы после выполнения.

1. <strong>Использование отладчика (</strong><code>Debugger</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Пошаговое выполнение кода с возможностью установки точек останова (breakpoints), просмотра значений переменных и стеков вызовов.

    - <strong>Инструменты&#58;</strong> Visual Studio, IntelliJ IDEA, Eclipse.

    - <strong>Преимущества&#58;</strong> Интерактивный и подробный анализ выполнения программы.

1. <strong>Тестирование (</strong><code>Unit Testing</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Написание и запуск тестов для проверки отдельных модулей программы.

    - <strong>Инструменты&#58;</strong> NUnit, JUnit, xUnit.

    - <strong>Преимущества&#58;</strong> Обнаружение и предотвращение ошибок на ранних стадиях разработки.

1. <strong>Вывод на консоль (</strong><code>Console Output</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Использование <code>Console&#46;WriteLine</code>, <code>print</code>, или аналогичных методов для вывода значений переменных и сообщений.

    - <strong>Преимущества&#58;</strong> Быстрый и простой способ проверки значений во время выполнения.

1. <strong>Анализ стеков вызовов (</strong><code>Stack Traces</code><strong>)&#58;</strong>

    - <strong>Описание&#58;</strong> Исследование стеков вызовов в случае исключений или сбоев.

    - <strong>Инструменты&#58;</strong> Встроенные возможности языков программирования, отладчики.

    - <strong>Преимущества&#58;</strong> Помогает понять путь выполнения до возникновения ошибки.

1. <strong>Профилирование&#58;</strong>

    - <strong>Описание&#58;</strong> Измерение производительности и выявление узких мест в программе.

    - <strong>Инструменты&#58;</strong> Visual Studio Profiler, JProfiler, YourKit.

    - <strong>Преимущества&#58;</strong> Оптимизация производительности и выявление проблемных участков кода.

:::note[Ссылки для изучения]

1. [Методы и инструменты отладки](https://learn.microsoft.com/ru-ru/visualstudio/debugger/write-better-code-with-visual-studio?view=vs-2022)
   :::

---

## <strong>Какие знаете паттерны? Объясните суть перечисленных</strong> [#q-14bee738d69b814cb98bd7f3031b37e5]

<strong>Порождающие паттерны&#58;</strong>

{/* prettier-ignore */}
1. <code>Singleton</code> <strong>(Одиночка)&#58;</strong>

    - <strong>Описание&#58;</strong> Гарантирует, что класс имеет только один экземпляр и предоставляет глобальную точку доступа к нему.

    - <strong>Пример&#58;</strong> Менеджер конфигурации, логгер.

1. <code>Factory Method</code> <strong>(Фабричный метод)&#58;</strong>

    - <strong>Описание&#58;</strong> Определяет интерфейс для создания объектов, но позволяет подклассам изменять тип создаваемого объекта.

    - <strong>Пример&#58;</strong> Создание объектов с разной реализацией интерфейса.

1. <code>Abstract Factory</code> <strong>(Абстрактная фабрика)&#58;</strong>

    - <strong>Описание&#58;</strong> Предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.

    - <strong>Пример&#58;</strong> Графические интерфейсы для разных ОС.

1. <code>Builder</code> <strong>(Строитель)&#58;</strong>

    - <strong>Описание&#58;</strong> Разделяет конструирование сложного объекта от его представления, позволяя создавать разные представления.

    - <strong>Пример&#58;</strong> Создание сложных объектов, таких как документ или автомобиль.

<strong>Структурные паттерны&#58;</strong>

{/* prettier-ignore */}
1. <code>Adapter</code> <strong>(Адаптер)&#58;</strong>

    - <strong>Описание&#58;</strong> Преобразует интерфейс класса в другой интерфейс, ожидаемый клиентами.

    - <strong>Пример&#58;</strong> Совместимость между несовместимыми интерфейсами.

1. <code>Decorator</code> <strong>(Декоратор)&#58;</strong>

    - <strong>Описание&#58;</strong> Динамически добавляет обязанности объекту, не изменяя его класс.

    - <strong>Пример&#58;</strong> Добавление новых функций к объекту, например, дополнительные интерфейсы пользователя.

1. <code>Facade</code> <strong>(Фасад)&#58;</strong>

    - <strong>Описание&#58;</strong> Предоставляет унифицированный интерфейс к набору интерфейсов подсистемы.

    - <strong>Пример&#58;</strong> Упрощение взаимодействия с комплексной системой.

1. <code>Proxy</code> <strong>(Прокси)&#58;</strong>

    - <strong>Описание&#58;</strong> Предоставляет суррогат или заменитель другого объекта для контроля доступа к нему.

    - <strong>Пример&#58;</strong> Удаленные объекты, ленивые объекты.

<strong>Поведенческие паттерны&#58;</strong>

{/* prettier-ignore */}
1. <code>Observer</code> <strong>(Наблюдатель)&#58;</strong>

    - <strong>Описание&#58;</strong> Определяет зависимость "один ко многим" между объектами, при которой изменение состояния одного объекта приводит к оповещению и обновлению всех зависимых объектов.

    - <strong>Пример&#58;</strong> Системы событий и подписок.

1. <code>Strategy</code> <strong>(Стратегия)&#58;</strong>

    - <strong>Описание&#58;</strong> Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми.

    - <strong>Пример&#58;</strong> Алгоритмы сортировки, выбор способа оплаты.

1. <code>Command</code> <strong>(Команда)&#58;</strong>

    - <strong>Описание&#58;</strong> Инкапсулирует запрос как объект, позволяя параметризовать клиентов с различными запросами, очередями или логами запросов, а также поддерживать отмену операций.

    - <strong>Пример&#58;</strong> Реализация операций undo/redo.

1. <code>State</code> <strong>(Состояние)&#58;</strong>

    - <strong>Описание&#58;</strong> Позволяет объекту изменять свое поведение при изменении его внутреннего состояния.

    - <strong>Пример&#58;</strong> Автомат состояний, поведение объектов в разных состояниях (например, TCP-соединение).

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

:::note[Ссылки для изучения]

1. [Паттерны ООП в метафорах](https://habr.com/ru/articles/136766/)
   :::

---

## <strong>В чем суть паттерна</strong> <code>Singleton</code><strong>? Почему его еще называют антипаттерном?</strong> [#q-14bee738d69b81a99e5cc6eb9aea5a38]

<strong>Суть паттерна</strong> <code>Singleton</code>
<strong>&#58;</strong>

- <strong>Описание&#58;</strong> Singleton гарантирует, что класс имеет только
  один экземпляр и предоставляет глобальную точку доступа к этому экземпляру.

- <strong>Пример&#58;</strong>

  ```csharp
  public class Singleton
  {
      private static Singleton _instance;
      private static readonly object _lock = new object();

      private Singleton() { }

      public static Singleton Instance
      {
          get
          {
              lock (_lock)
              {
                  if (_instance == null)
                  {
                      _instance = new Singleton();
                  }
                  return _instance;
              }
          }
      }
  }
  ```

#### Почему <code>Singleton</code> называют антипаттерном&#58;

{/* prettier-ignore */}
1. <strong>Скрытая зависимость&#58;</strong>

    - <strong>Описание&#58;</strong> Singleton скрывает зависимости классов, затрудняя понимание и тестирование кода.

    - <strong>Проблема&#58;</strong> Приводит к сильной связанности, затрудняя рефакторинг.

1. <strong>Проблемы с тестированием&#58;</strong>

    - <strong>Описание&#58;</strong> Singleton затрудняет юнит-тестирование из-за глобального состояния.

    - <strong>Проблема&#58;</strong> Сложно создать изолированные тесты, требует использования моков и заглушек.

1. <strong>Проблемы с многопоточностью&#58;</strong>

    - <strong>Описание&#58;</strong> Требует осторожного управления многопоточностью, чтобы избежать проблем с конкурентным доступом.

    - <strong>Проблема&#58;</strong> Неочевидные ошибки и трудности с отладкой.

1. <strong>Глобальное состояние&#58;</strong>

    - <strong>Описание&#58;</strong> Введение глобального состояния нарушает принципы объектно-ориентированного проектирования.

    - <strong>Проблема&#58;</strong> Приводит к труднообнаруживаемым ошибкам и непредсказуемому поведению программы.

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

:::note[Ссылки для изучения]

1. [Подводные камни паттерна Singleton](https://tproger.ru/translations/singleton-pitfalls)
   :::

---

## <strong>Для чего нужен паттерн</strong> <code>Strategy</code><strong>?</strong> [#q-14bee738d69b814c8350dc61cd059b7d]

Паттерн <code>Strategy</code> определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Позволяет изменять алгоритмы независимо от клиентов, которые их используют.

<strong>Основные элементы&#58;</strong>

- <strong>Контекст (Context)&#58;</strong> Класс, использующий стратегию.

- <strong>Интерфейс стратегии (Strategy Interface)&#58;</strong> Общий интерфейс
  для всех алгоритмов.

- <strong>Конкретные стратегии (Concrete Strategies)&#58;</strong> Реализации
  различных алгоритмов, соответствующих интерфейсу стратегии.

<strong>Пример использования&#58;</strong>

- <strong>Сортировка&#58;</strong> Можно выбрать, какой алгоритм сортировки
  использовать (быстрая сортировка, сортировка слиянием и т.д.), без изменения
  клиента.

- <strong>Оплата&#58;</strong> Разные способы оплаты (кредитная карта, PayPal,
  банковский перевод) реализуются как отдельные стратегии.

<strong>Преимущества&#58;</strong>

- <strong>Гибкость&#58;</strong> Легко менять алгоритмы в рантайме.

- <strong>Расширяемость&#58;</strong> Добавление новых стратегий без изменения
  существующего кода.

- <strong>Поддержка принципа открытости/закрытости&#58;</strong> Код открыт для
  расширения, но закрыт для модификации.

<strong>Пример кода&#58;</strong>

```csharp
public interface IStrategy
{
    void Execute();
}

public class ConcreteStrategyA : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("Strategy A");
    }
}

public class ConcreteStrategyB : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("Strategy B");
    }
}

public class Context
{
    private IStrategy _strategy;

    public void SetStrategy(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void ExecuteStrategy()
    {
        _strategy.Execute();
    }
}

// Использование
Context context = new Context();
context.SetStrategy(new ConcreteStrategyA());
context.ExecuteStrategy(); // Вывод: "Strategy A"
context.SetStrategy(new ConcreteStrategyB());
context.ExecuteStrategy(); // Вывод: "Strategy B"
```

:::note[Ссылки для изучения]

1. [Практическое использование шаблона Strategy](https://habr.com/ru/articles/487858/)
   :::

---

## <strong>Какие ключевые различия между распределенными системами и монолитными?</strong> [#q-14bee738d69b816196bcee707d25bb05]

<strong>
  Ключевые различия между распределенными системами и монолитными&#58;
</strong>

<strong>Монолитные системы&#58;</strong>

{/* prettier-ignore */}
1. <strong>Архитектура&#58;</strong>

    - <strong>Описание&#58;</strong> Все компоненты приложения разрабатываются и развертываются как единое целое.

    - <strong>Преимущества&#58;</strong> Простота разработки и развертывания, легко отлаживать и тестировать.

1. <strong>Связь&#58;</strong>

    - <strong>Описание&#58;</strong> Взаимодействие между модулями происходит через вызовы методов или функции внутри одного процесса.

    - <strong>Преимущества&#58;</strong> Высокая производительность, так как отсутствуют сетевые задержки.

1. <strong>Масштабируемость&#58;</strong>

    - <strong>Описание&#58;</strong> Масштабируется целиком, обычно вертикально (добавление ресурсов одному серверу).

    - <strong>Недостатки&#58;</strong> Ограниченная гибкость, сложность масштабирования отдельных компонентов.

1. <strong>Развертывание&#58;</strong>

    - <strong>Описание&#58;</strong> Все компоненты должны развертываться одновременно.

    - <strong>Недостатки&#58;</strong> Трудности с частыми релизами и обновлениями.

<strong>Распределенные системы&#58;</strong>

{/* prettier-ignore */}
1. <strong>Архитектура&#58;</strong>

    - <strong>Описание&#58;</strong> Система состоит из множества автономных сервисов, которые могут разрабатываться и развертываться независимо друг от друга.

    - <strong>Преимущества&#58;</strong> Гибкость, возможность использовать разные технологии для разных сервисов.

1. <strong>Связь&#58;</strong>

    - <strong>Описание&#58;</strong> Взаимодействие между сервисами происходит через сетевые протоколы (HTTP, gRPC, Message Queues).

    - <strong>Недостатки&#58;</strong> Сетевые задержки и возможные сбои в связи.

1. <strong>Масштабируемость&#58;</strong>

    - <strong>Описание&#58;</strong> Масштабируются отдельно, обычно горизонтально (добавление новых экземпляров сервисов).

    - <strong>Преимущества&#58;</strong> Легкость масштабирования отдельных компонентов, улучшение отказоустойчивости.

1. <strong>Развертывание&#58;</strong>

    - <strong>Описание&#58;</strong> Сервисы могут развертываться и обновляться независимо друг от друга.

    - <strong>Преимущества&#58;</strong> Частые релизы, минимизация простоев.

<strong>Итог&#58;</strong>

- <strong>Монолитные системы&#58;</strong> Простота, высокая производительность,
  трудности с масштабируемостью и частыми релизами.

- <strong>Распределенные системы&#58;</strong> Гибкость, легкость
  масштабирования, независимое развертывание, сложность управления связью и
  отказоустойчивостью.

:::note[Ссылки для изучения]

1. [Сравнение монолитной и микросервисной архитектуры](https://habr.com/ru/companies/haulmont/articles/758780/)
   :::

---

## <strong>Какие паттерны проектирования распределенных систем вы знаете?</strong> [#q-14bee738d69b81cda803cd7be0a9afad]

<strong>Паттерны проектирования распределенных систем&#58;</strong>

{/* prettier-ignore */}
1. <code>Microservices</code> <strong>(Микросервисы)&#58;</strong>

    - <strong>Описание&#58;</strong> Разделение системы на мелкие, независимые сервисы, каждый из которых отвечает за конкретную бизнес-функцию.

    - <strong>Пример&#58;</strong> Разделение приложения на сервисы для управления пользователями, платежами и уведомлениями.

1. <code>Service Mesh</code> <strong>(Сервисная сетка)&#58;</strong>

    - <strong>Описание&#58;</strong> Инфраструктурный слой, управляющий взаимодействием между сервисами в распределенной системе, обеспечивая балансировку нагрузки, безопасность и наблюдаемость.

    - <strong>Пример&#58;</strong> Istio, Linkerd.

1. <code>API Gateway</code> <strong>(Шлюз API)&#58;</strong>

    - <strong>Описание&#58;</strong> Единственная точка входа для всех клиентских запросов, которая маршрутизирует запросы к соответствующим микросервисам, обеспечивает безопасность, кэширование и трансформацию запросов.

    - <strong>Пример&#58;</strong> Использование NGINX или AWS API Gateway.

1. <code>Circuit Breaker</code> <strong>(Размыкатель цепи)&#58;</strong>

    - <strong>Описание&#58;</strong> Паттерн для предотвращения каскадных отказов в распределенной системе, временно блокируя вызовы к неудачному сервису.

    - <strong>Пример&#58;</strong> Hystrix, Resilience4j.

1. <code>Event Sourcing</code> <strong>(Событийное хранилище)&#58;</strong>

    - <strong>Описание&#58;</strong> Хранение состояния системы как последовательности событий, что позволяет восстанавливать текущее состояние путем повторного проигрывания этих событий.

    - <strong>Пример&#58;</strong> Использование Apache Kafka для хранения и обработки событий.

1. <code>CQRS</code> <strong>(Command Query Responsibility Segregation)&#58;</strong>

    - <strong>Описание&#58;</strong> Разделение модели данных на команды (изменение состояния) и запросы (чтение состояния) для улучшения производительности и масштабируемости.

    - <strong>Пример&#58;</strong> Отдельные базы данных для чтения и записи данных.

1. <code>Saga</code> <strong>(Сага)&#58;</strong>

    - <strong>Описание&#58;</strong> Управление распределенными транзакциями путем координации последовательности локальных транзакций в разных сервисах, обеспечивая согласованность в случае отказа.

    - <strong>Пример&#58;</strong> Оркестрация саг с использованием координатора или хореография саг.

1. <code>Data Sharding</code> <strong>(Шардинг данных)&#58;</strong>

    - <strong>Описание&#58;</strong> Разделение базы данных на несколько более мелких, независимых частей (шардов) для улучшения производительности и масштабируемости.

    - <strong>Пример&#58;</strong> Разделение пользователей по регионам на отдельные шарды.

:::note[Ссылки для изучения]

1. [Топ-5 архитектурных паттернов для распределительных систем](https://tproger.ru/translations/top-5-arhitekturnyh-patternov-dlja-raspredeljonnyh-sistem)
   :::

---

## <strong>Какие есть принципы работы</strong> <code>Message bus</code><strong>? Почему могут возникать дубликаты в очередях?</strong> [#q-14bee738d69b813eaa9af1aa3a25f0f7]

<strong>Принципы работы</strong> <code>Message Bus</code>
<strong>&#58;</strong>

{/* prettier-ignore */}
1. <strong>Коммуникация через сообщения&#58;</strong>

    - <strong>Описание&#58;</strong> Компоненты системы обмениваются сообщениями через центральную шину сообщений (Message Bus).

    - <strong>Пример&#58;</strong> Компоненты отправляют и получают сообщения через брокер сообщений, такие как RabbitMQ или Kafka.

1. <strong>Асинхронность&#58;</strong>

    - <strong>Описание&#58;</strong> Сообщения обрабатываются асинхронно, что позволяет декомпозировать задачи и улучшить масштабируемость.

    - <strong>Пример&#58;</strong> Отправитель сообщения не ждет немедленного ответа от получателя.

1. <strong>Декуплинг&#58;</strong>

    - <strong>Описание&#58;</strong> Компоненты системы не зависят напрямую друг от друга, что позволяет легко изменять и расширять систему.

    - <strong>Пример&#58;</strong> Сервисы взаимодействуют через сообщения, а не вызывают методы друг друга напрямую.

1. <strong>Надежность&#58;</strong>

    - <strong>Описание&#58;</strong> Сообщения сохраняются и доставляются даже в случае временных сбоев системы.

    - <strong>Пример&#58;</strong> Сообщения сохраняются в очереди до тех пор, пока не будут успешно обработаны.

#### Причины появления дубликатов в очередях&#58;

{/* prettier-ignore */}
1. <strong>Повторная отправка сообщений&#58;</strong>

    - <strong>Описание&#58;</strong> Отправитель может повторно отправить сообщение, если не получил подтверждение о доставке.

    - <strong>Проблема&#58;</strong> В случае временных сбоев или задержек подтверждение может не дойти до отправителя.

1. <strong>Повторное получение сообщений&#58;</strong>

    - <strong>Описание&#58;</strong> Получатель может повторно получать сообщение, если не отправил подтверждение о получении.

    - <strong>Проблема&#58;</strong> В случае временных сбоев подтверждение может не дойти до отправителя.

1. <strong>Сбои брокера сообщений&#58;</strong>

    - <strong>Описание&#58;</strong> Брокер сообщений может отправить дубликаты при восстановлении после сбоя.

    - <strong>Проблема&#58;</strong> Непредвиденное поведение брокера сообщений при перезапусках или восстановлении.

1. <strong>Сетевая нестабильность&#58;</strong>

    - <strong>Описание&#58;</strong> Сетевые сбои или задержки могут приводить к повторной отправке и получению сообщений.

    - <strong>Проблема&#58;</strong> Потеря или задержка пакетов в сети.

<code>Message Bus</code> обеспечивает асинхронную и надежную коммуникацию между
компонентами системы, но дубликаты могут возникать из-за повторных отправок,
сбоев и сетевой нестабильности. Для обработки дубликатов часто применяются
идемпотентные операции и уникальные идентификаторы сообщений.

:::note[Ссылки для изучения]

1. [Гайд по Message Bus](https://www.artofba.com/post/business_analysis_message_bus-1)
   :::

---

## <strong>Какие принципы построения идемпотентных сервисов знаете?</strong> [#q-14bee738d69b81088ea5ce2163b50ff0]

<strong>Принципы построения идемпотентных сервисов&#58;</strong>

{/* prettier-ignore */}
1. <strong>Уникальные идентификаторы запросов&#58;</strong>

    - Описание&#58; каждой логической операции назначают ключ идемпотентности; повторные попытки этой операции используют тот же ключ. Новый ключ на каждый повтор не предотвращает дубликаты.

    - <strong>Пример&#58;</strong> Использование UUID для каждого запроса.

1. <strong>Хранение состояния&#58;</strong>

    - <strong>Описание&#58;</strong> Сервис должен хранить состояние предыдущих операций, чтобы определить, был ли запрос уже обработан.

    - <strong>Пример&#58;</strong> Сохранение уникальных идентификаторов и результатов операций в базе данных.

1. <strong>Идемпотентные операции&#58;</strong>

    - <strong>Описание&#58;</strong> Операции должны быть разработаны так, чтобы повторное выполнение не изменяло результат.

    - <strong>Пример&#58;</strong> Обновление записи в базе данных с проверкой текущего состояния (например, проверка баланса перед обновлением).

1. <strong>Обработка на уровне приложения&#58;</strong>

    - <strong>Описание&#58;</strong> Приложение должно проверять уникальные идентификаторы и состояния запросов перед выполнением операции.

    - <strong>Пример&#58;</strong> Использование мидлвэров или фильтров для проверки идемпотентности.

1. <strong>Использование дедупликации&#58;</strong>

    - <strong>Описание&#58;</strong> Система должна уметь удалять дубликаты сообщений на уровне очереди или брокера сообщений.

    - <strong>Пример&#58;</strong> Настройка механизмов дедупликации в Apache Kafka или RabbitMQ.

1. <strong>Проверка и согласование данных&#58;</strong>

    - <strong>Описание&#58;</strong> Перед выполнением операции проверять актуальность и согласованность данных.

    - <strong>Пример&#58;</strong> Проверка текущего состояния объекта перед его изменением (например, проверка версии записи в базе данных).

#### Учебная заготовка ниже хранит состояние только в памяти и не защищена от конкурентных вызовов. Для платежей нужны долговечная запись ключа и результата, атомарность с бизнес-изменением и согласование с внешним провайдером; одного Dictionary недостаточно.

```csharp
public class PaymentService
{
    private readonly Dictionary<Guid, Payment> _processedPayments = new Dictionary<Guid, Payment>();

    public PaymentResult ProcessPayment(Payment payment)
    {
        if (_processedPayments.ContainsKey(payment.Id))
        {
            return new PaymentResult { Success = false, Message = "Payment already processed." };
        }

        // Логика обработки платежа
        _processedPayments[payment.Id] = payment;

        return new PaymentResult { Success = true, Message = "Payment processed successfully." };
    }
}
```

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

:::note[Ссылки для изучения]

1. [Идемпотентность микросервисов](https://appmaster.io/ru/glossary/idempotentnost-mikroservisov)
   :::

---

## <strong>Расскажите, как работают асинхронные методы? Чем асинхронность отличается от параллелизма?</strong> [#q-14bee738d69b81899d7ff0738fa564da]

<strong>Как работают асинхронные методы&#58;</strong>

{/* prettier-ignore */}
1. <strong>Определение&#58;</strong> Асинхронные методы позволяют выполнять операции без блокировки основного потока, освобождая его для других задач.

1. <strong>Ключевые слова&#58;</strong> В C# используются ключевые слова <code>async</code> и <code>await</code>.

    - <code>async</code><strong>&#58;</strong> Обозначает метод как асинхронный.

    - <code>await</code><strong>&#58;</strong> Приостанавливает выполнение метода до завершения асинхронной задачи.

1. <strong>Потоки&#58;</strong> Асинхронные методы не обязательно создают новые потоки, они могут использовать существующие потоки более эффективно.

1. <strong>Пример&#58;</strong>

    ```csharp
    public async Task<string> GetDataAsync()
    {
        using (var client = new HttpClient())
        {
            string result = await client.GetStringAsync("http://example.com");
            return result;
        }
    }
    ```

#### Асинхронность vs Параллелизм&#58;

<strong>Асинхронность&#58;</strong>

- <strong>Описание&#58;</strong> Выполнение задач, которые могут быть
  приостановлены и возобновлены, не блокируя основной поток. Часто используется
  для операций ввода-вывода (I/O).

- <strong>Пример&#58;</strong> Чтение данных с диска или получение данных по
  сети.

<strong>Параллелизм&#58;</strong>

- <strong>Описание&#58;</strong> Одновременное выполнение нескольких задач,
  обычно с использованием многопоточности или многоядерных процессоров.

- <strong>Пример&#58;</strong> Одновременное выполнение нескольких вычислительно
  интенсивных задач.

#### Основные различия&#58;

- <strong>Асинхронность&#58;</strong> Фокусируется на эффективном использовании
  ресурсов, приостанавливая задачи до получения данных, освобождая основной
  поток для других задач. Подходит для операций ввода-вывода.

- <strong>Параллелизм&#58;</strong> Фокусируется на одновременном выполнении
  задач, улучшая производительность путем использования нескольких потоков или
  процессоров. Подходит для вычислительных задач.

:::note[Ссылки для изучения]

1. [Параллелизм против многопоточности](https://habr.com/ru/articles/337528/)
   :::
