C# | Вопросы собесов
5.09K subscribers
34 photos
1 file
977 links
Download Telegram
📌 Внешние ключи должны быть в базе данных?

💬 Спрашивают в 11% собеседований

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

🤔 Зачем нужны внешние ключи

1️⃣ Целостность данных:

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

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

2️⃣ Упрощение запросов:

Внешние ключи облегчают написание запросов SQL, которые объединяют данные из нескольких таблиц. Они обеспечивают логическую связь, которая позволяет объединять таблицы в запросах.

Пример: Получение всех заказов вместе с информацией о клиенте, сделавшем заказ.

3️⃣ Поддержка каскадных операций:

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

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

4️⃣ Улучшение целостности данных:

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

Пример: Невозможно добавить заказ в таблицу Orders, если нет соответствующего клиента в таблице Customers.

🤔 Как использовать внешние ключи

1️⃣ Создание внешнего ключа:

Внешний ключ создается при создании таблицы или добавляется позже с помощью команды ALTER TABLE.

Пример создания внешнего ключа при создании таблицы:
     CREATE TABLE Orders (
OrderID int PRIMARY KEY,
OrderDate datetime,
CustomerID int,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);


2️⃣ Добавление внешнего ключа в существующую таблицу:

Если таблица уже существует, внешний ключ можно добавить с помощью команды ALTER TABLE.

Пример:
     ALTER TABLE Orders
ADD CONSTRAINT FK_CustomerOrder
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID);


3️⃣ Каскадные операции:

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

Пример настройки каскадного удаления:
     CREATE TABLE Orders (
OrderID int PRIMARY KEY,
OrderDate datetime,
CustomerID int,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
ON DELETE CASCADE
);


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

🤔 Пример 1: Базовая установка внешнего ключа
CREATE TABLE Customers (
CustomerID int PRIMARY KEY,
CustomerName varchar(255)
);

CREATE TABLE Orders (
OrderID int PRIMARY KEY,
OrderDate datetime,
CustomerID int,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);


🤔 Пример 2: Каскадное удаление
CREATE TABLE Orders (
OrderID int PRIMARY KEY,
OrderDate datetime,
CustomerID int,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
ON DELETE CASCADE
);


🤔 Краткий ответ

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое Entity Framework (EF) и его основные компоненты?
Anonymous Quiz
91%
DbContext, DbSet, LINQ to Entities.
5%
DataTable, DataSet, DataRow.
2%
Collection, List, Array.
2%
Index, Key, Value.
🤯2
📌 Что если покрыть код контроллера тестами?

💬 Спрашивают в 11% собеседований

Покрытие кода контроллера тестами является важной практикой, которая помогает повысить качество и надежность приложения. Рассмотрим, что это означает, зачем это нужно, и как это делается.

🤔 Что такое тесты для контроллеров

Тесты для контроллеров — это автоматические тесты, которые проверяют функциональность методов контроллеров в веб-приложениях. Эти тесты могут быть двух основных типов:

1️⃣ Модульные тесты (Unit Tests):

Проверяют отдельные методы контроллеров изолированно от других компонентов системы, используя заглушки или моки для зависимостей.

2️⃣ Интеграционные тесты (Integration Tests):

Проверяют взаимодействие контроллера с другими компонентами системы, такими как сервисы, репозитории и базы данных.

🤔 Зачем нужно покрывать код контроллеров тестами

1️⃣ Проверка правильности кода:

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

2️⃣ Обнаружение ошибок:

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

3️⃣ Поддержка рефакторинга:

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

4️⃣ Документация:

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

5️⃣ Улучшение архитектуры:

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

🤔 Как покрывать код контроллеров тестами

🤔 Модульные тесты

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

Пример модульного теста контроллера с использованием библиотеки xUnit и Moq:
using Moq;
using Xunit;
using MyWebApp.Controllers;
using MyWebApp.Services;
using Microsoft.AspNetCore.Mvc;

public class MyControllerTests
{
[Fact]
public void Get_ReturnsOkResult_WithListOfItems()
{
// Arrange
var mockService = new Mock<IMyService>();
mockService.Setup(service => service.GetItems()).Returns(new List<string> { "Item1", "Item2" });

var controller = new MyController(mockService.Object);

// Act
var result = controller.Get();

// Assert
var okResult = Assert.IsType<OkObjectResult>(result);
var items = Assert.IsType<List<string>>(okResult.Value);
Assert.Equal(2, items.Count);
}
}


🤔 Интеграционные тесты

Интеграционные тесты проверяют взаимодействие контроллера с другими компонентами системы. Обычно для таких тестов используется реальная база данных или её тестовый аналог.

Пример интеграционного теста с использованием xUnit и TestServer из Microsoft.AspNetCore.TestHost:
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;

public class MyControllerIntegrationTests : IClassFixture<WebApplicationFactory<MyWebApp.Startup>>
{
private readonly HttpClient _client;

public MyControllerIntegrationTests(WebApplicationFactory<MyWebApp.Startup> factory)
{
_client = factory.CreateClient();
}

[Fact]
public async Task Get_ReturnsOkResult_WithListOfItems()
{
// Act
var response = await _client.GetAsync("/api/my");

// Assert
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
Assert.Contains("Item1", responseString);
}
}


