C# | Вопросы собесов
Open in Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
Show more5 015
Subscribers
No data24 hours
+47 days
+2630 days
Posts Archive
5 016
🤔 В каком случае использовать интерфейс, в каком абстрактный класс?
Выбор между интерфейсом и абстрактным классом в C# зависит от нескольких факторов, таких как потребности в наследовании, степень общности, возможность множественного наследования и необходимость реализации по умолчанию.
🚩Когда использовать интерфейсы
🟠Множественное наследование
Класс может реализовывать несколько интерфейсов, но наследоваться только от одного класса. Используйте интерфейсы, когда требуется множественное наследование.
public interface IDriveable
{
void Drive();
}
public interface IFlyable
{
void Fly();
}
public class FlyingCar : IDriveable, IFlyable
{
public void Drive() { /* Реализация вождения */ }
public void Fly() { /* Реализация полета */ }
}
🟠Общее поведение без реализации
Используйте интерфейсы, чтобы определить общий набор методов и свойств без предоставления какой-либо реализации. Это позволяет разным классам реализовать интерфейс по-своему.
public interface IShape
{
double GetArea();
}
public class Circle : IShape
{
public double Radius { get; set; }
public double GetArea() => Math.PI * Radius * Radius;
}
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double GetArea() => Width * Height;
}
🟠Гибкость и полиморфизм
Интерфейсы позволяют легко менять реализацию и обеспечивают гибкость в коде. Можно использовать интерфейсы для создания полиморфных коллекций или методов, которые работают с разными реализациями интерфейсов.
public void DrawShapes(IEnumerable<IShape> shapes)
{
foreach (var shape in shapes)
{
Console.WriteLine($"Area: {shape.GetArea()}");
}
}
🚩Когда использовать
🟠Частичная реализация
Используйте абстрактные классы, если вы хотите предоставить некоторую общую реализацию, которую могут использовать подклассы. Абстрактные классы могут содержать как абстрактные, так и не абстрактные методы.
public abstract class Animal
{
public abstract void MakeSound();
public void Sleep() => Console.WriteLine("Sleeping");
}
public class Dog : Animal
{
public override void MakeSound() => Console.WriteLine("Bark");
}
🟠Шаблонный метод
Абстрактные классы хорошо подходят для реализации паттерна "Шаблонный метод", где общий алгоритм реализован в абстрактном классе, а конкретные шаги определены в подклассах.
public abstract class Game
{
public void Play()
{
Initialize();
StartPlay();
EndPlay();
}
protected abstract void Initialize();
protected abstract void StartPlay();
protected abstract void EndPlay();
}
public class Football : Game
{
protected override void Initialize() => Console.WriteLine("Football Game Initialized");
protected override void StartPlay() => Console.WriteLine("Football Game Started");
protected override void EndPlay() => Console.WriteLine("Football Game Ended");
}
Ставь 👍 и забирай 📚 Базу знаний5 016
🤔 Что такое абстракция?
Абстракция — это принцип ООП, который выделяет только важные характеристики объекта, скрывая сложные детали его реализации. Это помогает упростить взаимодействие с объектами и сконцентрироваться на их использовании, а не на внутренней структуре.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Что такое куки и где оно хранится в запросе?
Это небольшие фрагменты данных, которые веб-сайты сохраняют на устройствах пользователей для хранения информации о сессии и отслеживания состояния. Куки используются для различных целей, таких как аутентификация пользователей, хранение настроек и предпочтений, а также отслеживание активности пользователей на сайте.
🚩Основные свойства
🟠Имя (Name)
Уникальный идентификатор для каждого куки.
🟠Значение (Value)
Данные, которые хранит куки.
🟠Домен (Domain)
Домен, для которого куки действителен.
🟠Путь (Path)
Путь на сервере, для которого куки действителен.
🟠Время истечения (Expiration/Max-Age)
Дата или время, когда куки должен быть удален.
🟠Безопасность (Secure)
Указывает, что куки должны передаваться только через HTTPS.
🟠HTTPOnly
Указывает, что куки недоступен через JavaScript, только через HTTP(S) запросы.
🚩Где хранятся
🟠Установка куки с сервера (Set-Cookie)
Сервер отправляет куки в ответе на запрос клиента с использованием заголовка
Set-Cookie.
HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; Expires=Wed, 09 Jun 2023 10:18:14 GMT
Content-Type: text/html
🟠Отправка куки клиентом (Cookie)
Браузер автоматически добавляет соответствующие куки в заголовок Cookie при каждом последующем запросе к серверу, для которого эти куки действительны.
GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123
🚩Пример использования
Установка куки на сервере (пример на Node.js с использованием Express)
const express = require('express');
const app = express();
app.get('/', (req, res) => {
// Устанавливаем куки
res.cookie('sessionId', 'abc123', {
maxAge: 900000,
httpOnly: true
});
res.send('Куки установлены');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Доступ к куки на клиенте (пример на JavaScript)
// Установка куки
document.cookie = "username=JohnDoe; expires=Thu, 18 Dec 2023 12:00:00 UTC; path=/";
// Получение всех куки
let cookies = document.cookie;
console.log(cookies);
🚩Важные моменты
🟠Безопасность
Куки с флагом Secure передаются только по HTTPS-соединениям. Куки с флагом HttpOnly недоступны через JavaScript, что помогает защитить их от XSS-атак.
🟠Размер и количество
Обычно один куки не должен превышать 4KB, и на одном домене может быть установлено не более 20-30 куки.
🟠Конфиденциальность
Куки могут содержать чувствительные данные, поэтому важно защищать их и использовать шифрование, если необходимо.
Ставь 👍 и забирай 📚 Базу знаний5 016
Скидки до 90% на Wildberries
На WB собрали стильную подборку одежды на любой вкус ✨
Внутри — модные платья, удобные джинсы, стильные куртки и другие популярные модели от проверенных брендов.
Кстати, сейчас на Wildberries действуют скидки до 90% и быстрая доставка от 1 дня.
Идеальный момент для обновления гардероба ❤️
Перейти на сайт
#реклама
wildberries.ru
О рекламодателе
5 016
🤔 Что делает new имяОбъекта()?
Оператор new:
- создаёт экземпляр класса или структуры;
- выделяет память в куче или стеке (в зависимости от типа);
- вызывает конструктор — по умолчанию или переданный;
- возвращает ссылку на объект (для reference-type) или сам объект (для value-type).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
Скидки до 90% на Wildberries
На WB собрали удобную и стильную обувь для всей семьи 🏃♂️
Модные кроссовки, удобные сабо, классические туфли и другие популярные модели от известных брендов.
Кстати, сейчас на Wildberries действуют скидки до 90% и быстрая доставка от 1 дня.
Отличный шанс пополнить свою коллекцию обуви ❤️
Перейти на сайт
#реклама
wildberries.ru
О рекламодателе
5 016
🤔 Можно ли передать значимый тип данных по ссылке?
Да, можно!
По умолчанию значимые типы (структуры,
int, double) передаются по значению.
Но их можно передать по ссылке с помощью ref или out.
🚩Передача по значению (обычное поведение)
Копия передаётся в метод, а оригинал не меняется.
void ChangeValue(int number)
{
number = 10; // Изменится только копия
}
int x = 5;
ChangeValue(x);
Console.WriteLine(x); // 5 (значение не изменилось)
🚩Передача значимого типа по ссылке (`ref`)
Позволяет менять оригинальную переменную.
void ChangeValue(ref int number)
{
number = 10; // Меняем оригинальное значение
}
int x = 5;
ChangeValue(ref x);
Console.WriteLine(x); // 10 (значение изменилось)
🚩Использование `out` (без начального значения)
out тоже передаёт по ссылке, но требует обязательного присвоения внутри метода.
void InitializeValue(out int number)
{
number = 100; // Обязательно присваиваем значение
}
int x;
InitializeValue(out x);
Console.WriteLine(x); // 100
Ставь 👍 и забирай 📚 Базу знаний5 016
🤔 Что под собой подразумевает mutex?
Mutex (мьютекс) — это механизм исключительного доступа. Он позволяет только одному потоку или процессу использовать ресурс в конкретный момент. Остальные ждут, пока мьютекс не освободится. Это полезно при межпоточном или межпроцессном взаимодействии.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Какие методы есть в 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));
});
}
Ставь 👍 и забирай 📚 Базу знаний5 016
🤔 Как работает асинхронный метод?
Асинхронный метод:
- выполняется без блокировки основного потока;
- использует ключевое слово async и возвращает Task/Task<T>;
- может приостанавливаться на await и продолжаться после завершения асинхронной операции.
Это позволяет эффективно использовать ресурсы и обрабатывать I/O без блокировок.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Что такое 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Ставь 👍 и забирай 📚 Базу знаний
5 016
🤔 Зачем нужны интерфейсы, если есть абстрактные классы?
Интерфейсы в C# позволяют определять набор методов, которые должны быть реализованы в классах, но не содержат реализации. В отличие от абстрактных классов, интерфейсы не могут содержать полей или реализаций методов (до C# 8.0), и класс может реализовать несколько интерфейсов, но наследовать только один абстрактный класс. Интерфейсы используются для создания гибких архитектур, когда классы могут реализовать множество интерфейсов, предоставляя различные поведения. Они помогают достигать полиморфизма и создавать легко тестируемые системы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Что такое interceptor?
Interceptor (перехватчик) — это паттерн программирования, используемый для перехвата и обработки вызовов методов, запросов или событий перед их исполнением или после. В контексте C# и .NET, интерцепторы чаще всего применяются в:
ASP.NET Core Middleware — для перехвата HTTP-запросов.
Entity Framework Core Interceptors — для перехвата SQL-запросов и изменений данных.
Aspect-Oriented Programming (AOP) — для добавления кода перед или после выполнения метода.
🚩Зачем нужен Interceptor?
🟠Логирование
можно записывать запросы, исключения, время выполнения.
🟠Безопасность
проверка прав доступа перед выполнением запроса.
🟠Транзакции
автоматическое управление транзакциями в базе данных.
🟠Изменение поведения методов
например, автоматическая подмена аргументов.
🟠Кэширование
можно сохранять результаты выполнения метода.
🚩Пример использования Interceptor в Entity Framework Core
Entity Framework Core позволяет использовать интерцепторы для перехвата SQL-запросов. Это может быть полезно, например, для логирования всех SQL-запросов.
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Data.Common;
using System.Threading;
using System.Threading.Tasks;
public class SqlInterceptor : DbCommandInterceptor
{
public override InterceptionResult<DbDataReader> ReaderExecuting(
DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
{
Console.WriteLine($"SQL Query: {command.CommandText}");
return base.ReaderExecuting(command, eventData, result);
}
}
Теперь подключим этот интерцептор в DbContext
using Microsoft.EntityFrameworkCore;
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new SqlInterceptor());
base.OnConfiguring(optionsBuilder);
}
}
🚩Пример использования Interceptor в ASP.NET Core (Middleware)
В ASP.NET Core интерцепторы можно реализовать через Middleware. Например, перехватим все HTTP-запросы и добавим в лог
public class RequestInterceptor
{
private readonly RequestDelegate _next;
public RequestInterceptor(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine($"HTTP Request: {context.Request.Method} {context.Request.Path}");
await _next(context);
}
}
Добавляем middleware в Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseMiddleware<RequestInterceptor>();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
app.Run();
Ставь 👍 и забирай 📚 Базу знаний5 016
🤔 Что такое interlocked?
Interlocked — это механизм для безопасного изменения чисел между потоками без использования блокировок. Он позволяет выполнять операции вроде прибавления или замены значений мгновенно и без конфликта, что важно для высокой производительности при простых действиях.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Что такое 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));
}
Ставь 👍 и забирай 📚 Базу знаний5 016
🤔 Как в кучах разделяются объекты?
В куче объекты разделяются по областям памяти: например, на молодой (Generation 0), средний (Generation 1) и старший (Generation 2) сегменты, чтобы оптимизировать сборку мусора. Также существует разделение на Large Object Heap (для больших объектов) и Small Object Heap.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Для чего нужны нереляционные базы данных?
Нереляционные базы данных (NoSQL) используются для работы с большими объёмами данных, структурированных или неструктурированных, а также для обеспечения гибкости и масштабируемости. Они подходят для хранения документов, ключей-значений, графов или временных рядов. Такие базы, как MongoDB или Redis, идеальны для приложений с динамической структурой данных или высокой нагрузкой.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Можно ли 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
}
}
Ставь 👍 и забирай 📚 Базу знаний5 016
🤔 Как происходит запрос интерфейса?
Когда компоненту нужен другой класс (зависимость), он объявляет интерфейс в своём конструкторе, а контейнер DI:
- Ищет зарегистрированную реализацию этого интерфейса.
- Создаёт экземпляр и передаёт его в зависимый класс.
Такой механизм называется инъекция через конструктор, и он наиболее распространён.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
5 016
🤔 Что такое контекст синхронизации?
"контекст синхронизации" (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 из асинхронных или вторичных потоков.
🟠Правильное управление потоками
Обеспечивает выполнение кода в контексте, для которого он предназначен, что особенно важно в многопоточных и сетевых приложениях.
Ставь 👍 и забирай 📚 Базу знаний