C# | Вопросы собесов
5.09K subscribers
34 photos
1 file
979 links
Download Telegram
🤔 Что такое полиморфизм подтипов?

Полиморфизм подтипов — это способность объектов разных классов, связанных отношениями наследования, обрабатываться единообразно. Это позволяет использовать объекты подклассов через ссылки на базовые классы, что делает код гибким и расширяемым.

🚩Основные понятия

🟠Наследование:
Классы могут наследовать другие классы, унаследуя их методы и свойства.
🟠Интерфейсы:
Классы могут реализовывать интерфейсы, обеспечивая конкретную реализацию методов интерфейса.
🟠Виртуальные методы:
Методы, объявленные как virtual в базовом классе, могут быть переопределены в производных классах с использованием ключевого слова override.
🟠Позднее связывание:
Метод, который будет вызван, определяется во время выполнения, а не во время компиляции.

Базовый класс и производные классы
public class Animal
{
// Виртуальный метод, который может быть переопределен в производных классах
public virtual void Speak()
{
Console.WriteLine("Animal speaks");
}
}

public class Dog : Animal
{
// Переопределение метода Speak для класса Dog
public override void Speak()
{
Console.WriteLine("Dog barks");
}
}

public class Cat : Animal
{
// Переопределение метода Speak для класса Cat
public override void Speak()
{
Console.WriteLine("Cat meows");
}
}


Использование полиморфизма подтипов
class Program
{
static void Main()
{
// Создание массива объектов типа Animal
Animal[] animals = new Animal[]
{
new Dog(),
new Cat(),
new Animal()
};

// Вызов метода Speak для каждого объекта в массиве
foreach (Animal animal in animals)
{
animal.Speak();
}
}
}


🟠Полиморфизм с интерфейсами
Полиморфизм также может быть достигнут через интерфейсы. В этом примере классы Dog и Cat реализуют интерфейс IAnimal, и метод Speak вызывается через интерфейс, что также демонстрирует полиморфизм подтипов.
public interface IAnimal
{
void Speak();
}

public class Dog : IAnimal
{
public void Speak()
{
Console.WriteLine("Dog barks");
}
}

public class Cat : IAnimal
{
public void Speak()
{
Console.WriteLine("Cat meows");
}
}

class Program
{
static void Main()
{
IAnimal[] animals = new IAnimal[]
{
new Dog(),
new Cat()
};

foreach (IAnimal animal in animals)
{
animal.Speak();
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4👾3
🤔 Что такое делегат?

Делегат в C# — это тип, который представляет ссылки на методы с определённой сигнатурой. Делегаты используются для передачи методов в качестве параметров и для обратных вызовов (callbacks). Они являются основой для событий и лямбда-выражений в C#. Делегаты позволяют вызывать методы динамически, что делает код более гибким.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥41👀1
🤔 Расскажи про принцип подстановки Барбары Лисков?

Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP) является одним из пяти принципов объектно-ориентированного программирования, известных под акронимом SOLID.

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

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

🚩Правила для соблюдения LSP

🟠Сохранение контрактов:
Производный класс должен соблюдать контракт, определённый базовым классом. Это включает в себя сигнатуры методов и ожидания (предусловия и постусловия).

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

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

🟠Предусловия не должны быть усилены:
Производный класс не должен усиливать предусловия методов базового класса. Предусловия - это условия, которые должны быть выполнены перед вызовом метода. В этом примере Penguin нарушает LSP, так как он не может летать. Если заменить экземпляр FlyingBird на Penguin, программа перестанет работать правильно.
public abstract class Bird
{
public abstract void Fly();
}

public class FlyingBird : Bird
{
public override void Fly()
{
Console.WriteLine("I can fly!");
}
}

public class Penguin : Bird
{
public override void Fly()
{
throw new NotSupportedException("Penguins cannot fly.");
}
}


Теперь классы FlyingBird и Penguin оба наследуют класс Bird и реализуют метод Move, но каждый делает это по-своему, не нарушая LSP.
public abstract class Bird
{
public abstract void Move();
}

public class FlyingBird : Bird
{
public override void Move()
{
Fly();
}

private void Fly()
{
Console.WriteLine("I can fly!");
}
}

public class Penguin : Bird
{
public override void Move()
{
Console.WriteLine("I waddle.");
}
}


🚩Плюсы

Повышенная гибкость и расширяемость:
Код, который соблюдает LSP, легче модифицировать и расширять без риска нарушения существующей функциональности.
Упрощённое тестирование:
Код, соответствующий LSP, легче тестировать, так как можно заменять объекты их подтипами в тестах без изменения поведения.
Повышенная поддерживаемость:
Такой код легче поддерживать и рефакторить, так как контракт между базовым и производным классами чётко определён и соблюдается.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍132
🤔 Что такое middleware в ASP.NET core?

Middleware — это компоненты, которые обрабатывают HTTP-запросы и ответы в ASP.NET Core. Каждый компонент middleware может либо обработать запрос, либо передать его следующему компоненту в конвейере. Они используются для выполнения задач, таких как аутентификация, логирование или обработка ошибок. Последовательность middleware определяет поведение приложения и порядок обработки запросов.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥8
🤔 Какие бывают типы?

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

🚩Основные типы данных:

🟠Простые типы (Value Types)
Простые типы хранят значения непосредственно и включают примитивные типы, перечисления и структуры.

🟠Примитивные типы
Целочисленные типы:
byte (8-битный, от 0 до 255)
sbyte (8-битный, от -128 до 127)
short (16-битный, от -32,768 до 32,767)
ushort (16-битный, от 0 до 65,535)
int (32-битный, от -2,147,483,648 до 2,147,483,647)
uint (32-битный, от 0 до 4,294,967,295)
long (64-битный, от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807)
ulong (64-битный, от 0 до 18,446,744,073,709,551,615)

🟠Типы с плавающей запятой:
float (32-битный, ±1.5e−45 до ±3.4e38, 7 знаков точности)
double (64-битный, ±5.0e−324 до ±1.7e308, 15-16 знаков точности)

🟠Десятичные типы:
decimal (128-битный, ±1.0 × 10−28 до ±7.9 × 10^28, 28-29 знаков точности)

🟠Прочие простые типы:
char (16-битный символ Unicode)
bool (логический тип, принимает значения true или false)

🟠Структуры и перечисления
Структуры (struct): Пользовательские типы данных, которые являются значимыми типами и могут содержать поля, методы, свойства и т.д.
Перечисления (enum): Тип, представляющий набор именованных констант.

🟠Ссылочные типы (Reference Types)
Ссылочные типы хранят ссылку на область памяти, где находятся данные. К ним относятся классы, интерфейсы, делегаты и массивы.

🚩Классы и интерфейсы

🟠Классы (class):
Основной строительный блок объектно-ориентированного программирования, могут содержать поля, методы, свойства, события и т.д.
🟠Интерфейсы (interface):
Контракты, определяющие набор методов и свойств, которые должны быть реализованы классами.

🚩Делегаты и события

🟠Делегаты (delegate):
Типы, представляющие ссылку на методы. Используются для реализации обратных вызовов и событий.
🟠События (event):
Механизм, через который объекты могут сообщать о произошедших действиях.

🚩Массивы и строки

🟠Массивы (Array):
Коллекции элементов одного типа, доступ к которым осуществляется по индексу.
🟠Строки (string):
Неизменяемые последовательности символов.

🚩Пользовательские типы

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

🚩Кортежи и анонимные типы

🟠Кортежи (Tuple):
Группировка значений различных типов.
🟠Анонимные типы:
Типы, созданные для хранения наборов значений, определённых на лету.
🟠Nullable-типы
Позволяют значимым типам принимать значение null.
int? nullableInt = null; // Nullable int


Пример использования простых типов:
int age = 30;
double salary = 50000.50;
bool isEmployed = true;
char grade = 'A';


Пример использования классов и интерфейсов:
public interface IAnimal
{
void Speak();
}

public class Dog : IAnimal
{
public void Speak()
{
Console.WriteLine("Bark");
}
}


Пример использования структуры:
public struct Point
{
public int X;
public int Y;

public Point(int x, int y)
{
X = x;
Y = y;
}
}


Пример использования перечисления:
public enum DaysOfWeek
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍142
🤔 Что такое лямбда выражения в С#?

Лямбда-выражения — это анонимные функции, которые используются для создания кратких методов или делегатов в C#. Они упрощают работу с LINQ, коллекциями и обратными вызовами. Лямбда-выражения могут захватывать переменные из своей области видимости, делая их удобным способом для создания замыканий. Используются для упрощения и улучшения читаемости кода.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥4
🤔 Что такое стейт машина?

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

🚩Зачем нужна

🟠Упрощения логики программы
Позволяет разбить сложную логику на более простые, управляемые состояния.
🟠Четкого определения поведения системы
Описывает, как система реагирует на различные события.
🟠Улучшения читабельности и поддержки кода
Легче понять и изменить поведение системы, когда оно описано в виде состояний и переходов.

🚩Как используется

🟠Игровую разработку
Для управления поведением персонажей.
🟠Системы управления
В промышленной автоматике.
🟠Разработку пользовательских интерфейсов
Для управления состояниями интерфейсов и переходами между ними.
🟠Протоколы связи
Для управления последовательностью сообщений и реакцией на них.
using System;

public enum TrafficLightState
{
Red,
Green,
Yellow
}

public class TrafficLight
{
private TrafficLightState _state;

public TrafficLight()
{
_state = TrafficLightState.Red;
}

public void ChangeState()
{
switch (_state)
{
case TrafficLightState.Red:
_state = TrafficLightState.Green;
break;
case TrafficLightState.Green:
_state = TrafficLightState.Yellow;
break;
case TrafficLightState.Yellow:
_state = TrafficLightState.Red;
break;
}
Console.WriteLine($"Состояние светофора: {_state}");
}
}

class Program
{
static void Main()
{
TrafficLight trafficLight = new TrafficLight();
trafficLight.ChangeState(); // Состояние светофора: Green
trafficLight.ChangeState(); // Состояние светофора: Yellow
trafficLight.ChangeState(); // Состояние светофора: Red
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14😁5🤔1👀1
🤔 Когда инициируется сборка мусора?

Сборка мусора в C# инициируется автоматически, когда система обнаруживает, что недостаточно доступной памяти или при достижении порогов работы сборщика. Также она может быть запущена вручную с помощью метода `GC.Collect()`. Garbage collector удаляет объекты, которые больше не используются программой, освобождая память. Сборка мусора помогает предотвратить утечки памяти и поддерживает эффективность приложения.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥4
🤔 Какой сейчас последний C#?

🚩Нововведения

🟠Primary Constructors для классов и структур
Позволяют определять конструкторы прямо в объявлении класса или структуры, что упрощает код и улучшает его читаемость.
public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
}


🟠Collection Literals
Обеспечивает более удобный синтаксис для создания коллекций.
var numbers = [1, 2, 3, 4, 5];


🟠Default Values для auto-properties
Теперь можно задавать значения по умолчанию для auto-properties, что делает код более лаконичным.
public string Name { get; set; } = "Unknown";


🟠Using aliases
Позволяет использовать алиасы для пространств имен, улучшая читаемость кода.
using Text = System.Text;


🟠Improved Lambda Expressions:
Улучшены возможности для работы с лямбда-выражениями, делая их более гибкими и мощными.

🚩Зачем нужны эти изменения?

Эти нововведения направлены на упрощение синтаксиса языка, улучшение читаемости и поддерживаемости кода, а также на повышение производительности и удобства разработки.
public class Program
{
public static void Main()
{
var person = new Person("John", 30);
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");

var numbers = [1, 2, 3, 4, 5];
numbers.ForEach(n => Console.WriteLine(n));

var name = new Name { Value = "Unknown" };
Console.WriteLine(name.Value);
}
}

public class Person(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
}

public class Name
{
public string Value { get; set; } = "Default Name";
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🤔 Что такое ООП?

ООП (Объектно-Ориентированное Программирование) — это парадигма программирования, основанная на концепции объектов, которые объединяют данные и методы для их обработки. Основные принципы ООП включают инкапсуляцию, наследование, полиморфизм и абстракцию. ООП позволяет моделировать реальный мир с помощью классов и объектов, улучшая структуру и повторное использование кода. В C# все программы строятся на основе классов, что делает его строго объектно-ориентированным языком.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
🤔 Как .NET 8 связан с async и await?

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

🟠Улучшенная производительность Task-based API
В .NET 8 были проведены оптимизации, которые улучшают производительность асинхронных операций. Это включает более эффективное управление задачами (Task), снижение накладных расходов на создание и завершение задач.

🟠Рефакторинг инфраструктуры асинхронных потоков
Внутренние изменения в библиотеке обеспечивают более эффективное управление асинхронными потоками, что приводит к улучшению производительности приложений, активно использующих асинхронные операции.

🟠Новые инструменты диагностики и мониторинга
В .NET 8 добавлены новые возможности для диагностики и мониторинга асинхронных операций, что помогает разработчикам лучше понимать и оптимизировать асинхронное выполнение в их приложениях.

Асинхронные методы позволяют выполнять длительные операции, такие как ввод-вывод или сетевые запросы, без блокировки основного потока выполнения. Вот пример использования async и await:
using System;
using System.Net.Http;
using System.Threading.Tasks;

public class Program
{
public static async Task Main(string[] args)
{
string url = "https://api.example.com/data";
string result = await FetchDataAsync(url);
Console.WriteLine(result);
}

public static async Task<string> FetchDataAsync(string url)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string responseData = await response.Content.ReadAsStringAsync();
return responseData;
}
}
}


🚩Зачем нужны?

🟠Производительность
Оптимизация асинхронных операций позволяет приложениям обрабатывать большее количество запросов и задач за единицу времени, что особенно важно для серверных приложений и веб-сервисов.
🟠Удобство разработки
Улучшенные инструменты и библиотеки облегчают написание, отладку и мониторинг асинхронного кода, что делает разработку более продуктивной.
🟠Масштабируемость
Асинхронные операции позволяют приложениям лучше масштабироваться, эффективно распределяя ресурсы и минимизируя задержки.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🤔 Что такое полиморфизм?

Полиморфизм — это принцип ООП, который позволяет объектам разных классов реагировать на одни и те же методы по-разному. В C# полиморфизм реализуется через наследование и интерфейсы, где один метод может работать с различными типами объектов. Полиморфизм позволяет создавать гибкие и расширяемые программы, где один интерфейс может быть реализован различными способами. Это делает код более универсальным и поддерживаемым.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥1
🤔 Что такое midleway?

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

🟠Обработка запросов
Middleware может перехватывать и изменять HTTP-запросы перед их передачей на основной сервер или конечную точку обработки.
🟠Обработка ответов
Middleware также может перехватывать и изменять HTTP-ответы перед их отправкой клиенту.
🟠Аутентификация и авторизация
Middleware может использоваться для проверки подлинности пользователей и определения их прав доступа.
🟠Логирование
Middleware может записывать информацию о запросах и ответах для целей мониторинга и отладки.
🟠Обработка ошибок
Middleware может перехватывать и обрабатывать ошибки, возникающие во время обработки запросов.
🟠Пример middleware в ASP.NET Core:
Мiddleware компоненты добавляются в конвейер обработки запросов через метод Configure в классе Startup.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Пример простого middleware, который логирует каждый запрос
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.iss.onethod} {context.Request.Path}");
await next.Invoke();
Console.WriteLine($"Response: {context.Response.StatusCode}");
});

// Добавление стандартного middleware для обработки статических файлов
app.UseStaticFiles();

// Добавление стандартного middleware для маршрутизации
app.UseRouting();

// Конечная точка обработки запросов
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
});
}
}


🚩Зачем нужен?

🟠Разделение ответственности
Middleware позволяет разбивать обработку запросов на отдельные компоненты, каждый из которых отвечает за свою часть логики.
🟠Повторное использование кода
Один и тот же middleware может использоваться в разных частях приложения или даже в разных приложениях.
🟠Гибкость и расширяемость
Middleware можно легко добавлять, удалять или заменять, что упрощает модификацию и расширение приложения.
🟠Поддерживаемость
Разделение логики на отдельные компоненты делает код более структурированным и легким для поддержки.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔2🤯2👾2
🤔 Принципы ООП?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🤔1👾1
🤔 Что такое конвейер обработки запросов?

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

🚩Как работает

1⃣Получение запроса
Когда сервер получает HTTP-запрос, он передается в первый компонент middleware в конвейере.

2⃣Последовательная обработка
Запрос проходит через каждый компонент middleware последовательно.
Каждый компонент может:
Обрабатывать запрос и передать его следующему компоненту.
Обрабатывать запрос и завершить его обработку, не передавая дальше.
Внести изменения в запрос или ответ.

