C# | Вопросы собесов
5.07K subscribers
33 photos
1 file
975 links
Download Telegram
🤔 Как понять, что в коде будет использоваться IQueryable, а не IEnumerable?

Если запрос выполняется на уровне базы данных или другого внешнего источника данных, используется IQueryable. Если данные уже загружены в память, используется IEnumerable.

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

boxing и unboxing — это два важных процесса, связанных с преобразованием типов между значимыми типами (value types) и ссылочными типами (reference types). Эти процессы играют ключевую роль в работе с обобщенными коллекциями и при взаимодействии между различными частями .NET Framework.

🚩Boxing

Это процесс преобразования переменной значимого типа (например, int или struct) в тип object или в любой другой тип интерфейса, реализуемый этим значимым типом. При боксинге переменная значимого типа оборачивается в объект ссылочного типа, и её значение копируется в новый объект на управляемой куче. Это необходимо, потому что все элементы в .NET в конечном итоге должны быть объектами.
int num = 123;
object obj = num; // Boxing


🚩Unboxing

Это обратный процесс, при котором содержимое объекта ссылочного типа преобразуется обратно в значимый тип. Требует явного указания типа, к которому нужно преобразовать, и может вызывать исключение InvalidCastException, если объект не может быть преобразован в желаемый значимый тип.
object obj = 123;  // Boxing
int num = (int)obj; // Unboxing


🟠Производительность
Боксинг и анбоксинг могут негативно сказаться на производительности, поскольку они влекут за собой операции с памятью, включая выделение памяти и сборку мусора. Поэтому рекомендуется минимизировать их использование, особенно в критичных по производительности частях приложения.
🟠Нужда
Несмотря на возможное негативное влияние на производительность, боксинг и анбоксинг необходимы для работы со значимыми типами в контекстах, где требуются объекты (например, при работе с коллекциями типа ArrayList).

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊1
🤔 Что такое try-catch?

try-catch — это механизм обработки исключений в C#.
Код, который может вызвать ошибку во время выполнения, помещается в блок try.
Если ошибка происходит, выполнение переходит в соответствующий блок catch.
Блок finally может использоваться для выполнения завершающих действий, выполняемых независимо от ошибок (например, закрытие файлов, соединений и т.д.).


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

IEnumerable — это интерфейс в базовой библиотеке классов .NET Framework, который определяет один метод: GetEnumerator(). Этот метод возвращает объект IEnumerator, который позволяет перебирать элементы коллекции (например, массива или списка) один за другим.

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

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

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

Когда вы реализуете интерфейс IEnumerable в своём классе, вы обязуете этот класс предоставлять метод GetEnumerator(), который возвращает IEnumerator. IEnumerator, в свою очередь, имеет методы для перехода к следующему элементу (MoveNext) и для получения текущего элемента (Current), а также метод Reset(), который возвращает перечислитель в начальное состояние.
using System;
using System.Collections;

public class DaysOfWeek : IEnumerable
{
private string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };

public IEnumerator GetEnumerator()
{
for (int index = 0; index < days.Length; index++)
{
// Yield each day of the week.
yield return days[index];
}
}
}

public class Program
{
public static void Main()
{
DaysOfWeek daysOfWeek = new DaysOfWeek();
foreach (string day in daysOfWeek)
{
Console.WriteLine(day);
}
}
}


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

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что делает new 'имя объекта'()?

Оператор new в C# создаёт новый экземпляр объекта и выделяет для него память в куче (Heap) или стеке (Stack), в зависимости от типа.

🚩Как работает `new`?

Для классов (class) – выделяет память в куче (Heap) и возвращает ссылку на объект.
Для структур (struct) – если структура создаётся без new, её поля остаются неинициализированными, но если использовать new, она получает значения по умолчанию.
Для массивов (T[]) – выделяет память в куче, даже если T – это struct.
Для делегатов – создаёт экземпляр делегата.

Пример: new с классом (class)
class Person
{
public string Name;

public Person(string name)
{
Name = name;
}
}

class Program
{
static void Main()
{
Person p1 = new Person("Alice"); // Создаём новый объект в куче
Console.WriteLine(p1.Name); // Alice
}
}


Пример: new со структурой (struct)
struct Point
{
public int X;
public int Y;

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

class Program
{
static void Main()
{
Point p1 = new Point(5, 10); // Создаёт структуру в стеке
Console.WriteLine(p1.X); // 5
}
}


Пример: new с массивом
int[] numbers = new int[5]; // Создаёт массив в куче
numbers[0] = 10;
Console.WriteLine(numbers[0]); // 10


🚩Что делает `new` за кулисами?

Выделение памяти в куче (для классов) или в стеке (для структур).
Вызов конструктора класса или структуры.
Возвращение ссылки на объект (для классов) или самого объекта (для структур).

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

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍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.

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

Это статические методы, которые позволяют работать с коллекциями, например, Where, Select, OrderBy. Они упрощают обработку данных и делают код читаемым.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
🤔 Как работает 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}");


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

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


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

Это делегат, представляющий метод, который принимает один или несколько аргументов и возвращает логическое значение (true или false). Предикаты часто используются для фильтрации коллекций, поиска элементов и других операций, связанных с условными проверками.

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

🟠Тип делегата
В C# предикат представлен делегатом Predicate<T>, который принимает один аргумент типа T и возвращает bool.

🟠Использование
Предикаты обычно используются в методах стандартных коллекций, таких как List<T>, для поиска, удаления и фильтрации элементов.

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

Определение предиката
public static bool IsEven(int number)
{
return number % 2 == 0;
}


Использование предиката с методом коллекции
using System;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// Использование предиката для поиска первого четного числа
int firstEven = numbers.Find(IsEven);
Console.WriteLine("First even number: " + firstEven);

// Использование предиката для удаления всех четных чисел
numbers.RemoveAll(IsEven);
Console.WriteLine("Numbers after removing evens: " + string.Join(", ", numbers));
}

public static bool IsEven(int number)
{
return number % 2 == 0;
}
}


🚩Лямбда-выражения как предикаты

Лямбда-выражения часто используются для определения предикатов непосредственно в месте вызова метода. Это делает код более компактным и удобочитаемым.

Пример использования лямбда-выражений
using System;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// Использование лямбда-выражения для поиска первого четного числа
int firstEven = numbers.Find(n => n % 2 == 0);
Console.WriteLine("First even number: " + firstEven);

// Использование лямбда-выражения для удаления всех четных чисел
numbers.RemoveAll(n => n % 2 == 0);
Console.WriteLine("Numbers after removing evens: " + string.Join(", ", numbers));
}
}


🚩Сценарии использования предикатов

🟠Фильтрация коллекций
Предикаты используются для определения условий фильтрации элементов в коллекциях.
List<int> evenNumbers = numbers.FindAll(IsEven);   


🟠Поиск элементов
Предикаты помогают находить элементы, соответствующие определенному условию.
int firstEven = numbers.Find(IsEven);   


🟠Удаление элементов
Предикаты используются для удаления элементов, соответствующих определенному условию.
numbers.RemoveAll(IsEven);


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Как можно не отслеживать сущность?

В Entity Framework можно не отслеживать сущность, чтобы она не попадала под управление контекста (DbContext) — это снижает нагрузку и повышает производительность при чтении данных.
Способы:
- Использовать AsNoTracking()
- Использовать проекцию в DTO (анонимные объекты или модели без привязки к EF)
Такой подход полезен, если изменения в объект не планируются.


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

Парадигмы программирования — это подходы к написанию кода.

🚩Инкапсуляция (Encapsulation)

Скрытие деталей и защита данных.
public class Car
{
private string _engine = "V8"; // Скрытое поле

public void Start() => Console.WriteLine("Машина завелась!");
}


🚩Наследование (Inheritance)

Класс-потомок получает свойства и методы родителя.
public class Animal 
{
public void Speak() => Console.WriteLine("Издаёт звук");
}

public class Dog : Animal { } // Наследует Animal

Dog dog = new Dog();
dog.Speak(); // Издаёт звук


🚩Полиморфизм (Polymorphism)

Один интерфейс – разные реализации.
public class Animal
{
public virtual void Speak() => Console.WriteLine("Неизвестный звук");
}

public class Cat : Animal
{
public override void Speak() => Console.WriteLine("Мяу!");
}

Animal myCat = new Cat();
myCat.Speak(); // Выведет "Мяу!"


🚩Абстракция (Abstraction)

Выделяем только важное, остальное скрываем.
public abstract class Vehicle
{
public abstract void Move();
}

public class Bicycle : Vehicle
{
public override void Move() => Console.WriteLine("Едет на педалях");
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊4
🤔 Есть прямоугольник и квадрат, цель вычислить площадь, что нарушает принцип Барбары Лисков?

Если класс "Квадрат" наследуется от "Прямоугольник" и переопределяет методы установки ширины и высоты так, что нарушает их независимость, это ломает принцип Лисков. Например, изменение ширины у квадрата изменяет и высоту, что не ожидается для прямоугольника.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Можно ли 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
}
}


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

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 В чём разница абстрактного класса и интерфейса?

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

Представляет собой класс, от которого нельзя создать экземпляр напрямую. Он предназначен для описания общего поведения и состояния своих подклассов. Абстрактные классы могут содержать реализацию некоторых методов и свойств. Это означает, что абстрактный класс может содержать как абстрактные методы (без реализации), так и методы с реализацией. Подклассы абстрактного класса обязаны реализовать все абстрактные методы, но они также наследуют реализованные методы и свойства.
public abstract class Животное
{
public abstract void Есть(); // Абстрактный метод, должен быть реализован в наследнике.

public void Дышать() // Метод с реализацией, наследуется всеми наследниками.
{
Console.WriteLine("Дыхание");
}
}


Интерфейс определяет контракт, который классы или структуры могут реализовывать. Интерфейсы могут содержать объявления методов, свойств, событий, но не их реализации. Класс или структура, реализующие интерфейс, должны предоставить реализацию для всех его членов. Важно отметить, что класс может реализовывать несколько интерфейсов, что обеспечивает форму множественного наследования.
public interface IЖивотное
{
void Есть(); // Метод, который должен быть реализован в классе.
}


🚩Основные различия

🟠Наследование
Класс может наследовать только от одного абстрактного класса (из-за ограничения одиночного наследования в C#), но может реализовывать множество интерфейсов.
🟠Члены
Абстрактные классы могут содержать реализацию методов и поля данных, в то время как интерфейсы могут содержать только объявления методов и свойств (без полей и реализации).
🟠Конструкторы и деструкторы
Абстрактные классы могут иметь конструкторы и деструкторы, в то время как интерфейсы - нет.
🟠Модификаторы доступа
В интерфейсах все члены по умолчанию являются public, и вы не можете указать другой модификатор доступа. В абстрактных классах вы можете использовать различные модификаторы доступа.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊6🤔1
🤔 Что такое конкурентность в многопоточности?

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


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

Делегат (delegate) — это указатель на метод(ы). Он может хранить:
1. Ссылку на один метод (одиночный делегат)
2. Ссылки на несколько методов (групповой делегат / multicast)
3. Анонимные методы и лямбда-выражения

🚩Делегат хранит ссылку на метод

Делегаты позволяют вызвать метод, даже если его имя заранее неизвестно.
Пример с одиночным делегатом
public delegate void MyDelegate(string message); // Объявляем делегат

public class Program
{
public static void ShowMessage(string msg) => Console.WriteLine($"Сообщение: {msg}");

public static void Main()
{
MyDelegate del = ShowMessage; // Делегат хранит ссылку на метод
del("Привет, делегаты!"); // Вызывает ShowMessage
}
}


🚩Делегат может хранить несколько методов (Multicast)

Делегаты можно связывать с несколькими методами с помощью +=. Пример группового делегата
public delegate void MyDelegate(string message);

public class Program
{
public static void Method1(string msg) => Console.WriteLine($"Метод 1: {msg}");
public static void Method2(string msg) => Console.WriteLine($"Метод 2: {msg}");

public static void Main()
{
MyDelegate del = Method1;
del += Method2; // Добавляем второй метод

del("Привет!");
// Выведет:
// Метод 1: Привет!
// Метод 2: Привет!
}
}


🚩Делегат может хранить анонимные методы и лямбды

Делегаты могут хранить "встроенные" методы (без отдельного определения).
Пример с анонимным методом
MyDelegate del = delegate (string msg) 
{
Console.WriteLine($"Анонимный метод: {msg}");
};
del("Привет!");


Пример с лямбда-выражением
MyDelegate del = msg => Console.WriteLine($"Лямбда: {msg}");
del("Привет!");


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

API (например, REST или GraphQL) обеспечивает прослойку между клиентом и базой данных, потому что:
1. Безопасность — база данных не должна быть напрямую доступна клиенту.
2. Инкапсуляция логики — в API можно реализовать бизнес-логику и валидации.
3. Гибкость — можно изменять структуру базы, не затрагивая клиента.
4. Масштабируемость — API может обрабатывать нагрузку, кешировать данные и распределять запросы.
5. Контроль доступа — через API проще реализовать авторизацию и аутентификацию.


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