🤔 Краткий ответ

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
1
📌 Какой слой rest и swap с точки зрения трехслойной архитектуры?

💬 Спрашивают в 11% собеседований

В трехслойной архитектуре (трехуровневая архитектура), также известной как многоуровневая архитектура, приложения разделяются на три логических слоя:

1️⃣ Презентационный слой (Presentation Layer):

Отвечает за взаимодействие с пользователем.

Веб-интерфейсы, мобильные приложения, десктопные приложения.

Примеры: HTML/CSS/JavaScript для веб-приложений, UI-компоненты в мобильных и десктопных приложениях.

2️⃣ Логический слой (Business Logic Layer):

Содержит бизнес-логику и правила приложения.

Обрабатывает данные, выполняет вычисления, применяет бизнес-правила.

Примеры: классы и методы, реализующие бизнес-логику, сервисы, обработчики данных.

3️⃣ Слой данных (Data Access Layer):

Отвечает за взаимодействие с источниками данных.

Операции с базами данных, файловыми системами, внешними сервисами.

Примеры: репозитории, Data Access Objects (DAO), API-клиенты для доступа к внешним системам.

🤔 REST и SWAP в контексте трехслойной архитектуры

🤔 REST

REST (Representational State Transfer):

REST — это архитектурный стиль для разработки веб-сервисов. RESTful сервисы используют стандартные HTTP методы (GET, POST, PUT, DELETE и т.д.) для работы с ресурсами.

С точки зрения трехслойной архитектуры:

Презентационный слой:

Вызовы REST API могут происходить с клиентской стороны (например, AJAX запросы из веб-интерфейса) или через клиентские приложения.

Пример: фронтенд веб-приложения, который взаимодействует с REST API.

Логический слой:

REST API реализует бизнес-логику и выступает посредником между презентационным слоем и слоем данных.

Пример: контроллеры и сервисы, обрабатывающие REST запросы и выполняющие соответствующую бизнес-логику.

Слой данных:

REST API может взаимодействовать с базой данных или другими источниками данных для получения и сохранения информации.

Пример: методы в API, которые выполняют запросы к базе данных через репозитории или DAO.

🤔 SWAP

SWAP (Simple Web API):

SWAP — это гипотетический или менее распространенный термин, часто интерпретируемый как упрощенный API для веб-приложений.

С точки зрения трехслойной архитектуры:

Презентационный слой:

Клиентские приложения или пользовательские интерфейсы могут вызывать методы SWAP для получения или отправки данных.

Пример: веб-страницы или мобильные приложения, обращающиеся к SWAP для выполнения операций.

Логический слой:

SWAP обрабатывает бизнес-логику аналогично REST API, предоставляя упрощенные конечные точки для взаимодействия с данными.

Пример: сервисы, которые реализуют простые операции (CRUD) без сложной бизнес-логики.

Слой данных:

SWAP взаимодействует с базой данных или другими источниками данных для выполнения операций чтения/записи.

Пример: методы SWAP, которые обращаются к базе данных через абстрактные уровни доступа к данным.

🤔 Заключение

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

🤔 Краткий ответ

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🤔 Какие ключевые слова используются в C# для реализации асинхронного программирования?
Anonymous Quiz
98%
async, await.
1%
parallel, concurrent.
0%
thread, lock.
1%
task, event.
🤯4
📌 Сравни паттерны Adapter и Decorator?

💬 Спрашивают в 11% собеседований

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

🤔 Adapter (Адаптер)

Описание:

Паттерн Adapter используется для приведения интерфейса одного класса к интерфейсу, ожидаемому клиентом. Он позволяет объектам с несовместимыми интерфейсами работать вместе.

Цель:

Преобразование интерфейса класса в другой интерфейс, который ожидает клиент.

Применение:

Когда нужно использовать существующий класс, но его интерфейс не соответствует потребностям клиента.

Когда необходимо интегрировать класс с внешней библиотекой, имеющей несовместимый интерфейс.

Пример:
// Существующий класс с несовместимым интерфейсом
public class LegacyPrinter
{
public void PrintLegacy(string text)
{
Console.WriteLine("Legacy print: " + text);
}
}

// Целевой интерфейс, который ожидает клиент
public interface IPrinter
{
void Print(string text);
}

// Адаптер, который приводит интерфейс LegacyPrinter к интерфейсу IPrinter
public class PrinterAdapter : IPrinter
{
private readonly LegacyPrinter _legacyPrinter;

public PrinterAdapter(LegacyPrinter legacyPrinter)
{
_legacyPrinter = legacyPrinter;
}

public void Print(string text)
{
_legacyPrinter.PrintLegacy(text);
}
}

// Использование адаптера
public class Client
{
public void ClientCode(IPrinter printer)
{
printer.Print("Hello, World!");
}
}