3⃣Передача управления
Компонент middleware может передать управление следующему компоненту, вызывая метод next.Invoke(). После завершения обработки запроса следующим компонентом, управление возвращается обратно к предыдущему компоненту.

4⃣Формирование ответа
Когда запрос доходит до конца конвейера и обработка завершается, ответ формируется и проходит обратно через все компоненты middleware в обратном порядке, что позволяет им вносить изменения в ответ перед его отправкой клиенту.

Настройка конвертатора обработки запросов в ASP.NET Core:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Логирование запросов
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.iss.onethod} {context.Request.Path}");
await next.Invoke();
Console.WriteLine($"Response: {context.Response.StatusCode}");
});

// Обработка статических файлов
app.UseStaticFiles();

// Маршрутизация
app.UseRouting();

// Аутентификация
app.UseAuthentication();

// Авторизация
app.UseAuthorization();

// Конечные точки обработки запросов
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
});
}
}


🚩Зачем нужен?

🟠Гибкость
Конвейер позволяет легко добавлять и удалять компоненты, изменяя способ обработки запросов.
🟠Модульность
Каждый компонент middleware выполняет свою задачу, что делает код более структурированным и легким для поддержки.
🟠Расширяемость
Можно легко добавить новые компоненты для обработки различных аспектов запросов, таких как кэширование, компрессия и другие.
🟠Повторное использование
Один и тот же компонент middleware может быть использован в разных приложениях, что снижает дублирование кода.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 В чём разница между string и StringBuilder?

`string` в C# — это неизменяемый тип данных, что означает, что каждое изменение строки создаёт новый объект в памяти. `StringBuilder` — это изменяемый тип, который позволяет эффективно манипулировать строками без создания новых объектов, что улучшает производительность при частых изменениях строк. `StringBuilder` предпочтительнее использовать для конкатенации строк в циклах или при выполнении множества операций со строками. `string` лучше подходит для случаев, когда строка не меняется.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥5
🤔 Какие методы есть в Action фильтре?

Используются для выполнения логики до и после выполнения метода действия контроллера. Они предоставляют механизм для выполнения кросс-секционных задач, таких как логирование, обработка исключений, валидация и т.д. Action фильтры реализуют интерфейс IActionFilter или IAsyncActionFilter.

🚩Методы в Action фильтре

🟠OnActionExecuting
Этот метод вызывается перед выполнением метода действия. Здесь можно добавить логику, которая будет выполняться до вызова действия, например, логирование или проверка условий.
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
}


🟠OnActionExecuted
Этот метод вызывается после выполнения метода действия. Здесь можно добавить логику, которая будет выполняться после вызова действия, например, логирование результатов или модификация ответа.
public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
}


🟠OnActionExecutionAsync
Этот метод объединяет функциональность OnActionExecuting и OnActionExecuted в одном асинхронном методе. Здесь можно определить логику, которая будет выполняться как до, так и после выполнения метода действия.
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия

var resultContext = await next();

// Логика после выполнения действия
}


🚩Реализации Action фильтра

Синхронный Action фильтр:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");
}

public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}


Асинхронный Action фильтр:
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");

var resultContext = await next();

// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}


🚩Применение Action фильтра

Action фильтр можно применять к контроллерам или действиям контроллера с помощью атрибута [ServiceFilter] или [TypeFilter]. Также его можно зарегистрировать глобально в Startup.cs.

Применение к контроллеру или действию:
[ServiceFilter(typeof(SampleActionFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}


Глобальная регистрация:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(config =>
{
config.Filters.Add(typeof(SampleActionFilter));
});
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Что такое async и await?

`async` и `await` — это ключевые слова в C#, которые используются для работы с асинхронным кодом. `async` обозначает метод как асинхронный, а `await` позволяет приостановить выполнение метода до завершения асинхронной операции, не блокируя основной поток. Это позволяет писать асинхронный код, который выглядит как синхронный, улучшая читаемость и производительность программ. Асинхронные операции полезны для выполнения долгих задач, таких как запросы к базе данных или сети.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥1
🤔 Как устроен роутинг в RabbitMQ?

Определяет, как сообщения от производителей (producers) направляются в очереди через обменники (exchanges).

1⃣Producers (Производители)
Отправляют сообщения в обменники.

2⃣Exchanges (Обменники)
Направляют сообщения в очереди на основе привязок (bindings) и типа обменника:
Direct Exchange: Сообщения направляются в очереди, соответствующие точному ключу маршрутизации.
Topic Exchange: Направляет сообщения в очереди по шаблону ключа маршрутизации.
Fanout Exchange: Широковещательно отправляет сообщения во все очереди, связанные с обменником.
Headers Exchange: Использует заголовки сообщений для маршрутизации.

3⃣Queues (Очереди)
Получают сообщения от обменников.

4⃣Bindings (Привязки)
Связывают обменники с очередями и определяют правила маршрутизации.

🚩Пример настройки

1⃣Объявление обменника и очереди
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.iss.onethod.queue
channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key='info')

connection.close()


2⃣Отправка сообщения
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
routing_key = 'info'
message = 'Hello, RabbitMQ!'
channel.basic_publish(exchange='direct_logs', routing_key=routing_key, body=message)

connection.close()


3⃣Получение сообщений
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.iss.onethod.queue
channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key='info')

def callback(ch, method, properties, body):
print(f"Received {body}")

channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
print('Waiting for messages. To exit press CTRL+C')
channel.start_consuming()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁7👍1
🤔 Что умеет Action фильтр?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
🤔 Какие типы Exchanged существуют?

🟠Direct
Сообщения направляются в очереди, которые связаны с обменником, если ключ маршрутизации сообщения точно совпадает с ключом маршрутизации, указанным в привязке. Логирование сообщений с разными уровнями важности, где каждая очередь получает сообщения с определенным уровнем (например, "info", "warning", "error").
channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");


🟠Topic
Сообщения направляются в очереди на основе шаблонов ключей маршрутизации. Поддерживаются подстановочные знаки: * (заменяет одно слово) и # (заменяет ноль или более слов). Маршрутизация сообщений в зависимости от нескольких критериев, например, "logs.error", "logs.info.user".
channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");


🟠Fanout
Широковещательно отправляет сообщения во все очереди, связанные с этим обменником, игнорируя ключ маршрутизации. Широковещательная рассылка сообщений всем подписчикам, например, рассылка уведомлений.
channel.ExchangeDeclare(exchange: "logs", type: "fanout");


🟠Headers
Направляет сообщения в очереди на основе заголовков сообщений, а не ключей маршрутизации. Можно задавать правила маршрутизации с использованием заголовков. Маршрутизация сообщений на основе различных свойств, таких как content-type или любые другие произвольные атрибуты.
channel.ExchangeDeclare(exchange: "headers_logs", type: "headers");


🚩Пример настройки обменников и привязок

Direct
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
var queueName = channel.QueueDeclare().QueueName;

channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "info");

connection.Close();


Topic
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");
var queueName = channel.QueueDeclare().QueueName;

channel.QueueBind(queue: queueName, exchange: "topic_logs", routingKey: "logs.*.user");

connection.Close();


Fanout
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "logs", type: "fanout");
var queueName = channel.QueueDeclare().QueueName;

channel.QueueBind(queue: queueName, exchange: "logs", routingKey: "");

connection.Close();


Headers
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "headers_logs", type: "headers");
var queueName = channel.QueueDeclare().QueueName;

var headers = new Dictionary<string, object>
{
{ "x-match", "all" },
{ "key1", "value1" },
{ "key2", "value2" }
};

channel.QueueBind(queue: queueName, exchange: "headers_logs", routingKey: "", arguments: headers);


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1