C# | Вопросы собесов
الذهاب إلى القناة على Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
إظهار المزيد5 006
المشتركون
-124 ساعات
-107 أيام
-230 أيام
أرشيف المشاركات
5 005
📌 Что такое атрибуты в C# и какова их основная цель?
💬 Спрашивают в 11% собеседований
🤔 Что такое атрибуты в C#
Атрибуты в C# — это специальные метаданные, которые могут быть добавлены к кодовым элементам (классам, методам, свойствам, полям и т.д.) для предоставления дополнительной информации о них. Эти метаданные могут быть использованы во время выполнения программы с помощью рефлексии для изменения поведения или конфигурации приложения.
🤔 Основная цель атрибутов
1️⃣ Метаданные: Предоставляют дополнительную информацию о кодовых элементах.
2️⃣ Конфигурация: Используются для настройки поведения компонентов и системы.
3️⃣ Валидация: Позволяют валидировать данные и параметры.
4️⃣ Документация: Описывают поведение и характеристики методов и классов.
5️⃣ Интеграция: Обеспечивают взаимодействие с внешними инструментами и библиотеками.
🤔 Примеры использования атрибутов
1️⃣ Пример: Объявление атрибута
Атрибуты объявляются путем создания классов, производных от
System.Attribute. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyCustomAttribute : Attribute
{
public string Description { get; }
public MyCustomAttribute(string description)
{
Description = description;
}
}
2️⃣ Пример: Применение атрибута
Атрибуты применяются путем указания их над соответствующими кодовыми элементами. [MyCustomAttribute("This is a sample class")]
public class SampleClass
{
[MyCustomAttribute("This is a sample method")]
public void SampleMethod()
{
// Метод
}
}
3️⃣ Пример: Использование атрибута с помощью рефлексии
Рефлексия используется для получения информации об атрибутах во время выполнения. using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(SampleClass);
// Получение атрибутов класса
object[] classAttributes = type.GetCustomAttributes(false);
foreach (var attr in classAttributes)
{
MyCustomAttribute myAttr = attr as MyCustomAttribute;
if (myAttr != null)
{
Console.WriteLine($"Class Attribute: {myAttr.Description}");
}
}
// Получение атрибутов метода
MethodInfo method = type.GetMethod("SampleMethod");
object[] methodAttributes = method.GetCustomAttributes(false);
foreach (var attr in methodAttributes)
{
MyCustomAttribute myAttr = attr as MyCustomAttribute;
if (myAttr != null)
{
Console.WriteLine($"Method Attribute: {myAttr.Description}");
}
}
}
}
🤔 Встроенные атрибуты
C# и .NET Framework включают множество встроенных атрибутов для различных целей:
1️⃣ Общие атрибуты:
➕ [Obsolete]: Указывает, что элемент устарел. [Obsolete("This method is obsolete. Use NewMethod instead.")]
public void OldMethod() { }
2️⃣ Атрибуты для сериализации:
➕ [Serializable]: Указывает, что класс может быть сериализован. [Serializable]
public class MySerializableClass { }
3️⃣ Атрибуты для тестирования:
➕ [TestMethod]: Используется в тестовых фреймворках, таких как MSTest, для обозначения метода тестирования. [TestMethod]
public void TestMethod1() { }
4️⃣ Атрибуты для ASP.NET:
➕ [HttpGet], [HttpPost]: Указывают, какие HTTP методы поддерживает контроллер в ASP.NET. [HttpGet]
public IActionResult Get() { }
🤔 Краткий ответ
Атрибуты в C# — это метаданные, добавляемые к кодовым элементам для предоставления дополнительной информации, конфигурации, валидации и интеграции с внешними инструментами. Они объявляются как классы, производные от System.Attribute, и используются с помощью рефлексии для изменения поведения программы во время выполнения.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
🤔 Какие основные различия между интерфейсами и абстрактными классами в C#?
5 005
📌 Каковы преимущества и недостатки использования контейнеров, таких как Docker в .NET приожениях?
💬 Спрашивают в 11% собеседований
Использование контейнеров, таких как Docker, в .NET приложениях имеет множество преимуществ, но также и некоторые недостатки. Вот основные из них:
🤔 Преимущества
1️⃣ Портативность:
➕ Контейнеры включают все необходимые зависимости и настройки, что позволяет легко переносить приложения между различными средами (разработка, тестирование, производство) без изменения кода.
➕ Пример: Docker-образ, созданный на локальной машине разработчика, может быть запущен на сервере производства без изменений.
2️⃣ Изолированность:
➕ Контейнеры изолируют приложения и их зависимости, предотвращая конфликты между различными версиями библиотек и инструментов.
➕ Пример: Разные версии .NET Core могут сосуществовать на одной машине в разных контейнерах.
3️⃣ Легкость масштабирования:
➕ Контейнеры легко масштабировать горизонтально, создавая новые экземпляры приложения в ответ на увеличивающуюся нагрузку.
➕ Пример: В Kubernetes можно легко добавить новые поды с контейнерами, чтобы справиться с повышенной нагрузкой.
4️⃣ Быстрое развертывание и запуск:
➕ Контейнеры запускаются быстрее, чем виртуальные машины, так как они не требуют загрузки всей операционной системы.
➕ Пример: Docker-контейнер может быть запущен за несколько секунд, тогда как виртуальная машина может загружаться несколько минут.
5️⃣ Консистентность среды:
➕ Контейнеры обеспечивают консистентность среды между разработкой, тестированием и продакшн-окружением.
➕ Пример: Одинаковая версия .NET Runtime и конфигурации могут быть гарантированы во всех средах.
6️⃣ Упрощенная CI/CD:
➕ Контейнеры интегрируются с инструментами CI/CD, что упрощает автоматизацию сборки, тестирования и развертывания.
➕ Пример: Jenkins или GitHub Actions могут использовать Docker для создания и тестирования приложений в изолированных средах.
🤔 Недостатки
1️⃣ Изучение и сложность:
➕ Понимание и настройка контейнеров и связанных инструментов требует времени и навыков.
➕ Пример: Изучение Docker, Docker Compose и Kubernetes может занять значительное время для команды.
2️⃣ Производительность:
➕ Хотя контейнеры легче, чем виртуальные машины, они все равно добавляют некоторую накладную на производительность.
➕ Пример: Контейнеры могут использовать больше ресурсов, чем напрямую запущенные на хосте процессы, особенно при интенсивных I/O операциях.
3️⃣ Безопасность:
➕ Контейнеры изолируют процессы, но изоляция не так сильна, как у виртуальных машин. Ошибки конфигурации могут привести к проблемам безопасности.
➕ Пример: Уязвимость в Docker или неправильная конфигурация сетевых правил могут привести к компрометации контейнера.
4️⃣ Ограничения хост-системы:
➕ Контейнеры зависят от хост-операционной системы и её ядра. Это может вызвать проблемы совместимости.
➕ Пример: Windows-контейнеры не могут быть запущены на Linux-системах и наоборот.
5️⃣ Управление состоянием и данными:
➕ Контейнеры лучше всего подходят для безгосударственных приложений. Управление состоянием и данными может быть сложным.
➕ Пример: Работа с постоянными данными требует настройки volume'ов или использование внешних систем хранения данных.
🤔 Краткий ответ
Преимущества использования Docker для .NET приложений включают портативность, изолированность, легкость масштабирования, быстрое развертывание, консистентность среды и упрощенную CI/CD. Недостатки включают сложность изучения, потенциальные накладные расходы на производительность, вопросы безопасности, ограничения хост-системы и сложности управления состоянием и данными.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
5 005
🤔 Как объявляются неявно типизированные локальные переменные в C#?
5 005
📌 Объясните принцип работы паттерна медиатор?
💬 Спрашивают в 11% собеседований
Паттерн Медиатор (Mediator) относится к поведенческим паттернам проектирования и предназначен для уменьшения зависимости между объектами, что облегчает их взаимодействие и повышает их повторное использование. Медиатор инкапсулирует способ взаимодействия множества объектов, предотвращая их прямое взаимодействие и вместо этого направляя взаимодействие через центральный объект — медиатор.
🤔 Принцип работы
1️⃣ Централизованное управление взаимодействиями: Медиатор управляет взаимодействиями между объектами, выступая в роли центрального узла. Объекты не взаимодействуют напрямую друг с другом, вместо этого они взаимодействуют через медиатор.
2️⃣ Ослабление связей: Объекты становятся менее зависимыми друг от друга, что облегчает их изменение, замену или повторное использование.
3️⃣ Снижение сложности: Медиатор снижает сложность системы, упрощая взаимодействие между множеством объектов.
🤔 Компоненты паттерна Медиатор
1️⃣ Медиатор (Mediator): Интерфейс, который определяет методы для взаимодействия с коллегами.
2️⃣ Конкретный Медиатор (Concrete Mediator): Реализация интерфейса медиатора. Хранит ссылки на коллег и координирует их взаимодействие.
3️⃣ Коллеги (Colleagues): Классы, которые взаимодействуют друг с другом через медиатор. Каждый коллега имеет ссылку на медиатор и использует его для взаимодействия с другими коллегами.
🤔 Пример реализации
Рассмотрим пример чата, где различные компоненты (пользователи) общаются друг с другом через медиатор (чат-комнату).
🤔 Интерфейс Медиатор
public interface IChatRoomMediator
{
void ShowMessage(User user, string message);
}
🤔 Конкретный Медиатор public class ChatRoom : IChatRoomMediator
{
public void ShowMessage(User user, string message)
{
string time = DateTime.Now.ToString("HH:mm");
string sender = user.Name;
Console.WriteLine($"{time} [{sender}]: {message}");
}
}
🤔 Коллега public class User
{
private IChatRoomMediator _chatRoom;
public string Name { get; private set; }
public User(IChatRoomMediator chatRoom, string name)
{
_chatRoom = chatRoom;
Name = name;
}
public void Send(string message)
{
_chatRoom.ShowMessage(this, message);
}
}
🤔 Использование class Program
{
static void Main(string[] args)
{
IChatRoomMediator chatRoom = new ChatRoom();
User user1 = new User(chatRoom, "Alice");
User user2 = new User(chatRoom, "Bob");
user1.Send("Hello, Bob!");
user2.Send("Hi, Alice!");
}
}
🤔 Объяснение
1️⃣ Медиатор (IChatRoomMediator): Интерфейс для взаимодействия с чат-комнатой.
2️⃣ Конкретный Медиатор (ChatRoom): Реализация интерфейса медиатора. Координирует взаимодействие между пользователями.
3️⃣ Коллега (User): Пользователь, который взаимодействует с другими пользователями через чат-комнату.
4️⃣ Использование: Пользователи отправляют сообщения через медиатор, который отвечает за отображение сообщений.
🤔 Краткий ответ
Паттерн Медиатор централизует взаимодействие между объектами, снижая их взаимозависимость. Объекты взаимодействуют через медиатор, который координирует их работу, упрощая структуру и повышая гибкость системы.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
📌 Чем .NET CORE отличается от .net framework?
💬 Спрашивают в 11% собеседований
.NET Core и .NET Framework — это две различные реализации платформы .NET, и между ними есть несколько ключевых различий:
1️⃣ Кросс-платформенность
➕ .NET Core: Разработан как кросс-платформенная платформа, поддерживающая Windows, macOS и Linux. Это позволяет разрабатывать и развертывать приложения на различных операционных системах.
➕ .NET Framework: Поддерживается только на Windows, что ограничивает его использование в средах, работающих под другими операционными системами.
2️⃣ Производительность и масштабируемость
➕ .NET Core: Оптимизирован для высокой производительности и масштабируемости. Часто используется для разработки высоконагруженных и облачных приложений.
➕ .NET Framework: Производительность также хороша, но в некоторых сценариях .NET Core показывает лучшие результаты благодаря более новым оптимизациям.
3️⃣ Модель развертывания
➕ .NET Core: Поддерживает автономное развертывание (self-contained deployment), где все зависимости, включая .NET Core runtime, включаются в пакет приложения. Также поддерживает развертывание с зависимостью от общесистемного runtime (framework-dependent deployment).
➕ .NET Framework: Приложения зависят от установленной версии .NET Framework на системе, что может вызвать проблемы совместимости.
4️⃣ Обновления и поддержка
➕ .NET Core: Регулярно обновляется, с новыми версиями, выпущенными каждые несколько лет. Это включает в себя как новые функции, так и улучшения производительности.
➕ .NET Framework: Получает обновления, но развитие замедлилось в пользу .NET Core и будущей унифицированной платформы .NET (начиная с .NET 5).
5️⃣ Архитектура и библиотеки
➕ .NET Core: Более модульная архитектура, с поддержкой NuGet для управления зависимостями. Поддерживает библиотеку .NET Standard, что облегчает создание кода, работающего на разных реализациях .NET.
➕ .NET Framework: Менее модульная, с монолитной установкой библиотек и зависимостей.
6️⃣ Инструменты и среда разработки
➕ .NET Core: Поддерживает новые инструменты и среды разработки, такие как Visual Studio Code и командная строка. Также интегрирован с DevOps-инструментами и контейнерами, такими как Docker.
➕ .NET Framework: Основной инструмент разработки — Visual Studio. Поддержка DevOps и контейнеров возможна, но требует дополнительных усилий.
7️⃣ Сценарии использования
➕ .NET Core: Подходит для разработки новых облачных приложений, микросервисов, и кросс-платформенных приложений.
➕ .NET Framework: Лучше подходит для существующих приложений, которые сильно зависят от Windows, таких как приложения Windows Forms или WPF.
🤔 Пример
🤔 .NET Core
// Пример консольного приложения на .NET Core
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, .NET Core!");
}
}
🤔 .NET Framework // Пример консольного приложения на .NET Framework
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, .NET Framework!");
}
}
}
🤔 Краткий ответ
➕ .NET Core: Кросс-платформенная, высокопроизводительная, модульная, с частыми обновлениями и поддержкой современных инструментов.
➕ .NET Framework: Только для Windows, менее частые обновления, монолитная структура, лучше подходит для старых приложений, зависящих от Windows.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
📌 В чем разница между переменными const, readonly и static?
💬 Спрашивают в 11% собеседований
В C#
const, readonly и static используются для разных целей и имеют разные характеристики. Давайте рассмотрим различия между ними.
🤔 `const`
➕ Описание: Поле, объявленное как const, является константой и должно быть инициализировано во время объявления. Значение const поля не может быть изменено после компиляции.
➕ Область применения: Константы компилируются в код и становятся частью метаданных сборки. Они не могут быть изменены в процессе выполнения программы.
➕ Тип данных: const поддерживает только примитивные типы данных, строки и enum.
🤔 Пример: public class MyClass
{
public const int MyConst = 10;
}
🤔 `readonly`
➕ Описание: Поле, объявленное как readonly, может быть инициализировано либо во время объявления, либо в конструкторе. Значение readonly поля может быть изменено только в конструкторе и не может быть изменено после этого.
➕ Область применения: readonly поля используются для значений, которые должны быть неизменными после инициализации объекта, но могут различаться между экземплярами класса.
➕ Тип данных: readonly поддерживает любые типы данных.
🤔 Пример: public class MyClass
{
public readonly int MyReadonly;
public MyClass(int value)
{
MyReadonly = value;
}
}
🤔 `static`
➕ Описание: Поле, объявленное как static, принадлежит классу, а не конкретному экземпляру. Оно является общим для всех экземпляров класса и хранится в одной области памяти.
➕ Область применения: static поля используются для значений, которые должны быть общими для всех экземпляров класса. Они могут быть изменены в любой момент времени.
➕ Тип данных: static поддерживает любые типы данных.
🤔 Пример: public class MyClass
{
public static int MyStatic;
static MyClass()
{
MyStatic = 10;
}
}
🤔 Краткое сравнение
| Характеристика | const | readonly | static |
|--------------------|----------------------------------|------------------------------------|------------------------------------|
| Инициализация | Во время объявления | Во время объявления или в конструкторе | В статическом конструкторе или во время объявления |
| Изменение | Нельзя изменять после компиляции | Можно изменять только в конструкторе | Можно изменять в любом месте кода |
| Область действия | Локальная для класса или метода | Локальная для экземпляра | Общая для всех экземпляров |
| Тип данных | Примитивные, строки, enum | Любые типы данных | Любые типы данных |
🤔 Краткий ответ
➕ const: Неизменяемая константа, инициализируется при объявлении, не может быть изменена.
➕ readonly: Неизменяемое поле после инициализации в конструкторе, поддерживает любые типы данных.
➕ static: Поле, общее для всех экземпляров класса, может быть изменено в любое время.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
📌 Можешь ли объяснить концепцию наследования в ООП?
💬 Спрашивают в 11% собеседований
Наследование — одна из ключевых концепций объектно-ориентированного программирования (ООП). Оно позволяет создавать новые классы на основе уже существующих, используя их свойства и методы, и при этом добавлять новые или изменять существующие.
🤔 Основные концепции наследования
1️⃣ Базовый класс (родительский класс, суперкласс): Класс, от которого наследуются другие классы.
2️⃣ Производный класс (дочерний класс, подкласс): Класс, который наследует свойства и методы базового класса.
🤔 Преимущества наследования
1️⃣ Повторное использование кода: Производный класс может использовать уже существующий код базового класса, что уменьшает дублирование кода.
2️⃣ Расширяемость: Производный класс может добавлять новые свойства и методы или переопределять существующие для расширения или изменения поведения.
3️⃣ Поддержка полиморфизма: Позволяет использовать один интерфейс для работы с объектами разных типов.
🤔 Пример наследования в C#
🤔 Базовый класс
public class Animal
{
public string Name { get; set; }
public void Eat()
{
Console.WriteLine("Eating...");
}
public virtual void MakeSound()
{
Console.WriteLine("Some generic animal sound");
}
}
🤔 Производный класс public class Dog : Animal
{
public void Bark()
{
Console.WriteLine("Woof!");
}
public override void MakeSound()
{
Console.WriteLine("Bark");
}
}
🤔 Использование классов class Program
{
static void Main()
{
Dog myDog = new Dog();
myDog.Name = "Buddy";
myDog.Eat(); // Наследованный метод
myDog.Bark(); // Метод производного класса
myDog.MakeSound(); // Переопределенный метод
}
}
🤔 Объяснение примера
1️⃣ Базовый класс `Animal`:
➕ Имеет свойство Name и метод Eat.
➕ Метод MakeSound объявлен как virtual, что позволяет его переопределить в производных классах.
2️⃣ Производный класс `Dog`:
➕ Наследует свойства и методы базового класса Animal.
➕ Добавляет новый метод Bark.
➕ Переопределяет метод MakeSound с использованием ключевого слова override.
3️⃣ Создание экземпляра `Dog`:
➕ Экземпляр класса Dog может использовать как унаследованные методы (Eat), так и методы, определенные в классе Dog (Bark).
➕ Переопределенный метод MakeSound заменяет версию из базового класса Animal.
🤔 Полиморфизм
Наследование позволяет реализовать полиморфизм, который позволяет обрабатывать объекты производных классов через ссылки на базовый класс.
🤔 Пример полиморфизма public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Meow");
}
}
class Program
{
static void Main()
{
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.MakeSound(); // Выведет: Bark
myCat.MakeSound(); // Выведет: Meow
}
}
🤔 Краткий ответ
Наследование в ООП позволяет создавать новые классы на основе существующих, используя их свойства и методы, и при этом добавляя или изменяя поведение. Это способствует повторному использованию кода, расширяемости и поддержке полиморфизма, позволяя обрабатывать объекты разных типов через единый интерфейс.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
📌 Можно ли взять любой метод и поменять его поведение в классе наследнике?
💬 Спрашивают в 11% собеседований
В C# вы можете изменить поведение методов в классе-наследнике при соблюдении определенных условий. Рассмотрим основные способы изменения поведения методов в наследуемых классах.
🤔 Переопределение виртуальных методов
Если метод базового класса объявлен с ключевым словом
virtual, его можно переопределить в классе-наследнике с использованием ключевого слова override.
🤔 Пример: public class BaseClass
{
public virtual void DoWork()
{
Console.WriteLine("BaseClass DoWork");
}
}
public class DerivedClass : BaseClass
{
public override void DoWork()
{
Console.WriteLine("DerivedClass DoWork");
}
}
class Program
{
static void Main()
{
BaseClass obj = new DerivedClass();
obj.DoWork(); // Выведет: "DerivedClass DoWork"
}
}
🤔 Сокрытие методов
Если метод базового класса не объявлен с ключевым словом virtual, вы можете скрыть его в классе-наследнике с использованием ключевого слова new. Однако, это не является переопределением в строгом смысле, и поведение метода будет зависеть от типа ссылки на объект.
🤔 Пример: public class BaseClass
{
public void DoWork()
{
Console.WriteLine("BaseClass DoWork");
}
}
public class DerivedClass : BaseClass
{
public new void DoWork()
{
Console.WriteLine("DerivedClass DoWork");
}
}
class Program
{
static void Main()
{
BaseClass objBase = new BaseClass();
objBase.DoWork(); // Выведет: "BaseClass DoWork"
DerivedClass objDerived = new DerivedClass();
objDerived.DoWork(); // Выведет: "DerivedClass DoWork"
BaseClass objPolymorphic = new DerivedClass();
objPolymorphic.DoWork(); // Выведет: "BaseClass DoWork"
}
}
🤔 Интерфейсы
Вы можете изменить или дополнить поведение, реализуя интерфейсы в классе-наследнике.
🤔 Пример: public interface IWork
{
void DoWork();
}
public class BaseClass : IWork
{
public virtual void DoWork()
{
Console.WriteLine("BaseClass DoWork");
}
}
public class DerivedClass : BaseClass
{
public override void DoWork()
{
Console.WriteLine("DerivedClass DoWork");
}
}
class Program
{
static void Main()
{
IWork obj = new DerivedClass();
obj.DoWork(); // Выведет: "DerivedClass DoWork"
}
}
🤔 Краткий ответ
В C# вы можете изменить поведение методов в классе-наследнике, если метод базового класса объявлен как virtual. В этом случае вы можете переопределить его с использованием override. Для методов, не объявленных как virtual, можно использовать сокрытие (new), но это не даст полиморфного поведения.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
👾 1096 вопросов собесов на С# Developer
🔒 База реальных собесов
🔒 База тестовых заданий
👾 Список менторов
👩💻 С# на каждый день
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
🖥 Python на каждый день
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
🖥 Frontend на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
👩💻 С/С++ на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
👩💻 Kotlin на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
👩💻 Java на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
👩💻 Swift на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
👩💻 PHP на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
🖥 Тестировщик на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Тесты для самопроверки
Список менторов
🖥 Data Science на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Тесты для самопроверки
Список менторов
👩💻 DevOps на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Тесты для самопроверки
Список менторов
👣 Golang на каждый день
Вопросы с собеседований
Вакансии с удалёнкой
Решение задач LeetCode
Тесты для самопроверки
Список менторов
⚙ Backend на каждый день
Вопросы с собеседований
Список менторов
5 005
📌 Способы расширить поведение классов в C# на практике?
💬 Спрашивают в 11% собеседований
🤔 Способы расширения поведения классов в C#
1️⃣ Наследование: Создание подклассов, которые наследуют и переопределяют методы базового класса.
public class BaseClass
{
public virtual void DoWork() { /* базовое поведение */ }
}
public class DerivedClass : BaseClass
{
public override void DoWork() { /* расширенное поведение */ }
}
2️⃣ Интерфейсы: Определение интерфейсов и их реализация в классах. public interface IWork
{
void DoWork();
}
public class MyClass : IWork
{
public void DoWork() { /* реализация интерфейса */ }
}
3️⃣ Декоратор: Оборачивание класса в другой класс для добавления поведения. public class BaseClass
{
public virtual void DoWork() { /* базовое поведение */ }
}
public class Decorator : BaseClass
{
private BaseClass _base;
public Decorator(BaseClass baseClass) { _base = baseClass; }
public override void DoWork()
{
_base.DoWork();
// Добавленное поведение
}
}
4️⃣ Адаптер: Преобразование интерфейса одного класса в интерфейс другого. public interface ITarget
{
void Request();
}
public class Adaptee
{
public void SpecificRequest() { /* специальное поведение */ }
}
public class Adapter : ITarget
{
private Adaptee _adaptee = new Adaptee();
public void Request() { _adaptee.SpecificRequest(); }
}
5️⃣ Расширяющие методы: Добавление методов к существующим типам без изменения их кода. public static class Extensions
{
public static void NewMethod(this ExistingClass obj)
{
// Добавленное поведение
}
}
🤔 Краткий ответ
Поведение классов в C# можно расширить через наследование, интерфейсы, паттерн декоратор, адаптер и расширяющие методы.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых5 005
🤔 Что такое исключения (exceptions) и как они обрабатываются в C#?
5 005
📌 Как сейчас делается Singleton?
💬 Спрашивают в 11% собеседований
В современном C# паттерн Singleton можно реализовать несколькими способами, каждый из которых имеет свои преимущества и предназначен для различных сценариев использования. Рассмотрим несколько распространенных подходов к реализации Singleton.
1️⃣ Ленивый Singleton (Lazy Initialization)
Ленивый Singleton инициализируется при первом обращении. Это обеспечивает отложенную инициализацию объекта и гарантирует потокобезопасность.
Пример:
public class Singleton
{
private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance => lazyInstance.Value;
private Singleton()
{
// Приватный конструктор
}
}
➕ Lazy<T>: Использование класса Lazy<T> позволяет легко и безопасно реализовать отложенную инициализацию.
2️⃣ Потокобезопасный Singleton (Thread-safe)
Этот подход использует lock для обеспечения потокобезопасности при создании экземпляра.
Пример:
public class Singleton
{
private static Singleton instance;
private static readonly object lockObj = new object();
private Singleton()
{
// Приватный конструктор
}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (lockObj)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
➕ Double-checked locking: Этот метод минимизирует накладные расходы, связанные с использованием lock, проверяя instance дважды.
3️⃣ Eager Initialization (Инициализация при загрузке)
Экземпляр Singleton создается при загрузке класса. Это гарантирует потокобезопасность за счет особенностей инициализации статических переменных в .NET.
Пример:
public class Singleton
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance => instance;
private Singleton()
{
// Приватный конструктор
}
}
➕ Простота: Этот метод прост и эффективен, но не поддерживает отложенную инициализацию.
4️⃣ Static Constructor (Статический конструктор)
Использование статического конструктора для инициализации Singleton.
Пример:
public class Singleton
{
private static readonly Singleton instance;
static Singleton()
{
instance = new Singleton();
}
public static Singleton Instance => instance;
private Singleton()
{
// Приватный конструктор
}
}
➕ Статический конструктор: Гарантирует инициализацию перед первым использованием любого члена класса.
5️⃣ Singleton с внедрением зависимостей (Dependency Injection)
В современных приложениях, особенно с использованием ASP.NET Core, Singleton часто регистрируется в контейнере внедрения зависимостей.
Пример:
public class SingletonService
{
public void DoWork()
{
// Выполнение работы
}
}
// Регистрация в контейнере служб
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<SingletonService>();
}
// Использование в контроллере
public class MyController : ControllerBase
{
private readonly SingletonService _singletonService;
public MyController(SingletonService singletonService)
{
_singletonService = singletonService;
}
public IActionResult Index()
{
_singletonService.DoWork();
return Ok();
}
}
🤔 Краткий ответ
В C# паттерн Singleton реализуется с использованием различных подходов: ленивой инициализации (с Lazy<T>), потокобезопасного двойного блокирования, инициализации при загрузке класса и статического конструктора. В современных приложениях также используется внедрение зависимостей (DI), особенно в ASP.NET Core, для обеспечения единственного экземпляра.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых