Перейти к содержимому
шпаргалка.
Esc
навигацияоткрыть⌘Jпредпросмотр
На этой странице

Платформа .NET

Все темы С# Developer

Что такое ASP.NET и чем ASP.NET Core отличается от классического ASP.NET?

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

Состав ASP.NET:

  1. Веб-сервисы:

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

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

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

Особенности:

  • Интеграция с .NET Framework:

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

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


Какие типы фильтров есть в ASP.NET Core MVC?

Типы фильтров действий в ASP.NET Core:

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

  1. Фильтры авторизации (Authorization Filter):

    • Фильтры авторизации проверяют право доступа первыми в конвейере фильтров. Аутентификацию обычно выполняет middleware, а не фильтр действия.
  2. Фильтры ресурсов (Resource Filter):

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

    • Выполняются перед и после выполнения метода действия контроллера, позволяют изменять аргументы метода или обрабатывать результаты выполнения.
  4. Фильтры результатов (Result Filter):

    • Выполняются перед и после выполнения результата действия (например, возврат View или Json), позволяют модифицировать результат.
  5. Фильтры исключений (Exception Filter):

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

Пример применения фильтров:

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 позволяют выполнять дополнительную логику на разных этапах обработки запроса, обеспечивая гибкость и возможность управления процессом выполнения действий и обработки результатов.


Что такое Web Service?

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

Особенности веб-служб ASP.NET:

  1. Отсутствие элементов управления логикой представления:

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

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

Состав веб-службы ASP.NET:

  1. Библиотека DLL:

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

    • Определяет веб-службу и является точкой входа для запросов к веб-службе.
    <%@ WebService Language="C#" CodeBehind="MyService.asmx.cs" Class="MyNamespace.MyService" %>
  3. Файл Codebehind:

    • Содержит класс, специально созданный для работы с веб-службами, реализующий методы, доступные для вызова.
    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, который содержит класс, специально созданный для работы с веб-службами. Они обеспечивают бизнес-логику и логику данных в интернете и предназначены для использования другими веб-службами или приложениями на различных платформах.


Что такое CLR?

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

Основные компоненты CLR:

  1. Компиляция:

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

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

Механизм работы CLR:

  1. Компиляция кода:

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

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

  2. Управление выполнением:

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

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

Пример работы CLR:

  • Написание программы на C#:

    public class HelloWorld
    {
        public static void Main()
        {
            System.Console.WriteLine("Hello, World!");
        }
    }
  • Компиляция в CIL:

    • Программа компилируется в промежуточный язык (CIL), который затем исполняется CLR.
  • Выполнение CLR:

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

Что такое сборщик мусора (Garbage Collector) на базовом уровне?

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

Основные функции:

  1. Освобождение памяти:

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

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

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

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


Что такое делегат?

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

Основные функции:

  1. Представление метода:

    • Делегат хранит ссылку на метод и может вызвать этот метод.
  2. Обратные вызовы:

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

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

Пример:

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

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

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

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


Отличается ли Delegate от Action?

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

Delegate

  1. Пользовательский тип:

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

    • Пример:

      public delegate void MyDelegate(string message);
  2. Гибкость:

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

Action

  1. Предопределенный тип:

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

    • Пример:

      Action<string> myAction = message => Console.WriteLine(message);
  2. Ограничения:

    • Action может принимать от 0 до 16 параметров, но всегда возвращает void.

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


Что такое LINQ и для чего используется? Приведите несколько примеров применения LINQ.

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

Основные использования:

  1. Запросы к коллекциям объектов:

    • LINQ to Objects: Выполнение запросов к коллекциям в памяти (например, массивы, списки).
  2. Запросы к базам данных:

    • LINQ to SQL / LINQ to Entities: Выполнение запросов к реляционным базам данных через ORM (например, Entity Framework).
  3. Запросы к XML:

    • LINQ to XML: Выполнение запросов к XML-документам.

Примеры применения LINQ:

  1. LINQ to Objects:

    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
    }
  2. LINQ to 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);
        }
    }
  3. LINQ to XML:

    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) с использованием удобного и выразительного синтаксиса.


Что такое пространство имен (namespace) и зачем это нужно?

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

Зачем это нужно:

  1. Организация кода:

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

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

Пример:

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

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

Использование:

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# используются для организации кода и предотвращения конфликтов имен, что делает код более управляемым и читаемым.


Какие исключения нельзя остановить в блоке catch?

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

  1. StackOverflowException:

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

    • Пример:

      try {
          RecursiveMethod();
      } catch (StackOverflowException ex) {
          // Не обрабатывается
      }
  2. OutOfMemoryException:

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

    • Пример:

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

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

    • Пример:

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

    • ExecutionEngineException устарело: современные версии runtime его не выбрасывают. Фатальную ошибку CLR нельзя считать обычным восстанавливаемым исключением.

    • Пример:

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

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


Какая разница между .NET Standard Class Library и .NET Core Class Library?

Разница между .NET Standard Class Library и .NET Core Class Library:

  1. .NET Standard Class Library:

    • Цель: Предназначена для обеспечения совместимости кода между различными реализациями .NET (например, .NET Framework, .NET Core, Xamarin).

    • Совместимость: Может использоваться в любых проектах, поддерживающих .NET Standard.

    • Пример: Подходит для создания библиотек, которые должны работать на разных платформах.

  2. .NET Core Class Library:

    • Цель: Предназначена для использования исключительно в .NET Core и .NET 5/6/7+ проектах.

    • Совместимость: Ограничена только .NET Core и последующими версиями .NET.

    • Пример: Подходит для создания библиотек, которые используют специфичные для .NET Core функции и не планируются для использования на других платформах.


Объясните разницу между отложенным и немедленным исполнением в LINQ. Приведите примеры.

Отложенное выполнение ( Deferred Execution ):

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

  • Примеры методов: Select, Where, Take.

Пример:
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); // Запрос выполняется здесь
}

Немедленное выполнение ( Immediate Execution ):

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

  • Примеры методов: ToList, ToArray, Count, First.

Пример:
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); // Доступ к уже выполненным результатам
}

Итог:

  • Отложенное выполнение: Запрос выполняется только при фактическом доступе к данным.

  • Немедленное выполнение: Запрос выполняется сразу и результаты сохраняются.


Для чего нужен метод ConfigureServices в Startup.cs?

Метод ConfigureServices в файле Startup.cs используется для настройки служб (сервисов) приложения в ASP.NET Core.

Основные задачи:

  1. Регистрация служб:

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

    • Примеры служб: базы данных, кэширование, аутентификация.

  2. Конфигурация параметров:

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

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

Пример:

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 задается отдельно.


Чем отличаются AddTransient и AddScoped в ASP.NET Core?

Разница между services.AddTransient и services.AddScoped в ASP.NET Core:

  1. services.AddTransient:

    • Время жизни: Создает новый экземпляр службы каждый раз при ее запросе.

    • Использование: Подходит для легковесных, статeless служб.

    • Пример:

      services.AddTransient<IMyService, MyService>();
  2. services.AddScoped:

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

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

    • Пример:

      services.AddScoped<IMyService, MyService>();

Итог:

  • AddTransient: Создает новый экземпляр каждый раз при запросе.

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


Что такое Kestrel?

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

Основные особенности:

  1. Высокая производительность:

    • Разработан для обеспечения высокой скорости обработки запросов.
  2. Кроссплатформенность:

    • Работает на Windows, Linux и macOS.
  3. Обработка HTTP-запросов:

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

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

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>();
            });
}

Kestrel — это высокопроизводительный, кроссплатформенный HTTP-сервер для ASP.NET Core приложений, используемый для обработки HTTP-запросов.


Опишите ASP.NET MVC request pipeline.

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

Основные этапы:

  1. Маршрутизация (Routing):

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

    • Пример: routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");

  2. Инициализация контроллера (Controller Initialization):

    • На основе маршрута создается экземпляр соответствующего контроллера.
  3. Выполнение действия (Action Execution):

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

    • Пример: public IActionResult Index() { /* ... */ }

  4. Обработка результатов действия (Result Execution):

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

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

Пример запроса:

  1. Запрос:

    • Клиент отправляет запрос: GET /Home/Index
  2. Маршрутизация:

    • Маршрут /Home/Index сопоставляется с HomeController и методом Index.
  3. Инициализация контроллера:

    • Создается экземпляр HomeController.
  4. Выполнение действия:

    • Вызывается метод Index контроллера.
  5. Обработка результата:

    • Метод Index возвращает представление.
  6. Генерация ответа:

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

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


Как в ASP.NET WebAPI настроить кэширование ответов на HTTP-запросы?

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

Основные методы:

  1. Кэширование ответа в ASP.NET Core:

    • ResponseCache задает HTTP-заголовки кэширования, но сам не хранит ответы на сервере. Для серверного output caching в ASP.NET Core 7+ нужны AddOutputCache, UseOutputCache и соответствующая политика. Классический System.Web.Mvc.OutputCache не работает как фильтр ApiController.
    [HttpGet]
    [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)]
    public IActionResult Get()
    {
        return Ok("Hello, World!");
    }
  2. Использование middleware:

    • Для более гибкой настройки кэширования можно использовать middleware для управления заголовками кэширования.
    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();
    }
  3. Настройка кэширования с помощью ResponseCacheAttribute:

    • В ASP.NET Core можно использовать атрибут ResponseCache для настройки кэширования.
    [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client, NoStore = false)]
    public IActionResult Get()
    {
        // Ваш код
        return Ok();
    }
  4. Настройка кэширования на стороне клиента:

    • Использование заголовков HTTP, таких как Cache-Control и Expires, для управления кэшированием на стороне клиента.
    [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;
    }

Пример:

  1. Пример серверного OutputCache в ASP.NET Core 7+:

    // 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();
  2. Использование атрибута ResponseCache в ASP.NET Core WebAPI:

    [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);
        }
    }

Расскажите о Rest Maturity Model

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

Уровни зрелости:

  1. Уровень 0 – Отсутствие REST:
    • Описание: Использование единственной точки входа (обычно единственный URL) и использование методов POST для всех операций.

    • Пример: SOAP или XML-RPC, где все взаимодействие происходит через один URI и один метод.

  2. Уровень 1 – Использование ресурсов:
    • Описание: Разделение API на множество ресурсов, где каждый ресурс имеет уникальный URI.

    • Пример: API, где каждый ресурс (например, /users, /orders) имеет свой собственный URI, но все еще используется только один HTTP метод (обычно POST).

  3. Уровень 2 – Использование HTTP методов:
    • Описание: Использование стандартных HTTP методов (GET, POST, PUT, DELETE) для выполнения операций на ресурсах.

    • Пример: API, где используется GET для чтения, POST для создания, PUT для обновления и DELETE для удаления ресурсов.

  4. Уровень 3 – Гипермедиа (HATEOAS):
    • Описание: Включение гипермедиа в ответы API, что позволяет клиентам динамически обнаруживать доступные действия и переходы на другие ресурсы.

    • Пример: В ответе на запрос включены ссылки на связанные действия или ресурсы (например, {"self": "/orders/1", "cancel": "/orders/1/cancel"}).


Для чего используются и как работают multi-stage билды в Docker?

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

Как работают multi-stage билды:

  1. Разделение на этапы:
    • В Dockerfile определяется несколько этапов сборки с использованием ключевого слова FROM для каждого этапа.

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

  2. Копирование артефактов:
    • Результаты (артефакты) из одного этапа могут быть скопированы в следующий этап с помощью команды COPY --from=stage_name.
  3. Финальный минимальный образ:
    • Финальный образ содержит только необходимые для работы приложения файлы, без инструментов и зависимостей, используемых на этапах сборки.

Пример использования multi-stage билдов в 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"]

Преимущества:

  1. Уменьшение размера образа:
    • Финальный образ содержит только необходимые файлы и зависимости, что снижает размер образа.
  2. Повышение безопасности:
    • Исключение инструментов сборки и временных файлов уменьшает поверхность атаки.
  3. Упрощение управления зависимостями:
    • Отделение этапов сборки и выполнения позволяет четко управлять зависимостями.

Что такое маршалинг?

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

Основные применения:

  1. Межпроцессное взаимодействие (Inter-process communication, IPC):
    • Передача данных между процессами, которые могут работать на одном или разных компьютерах.
  2. Удаленные вызовы процедур (Remote Procedure Calls, RPC):
    • Вызов методов или процедур на удаленных серверах, часто с использованием сетевых протоколов.
  3. Интеграция разных технологий:
    • Взаимодействие между компонентами, написанными на разных языках программирования или работающими в разных средах (например, взаимодействие между C# и COM-объектами).

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

P/Invoke для вызова нативного кода:
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);
    }
}

Основные задачи маршалинга:

  1. Преобразование данных:
    • Преобразование данных из одного представления в другое, подходящее для передачи или использования в другом контексте.
  2. Управление памятью:
    • Обеспечение правильного управления памятью при передаче данных между разными средами.
  3. Сериализация и десериализация:
    • Преобразование объектов в формат, пригодный для хранения или передачи (например, JSON, XML) и обратно.

Как работает async / await (подробно)? Почему нельзя использовать async void методы?

async / await : Как работает:
  1. async метод:
    • Определяет метод как асинхронный, позволяет использовать await внутри метода.

    • Возвращает Task или Task<T>, что позволяет методам асинхронно ожидать завершения.

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

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

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

async void методы

Почему нельзя использовать:
  1. Нет возможности await :
    • Невозможно ожидать завершения async void метода, что затрудняет обработку ошибок и отладку.
  2. Обработка исключений:
    • Исключения не могут быть пойманы вызывающим кодом, что может привести к неожиданным сбоям.
  3. Потеря возможности компоновки:
    • Методы, возвращающие Task, могут быть легко комбинированы и использованы в других асинхронных операциях.
Использование:
  • async void следует использовать только для обработчиков событий, где нет необходимости в возвращаемом значении или обработке ошибок.
Пример использования в обработчике событий:
private async void Button_Click(object sender, EventArgs e)
{
    await FetchDataAsync();
}
Итог:
  • async / await позволяет писать асинхронный код, который выглядит синхронным, улучшая читаемость и поддержку.

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


Как работает lock? Можно ли использовать структуры внутри выражения lock?

lock в C#: Как работает:
  • Определение: lock обеспечивает эксклюзивный доступ к определенному ресурсу для одного потока, предотвращая одновременный доступ из других потоков.

  • Синтаксис: Заключает критическую секцию кода, которая должна выполняться атомарно.

  • Механизм: Использует объект-закрытие (object lock), чтобы определить область блокировки. Внутри lock блокируется указанное объектное выражение, и освобождается после выхода из блока.

Пример:
private static readonly object _lockObject = new object();

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

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

Можно ли использовать структуры:
  • Нет, нельзя: Нельзя использовать структуры (значимые типы) внутри выражения lock.

  • Причина: lock требует ссылочный тип (object), так как структуру можно легко скопировать, что приведет к неэффективной блокировке и потенциальным ошибкам.


Что такое Expression Tree?

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

Возможности:
  1. Динамическое создание и модификация кода:
    • Позволяет программно создавать и изменять выражения.
  2. Компиляция и выполнение:
    • Выражения могут быть скомпилированы в исполняемый код и выполнены.
  3. Анализ и трансформация:
    • Позволяет анализировать структуру кода, оптимизировать или преобразовывать выражения перед выполнением.
Пример использования Expression Tree в C#:
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
    }
}

Как в .NET Core можно настроить хранение секретов на компьютерах разработчиков и на рабочих средах?

В .NET Core можно настроить хранение секретов на компьютерах разработчиков и на рабочих средах с помощью следующих подходов:

На компьютерах разработчиков:

  1. Secret Manager:
    • Описание: Secret Manager держит секреты разработки вне проекта. Он не шифрует хранилище и не предназначен для производственной среды.

    • Использование: Секреты хранятся в локальной пользовательской конфигурации.

    • Команды:
      # Установка Secret Manager
      dotnet user-secrets init
      
      # Добавление секретов
      dotnet user-secrets set "MySecret" "Value"
    • Пример кода для чтения секретов:
      public class Program
      {
          public static void Main(string[] args)
          {
              var builder = new ConfigurationBuilder()
                  .AddUserSecrets<Program>();
              var configuration = builder.Build();
      
              string mySecret = configuration["MySecret"];
              // Передайте секрет нужному компоненту; не выводите его в лог.
          }
      }

На рабочих средах:

  1. Переменные окружения (Environment Variables):
    • Описание: Секреты могут быть заданы как переменные окружения.

    • Пример настройки: В среде (например, в Azure или Docker) задать переменные окружения.

    • Пример кода для чтения переменных окружения:
      public class Program
      {
          public static void Main(string[] args)
          {
              var builder = new ConfigurationBuilder()
                  .AddEnvironmentVariables();
              var configuration = builder.Build();
      
              string mySecret = configuration["MySecret"];
              // Передайте секрет нужному компоненту; не выводите его в лог.
          }
      }
  2. Azure Key Vault:
    • Описание: Облачное хранилище для управления доступом и защитой секретов.

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

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

    • Пример кода для чтения секретов из Key Vault:
      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, для управления и защиты секретов.


Как включить CORS в AspNetCore?

Включение CORS в ASP.NET Core :

Шаги:

  1. Добавить сервисы CORS в Startup.cs :
    • В методе ConfigureServices добавить сервисы CORS с нужной политикой.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigin",
                builder =>
                {
                    builder.WithOrigins("http://example.com")
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
        });
    
        services.AddControllers();
    }
  2. Включить CORS в обработке запросов:
    • В методе Configure добавить использование CORS.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseRouting();
    
        app.UseCors("AllowSpecificOrigin");
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
  3. (Опционально) Настроить CORS на уровне контроллера или действия:
    • Использовать атрибут [EnableCors] для настройки CORS на уровне контроллера или действия.
    [ApiController]
    [Route("[controller]")]
    public class MyController : ControllerBase
    {
        [EnableCors("AllowSpecificOrigin")]
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("CORS is enabled!");
        }
    }

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


Что такое CPU и IO-bound задачи?

CPU-bound задачи:

Определение: Задачи, ограниченные вычислительной мощностью процессора, где производительность зависит от скорости обработки данных CPU.

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

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

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

Оптимизация:
  • Увеличение мощности процессора.

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

Пример кода на C#:
void CalculateFactorial()
{
    long result = 1;
    for (int i = 1; i <= 20; i++)
    {
        result *= i;
    }
    Console.WriteLine(result);
}
IO-bound задачи:

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

Примеры:
  • Чтение и запись файлов.

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

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

Оптимизация:
  • Асинхронное выполнение (async/await).

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

Пример кода на C#:
async Task ReadFileAsync()
{
    using (var reader = new StreamReader("file.txt"))
    {
        string content = await reader.ReadToEndAsync();
        Console.WriteLine(content);
    }
}
Итог:
  • CPU-bound задачи: Ограничены производительностью процессора, выигрывают от улучшения вычислительных мощностей.

  • IO-bound задачи: Ограничены скоростью операций ввода-вывода, выигрывают от асинхронного и параллельного выполнения.

Эта страница была полезной?