var legacyPrinter = new LegacyPrinter();
var adapter = new PrinterAdapter(legacyPrinter);
var client = new Client();
client.ClientCode(adapter);


🤔 Decorator (Декоратор)

Описание:

Паттерн Decorator используется для динамического добавления новых функциональных возможностей объекту. Он предоставляет гибкую альтернативу наследованию для расширения функциональности.

Цель:

Добавление новых обязанностей объекту динамически.

Пример:
// Базовый интерфейс
public interface INotifier
{
void Send(string message);
}

// Конкретный компонент
public class EmailNotifier : INotifier
{
public void Send(string message)
{
Console.WriteLine("Sending Email: " + message);
}
}

// Базовый декоратор
public class NotifierDecorator : INotifier
{
private readonly INotifier _wrappee;

public NotifierDecorator(INotifier notifier)
{
_wrappee = notifier;
}

public virtual void Send(string message)
{
_wrappee.Send(message);
}
}

// Конкретный декоратор
public class SMSNotifier : NotifierDecorator
{
public SMSNotifier(INotifier notifier) : base(notifier) { }

public override void Send(string message)
{
base.Send(message);
Console.WriteLine("Sending SMS: " + message);
}
}

// Использование декоратора
var emailNotifier = new EmailNotifier();
var smsNotifier = new SMSNotifier(emailNotifier);
smsNotifier.Send("Hello, World!");


🤔 Краткий ответ

Паттерн Adapter преобразует интерфейс одного класса к интерфейсу, ожидаемому клиентом, что позволяет несовместимым объектам работать вместе. Паттерн Decorator динамически добавляет новые обязанности объекту, оборачивая его, и предоставляет гибкую альтернативу наследованию для расширения функциональности. Adapter используется для приведения интерфейсов в соответствие, а Decorator — для расширения возможностей объектов.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какие типы данных используются для работы с датами и временем в C#?
Anonymous Quiz
97%
DateTime, TimeSpan.
1%
Calendar, Clock.
2%
Timestamp, Stopwatch.
0%
Period, Interval.
👍1🤔1
📌 Что делает паттерн проектирования Factory?

💬 Спрашивают в 11% собеседований

Паттерн проектирования Factory (Фабрика) — это порождающий паттерн, который предоставляет интерфейс для создания объектов в суперклассе, но позволяет подклассам изменять тип создаваемых объектов. Основная идея заключается в том, чтобы вынести создание объектов из кода, который их использует, в отдельный компонент или метод. Это помогает уменьшить зависимость кода от конкретных классов и улучшить его гибкость и расширяемость.

🤔 Основные аспекты паттерна Factory

1️⃣ Абстрагирование процесса создания объектов:

Паттерн Factory позволяет отделить логику создания объектов от логики их использования.

Это помогает избежать жесткой привязки к конкретным классам и облегчает изменение или расширение типов создаваемых объектов.

2️⃣ Гибкость и расширяемость:

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

3️⃣ Снижение сложности кода:

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

🤔 Виды паттерна Factory

1️⃣ Простая фабрика (Simple Factory):

Не является отдельным паттерном, а скорее идиомой или шаблоном. Фабричный метод находится в одном классе, который создает объекты различных типов.

Пример:
     public class SimpleFactory
{
public IProduct CreateProduct(string type)
{
if (type == "A")
return new ProductA();
else if (type == "B")
return new ProductB();
else
throw new ArgumentException("Unknown product type.");
}
}


2️⃣ Фабричный метод (Factory Method):

Определяет интерфейс для создания объекта, но позволяет подклассам изменять тип создаваемого объекта.

Пример:
     public abstract class Creator
{
public abstract IProduct FactoryMethod();
}

public class ConcreteCreatorA : Creator
{
public override IProduct FactoryMethod()
{
return new ProductA();
}
}

public class ConcreteCreatorB : Creator
{
public override IProduct FactoryMethod()
{
return new ProductB();
}
}


🤔 Краткий ответ

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
📌 Как сейчас делается 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, для обеспечения единственного экземпляра.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2
🤔 Что такое исключения (exceptions) и как они обрабатываются в C#?
Anonymous Quiz
99%
Блоками try, catch, finally.
1%
Методами include, require.
1%
Операторами check, uncheck.
0%
Командами start, end.
1
📌 Способы расширить поведение классов в 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# можно расширить через наследование, интерфейсы, паттерн декоратор, адаптер и расширяющие методы.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🔥1
📌 Можно ли взять любой метод и поменять его поведение в классе наследнике?

💬 Спрашивают в 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), но это не даст полиморфного поведения.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
🤔 Какие существуют уровни доступа к членам класса в C#?
Anonymous Quiz
99%
public, private, protected, internal, protected internal.
0%
open, closed, abstract, final.
1%
internal, external, global, local.
0%
static, dynamic, final, transient.
1
📌 Можешь ли объяснить концепцию наследования в ООП?

💬 Спрашивают в 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
}
}


🤔 Краткий ответ

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
📌 В чем разница между переменными 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: Поле, общее для всех экземпляров класса, может быть изменено в любое время.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
📌 Чем .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.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍131