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

Контакт для рекламы: @sendme_ads
Download Telegram
🤔 Какие методы есть в 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));
});
}


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Что такое индексы, какие типы бывают, использовал ли их на практике?

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

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

Привязка данных (Data Binding) — это механизм, который позволяет автоматически синхронизировать данные между источником (например, моделью) и интерфейсом (например, элементами UI).

🚩Односторонняя привязка (One-Way Binding)

Данные идут только в одном направлении: из модели в UI.
- Для вывода данных, которые не должны изменяться пользователем
- Например, для отображения текущего времени
Пример в WPF
<TextBlock Text="{Binding UserName}" />


🚩Двусторонняя привязка (Two-Way Binding)

Данные синхронизируются в обе стороны: UI ↔️ Модель
- В формах ввода (например, TextBox), чтобы обновлять данные в модели
- Используется в MVVM
Пример в WPF
<TextBox Text="{Binding UserName, Mode=TwoWay}" />


🚩Привязка к событиям (Event Binding)

Позволяет связывать UI с методами обработки событий.
- Для обработки кнопок (Button.Click)
- В реактивных фреймворках (Blazor, WinForms)
Пример в Blazor
<button @onclick="IncrementCount">Добавить</button>

@code {
private int count = 0;
private void IncrementCount() => count++;
}


🚩Привязка к командам (Command Binding)

Используется в паттерне MVVM вместо событий
- В WPF и Xamarin
- Позволяет отделить логику от UI
Пример в WPF
<Button Content="Сохранить" Command="{Binding SaveCommand}" />


🚩Привязка к коллекциям (ItemsSource Binding)

Позволяет привязывать списки к элементам UI (ListBox, DataGrid)
- В списках, таблицах, дропдаунах
Пример в WPF
<ListBox ItemsSource="{Binding Users}" DisplayMemberPath="Name" />


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

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


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

"контекст синхронизации" (SynchronizationContext) — это класс, который предоставляет возможность управлять способом, которым операции переключаются обратно в основной поток или контекст для продолжения выполнения после асинхронной операции. Это важно для приложений с графическим пользовательским интерфейсом, таких как Windows Forms и WPF, где доступ к элементам пользовательского интерфейса разрешён только из основного потока.

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

Абстрагирует модель синхронизации для различных сред выполнения. Например, в приложениях Windows Forms и WPF управление элементами UI должно происходить в главном потоке. SynchronizationContext предоставляет методы для отправки (Send) и постановки (Post) задач, которые должны выполняться в правильном контексте.
🟠Send
синхронно отправляет делегат на выполнение в контекст синхронизации.
🟠Post
асинхронно отправляет делегат на выполнение в контекст синхронизации.

🚩Применение SynchronizationContext

Используется для того, чтобы после асинхронной операции вернуться в правильный поток и безопасно обновить UI или выполнить код, который требует выполнения в определённом потоке.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LoadDataAsync();
}

private async void LoadDataAsync()
{
string data = await GetDataAsync();
// Асинхронно получаем данные и обновляем UI
Dispatcher.Invoke(() => DisplayData(data));
}

private Task<string> GetDataAsync()
{
return Task.Run(() =>
{
// Имитация долгой операции
Thread.Sleep(5000);
return "Data loaded";
});
}

private void DisplayData(string data)
{
MyTextBox.Text = data;
}
}


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

🟠Безопасность потоков
Позволяет безопасно обращаться к элементам UI из асинхронных или вторичных потоков.
🟠Правильное управление потоками
Обеспечивает выполнение кода в контексте, для которого он предназначен, что особенно важно в многопоточных и сетевых приложениях.

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

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


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

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

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

🟠Гонки данных (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)
{
// Дополнительные действия
}
}
}


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

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


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

Да, можно! Обобщённые (generic) методы могут существовать в обычных (не-generic) классах.

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

Generic-метод — это метод, у которого тип параметра задаётся при вызове, даже если сам класс не является обобщённым.
Пример: Обобщённый метод в обычном классе
public class Utils
{
public static void Print<T>(T value) // Обобщённый метод
{
Console.WriteLine($"Тип: {typeof(T)}, Значение: {value}");
}
}

class Program
{
static void Main()
{
Utils.Print(100); // Тип: System.Int32, Значение: 100
Utils.Print("Hello"); // Тип: System.String, Значение: Hello
Utils.Print(3.14); // Тип: System.Double, Значение: 3.14
}
}


Ставь 👍 и забирай 📚 Базу знаний
🤔 Все ли HTTP-методы идемпотентные?

Нет.
Вот классификация:
Идемпотентные:
- GET — многократный вызов не меняет состояние.
- PUT — задаёт конкретное состояние ресурса.
- DELETE — может быть вызван многократно с тем же результатом.
- HEAD, OPTIONS — тоже идемпотентны.
Неидемпотентные:
- POST — каждый вызов может создавать новый ресурс или изменять состояние (непредсказуемо).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊2
🤔 Что такое инверсия зависимостей?

Инверсия зависимостей — это принцип SOLID, который говорит:
> Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций.

Это значит, что вместо жёстких зависимостей на конкретные классы, код должен работать через абстракции (interface или abstract class).

🚩Проблема без инверсии зависимостей
Допустим, у нас есть класс EmailSender, который отправляет письма:
public class EmailSender
{
public void Send(string message)
{
Console.WriteLine($"Отправка email: {message}");
}
}

public class NotificationService
{
private EmailSender _emailSender = new EmailSender();

public void Notify(string message)
{
_emailSender.Send(message);
}
}


🚩Решение: Инверсия зависимостей

Чтобы избавиться от жёсткой зависимости, вводим абстракцию (IMessageSender):
public interface IMessageSender
{
void Send(string message);
}

public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine($"Отправка email: {message}");
}
}

public class SmsSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine($"Отправка SMS: {message}");
}
}


Теперь NotificationService зависит не от конкретного класса, а от интерфейса:
public class NotificationService
{
private readonly IMessageSender _messageSender;

public NotificationService(IMessageSender messageSender)
{
_messageSender = messageSender;
}

public void Notify(string message)
{
_messageSender.Send(message);
}
}


Теперь мы можем подставлять любую реализацию IMessageSender:
var emailNotifier = new NotificationService(new EmailSender());
emailNotifier.Notify("Привет через Email!");

var smsNotifier = new NotificationService(new SmsSender());
smsNotifier.Notify("Привет через SMS!");


Вывод
Отправка email: Привет через Email!
Отправка SMS: Привет через SMS!


🚩Преимущества инверсии зависимостей

Гибкость – можно легко заменять зависимости.
Тестируемость – можно подставить Mock-объект вместо EmailSender.
Меньше изменений в коде – можно добавить новые способы отправки сообщений без изменения NotificationService.

Ставь 👍 и забирай 📚 Базу знаний
🤔 В чем разница между асинхронностью и многопоточностью?

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

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

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

🚩Почему абстрактный метод требует абстрактного класса?

Абстрактный метод — это метод, который объявлен, но не имеет реализации. Он выступает как "контракт", который обязан быть реализован в производном классе.
public abstract class Shape
{
public abstract double CalculateArea();
}


Абстрактные методы имеют следующие особенности:
Они не могут содержать тело (реализацию).
Их цель — заставить производные классы реализовать конкретную функциональность.
Они всегда принадлежат абстрактным классам.

🚩Пример ошибки

Если попытаться объявить абстрактный метод в обычном классе, компилятор выдаст ошибку
public class RegularClass
{
public abstract void SomeMethod(); // Ошибка: абстрактный метод может быть только в абстрактном классе
}


🚩Логика дизайна

C# требует, чтобы абстрактные методы находились только в абстрактных классах, потому что:
Абстрактные классы могут содержать как абстрактные, так и обычные методы. Это позволяет определять базовое поведение в абстрактном классе и оставлять специфическую реализацию производным классам.
Обычные классы не могут содержать абстрактные методы, так как они предназначены для создания объектов, а объект не может содержать "незавершённый" метод.

Ставь 👍 и забирай 📚 Базу знаний
🤔 В чем разница Redis и Memcached?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔1
🤔 Что такое value-type?

Value Type (тип значения) – это тип данных, который хранит своё значение непосредственно в памяти (обычно в стеке), а не ссылку на объект в куче (heap), как это делает ссылочный тип (Reference Type).

🚩Какие типы данных являются Value Type?

Простые типы (int, double, bool, char, byte, float, decimal, etc.)
Структуры (struct)
Перечисления (enum)
Nullable-значения (int?, double?)

🚩Пример Value Type

int a = 10;
int b = a; // Значение копируется

b = 20;
Console.WriteLine(a); // 10 (остался неизменным)
Console.WriteLine(b); // 20


🚩Где хранятся Value Type?

Value Type обычно хранятся в стеке (stack) – это быстрая область памяти.
Если структура (struct) является частью объекта (который хранится в куче), то её значение хранится внутри объекта в куче.
struct Point
{
public int X;
public int Y;
}

class Program
{
static void Main()
{
Point p1 = new Point { X = 5, Y = 10 };
Point p2 = p1; // Копирование структуры (создаётся новый экземпляр)

p2.X = 20;
Console.WriteLine(p1.X); // 5 (остался неизменным)
Console.WriteLine(p2.X); // 20
}
}


🚩Когда использовать Value Type?

Если данные небольшие и часто изменяются – struct
Если объект недолговечный и не требует сложного поведения
Если производительность важна – Value Type быстрее из-за работы в стеке

Ставь 👍 и забирай 📚 Базу знаний
🔥1💊1
🤔 Какие виды связей бывают у join`ов?

Связи бывают: один к одному, один ко многим, многие ко многим. Они определяют, как таблицы взаимодействуют друг с другом через ключи.

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


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

Ключи должны быть:
- Уникальными
- Иметь устойчивую реализацию GetHashCode() и Equals()
Подходящие типы:
- Примитивы (int, string, GUID и т.п.)
- Структуры (например, кастомные value types)
- Объекты (если правильно переопределены Equals и GetHashCode)


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

В C# существует множество различных типов данных, которые можно разделить на две основные категории: значимые типы (value types) и ссылочные типы (reference types). Рассмотрим каждую из этих категорий и их подтипы.

🚩Значимые типы (Value Types)

Значимые типы хранят данные непосредственно в своей памяти. Они обычно располагаются в стеке и имеют фиксированный размер. К значимым типам относятся:

🟠Простые типы (Simple Types)
Числовые типы
Целочисленные типы:
byte (8 бит)
sbyte (8 бит)
short (16 бит)
ushort (16 бит)
int (32 бита)
uint (32 бита)
long (64 бита)
ulong (64 бита)
Вещественные типы:
float (32 бита)
double (64 бита)
Десятичный тип:
decimal (128 бит)
Логический тип
bool (1 бит, значения true или false)
Символьный тип
char (16 бит, символы в формате Unicode)

🟠Структуры (Structs)
Пользовательские типы, которые могут содержать поля, свойства и методы. Пример: struct Point { public int X; public int Y; }

🟠Перечисления (Enums)
Специальные типы, представляющие набор именованных констант. Пример: enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }

🟠Nullable Types
Типы, которые могут принимать значение null. Пример: int?, double?

🚩Ссылочные типы (Reference Types)

🟠Классы (Classes)
Основные объекты в C#, могут содержать поля, свойства, методы и события. Пример: class Person { public string Name; public int Age; }

🟠Интерфейсы (Interfaces)
Определяют контракт, который должны реализовать классы. Пример: interface IMovable { void Move(); }

🟠Массивы (Arrays)
Коллекции однотипных элементов. Пример: int[] numbers = new int[5];

🟠Делегаты (Delegates)
Типы, которые представляют собой ссылки на методы. Пример: delegate void Process(int value);

🟠Строки (Strings)
Непосредственно представляют собой последовательность символов. Пример: string message = "Hello, World!";

🟠Записи (Records)
Новый тип в C# 9.0, предназначенный для неизменяемых объектов. Пример: record Person(string Name, int Age);

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

Значимые типы
int a = 5;
float b = 3.14f;
bool isTrue = true;
char letter = 'A';


Ссылочные типы
string message = "Hello, World!";
Person person = new Person { Name = "Alice", Age = 30 };

int[] numbers = new int[] { 1, 2, 3, 4, 5 };


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

Это метод интерфейса IDisposable, предназначенный для явного освобождения неуправляемых ресурсов, таких как файловые дескрипторы, сокеты или подключение к базе данных. Его нужно вызывать вручную (или через using), чтобы предотвратить утечки памяти и других ресурсов.

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

Можно ограничить типы, которые передаются в шаблоны (generics), с помощью ключевого слова where. Это позволяет указать, какие типы подходят для использования, обеспечивая безопасность и предсказуемость кода. Вот основные виды ограничений:

🟠Класс или структура
where T : class — только классы.
where T : struct — только структуры.

🟠Интерфейс
Указание интерфейса, который должен реализовать тип:

   public class MyClass<T> where T : IDisposable { }


🟠Базовый класс
Указание, что тип должен быть наследником определённого класса:

   public class MyClass<T> where T : Exception { }


🟠Конструктор
Ограничение на наличие конструктора без параметров:

   public class MyClass<T> where T : new() { }


🟠Комбинированные ограничения
Можно объединять несколько условий:

   public class MyClass<T> where T : class, IDisposable, new() { }


Ставь 👍 и забирай 📚 Базу знаний