C# | Вопросы собесов
4.99K subscribers
39 photos
1 file
1.5K links
Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy

Контакт для рекламы: @easyoffer_adv
Download Telegram
🤔 Как по ключу получить значение?

Для получения значения по ключу в словаре (Dictionary<TKey, TValue>) используются методы и свойства, такие как индексатор [], метод TryGetValue, и метод ContainsKey.

🟠Индексатор `[]`
Индексатор позволяет получить значение по ключу напрямую. Если ключ отсутствует в словаре, будет выброшено исключение KeyNotFoundException.
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};

try
{
string value = dictionary[2]; // Получение значения по ключу 2
Console.WriteLine(value); // Выведет "Two"
}
catch (KeyNotFoundException)
{
Console.WriteLine("Key not found");
}


🟠Метод `TryGetValue`
Метод TryGetValue позволяет безопасно получить значение по ключу. Он возвращает true, если ключ найден, и false, если ключ отсутствует. При этом значение записывается в выходной параметр.
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};

if (dictionary.TryGetValue(2, out string value))
{
Console.WriteLine(value); // Выведет "Two"
}
else
{
Console.WriteLine("Key not found");
}


🟠Метод `ContainsKey`
Метод ContainsKey проверяет наличие ключа в словаре. Его можно использовать в сочетании с индексатором для получения значения.
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};

if (dictionary.ContainsKey(2))
{
string value = dictionary[2];
Console.WriteLine(value); // Выведет "Two"
}
else
{
Console.WriteLine("Key not found");
}


Ставь 👍 и забирай 📚 Базу знаний
🤔 Какой самый оптимальный тип данных для подсчёта денег?

Лучше использовать decimal (в .NET) — он:
- обеспечивает высокую точность;
- не подвержен ошибкам округления, как float или double;
- специально разработан для финансовых расчётов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍5🔥1
🤔 Какие типы данных можно использовать у Dictionary в качестве ключа?

В C# ключ (TKey) в Dictionary<TKey, TValue> должен быть уникальным и поддерживать сравнение.
Лучше всего использовать неизменяемые (immutable) типы, такие как:
Примитивные типы (int, string, char, bool, Guid, enum)
Кортежи (Tuple, ValueTuple)
Неизменяемые структуры (struct, если переопределён Equals и GetHashCode)

🚩Какие типы подходят в качестве ключа?

Числовые типы (int, double, long)
var dict = new Dictionary<int, string>
{
{1, "Один"},
{2, "Два"}
};
Console.WriteLine(dict[1]); // Вывод: Один


string (лучший выбор)
var dict = new Dictionary<string, int>
{
{"apple", 10},
{"banana", 5}
};
Console.WriteLine(dict["apple"]); // 10


Guid (уникальные идентификаторы)
var dict = new Dictionary<Guid, string>
{
{Guid.NewGuid(), "User1"},
{Guid.NewGuid(), "User2"}
};


enum (хороший вариант)
enum Status { New, Processing, Completed }

var dict = new Dictionary<Status, string>
{
{Status.New, "Заказ создан"},
{Status.Processing, "Заказ в обработке"}
};


Можно использовать несколько значений в качестве ключа:
var dict = new Dictionary<(int, string), string>
{
{(1, "apple"), "Красное яблоко"},
{(2, "banana"), "Жёлтый банан"}
};
Console.WriteLine(dict[(1, "apple")]); // Красное яблоко


🚩Какие типы нельзя использовать в качестве ключа?

List<T> (и другие изменяемые коллекции)
var dict = new Dictionary<List<int>, string>(); // Ошибка при использовании в качестве ключа!


class, если не переопределён Equals и GetHashCode
class Person { public string Name; }
var dict = new Dictionary<Person, string>(); // Плохо!


Нужно переопределить Equals и GetHashCode
class Person
{
public string Name { get; }

public Person(string name) => Name = name;

public override bool Equals(object? obj)
{
return obj is Person other && Name == other.Name;
}

public override int GetHashCode() => Name.GetHashCode();
}


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Что такое SignalR?

SignalR — это библиотека от Microsoft для обеспечения двусторонней связи в реальном времени между клиентом и сервером. Она использует протоколы, такие как WebSockets, для высокой производительности, а в случае их недоступности — другие технологии, например, long polling. SignalR упрощает разработку чатов, уведомлений и других динамичных приложений.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥1
🤔 Какие минусы есть у индексов с точки зрения оптимизации?

Индексы в базах данных, таких как SQL Server, MySQL или PostgreSQL, существенно улучшают производительность запросов, особенно для операций поиска, сортировки и фильтрации. Однако у индексов есть и минусы, которые могут негативно сказаться на производительности и других аспектах работы базы данных.

🟠Увеличение времени записи
Индексы замедляют операции вставки (INSERT), обновления (UPDATE) и удаления (DELETE), так как при каждом изменении данных необходимо также обновлять индексы.
Вставка: При вставке новой записи нужно обновить все соответствующие индексы.
Обновление: При обновлении записи могут изменяться индексируемые колонки, что требует обновления индексов.
Удаление: При удалении записи нужно удалить соответствующие записи из индексов.

🟠Дополнительное использование памяти и дискового пространства
Индексы занимают дополнительное пространство на диске и в оперативной памяти. Чем больше индексов на таблице, тем больше требуется места для их хранения.
Дисковое пространство: Каждому индексу требуется место на диске для хранения его данных.
Память: Индексы занимают память при их использовании, особенно в случае часто запрашиваемых индексов, которые кэшируются в оперативной памяти.

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

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

🟠Сложность управления
Управление индексами требует дополнительного администрирования и мониторинга. Нужно следить за эффективностью индексов, удалять неиспользуемые индексы и создавать новые по мере изменения запросов и структуры данных.

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

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

🚩Пример ситуации

CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
DepartmentID INT,
Salary DECIMAL(10, 2)
);

CREATE INDEX idx_firstname ON Employees(FirstName);
CREATE INDEX idx_lastname ON Employees(LastName);
CREATE INDEX idx_department ON Employees(DepartmentID);


🚩Минусы

➖Вставка данных
INSERT INTO Employees (EmployeeID, FirstName, LastName, DepartmentID, Salary)
VALUES (1, 'John', 'Doe', 10, 60000.00);


➖Обновление данных
UPDATE Employees
SET Salary = Salary * 1.05
WHERE DepartmentID = 10;


Ставь 👍 и забирай 📚 Базу знаний
🤔 Какие ресурсы очищают Dispose и Finalize?

- Dispose используется для ручного освобождения ресурсов, таких как:
- Файлы
- Соединения с базами данных
- Сетевые сокеты
- Таймеры и обработчики событий
- Finalize вызывается автоматически сборщиком мусора, чтобы освободить неуправляемые ресурсы (например, дескрипторы ОС, ресурсы вне .NET).
Dispose — быстрее и надёжнее, потому что вызывается явно, в отличие от непредсказуемого Finalize.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 В чём преимущество блока using?

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

🚩Основные преимущества блока

🟠Автоматическое освобождение ресурсов
Блок using гарантирует, что метод Dispose() будет вызван автоматически, когда выполнение кода выйдет из блока using, даже если возникнет исключение. Это освобождает программиста от необходимости вручную вызывать Dispose() и уменьшает вероятность ошибок.
using (StreamReader reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// StreamReader автоматически закрывается и освобождает ресурсы после выхода из блока using.


🟠Сокращение количества кода
Использование блока using уменьшает количество необходимого кода для обеспечения правильного освобождения ресурсов.
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Работа с базой данных
}
// SqlConnection автоматически закрывается и освобождает ресурсы после выхода из блока using.


🟠Повышенная надежность
Блок using повышает надежность кода, так как гарантирует, что ресурсы будут освобождены даже в случае возникновения исключений.
try
{
using (StreamWriter writer = new StreamWriter("file.txt"))
{
writer.WriteLine("Hello, World!");
}
}
catch (Exception ex)
{
Console.WriteLine($"Произошла ошибка: {ex.Message}");
}
// StreamWriter автоматически закрывается и освобождает ресурсы после выхода из блока using, даже если произошла ошибка.


🟠Чистый и понятный код
Код, использующий блок using, выглядит более чистым и упрощает понимание и сопровождение.
using (MemoryStream memoryStream = new MemoryStream())
{
// Работа с MemoryStream
}
// MemoryStream автоматически освобождается после выхода из блока using.


🚩Пример использования блока `using`

Работа с файлами
using System;
using System.IO;

class Program
{
static void Main()
{
using (StreamReader reader = new StreamReader("example.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// StreamReader автоматически закрывается и освобождает ресурсы после выхода из блока using.
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍1🔥1
🤔 Когда можно использовать using?

Ключевое слово using используется в двух основных контекстах: для управления областью видимости объектов, реализующих интерфейс IDisposable, и для включения пространств имён.

🟠Управление областью видимости объектов (IDisposable)
Можно использовать для создания блока кода, внутри которого объекты, реализующие интерфейс IDisposable, автоматически освобождаются по завершении блока. Это удобно для управления ресурсами, такими как файловые потоки, базы данных или другие ресурсы системы, которые требуют явного освобождения.
using (StreamWriter writer = new StreamWriter("example.txt"))
{
writer.WriteLine("Hello, world!");
}
// Здесь объект writer уже автоматически закрыт и освобожден.


🟠Включение пространств имён
Также используется для объявления пространств имен, которые будут использоваться в коде, позволяя обращаться к классам внутри этих пространств без полного указания их имён.
using System;
using System.IO;
using System.Text;

// Теперь можно использовать классы из System, System.IO и System.Text без полного указания имени.


🟠using для статических классов (C# 6.0 и выше)
Для включения статических классов, что позволяет обращаться к статическим членам класса напрямую без указания имени класса.
using static System.Console;
using static System.Math;

class Program
{
static void Main()
{
WriteLine(Sqrt(144)); // Использование метода WriteLine и Sqrt без указания классов Console и Math
}
}


Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое конкурентность в многопоточности?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Зачем сделали ref & out для ссылочных типов?

В C# ключевые слова ref и out используются для передачи аргументов по ссылке, что позволяет методам изменять значения этих аргументов. Эти механизмы полезны как для значимых типов (структур), так и для ссылочных типов (объектов). Давайте рассмотрим более детально, зачем и как их используют для ссылочных типов.

🚩`ref`

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

🚩`out`

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

🚩Как используются `ref` и `out`?

Пример использования ref
class Program
{
static void ChangeReference(ref MyClass obj)
{
obj = new MyClass { Value = 20 };
}

static void Main()
{
MyClass myObj = new MyClass { Value = 10 };
ChangeReference(ref myObj);
Console.WriteLine(myObj.Value); // Output: 20
}
}

class MyClass
{
public int Value { get; set; }
}


Пример использования out
class Program
{
static void InitializeObject(out MyClass obj)
{
obj = new MyClass { Value = 30 };
}

static void Main()
{
MyClass myObj;
InitializeObject(out myObj);
Console.WriteLine(myObj.Value); // Output: 30
}
}

class MyClass
{
public int Value { get; set; }
}


🚩Почему это нужно?

🟠Гибкость
ref и out добавляют гибкости при работе с методами, позволяя им изменять ссылки на объекты или создавать и возвращать новые объекты.

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

🟠Логика инициализации
out полезен для методов, которые должны вернуть несколько значений или инициализировать объекты, которые не могут быть инициализированы заранее.

Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое атрибуты и какова их основная цель?

Это метаданные, добавляемые к элементам кода (классам, методам, свойствам) для описания их поведения. Они позволяют изменять или дополнять поведение во время выполнения, например, управлять сериализацией или валидацией.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Как работает threadpool?

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

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

🟠Создание потоков — дорогостоящая операция
Каждый раз создавать новый поток — медленно и неэффективно.
🟠Пул потоков позволяет повторно использовать уже созданные потоки
вместо их постоянного создания и удаления.
🟠Автоматическое управление количеством потоков
в зависимости от нагрузки.
🟠Идеально подходит для небольших, кратковременных задач
Обработки HTTP-запросов
Выполнения задач в фоне
Асинхронного выполнения операций

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

🟠Когда вы отправляете задачу в ThreadPool
он берет поток из пула и выполняет задачу.
🟠Если в пуле нет свободных потоков
создается новый (но их количество ограничено).
🟠Когда задача выполнена, поток не уничтожается
а возвращается в пул и может быть использован снова.
🟠ThreadPool сам регулирует количество потоков
в зависимости от загрузки системы.

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

using System;
using System.Threading;

class Program
{
static void Main()
{
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(DoWork, i);
}

Console.ReadLine(); // Ждём завершения потоков
}

static void DoWork(object? state)
{
Console.WriteLine($"Задача {state} выполняется в потоке {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(1000); // Симуляция работы
Console.WriteLine($"Задача {state} завершена");
}
}


🚩Максимальное и минимальное количество потоков

ThreadPool управляет количеством потоков сам, но их можно настраивать
int minWorker, minIOC;
ThreadPool.GetMinThreads(out minWorker, out minIOC);
Console.WriteLine($"Мин. количество потоков: {minWorker}");

ThreadPool.SetMinThreads(4, 4); // Устанавливаем минимум потоков

int maxWorker, maxIOC;
ThreadPool.GetMaxThreads(out maxWorker, out maxIOC);
Console.WriteLine($"Макс. количество потоков: {maxWorker}");


Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое hashset?

HashSet<T> — это коллекция уникальных элементов, которая обеспечивает быстрый поиск, добавление и удаление. В основе HashSet<T> лежит хеш-таблица, что делает операции очень быстрыми (почти за O(1) в среднем случае).

🚩Создание и использование `HashSet<T>`

Простой пример
HashSet<int> numbers = new HashSet<int> { 1, 2, 3, 4, 5 };

// Добавление элементов (дубликаты не добавляются)
numbers.Add(3); // Уже есть в HashSet, не добавится
numbers.Add(6); // Добавится

// Вывод всех элементов
foreach (int num in numbers)
{
Console.Write(num + " ");
}


Вывод
1 2 3 4 5 6


🚩Основные операции

Пример работы с Contains и Remove
if (numbers.Contains(3))
{
numbers.Remove(3);
}

Console.WriteLine(string.Join(", ", numbers));


Вывод
1, 2, 4, 5, 6


🚩Операции над множествами

HashSet<T> поддерживает математические операции над множествами, такие как пересечение, объединение и разность.

Пересечение (IntersectWith)
HashSet<int> set1 = new HashSet<int> { 1, 2, 3, 4 };
HashSet<int> set2 = new HashSet<int> { 3, 4, 5, 6 };

set1.IntersectWith(set2); // Оставит только {3, 4}
Console.WriteLine(string.Join(", ", set1));


Вывод
3, 4


Объединение (UnionWith)
set1 = new HashSet<int> { 1, 2, 3 };
set2 = new HashSet<int> { 3, 4, 5 };

set1.UnionWith(set2); // set1 = {1, 2, 3, 4, 5}
Console.WriteLine(string.Join(", ", set1));


Вывод
1, 2, 3, 4, 5


Разность (ExceptWith)
set1 = new HashSet<int> { 1, 2, 3, 4, 5 };
set2 = new HashSet<int> { 3, 4 };

set1.ExceptWith(set2); // Удалит {3, 4}, останется {1, 2, 5}
Console.WriteLine(string.Join(", ", set1));


Вывод
1, 2, 5


Ставь 👍 и забирай 📚 Базу знаний
🤔 Как сделать связь один к одному?

Для связи "один к одному" создаётся внешний ключ в одной таблице, связанный с первичным ключом другой таблицы, и для внешнего ключа добавляется ограничение уникальности.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Какие проблемы могут быть при многопоточности и как их избежать?

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

🚩Основные проблемы

🟠Гонки данных (Race Conditions)
Проблема: Два или более потоков пытаются одновременно изменить общие данные или один поток читает данные во время их изменения другим потоком, что приводит к непредсказуемым результатам.
Решение: Использование механизмов синхронизации, таких как блокировки (locks), мьютексы (mutexes) и семафоры (semaphores), для контроля доступа к общим ресурсам.

🟠Взаимная блокировка (Deadlock)
Проблема: Два или более потоков бесконечно ожидают ресурсы, заблокированные друг другом, в результате чего они не могут продолжить выполнение.
Решение: Разработка программы таким образом, чтобы потоки запрашивали ресурсы всегда в одном и том же порядке, использование таймаутов для блокировок, чтобы потоки могли выйти из состояния ожидания.

🟠Голодание (Starvation)
Проблема: Один или несколько потоков не могут получить доступ к необходимым ресурсам, потому что другие потоки постоянно занимают их.
Решение: Применение справедливых блокировок (fair locks) или алгоритмов планирования, которые обеспечивают всем потокам равный доступ к ресурсам.

🟠Переключение контекста (Context Switching)
Проблема: Частое переключение контекста между потоками может значительно снизить производительность системы, особенно если потоки часто блокируются и разблокируются.
Решение: Оптимизация количества потоков, уменьшение зависимостей между потоками и уменьшение использования блокировок.

🟠Проблемы с проектированием
Проблема: Неправильное проектирование многопоточной архитектуры может привести к сложностям в поддержке и расширении программного обеспечения.
Решение: Использование абстракций высокого уровня для работы с потоками, таких как пулы потоков, параллельные библиотеки (например, TPL в .NET) и модели акторов.

private static readonly object _lock = new object();
private static int _sharedResource;

public static void UpdateResource()
{
lock (_lock)
{
_sharedResource++;
// Выполнение некоторой работы с общим ресурсом
}
}


Избегание взаимной блокировки
private static readonly object _lock1

= new object();
private static readonly object _lock2 = new object();

public static void Method1()
{
lock (_lock1)
{
// Некоторые действия
lock (_lock2)
{
// Дополнительные действия
}
}
}

public static void Method2()
{
lock (_lock1)
{
// Аналогичные действия
lock (_lock2)
{
// Дополнительные действия
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
🤔 В чём заключается реализация паттерна абстрактной фабрики

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Какие методы есть в 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));
});
}


Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое метод Finalize?

Метод Finalize() представляет собой специальный метод, который предназначен для выполнения финальной очистки ресурсов перед тем, как объект будет уничтожен сборщиком мусора. Это метод, который может быть определен в классе для очистки неуправляемых ресурсов, если класс не реализует интерфейс IDisposable.

🚩Особенности метода

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

🟠Определение в базовом классе `Object`
Все объекты наследуют от базового класса Object, который предоставляет реализацию Finalize(). Однако в большинстве случаев Finalize() не имеет реализации и не делает ничего, пока не будет переопределен в производном классе.

🟠Замедление сборки мусора
Наличие объектов с финализаторами может замедлить процесс сборки мусора, так как объекты, требующие финализации, должны быть обработаны дважды: сначала они помещаются в очередь финализации, а затем их память освобождается после выполнения Finalize().

class ResourceWrapper
{
// Конструктор
public ResourceWrapper() {
// Инициализация ресурсов
}

// Финализатор
~ResourceWrapper() {
// Код очистки ресурсов
}
}


Ставь 👍 и забирай 📚 Базу знаний
🔥1
🤔 Пример паттерна Строитель?

Например, при создании объекта типа "Отчёт":
- У объекта много параметров (заголовок, дата, содержимое, автор, таблицы).
- С помощью билдера можно поочерёдно вызывать методы SetTitle(), SetContent(), SetFooter() и получить готовый объект методом Build().
Этот подход улучшает читаемость и гибкость кода.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что такое I/O bound и CPU bound?

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

I/O-bound (ограничение ввода-вывода)
CPU-bound (ограничение процессора)

🚩I/O-bound (ограничение ввода-вывода)

Основная проблема: программа ждет завершения операций ввода-вывода (диска, сети, базы данных, файловой системы и т. д.), а не загружает процессор.
Примеры:
- Чтение и запись файлов на диск
- Запросы к базе данных
- HTTP-запросы к API
- Чтение данных из сети
Решение: Использование асинхронного программирования (async/await), чтобы не блокировать поток.
public async Task<string> FetchDataAsync()
{
using HttpClient client = new HttpClient();
return await client.GetStringAsync("https://example.com");
}


🚩CPU-bound (ограничение процессора)

Основная проблема: процессор сильно загружен вычислениями, и узким местом становится скорость обработки данных, а не ввод-вывод.
Примеры:
- Генерация больших отчетов
- Кодирование/декодирование видео
- Комплексные математические вычисления
- Сортировка больших массивов
public static long CalculateFactorial(int number)
{
return Enumerable.Range(1, number).Aggregate(1, (a, b) => a * b);
}

public async Task<long> ComputeAsync(int number)
{
return await Task.Run(() => CalculateFactorial(number));
}


Ставь 👍 и забирай 📚 Базу знаний
🤔 Для чего нужны нереляционные базы данных?

Нереляционные базы данных (NoSQL) используются для работы с большими объёмами данных, структурированных или неструктурированных, а также для обеспечения гибкости и масштабируемости. Они подходят для хранения документов, ключей-значений, графов или временных рядов. Такие базы, как MongoDB или Redis, идеальны для приложений с динамической структурой данных или высокой нагрузкой.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний