---
title: Платформа .NET
seo:
  title: "Платформа .NET — С# Developer"
  description: "Тема «Платформа .NET» для собеседования С# Developer. Что такое ASP.NET и чем ASP.NET Core отличается от классического ASP.NET? Какие типы фильтров есть в ASP.NET Core MVC?"
---

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

## Что такое ASP.NET и чем ASP.NET Core отличается от классического ASP.NET? [#q-14bee738d69b81baa624da73c4284d25]

ASP.NET — семейство технологий Microsoft для веб-приложений. Классический ASP.NET основан на .NET Framework; ASP.NET Core — отдельная современная кроссплатформенная платформа для .NET. Ниже классические ASMX-примеры относятся к .NET Framework.

#### Состав <code>ASP&#46;NET</code>&#58;

{/* prettier-ignore */}
1. <strong>Веб-сервисы</strong>&#58;

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

1. <strong>Программная инфраструктура</strong>&#58;

    - Набор инструментов и библиотек для разработки, тестирования и развертывания веб-приложений.

1. <strong>Модель программирования</strong>&#58;

    - Обеспечивает удобные средства для написания кода, включая поддержку серверных и клиентских сценариев, а также работу с данными.

#### Особенности&#58;

{/* prettier-ignore */}
- <strong>Интеграция с .NET Framework</strong>&#58;

    - ASP.NET входит в состав платформы .NET Framework и является развитием более старой технологии Microsoft ASP, предлагая улучшенные возможности и производительность.

ASP.NET предоставляет мощные инструменты и возможности для разработки современных веб-приложений, включая поддержку веб-сервисов, программной инфраструктуры и удобной модели программирования, интегрированной в .NET Framework.

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

1. [Гайд по ASP.NET](https://blog.skillfactory.ru/glossary/asp-net/)
   :::

---

## Какие типы фильтров есть в ASP.NET Core MVC? [#q-14bee738d69b81b3ac47d849246ec6d0]

Типы фильтров действий в ASP.NET Core&#58;

Основные категории фильтров ASP.NET Core MVC&#58;

{/* prettier-ignore */}
1. <strong>Фильтры авторизации (</strong><code>Authorization Filter</code><strong>)</strong>&#58;

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

1. <strong>Фильтры ресурсов (</strong><code>Resource Filter</code><strong>)</strong>&#58;

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

1. <strong>Фильтры действий (</strong><code>Action Filter</code><strong>)</strong>&#58;

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

1. <strong>Фильтры результатов (</strong><code>Result Filter</code><strong>)</strong>&#58;

    - Выполняются перед и после выполнения результата действия (например, возврат View или Json), позволяют модифицировать результат.

1. <strong>Фильтры исключений (</strong><code>Exception Filter</code><strong>)</strong>&#58;

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

#### Пример применения фильтров&#58;

```csharp
public class MyActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Логика перед выполнением действия
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Логика после выполнения действия
    }
}

public class MyExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        // Логика обработки исключений
    }
}
```

Фильтры в ASP.NET Core позволяют выполнять дополнительную логику на разных этапах обработки запроса, обеспечивая гибкость и возможность управления процессом выполнения действий и обработки результатов.

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

1. [Фильтры действий в ASP.NET](https://habr.com/ru/companies/otus/articles/774056/)
   :::

---

## <strong>Что такое</strong> <code>Web Service</code><strong>?</strong> [#q-14bee738d69b811281ffee55b98b1dd5]

<strong>Веб-службы</strong> <code>ASP&#46;NET</code> — это тип проектов
веб-приложения, которые обеспечивают бизнес-логику в интернете и используют
логику данных. Они предназначены для взаимодействия с другими веб-службами,
программами на альтернативных платформах или веб-формами.

#### Особенности веб-служб <code>ASP&#46;NET</code>&#58;

{/* prettier-ignore */}
1. <strong>Отсутствие элементов управления логикой представления</strong>&#58;

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

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

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

#### Состав веб-службы <code>ASP&#46;NET</code>&#58;

{/* prettier-ignore */}
1. <strong>Библиотека DLL</strong>&#58;

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

1. <strong>Файл ASMX</strong>&#58;

    - Определяет веб-службу и является точкой входа для запросов к веб-службе.

    ```csharp
    <%@ WebService Language="C#" CodeBehind="MyService.asmx.cs" Class="MyNamespace.MyService" %>
    ```

1. <strong>Файл Codebehind</strong>&#58;

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

    ```csharp
    using System.Web.Services;

    namespace MyNamespace
    {
        [WebService(Namespace = "http://tempuri.org/")]
        public class MyService : WebService
        {
            [WebMethod]
            public string HelloWorld()
            {
                return "Hello, World!";
            }
        }
    }
    ```

Веб-службы ASP.NET состоят из библиотеки DLL, файла ASMX и файла Codebehind, который содержит класс, специально созданный для работы с веб-службами. Они обеспечивают бизнес-логику и логику данных в интернете и предназначены для использования другими веб-службами или приложениями на различных платформах.

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

1. [Архитектура веб-служб в .NET](https://intuit.ru/studies/courses/1118/143/lecture/3963)
   :::

---

## <strong>Что такое</strong> <code>CLR</code><strong>?</strong> [#q-14bee738d69b818593fffc5620150b28]

<strong>Common Language Runtime (</strong>
<code>CLR</code>
<strong>)</strong> — это исполняющая среда для байт-кода CIL (MSIL), в который
компилируются программы, написанные на .NET-совместимых языках программирования
(C#, Managed C++, Visual Basic .NET, F#, и другие).

#### Основные компоненты <code>CLR</code>&#58;

{/* prettier-ignore */}
1. <strong>Компиляция</strong>&#58;

    - CLR компилирует код приложения на языке CIL (Common Intermediate Language) во время его исполнения (JIT-компиляция).

1. <strong>Библиотека классов</strong>&#58;

    - Предоставляет MSIL-программам доступ к библиотеке классов .NET Framework, обеспечивая доступ к стандартным функциям и службам.

#### Механизм работы <code>CLR</code>&#58;

{/* prettier-ignore */}
1. <strong>Компиляция кода</strong>&#58;

    - Программы, написанные на .NET-совместимых языках, сначала компилируются в CIL.

    - CLR затем компилирует CIL-код в машинный код во время выполнения программы.

1. <strong>Управление выполнением</strong>&#58;

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

1. <strong>Интероперабельность</strong>&#58;

    - CLR обеспечивает взаимодействие между управляемым кодом (кодом .NET) и неуправляемым кодом (кодом, который не работает под управлением CLR, например, API Windows).

#### Пример работы CLR&#58;

- Написание программы на C#&#58;

  ```csharp
  public class HelloWorld
  {
      public static void Main()
      {
          System.Console.WriteLine("Hello, World!");
      }
  }
  ```

- Компиляция в CIL&#58;
  - Программа компилируется в промежуточный язык (CIL), который затем исполняется CLR.

- Выполнение CLR&#58;
  - При запуске программы CLR компилирует CIL-код в машинный код и управляет его выполнением.

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

1. [Обзор среды CLR](https://learn.microsoft.com/ru-ru/dotnet/standard/clr)
   :::

---

## <strong>Что такое сборщик мусора (</strong><code>Garbage Collector</code><strong>) на базовом уровне?</strong> [#q-14bee738d69b8149a87dff0a98dd9e67]

<strong>Сборщик мусора (</strong>
<code>Garbage Collector</code>
<strong>)</strong> — это автоматическая система управления памятью, которая
освобождает память, занимаемую объектами, которые больше не используются в
программе.

#### Основные функции&#58;

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

    - Освобождает память недостижимых объектов, включая недостижимые циклы ссылок. Ненужный объект с достижимой ссылкой остается живым.

1. <strong>Предотвращение утечек памяти</strong>&#58;

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

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

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

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

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

1. [Основы сборки мусора](https://learn.microsoft.com/ru-ru/dotnet/standard/garbage-collection/fundamentals)
   :::

---

## <strong>Что такое делегат?</strong> [#q-14bee738d69b8137ae15c98a011af75b]

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

#### Основные функции&#58;

{/* prettier-ignore */}
1. <strong>Представление метода</strong>&#58;

    - Делегат хранит ссылку на метод и может вызвать этот метод.

1. <strong>Обратные вызовы</strong>&#58;

    - Используются для реализации обратных вызовов и событий.

1. <strong>Многоадресные делегаты</strong>&#58;

    - Делегаты могут ссылаться на несколько методов и вызывать их последовательно.

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

```csharp
// Определение делегата
public delegate void MyDelegate(string message);

// Метод, соответствующий делегату
public void ShowMessage(string message) {
    Console.WriteLine(message);
}

// Использование делегата
MyDelegate del = ShowMessage;
del("Hello, World!"); // Выведет "Hello, World!"
```

Делегат в C# представляет собой тип, который содержит ссылку на метод, позволяет передавать методы как параметры и используется для событий и обратных вызовов.

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

1. [Делегаты в C#](https://learn.microsoft.com/ru-ru/dotnet/csharp/programming-guide/delegates/)
   :::

---

## <strong>Отличается ли</strong> <code>Delegate</code> <strong>от</strong> <code>Action</code><strong>?</strong> [#q-14bee738d69b81268a97ebef18858477]

<code>Delegate</code> и <code>Action</code> — оба являются типами делегатов в
C#, но имеют некоторые отличия.

#### <code>Delegate</code>

{/* prettier-ignore */}
1. <strong>Пользовательский тип</strong>&#58;

    - System.Delegate — базовый класс типов делегатов. Ключевое слово delegate объявляет пользовательский тип делегата; это не одно и то же.

    - Пример&#58;

        ```csharp
        public delegate void MyDelegate(string message);
        ```

1. <strong>Гибкость</strong>&#58;

    - Позволяет определять делегаты с любыми параметрами и возвращаемыми значениями.

#### <code>Action</code>

{/* prettier-ignore */}
1. <strong>Предопределенный тип</strong>&#58;

    - Action — это предопределенный делегат в .NET, который представляет метод, принимающий параметры и не возвращающий значение (<code>void</code>).

    - Пример&#58;

        ```csharp
        Action<string> myAction = message => Console.WriteLine(message);
        ```

1. <strong>Ограничения</strong>&#58;

    - Action может принимать от 0 до 16 параметров, но всегда возвращает <code>void</code>.

Action — готовое семейство делегатов с результатом void; delegate позволяет объявить собственную сигнатуру. Все такие типы наследуются от System.MulticastDelegate, а через него — от System.Delegate.

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

1. [Отличие между Delegate от Action](https://stackoverflow.com/questions/18740815/what-is-the-difference-between-using-a-delegate-and-using-funct-actiont-in-a#:~:text=%D0%95%D0%B4%D0%B8%D0%BD%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B5%20%D0%BE%D1%82%D0%BB%D0%B8%D1%87%D0%B8%D0%B5%20%D0%B7%D0%B0%D0%BA%D0%BB%D1%8E%D1%87%D0%B0%D0%B5%D1%82%D1%81%D1%8F%20%D0%B2%20%D1%82%D0%BE%D0%BC%2C,%D0%BF%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B%20%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE%20%D0%BF%D0%BE%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8E)
   :::

---

## <strong>Что такое</strong> <code>LINQ</code> <strong>и для чего используется? Приведите несколько примеров применения</strong> <code>LINQ</code><strong>.</strong> [#q-14bee738d69b81eda476c98c8c9d515b]

<code>LINQ</code> <strong>(Language Integrated Query)</strong> — это технология
в .NET, которая позволяет выполнять запросы к коллекциям данных прямо в коде,
используя синтаксис, аналогичный SQL.

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

{/* prettier-ignore */}
1. <strong>Запросы к коллекциям объектов</strong>&#58;

    - LINQ to Objects&#58; Выполнение запросов к коллекциям в памяти (например, массивы, списки).

1. <strong>Запросы к базам данных</strong>&#58;

    - LINQ to SQL / LINQ to Entities&#58; Выполнение запросов к реляционным базам данных через ORM (например, Entity Framework).

1. <strong>Запросы к XML</strong>&#58;

    - LINQ to XML&#58; Выполнение запросов к XML-документам.

#### Примеры применения <code>LINQ</code>&#58;

1. <strong>LINQ to Objects</strong>&#58;

   ```sql
   var numbers = new List<int> { 1, 2, 3, 4, 5 };
   var evenNumbers = from n in numbers
                     where n % 2 == 0
                     select n;
   foreach (var num in evenNumbers) {
       Console.WriteLine(num); // Выведет 2, 4
   }
   ```

1. <strong>LINQ to SQL</strong>&#58;

   ```sql
   using (var context = new MyDataContext()) {
       var query = from p in context.Products
                   where p.Price > 50
                   select p;
       foreach (var product in query) {
           Console.WriteLine(product.Name);
       }
   }
   ```

1. <strong>LINQ to XML</strong>&#58;

   ```sql
   var xml = XDocument.Load("data.xml");
   var items = from item in xml.Descendants("Item")
               where (int)item.Element("Price") > 100
               select item;
   foreach (var item in items) {
       Console.WriteLine(item.Element("Name").Value);
   }
   ```

LINQ используется для выполнения запросов к различным типам данных (объекты, базы данных, XML) с использованием удобного и выразительного синтаксиса.

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

1. [LINQ в C#](https://metanit.com/sharp/tutorial/15.1.php)
   :::

---

## <strong>Что такое пространство имен (</strong><code>namespace</code><strong>) и зачем это нужно?</strong> [#q-14bee738d69b818f8ae3c83dda80bcf2]

<strong>Пространство имен (</strong>
<code>namespace</code>
<strong>)</strong> — это логическая группировка классов, интерфейсов, структур,
перечислений и делегатов, которая используется для организации кода и
предотвращения конфликтов имен.

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

{/* prettier-ignore */}
1. <strong>Организация кода</strong>&#58;

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

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

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

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

```csharp
namespace MyApp.Utilities
{
    public class UtilityClass
    {
        public void DoSomething() { /* ... */ }
    }
}

namespace MyApp.Models
{
    public class User
    {
        public string Name { get; set; }
    }
}
```

#### Использование&#58;

```csharp
using MyApp.Utilities;
using MyApp.Models;

class Program
{
    static void Main()
    {
        UtilityClass utility = new UtilityClass();
        utility.DoSomething();

        User user = new User { Name = "John Doe" };
        Console.WriteLine(user.Name);
    }
}
```

Пространства имен в C# используются для организации кода и предотвращения конфликтов имен, что делает код более управляемым и читаемым.

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

1. [Классы и пространства имён в C#](https://professorweb.ru/my/csharp/charp_theory/level1/1_9.php)
   :::

---

## <strong>Какие исключения нельзя остановить в блоке</strong> <code>catch</code><strong>?</strong> [#q-14bee738d69b81e0a46fd0b0f0d3d2d7]

Возможность обработки зависит от исключения и версии runtime. Переполнение стека, возникшее при выполнении, обычно завершает процесс; OutOfMemoryException можно поймать, но восстановление часто ограничено нехваткой памяти.

{/* prettier-ignore */}
1. <code>StackOverflowException</code>&#58;

    - Возникает при переполнении стека из-за чрезмерной рекурсии.

    - Пример&#58;

        ```csharp
        try {
            RecursiveMethod();
        } catch (StackOverflowException ex) {
            // Не обрабатывается
        }
        ```

1. <code>OutOfMemoryException</code>&#58;

    - Возникает, когда системе не хватает памяти для продолжения выполнения.

    - Пример&#58;

        ```csharp
        try {
            // Код, вызывающий OutOfMemoryException
        } catch (OutOfMemoryException ex) {
            // Не обрабатывается корректно
        }
        ```

1. <code>ThreadAbortException</code>&#58;

    - ThreadAbortException относится к .NET Framework&#58; после catch оно обычно выбрасывается повторно. В .NET Core и .NET 5+ Thread.Abort не поддерживается и вызывает PlatformNotSupportedException.

    - Пример&#58;

        ```csharp
        try {
            Thread.CurrentThread.Abort();
        } catch (ThreadAbortException ex) {
            // Поток будет прерван после catch
        }
        ```

1. <code>ExecutionEngineException</code>&#58;

    - ExecutionEngineException устарело&#58; современные версии runtime его не выбрасывают. Фатальную ошибку CLR нельзя считать обычным восстанавливаемым исключением.

    - Пример&#58;

        ```csharp
        try {
            // Код, вызывающий ExecutionEngineException
        } catch (ExecutionEngineException ex) {
            // Не обрабатывается корректно
        }
        ```

Не объединяйте эти случаи&#58; OutOfMemoryException перехватывается, реальное переполнение стека обычно нет, а ThreadAbortException и ExecutionEngineException требуют оговорок о версии .NET.

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

1. [Исключения из исключений в .NET](https://habr.com/ru/companies/arcadia/articles/594681/)
   :::

---

## <strong>Какая разница между</strong> <code>&#46;NET Standard Class Library</code> <strong>и</strong> <code>&#46;NET Core Class Library</code><strong>?</strong> [#q-14bee738d69b8157be7befdd1d8b7ff6]

Разница между <code>&#46;NET Standard Class Library</code> и <code>&#46;NET Core Class Library</code>&#58;

{/* prettier-ignore */}
1. <strong>.NET Standard Class Library</strong>&#58;

    - <strong>Цель</strong>&#58; Предназначена для обеспечения совместимости кода между различными реализациями .NET (например, .NET Framework, .NET Core, Xamarin).

    - <strong>Совместимость</strong>&#58; Может использоваться в любых проектах, поддерживающих .NET Standard.

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

1. <strong>.NET Core Class Library</strong>&#58;

    - <strong>Цель</strong>&#58; Предназначена для использования исключительно в .NET Core и .NET 5/6/7+ проектах.

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

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

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

1. [Разница между SCL и CSL](https://stackoverflow.com/questions/42939454/what-is-the-difference-between-net-core-and-net-standard-class-library-project)
   :::

---

## <strong>Объясните разницу между отложенным и немедленным исполнением в</strong> <code>LINQ</code><strong>. Приведите примеры.</strong> [#q-14bee738d69b81ce8398e225b6370e07]

<strong>Отложенное выполнение (</strong>
<code>Deferred Execution</code>
<strong>)</strong>&#58;

- Запрос не выполняется сразу, а только при фактическом доступе к данным (например, при переборе результатов).

- Примеры методов&#58; <code>Select</code>, <code>Where</code>, <code>Take</code>.

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

```csharp
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var query = numbers.Where(n => n > 2); // Запрос не выполнен
foreach (var number in query)
{
    Console.WriteLine(number); // Запрос выполняется здесь
}
```

<strong>Немедленное выполнение (</strong>
<code>Immediate Execution</code>
<strong>)</strong>&#58;

- Запрос выполняется сразу и возвращает результаты в виде коллекции или другого значения.

- Примеры методов&#58; <code>ToList</code>, <code>ToArray</code>, <code>Count</code>, <code>First</code>.

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

```csharp
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var results = numbers.Where(n => n > 2).ToList(); // Запрос выполнен немедленно
foreach (var number in results)
{
    Console.WriteLine(number); // Доступ к уже выполненным результатам
}
```

#### Итог&#58;

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

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

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

1. [Отложенное и немедленное исполнение в LINQ](https://metanit.com/sharp/tutorial/15.8.php)
   :::

---

## <strong>Для чего нужен метод</strong> <code>ConfigureServices</code> <strong>в</strong> <code>Startup&#46;cs</code><strong>?</strong> [#q-14bee738d69b81e5b312d30bb3d82a4e]

<strong>Метод</strong> <code>ConfigureServices</code> в файле
<code>Startup&#46;cs</code> используется для настройки служб (сервисов)
приложения в ASP.NET Core.

#### Основные задачи&#58;

{/* prettier-ignore */}
1. <strong>Регистрация служб</strong>&#58;

    - Добавление служб в контейнер внедрения зависимостей (Dependency Injection).

    - Примеры служб&#58; базы данных, кэширование, аутентификация.

1. <strong>Конфигурация параметров</strong>&#58;

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

1. <strong>Добавление middleware</strong>&#58;

    - Регистрация зависимостей middleware возможна здесь, но сам HTTP-конвейер задается вызовами app.Use... в Configure или Program.cs.

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

```csharp
public void ConfigureServices(IServiceCollection services)
{
    // Регистрация службы базы данных
    services.AddDbContext<MyDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    // Регистрация служб MVC
    services.AddControllersWithViews();

    // Регистрация пользовательских служб
    services.AddScoped<IMyService, MyService>();
}
```

ConfigureServices регистрирует службы в DI-контейнере. В современном минимальном хостинге это обычно builder.Services в Program.cs; порядок middleware задается отдельно.

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

1. [Класс Startup и Program.cs](https://habr.com/ru/companies/otus/articles/542494/)
   :::

---

## Чем отличаются AddTransient и AddScoped в ASP.NET Core? [#q-14bee738d69b810eb762dd6b1c1f77c2]

Разница между <code>services&#46;AddTransient</code> и <code>services&#46;AddScoped</code> в ASP.NET Core&#58;

{/* prettier-ignore */}
1. <code>services&#46;AddTransient</code>&#58;

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

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

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

        ```csharp
        services.AddTransient<IMyService, MyService>();
        ```

1. <code>services&#46;AddScoped</code>&#58;

    - Время жизни&#58; один экземпляр на DI-scope. В обычном HTTP-конвейере ASP.NET Core scope создается для каждого запроса; scope также можно создать явно.

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

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

        ```csharp
        services.AddScoped<IMyService, MyService>();
        ```

#### Итог&#58;

- <code>AddTransient</code>&#58; Создает новый экземпляр каждый раз при запросе.

- AddScoped&#58; один экземпляр на scope, обычно на HTTP-запрос.

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

1. [Разница между AddTransient и AddScope](https://habr.com/ru/companies/otus/articles/539762/)
   :::

---

## <strong>Что такое</strong> <code>Kestrel</code><strong>?</strong> [#q-14bee738d69b8194b64fdcafd050b276]

<code>Kestrel</code> — это кроссплатформенный, высокопроизводительный
HTTP-сервер, встроенный в ASP.NET Core.

#### Основные особенности&#58;

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

    - Разработан для обеспечения высокой скорости обработки запросов.

1. <strong>Кроссплатформенность</strong>&#58;

    - Работает на Windows, Linux и macOS.

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

    - Используется как встроенный веб-сервер для обработки HTTP-запросов в ASP.NET Core приложениях.

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

```csharp
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseKestrel();
                webBuilder.UseStartup<Startup>();
            });
}
```

<code>Kestrel</code> — это высокопроизводительный, кроссплатформенный
HTTP-сервер для [ASP.NET](http://asp.net/) Core приложений, используемый для
обработки HTTP-запросов.

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

1. [Kestrel веб-сервис в ASP.NET](https://learn.microsoft.com/ru-ru/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-8.0)
   :::

---

## <strong>Опишите</strong> <code>ASP&#46;NET</code> <code>MVC</code> <code>request pipeline</code><strong>.</strong> [#q-14bee738d69b819fa569cccad7f567b8]

<code>ASP&#46;NET</code> <code>MVC</code> <code>request pipeline</code> — это
последовательность этапов обработки HTTP-запроса, который проходит через
приложение ASP.NET MVC.

#### Основные этапы&#58;

{/* prettier-ignore */}
1. <strong>Маршрутизация (Routing)</strong>&#58;

    - Запрос сопоставляется с маршрутами, определенными в приложении.

    - Пример&#58; <code>routes&#46;MapRoute&#40;&#34;default&#34;&#44; &#34;&#123;controller&#61;Home&#125;&#47;&#123;action&#61;Index&#125;&#47;&#123;id&#63;&#125;&#34;&#41;&#59;</code>

1. <strong>Инициализация контроллера (Controller Initialization)</strong>&#58;

    - На основе маршрута создается экземпляр соответствующего контроллера.

1. <strong>Выполнение действия (Action Execution)</strong>&#58;

    - Контроллер вызывает метод действия, соответствующий запрашиваемому маршруту.

    - Пример&#58; <code>public IActionResult Index&#40;&#41; &#123; &#47;&#42; &#46;&#46;&#46; &#42;&#47; &#125;</code>

1. <strong>Обработка результатов действия (Result Execution)</strong>&#58;

    - Метод действия возвращает результат (например, представление или JSON-данные), который обрабатывается.

1. <strong>Генерация ответа (Response Generation)</strong>&#58;

    - Созданный результат (например, HTML-страница) отправляется обратно клиенту.

#### Пример запроса&#58;

{/* prettier-ignore */}
1. <strong>Запрос</strong>&#58;

    - Клиент отправляет запрос&#58; <code>GET &#47;Home&#47;Index</code>

1. <strong>Маршрутизация</strong>&#58;

    - Маршрут <code>&#47;Home&#47;Index</code> сопоставляется с <code>HomeController</code> и методом <code>Index</code>.

1. <strong>Инициализация контроллера</strong>&#58;

    - Создается экземпляр <code>HomeController</code>.

1. <strong>Выполнение действия</strong>&#58;

    - Вызывается метод <code>Index</code> контроллера.

1. <strong>Обработка результата</strong>&#58;

    - Метод <code>Index</code> возвращает представление.

1. <strong>Генерация ответа</strong>&#58;

    - Представление рендерится в HTML и отправляется клиенту.

ASP.NET MVC request pipeline обрабатывает запросы через последовательность этапов&#58; маршрутизация, инициализация контроллера, выполнение действия, обработка результата и генерация ответа, обеспечивая гибкость и управляемость процесса обработки запросов.

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

1. [Обработка в ASP.NET](https://habr.com/ru/articles/62694/)
   :::

---

## <strong>Как в</strong> <code>ASP&#46;NET</code> <code>WebAPI</code> <strong>настроить кэширование ответов на HTTP-запросы?</strong> [#q-14bee738d69b81eb9234c3bb315f5db1]

Для настройки кэширования ответов на HTTP-запросы в ASP.NET WebAPI можно использовать заголовки <code>Cache&#45;Control</code> и <code>Expires</code>, а также атрибуты кэширования.

#### Основные методы&#58;

{/* prettier-ignore */}
1. Кэширование ответа в ASP.NET Core&#58;

    - ResponseCache задает HTTP-заголовки кэширования, но сам не хранит ответы на сервере. Для серверного output caching в ASP.NET Core 7+ нужны AddOutputCache, UseOutputCache и соответствующая политика. Классический System.Web.Mvc.OutputCache не работает как фильтр ApiController.

    ```csharp
    [HttpGet]
    [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)]
    public IActionResult Get()
    {
        return Ok("Hello, World!");
    }
    ```

1. <strong>Использование</strong> <code>middleware</code>&#58;

    - Для более гибкой настройки кэширования можно использовать middleware для управления заголовками кэширования.

    ```csharp
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.Use(async (context, next) =>
        {
            context.Response.Headers["Cache-Control"] = "public,max-age=60";
            await next();
        });

        app.UseMvc();
    }
    ```

1. <strong>Настройка кэширования с помощью</strong> <code>ResponseCacheAttribute</code>&#58;

    - В ASP.NET Core можно использовать атрибут <code>ResponseCache</code> для настройки кэширования.

    ```csharp
    [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client, NoStore = false)]
    public IActionResult Get()
    {
        // Ваш код
        return Ok();
    }
    ```

1. <strong>Настройка кэширования на стороне клиента</strong>&#58;

    - Использование заголовков HTTP, таких как <code>Cache&#45;Control</code> и <code>Expires</code>, для управления кэшированием на стороне клиента.

    ```csharp
    [HttpGet]
    public HttpResponseMessage Get()
    {
        var response = Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent("Hello, World!");
        response.Headers.CacheControl = new CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromMinutes(1)
        };
        return response;
    }
    ```

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

1. Пример серверного OutputCache в ASP.NET Core 7+&#58;

   ```csharp
   // Program.cs, ASP.NET Core 7+
   var builder = WebApplication.CreateBuilder(args);
   builder.Services.AddOutputCache();
   var app = builder.Build();
   app.UseOutputCache();
   app.MapGet("/api/data", () => new { Message = "Hello" })
       .CacheOutput(policy => policy.Expire(TimeSpan.FromSeconds(60)));
   app.Run();
   ```

1. <strong>Использование атрибута</strong> <code>ResponseCache</code>
   <strong>в ASP.NET Core WebAPI</strong>&#58;

   ```csharp
   [ApiController]
   [Route("api/[controller]")]
   public class MyApiController : ControllerBase
   {
       [HttpGet]
       [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any, NoStore = false)]
       public IActionResult Get()
       {
           var data = new { Message = "Hello" };
           return Ok(data);
       }
   }
   ```

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

1. [Кэширование ответов в ASP.NET](https://learn.microsoft.com/ru-ru/aspnet/core/performance/caching/response?view=aspnetcore-8.0)
   :::

---

## <strong>Расскажите о</strong> <code>Rest Maturity Model</code> [#q-14bee738d69b813aa802f0f6bfdb94f2]

<code>REST Maturity Model</code> (Модель зрелости REST) – это модель,
предложенная Леонардом Ричардсоном, для оценки зрелости REST API на основе их
соответствия архитектурным принципам REST.

#### Уровни зрелости&#58;

{/* prettier-ignore */}
1. <strong>Уровень 0 – Отсутствие REST&#58;</strong>

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

    - <strong>Пример&#58;</strong> SOAP или XML-RPC, где все взаимодействие происходит через один URI и один метод.

1. <strong>Уровень 1 – Использование ресурсов&#58;</strong>

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

    - <strong>Пример&#58;</strong> API, где каждый ресурс (например, <code>&#47;users</code>, <code>&#47;orders</code>) имеет свой собственный URI, но все еще используется только один HTTP метод (обычно POST).

1. <strong>Уровень 2 – Использование HTTP методов&#58;</strong>

    - <strong>Описание&#58;</strong> Использование стандартных HTTP методов (GET, POST, PUT, DELETE) для выполнения операций на ресурсах.

    - <strong>Пример&#58;</strong> API, где используется GET для чтения, POST для создания, PUT для обновления и DELETE для удаления ресурсов.

1. <strong>Уровень 3 – Гипермедиа (HATEOAS)&#58;</strong>

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

    - <strong>Пример&#58;</strong> В ответе на запрос включены ссылки на связанные действия или ресурсы (например, <code>&#123;&#34;self&#34;&#58; &#34;&#47;orders&#47;1&#34;&#44; &#34;cancel&#34;&#58; &#34;&#47;orders&#47;1&#47;cancel&#34;&#125;</code>).

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

1. [Является ли ваша служба RESTful?](https://habr.com/ru/articles/319984/)
   :::

---

## <strong>Для чего используются и как работают</strong> <code>multi&#45;stage</code> <strong>билды в Docker?</strong> [#q-14bee738d69b81e39e34cb9db1a88e69]

<code>Multi&#45;stage</code> <strong>билды в Docker</strong> используются для
создания оптимизированных Docker-образов, уменьшая их размер и улучшая
безопасность. Это достигается путем разделения процесса сборки на несколько
этапов, где промежуточные этапы не включаются в финальный образ.

#### Как работают <code>multi&#45;stage</code> билды&#58;

{/* prettier-ignore */}
1. <strong>Разделение на этапы&#58;</strong>

    - В Dockerfile определяется несколько этапов сборки с использованием ключевого слова <code>FROM</code> для каждого этапа.

    - Каждый этап может использовать разные базовые образы и выполнять различные действия.

1. <strong>Копирование артефактов&#58;</strong>

    - Результаты (артефакты) из одного этапа могут быть скопированы в следующий этап с помощью команды <code>COPY &#45;&#45;from&#61;stage&#95;name</code>.

1. <strong>Финальный минимальный образ&#58;</strong>

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

#### Пример использования <code>multi&#45;stage</code> билдов в Dockerfile&#58;

```dockerfile
# Первый этап: сборка приложения
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o out

# Второй этап: создание минимального образа для выполнения
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "MyApp.dll"]
```

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

{/* prettier-ignore */}
1. <strong>Уменьшение размера образа&#58;</strong>

    - Финальный образ содержит только необходимые файлы и зависимости, что снижает размер образа.

1. <strong>Повышение безопасности&#58;</strong>

    - Исключение инструментов сборки и временных файлов уменьшает поверхность атаки.

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

    - Отделение этапов сборки и выполнения позволяет четко управлять зависимостями.

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

1. [What is multi-stage on Docker?](https://www.geeksforgeeks.org/what-is-an-multistage-dockerfile/)
   :::

---

## <strong>Что такое маршалинг?</strong> [#q-14bee738d69b8181aee7fb794cd21986]

<strong>Маршалинг (</strong>
<code>Marshaling</code>
<strong>)</strong> – это процесс преобразования объектов или данных из одного
формата или контекста в другой, для передачи между различными компонентами
программного обеспечения или между разными средами выполнения.

#### Основные применения&#58;

{/* prettier-ignore */}
1. <strong>Межпроцессное взаимодействие (Inter-process communication, IPC)&#58;</strong>

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

1. <strong>Удаленные вызовы процедур (Remote Procedure Calls, RPC)&#58;</strong>

    - Вызов методов или процедур на удаленных серверах, часто с использованием сетевых протоколов.

1. <strong>Интеграция разных технологий&#58;</strong>

    - Взаимодействие между компонентами, написанными на разных языках программирования или работающими в разных средах (например, взаимодействие между C# и COM-объектами).

#### Пример использования маршалинга в C#&#58;

<strong>P/Invoke для вызова нативного кода&#58;</strong>

```csharp
using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);

    static void Main()
    {
        MessageBox(IntPtr.Zero, "Hello, World!", "Hello", 0);
    }
}
```

#### Основные задачи маршалинга&#58;

{/* prettier-ignore */}
1. <strong>Преобразование данных&#58;</strong>

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

1. <strong>Управление памятью&#58;</strong>

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

1. <strong>Сериализация и десериализация&#58;</strong>

    - Преобразование объектов в формат, пригодный для хранения или передачи (например, JSON, XML) и обратно.

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

1. [Маршалинг типов в .NET](https://docs.microsoft.com/ru-ru/dotnet/standard/native-interop/type-marshaling#:~:text=%D0%9C%D0%B0%D1%80%D1%88%D0%B0%D0%BB%D0%B8%D0%BD%D0%B3%20%E2%80%94%20%D1%8D%D1%82%D0%BE%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%20%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F,%D0%B2%20%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D0%BC%D0%BE%D0%BC%20%D0%B8%20%D0%BD%D0%B5%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D0%BC%D0%BE%D0%BC%20%D0%BA%D0%BE%D0%B4%D0%B5)
   :::

---

## <strong>Как работает</strong> <code>async</code> <strong>/</strong> <code>await</code> <strong>(подробно)? Почему нельзя использовать</strong> <code>async void</code> <strong>методы?</strong> [#q-14bee738d69b816eab32d0cb14492359]

<code>async &#47; await</code>
<strong>&#58;</strong>

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

{/* prettier-ignore */}
1. <code>async</code> <strong>метод&#58;</strong>

    - Определяет метод как асинхронный, позволяет использовать await внутри метода.

    - Возвращает <code>Task</code> или <code>Task&#60;T&#62;</code>, что позволяет методам асинхронно ожидать завершения.

1. <code>await</code> <strong>метод&#58;</strong>

    - Приостанавливает выполнение метода до завершения ожидаемой задачи.

    - Возвращает управление вызывающему потоку, позволяя выполнять другие задачи.

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

```csharp
public async Task<int> FetchDataAsync()
{
    HttpClient client = new HttpClient();
    string data = await client.GetStringAsync("http://example.com");
    return data.Length;
}
```

#### <code>async void</code> методы

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

{/* prettier-ignore */}
1. <strong>Нет возможности</strong> <code>await</code><strong>&#58;</strong>

    - Невозможно ожидать завершения async void метода, что затрудняет обработку ошибок и отладку.

1. <strong>Обработка исключений&#58;</strong>

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

1. <strong>Потеря возможности компоновки&#58;</strong>

    - Методы, возвращающие <code>Task</code>, могут быть легко комбинированы и использованы в других асинхронных операциях.

<strong>Использование&#58;</strong>

- <code>async void</code> следует использовать только для обработчиков событий,
  где нет необходимости в возвращаемом значении или обработке ошибок.

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

```csharp
private async void Button_Click(object sender, EventArgs e)
{
    await FetchDataAsync();
}
```

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

- <strong>async / await</strong> позволяет писать асинхронный код, который
  выглядит синхронным, улучшая читаемость и поддержку.

- <strong>async void</strong> следует избегать, кроме как в обработчиках
  событий, из-за проблем с обработкой ошибок и невозможностью ожидания
  завершения.

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

1. [Асинхронное ключевое слово](https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/async)
   :::

---

## <strong>Как работает</strong> <code>lock</code><strong>? Можно ли использовать структуры внутри выражения</strong> <code>lock</code><strong>?</strong> [#q-14bee738d69b8178935bfbaa3c57cc79]

<code>lock</code> <strong>в C#&#58;</strong>

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

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

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

- <strong>Механизм&#58;</strong> Использует объект-закрытие (object lock), чтобы
  определить область блокировки. Внутри <code>lock</code> блокируется указанное
  объектное выражение, и освобождается после выхода из блока.

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

```csharp
private static readonly object _lockObject = new object();

public void CriticalSection()
{
    lock (_lockObject)
    {
        // Код внутри этого блока может быть выполнен только одним потоком одновременно
    }
}
```

#### Использование структур в lock

<strong>Можно ли использовать структуры&#58;</strong>

- <strong>Нет, нельзя&#58;</strong> Нельзя использовать структуры (значимые
  типы) внутри выражения <code>lock</code>.

- <strong>Причина&#58;</strong> <code>lock</code> требует ссылочный тип
  (object), так как структуру можно легко скопировать, что приведет к
  неэффективной блокировке и потенциальным ошибкам.

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

1. [Инструкция по блокировке](https://learn.microsoft.com/ru-ru/dotnet/csharp/language-reference/statements/lock)
   :::

---

## <strong>Что такое</strong> <code>Expression Tree</code><strong>?</strong> [#q-14bee738d69b81b1b3d5d1e247509194]

<code>Expression Tree</code> <strong>(Дерево выражений)</strong> – это структура
данных в .NET, которая представляет синтаксическое дерево выражения кода,
позволяя анализировать и выполнять код во время выполнения.

<strong>Возможности&#58;</strong>

{/* prettier-ignore */}
1. <strong>Динамическое создание и модификация кода&#58;</strong>

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

1. <strong>Компиляция и выполнение&#58;</strong>

    - Выражения могут быть скомпилированы в исполняемый код и выполнены.

1. <strong>Анализ и трансформация&#58;</strong>

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

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

```csharp
using System;
using System.Linq.Expressions;

class Program
{
    static void Main()
    {
        // Создание параметра для выражения
        ParameterExpression param = Expression.Parameter(typeof(int), "x");

        // Создание выражения для x * 2
        Expression multiply = Expression.Multiply(param, Expression.Constant(2));

        // Создание лямбда-выражения
        Expression<Func<int, int>> lambda = Expression.Lambda<Func<int, int>>(multiply, param);

        // Компиляция и выполнение
        Func<int, int> compiled = lambda.Compile();
        int result = compiled(5);

        Console.WriteLine(result); // Вывод: 10
    }
}
```

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

1. [Expression Trees в C#](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/expression-trees/)
   :::

---

## <strong>Как в</strong> <code>&#46;NET Core</code> <strong>можно настроить хранение секретов на компьютерах разработчиков и на рабочих средах?</strong> [#q-14bee738d69b81a5a067ece905efcae0]

В <code>&#46;NET Core</code> можно настроить хранение секретов на компьютерах разработчиков и на рабочих средах с помощью следующих подходов&#58;

#### На компьютерах разработчиков&#58;

{/* prettier-ignore */}
1. <strong>Secret Manager&#58;</strong>

    - Описание&#58; Secret Manager держит секреты разработки вне проекта. Он не шифрует хранилище и не предназначен для производственной среды.

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

    - <strong>Команды&#58;</strong>

        ```csharp
        # Установка Secret Manager
        dotnet user-secrets init

        # Добавление секретов
        dotnet user-secrets set "MySecret" "Value"
        ```

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

        ```csharp
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = new ConfigurationBuilder()
                    .AddUserSecrets<Program>();
                var configuration = builder.Build();

                string mySecret = configuration["MySecret"];
                // Передайте секрет нужному компоненту; не выводите его в лог.
            }
        }
        ```

#### На рабочих средах&#58;

{/* prettier-ignore */}
1. <strong>Переменные окружения (Environment Variables)&#58;</strong>

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

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

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

        ```csharp
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = new ConfigurationBuilder()
                    .AddEnvironmentVariables();
                var configuration = builder.Build();

                string mySecret = configuration["MySecret"];
                // Передайте секрет нужному компоненту; не выводите его в лог.
            }
        }
        ```

1. <strong>Azure Key Vault&#58;</strong>

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

    - <strong>Настройка&#58;</strong>

        - Создать хранилище секретов в Azure Key Vault.

        - Настроить доступ для приложения.

    - <strong>Пример кода для чтения секретов из Key Vault&#58;</strong>

        ```csharp
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = new ConfigurationBuilder()
                    .AddAzureKeyVault(new Uri("https://<your-keyvault-name>.vault.azure.net/"),
                        new Azure.Identity.DefaultAzureCredential());
                var configuration = builder.Build();

                string mySecret = configuration["MySecret"];
                // Передайте секрет нужному компоненту; не выводите его в лог.
            }
        }
        ```

Для хранения секретов на компьютерах разработчиков в .NET Core используется Secret Manager. На рабочих средах предпочтительны переменные окружения или более защищенные решения, такие как Azure Key Vault, для управления и защиты секретов.

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

1. [Безопасное хранение секретов приложений в разработке](https://learn.microsoft.com/ru-ru/aspnet/core/security/app-secrets?view=aspnetcore-8.0&tabs=windows)
   :::

---

## <strong>Как включить</strong> <code>CORS</code> <strong>в</strong> <code>AspNetCore</code><strong>?</strong> [#q-14bee738d69b81f19501f585e875f3a5]

<strong>Включение</strong> <code>CORS</code> <strong>в</strong>
<code>ASP&#46;NET Core</code>
<strong>&#58;</strong>

#### Шаги&#58;

{/* prettier-ignore */}
1. <strong>Добавить сервисы</strong> <code>CORS</code> <strong>в</strong> <code>Startup&#46;cs</code><strong>&#58;</strong>

    - В методе <code>ConfigureServices</code> добавить сервисы CORS с нужной политикой.

    ```csharp
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigin",
                builder =>
                {
                    builder.WithOrigins("http://example.com")
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
        });

        services.AddControllers();
    }
    ```

1. <strong>Включить</strong> <code>CORS</code> <strong>в обработке запросов&#58;</strong>

    - В методе <code>Configure</code> добавить использование CORS.

    ```csharp
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseCors("AllowSpecificOrigin");

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    ```

1. <strong>(Опционально) Настроить</strong> <code>CORS</code> <strong>на уровне контроллера или действия&#58;</strong>

    - Использовать атрибут <code>&#91;EnableCors&#93;</code> для настройки CORS на уровне контроллера или действия.

    ```csharp
    [ApiController]
    [Route("[controller]")]
    public class MyController : ControllerBase
    {
        [EnableCors("AllowSpecificOrigin")]
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("CORS is enabled!");
        }
    }
    ```

Включение <code>CORS</code> в <code>ASP&#46;NET Core</code> включает добавление и настройку сервиса <code>CORS</code> в <code>Startup&#46;cs</code>, и его применение в конвейере обработки запросов. Это позволяет управлять политиками доступа для кросс-доменных запросов.

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

1. [Включение запросов CORS в ASP.NET Core](https://learn.microsoft.com/ru-ru/aspnet/core/security/cors?view=aspnetcore-8.0)
   :::

---

## <strong>Что такое</strong> <code>CPU</code> <strong>и</strong> <code>IO&#45;bound</code> <strong>задачи?</strong> [#q-14bee738d69b81c1a27de67b5df9ed2e]

<code>CPU&#45;bound</code> <strong>задачи&#58;</strong>

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

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

- Сложные вычисления (например, вычисление факториала больших чисел).

- Обработка изображений и видео.

- Шифрование и дешифрование данных.

<strong>Оптимизация&#58;</strong>

- Увеличение мощности процессора.

- Параллелизация задач (многопоточность, многопроцессорность).

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

```csharp
void CalculateFactorial()
{
    long result = 1;
    for (int i = 1; i <= 20; i++)
    {
        result *= i;
    }
    Console.WriteLine(result);
}
```

<code>IO&#45;bound</code> <strong>задачи&#58;</strong>

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

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

- Чтение и запись файлов.

- Запросы к базам данных.

- Сетевые запросы (HTTP, FTP).

<strong>Оптимизация&#58;</strong>

- Асинхронное выполнение (async/await).

- Параллельное выполнение операций ввода-вывода.

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

```csharp
async Task ReadFileAsync()
{
    using (var reader = new StreamReader("file.txt"))
    {
        string content = await reader.ReadToEndAsync();
        Console.WriteLine(content);
    }
}
```

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

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

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

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

1. [CPU и IO-Bound задачи](https://backendinterview.ru/os#:~:text=CPU%2DBound%20%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8%20%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B6%D0%B0%D1%8E%D1%82%20%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5%20%D0%BC%D0%BE%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B8,%D1%85%D0%B2%D0%B0%D1%82%D0%B8%D1%82%20%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D0%BE%D0%B2%20%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%80%D0%B5%D0%B7%D1%83%D0%BB%D1%8C%D1%82%D0%B0%D1%82%D1%8B)
   :::
