C# | Вопросы собесов
5.1K subscribers
36 photos
1 file
987 links
Download Telegram
📌 Какие минусы у микросервисов?

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

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

1️⃣ Сложность управления

Описание:

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

Проблемы:

Трудность в мониторинге и управлении состоянием множества сервисов.

Усложнение оркестрации и деплоя (развёртывания).

2️⃣ Межсервисное взаимодействие

Описание:

Микросервисы взаимодействуют друг с другом по сети, используя HTTP, gRPC или другие протоколы.

Проблемы:

Возрастают сетевые задержки и накладные расходы на сериализацию/десериализацию данных.

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

3️⃣ Сложность тестирования

Описание:

Тестирование микросервисных систем становится более сложным по сравнению с монолитными приложениями.

Проблемы:

Необходимость тестирования взаимодействий между сервисами.

Сложность воссоздания тестовой среды, которая точно отражает производственную.

4️⃣ Управление данными и консистентность

Описание:

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

Проблемы:

Сложность поддержания консистентности данных между различными сервисами.

Необходимость реализации распределённых транзакций или механизмов компенсации.

5️⃣ Повышенные требования к инфраструктуре

Описание:

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

Проблемы:

Увеличение затрат на инфраструктуру и её поддержку.

Необходимость в новых инструментах и технологиях, таких как Kubernetes, для эффективного управления контейнерами.

6️⃣ Организационные сложности

Описание:

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

Проблемы:

Необходимость переквалификации команды разработчиков и операционной команды.

Потребность в новой культуре взаимодействия между командами (DevOps, CI/CD).

🤔 Пример сложностей

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

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

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

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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3
🤔 Какой модификатор доступа позволяет доступ к члену класса только изнутри самого класса и производных классов?
Anonymous Quiz
14%
private
74%
protected
10%
internal
1%
public
👍1
📌 Что такое .NET Core?

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

.NET Core — это кроссплатформенная, высокопроизводительная и модульная среда выполнения, разработанная компанией Microsoft. Она предназначена для создания современных приложений, которые могут быть развёрнуты на различных операционных системах, включая Windows, macOS и Linux. .NET Core является частью более широкой экосистемы .NET и представляет собой значительное развитие по сравнению с традиционным .NET Framework. Рассмотрим основные особенности и компоненты .NET Core подробнее.

🤔 Основные особенности .NET Core

1️⃣ Кроссплатформенность:

.NET Core поддерживает работу на различных операционных системах: Windows, macOS и Linux.

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

2️⃣ Высокая производительность:

.NET Core оптимизирован для высокой производительности и эффективности.

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

3️⃣ Модульная архитектура:

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

Это уменьшает объём занимаемого пространства и улучшает управляемость зависимостями.

4️⃣ Открытый исходный код:

Исходный код .NET Core является открытым и доступен на GitHub.

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

5️⃣ Унифицированная платформа:

.NET Core объединяет несколько различных платформ (например, ASP.NET для веб-разработки, Xamarin для мобильной разработки и т.д.) под единым фреймворком.

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

🤔 Компоненты .NET Core

1️⃣ CLR (Common Language Runtime):

Среда выполнения, которая управляет исполнением .NET приложений. Включает в себя управление памятью, выполнение кода, компиляцию JIT (Just-In-Time) и сборку мусора.

2️⃣ Библиотека классов (Base Class Library, BCL):

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

3️⃣ CLI (Command-Line Interface):

Интерфейс командной строки, который предоставляет инструменты для создания, компиляции и развёртывания приложений .NET Core.

4️⃣ SDK (Software Development Kit):

Набор инструментов и библиотек для разработки приложений на .NET Core. Включает компиляторы, библиотеку классов и инструменты для работы с проектами.

5️⃣ ASP.NET Core:

Фреймворк для разработки веб-приложений и веб-API на .NET Core. Поддерживает разработку высокопроизводительных, масштабируемых и облачно-ориентированных веб-приложений.

🤔 Пример создания простого приложения на .NET Core

Для создания простого консольного приложения на .NET Core можно использовать следующие команды CLI:

1️⃣ Установка .NET Core SDK:

Загрузите и установите .NET Core SDK с официального сайта [Microsoft .NET](https://dotnet.microsoft.com/download).

2️⃣ Создание нового проекта:
   dotnet new console -n MyConsoleApp
cd MyConsoleApp


3️⃣ Редактирование кода:

Откройте файл Program.cs и внесите изменения:
   using System;

namespace MyConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, .NET Core!");
}
}
}


4️⃣ Запуск приложения:
   dotnet run


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

.NET Core — это кроссплатформенная, высокопроизводительная и модульная среда выполнения, созданная Microsoft. Она поддерживает Windows, macOS и Linux, позволяет создавать современные приложения и является частью экосистемы .NET.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 Какой модификатор доступа позволяет доступ только внутри того же класса?
Anonymous Quiz
1%
Public
9%
Protected
85%
Private
5%
Internal
👀5
📌 Что такое куча?

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

В программировании куча (heap) — это область памяти, которая используется для динамического распределения памяти. В отличие от стека, где память выделяется и освобождается автоматически при вызове и завершении функций, куча позволяет разработчику вручную контролировать выделение и освобождение памяти. В контексте C# и .NET, куча имеет свои особенности, связанные с управлением памятью и сборкой мусора (Garbage Collection).

🤔 Основные характеристики кучи

1️⃣ Динамическое распределение памяти:

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

Память в куче выделяется и освобождается динамически, в отличие от статически выделенной памяти на стеке.

2️⃣ Управление памятью:

Память, выделенная в куче, не освобождается автоматически при выходе из функции или блока кода. Разработчик должен явно освобождать её, если это необходимо (в языках с ручным управлением памятью, таких как C и C++).

В C# и .NET, освобождение памяти в куче осуществляется автоматически с помощью сборщика мусора.

3️⃣ Сборка мусора (Garbage Collection):

В .NET среде управляемая куча используется для хранения объектов, и память управляется сборщиком мусора.

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

🤔 Пример использования кучи в C#

Когда вы создаете новый объект в C#, он размещается в управляемой куче. Рассмотрим простой пример:
class Program
{
static void Main()
{
Person person = new Person();
person.Name = "John";
Console.WriteLine(person.Name);
}
}

class Person
{
public string Name { get; set; }
}


В этом примере:

1️⃣ Person person = new Person(); — создается новый объект типа Person, и память для этого объекта выделяется в куче.

2️⃣ Сборщик мусора автоматически освобождает память, занимаемую объектом Person, когда он больше не нужен (например, после завершения метода Main).

🤔 Сравнение с стеком

1️⃣ Стек (Stack):

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

Используется для хранения значимых типов (например, int, float, структуры) и указателей на объекты.

Быстрое выделение и освобождение памяти, но ограниченное пространство.

2️⃣ Куча (Heap):

Память выделяется и освобождается динамически.

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

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

🤔 Преимущества и недостатки кучи

Преимущества:

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

Подходит для хранения больших объёмов данных и объектов, размер которых неизвестен во время компиляции.

Недостатки:

Более медленное выделение и освобождение памяти по сравнению со стеком.

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

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

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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Какая из концепций ООП описывает способность метода работать с объектами разных типов?
Anonymous Quiz
6%
Наследование
72%
Полиморфизм
4%
Инкапсуляция
19%
Абстракция
📌 Где мы используем интерфейсы?

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

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

🤔 Основные случаи использования интерфейсов

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

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

Пример:
     public interface ILogger
{
void Log(string message);
}

public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}


2️⃣ Поддержка полиморфизма:

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

Пример:
     public interface IShape
{
double Area();
}

public class Circle : IShape
{
public double Radius { get; set; }
public double Area() => Math.PI * Radius * Radius;
}

public class Square : IShape
{
public double Side { get; set; }
public double Area() => Side * Side;
}


3️⃣ Ослабление связей (Decoupling):

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

Пример:
     public interface IDataAccess
{
void SaveData(string data);
}

public class DatabaseAccess : IDataAccess
{
public void SaveData(string data)
{
// Сохранение данных в базу данных
}
}

public class FileAccess : IDataAccess
{
public void SaveData(string data)
{
// Сохранение данных в файл
}
}

public class DataService
{
private readonly IDataAccess _dataAccess;

public DataService(IDataAccess dataAccess)
{
_dataAccess = dataAccess;
}

public void Save(string data)
{
_dataAccess.SaveData(data);
}
}


4️⃣ Поддержка множественного наследования:

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

Пример:
     public interface IFlyable
{
void Fly();
}

public interface IWalkable
{
void Walk();
}

public class Bird : IFlyable, IWalkable
{
public void Fly()
{
// Логика полета
}

public void Walk()
{
// Логика ходьбы
}
}


5️⃣ Инъекция зависимостей (Dependency Injection):

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

Пример:
     public interface IEmailService
{
void SendEmail(string to, string subject, string body);
}

public class EmailService : IEmailService
{
public void SendEmail(string to, string subject, string body)
{
// Логика отправки email
}
}

public class Notification
{
private readonly IEmailService _emailService;

public Notification(IEmailService emailService)
{
_emailService = emailService;
}

public void NotifyUser(string userEmail)
{
_emailService.SendEmail(userEmail, "Notification", "You have a new notification.");
}
}


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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🤯1
🤔 Какой метод LINQ используется для получения пересечения двух последовательностей?
Anonymous Quiz
21%
Union
49%
Intersect
8%
Concat
22%
Join
👀5
📌 Что такое мультикаст-делегат?

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

Мультикаст-делегат в C# - это тип делегата, который может ссылаться на несколько методов. Это позволяет вызывать несколько методов в одном вызове делегата. Такая возможность полезна для выполнения последовательности действий, таких как уведомление нескольких подписчиков о событии.

🤔 Основные понятия

1️⃣ Делегат: Делегат - это тип, который определяет сигнатуру метода и может ссылаться на любой метод с совместимой сигнатурой. Делегаты похожи на указатели на функции в C++, но являются типобезопасными и встроены в систему типов C#.

2️⃣ Мультикаст-делегат: Это делегат, который может содержать список методов. Когда вызывается мультикаст-делегат, все методы в его списке вызываются в порядке их добавления.

🤔 Почему это нужно

Уведомление нескольких объектов: Мультикаст-делегаты широко используются в системе событий .NET. Например, когда происходит какое-то событие (например, изменение состояния объекта), все подписчики на это событие могут быть уведомлены через мультикаст-делегат.

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

🤔 Использование мультикаст-делегатов

Создадим простой пример, где мультикаст-делегат используется для уведомления нескольких методов:
using System;

public class Program
{
// Определяем делегат, который принимает строку и ничего не возвращает
public delegate void Notify(string message);

// Метод, который соответствует сигнатуре делегата
public static void SendEmail(string message)
{
Console.WriteLine($"Email sent: {message}");
}

// Другой метод, который соответствует сигнатуре делегата
public static void LogMessage(string message)
{
Console.WriteLine($"Log entry: {message}");
}

public static void Main()
{
// Создаем экземпляр делегата и добавляем методы
Notify notifyDel = SendEmail;
notifyDel += LogMessage;

// Вызываем делегат
notifyDel("System update available.");

// Удаляем метод из делегата
notifyDel -= LogMessage;

// Вызываем делегат снова
notifyDel("Security patch applied.");
}
}


🤔 Объяснение кода

1️⃣ Определение делегата: Мы объявляем делегат Notify, который принимает строку в качестве параметра и не возвращает значение.

2️⃣ Создание методов: Два метода SendEmail и LogMessage, которые соответствуют сигнатуре делегата Notify.

3️⃣ Создание экземпляра делегата: Мы создаем экземпляр делегата и добавляем методы в список вызовов.

4️⃣ Вызов делегата: Когда мы вызываем делегат, он вызывает все методы в своем списке.

5️⃣ Удаление метода из делегата: Мы удаляем метод LogMessage из списка вызовов делегата.

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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31
🤔 Какое ключевое слово в C# используется для объявления блока кода, который гарантированно выполнится после завершения блока try?
Anonymous Quiz
86%
finally
12%
catch
0%
dispose
1%
using
📌 Что такое IoC-контейнеры?

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

IoC (Inversion of Control) контейнеры – это фреймворки или библиотеки, которые управляют созданием и внедрением зависимостей в приложении. Они помогают реализовать принцип внедрения зависимостей (Dependency Injection), что делает код более гибким, тестируемым и легко расширяемым.

🤔 Основные понятия

1️⃣ Inversion of Control (IoC): IoC – это принцип, при котором управление объектами и их зависимостями передается внешней системе или фреймворку, вместо того чтобы объекты самостоятельно управляли своими зависимостями.

2️⃣ Dependency Injection (DI): DI – это метод внедрения зависимостей, при котором зависимости (объекты, от которых зависит другой объект) предоставляются внешним источником (например, IoC-контейнером) вместо того, чтобы объект создавал их самостоятельно.

🤔 Почему это нужно

Упрощение тестирования: Легко заменять зависимости на заглушки или моки, что облегчает тестирование.

Снижение связности кода: Объекты не зависят от конкретных реализаций своих зависимостей, а зависят от абстракций (интерфейсов), что упрощает изменение и расширение кода.

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

🤔 Пример использования IoC-контейнера

Рассмотрим простой пример использования популярного IoC-контейнера Autofac в C#:

1️⃣ Установка Autofac: Добавляем пакет Autofac через NuGet Package Manager.

2️⃣ Создание интерфейсов и классов:
public interface ILogger
{
void Log(string message);
}

public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}

public interface IService
{
void Serve();
}

public class Service : IService
{
private readonly ILogger _logger;

public Service(ILogger logger)
{
_logger = logger;
}

public void Serve()
{
_logger.Log("Service Called");
}
}


3️⃣ Настройка и использование IoC-контейнера:
using Autofac;

class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();

// Регистрируем зависимости
builder.RegisterType<ConsoleLogger>().As<ILogger>();
builder.RegisterType<Service>().As<IService>();

// Строим контейнер
var container = builder.Build();

// Разрешаем зависимости
var service = container.Resolve<IService>();
service.Serve();
}
}


🤔 Объяснение кода

1️⃣ Интерфейсы и реализации: Мы создаем интерфейсы ILogger и IService, а также их реализации ConsoleLogger и Service.

2️⃣ Регистрация зависимостей: С помощью ContainerBuilder регистрируем классы ConsoleLogger и Service как реализации соответствующих интерфейсов.

3️⃣ Разрешение зависимостей: С помощью контейнера разрешаем зависимости и вызываем метод Serve у объекта Service, который использует ConsoleLogger для логирования.

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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой из следующих методов C# используется для явного указания, что объект должен быть собран сборщиком мусора?
Anonymous Quiz
64%
Dispose()
12%
SuppressFinalize()
22%
Collect()
2%
Abort()
👾1
📌 Что такое принцип подстановки Барбары Лисков?

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

Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP) - это один из пяти принципов SOLID, который гласит, что объекты подтипов должны быть заменяемы объектами базового типа без нарушения правильности работы программы. Это означает, что если класс B является подтипом класса A, то объекты класса A могут быть заменены объектами класса B без изменения желаемого поведения программы.

🤔 Основные понятия

1️⃣ Наследование: Подтипы должны наследовать не только интерфейс, но и поведение базовых типов.

2️⃣ Замена: Класс-наследник должен корректно работать в любом контексте, где ожидается объект базового класса.

3️⃣ Контракт: Подтип должен соблюдать контракт базового типа, что включает предусловия, постусловия и инварианты.

🤔 Почему это нужно

Упрощение понимания и поддержки кода: Код, который следует LSP, более предсказуем и понятен, что облегчает его поддержку.

Повышение надежности: Соблюдение принципа помогает избежать неожиданных ошибок при замене объектов базового класса на объекты подклассов.

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

🤔 Пример нарушения LSP

Рассмотрим пример, где нарушение LSP приводит к некорректному поведению программы:
public class Rectangle
{
public virtual int Width { get; set; }
public virtual int Height { get; set; }

public int GetArea()
{
return Width * Height;
}
}

public class Square : Rectangle
{
public override int Width
{
set { base.Width = base.Height = value; }
}

public override int Height
{
set { base.Width = base.Height = value; }
}
}


🤔 Проблема

В этом примере Square (квадрат) наследует от Rectangle (прямоугольник). Однако, квадрат имеет особое свойство: его ширина и высота всегда равны. При попытке установить ширину или высоту квадрата, изменяется и другое значение, что нарушает поведение прямоугольника.

🤔 Исправление

Лучше использовать композицию вместо наследования для избежания такой проблемы:
public interface IShape
{
int GetArea();
}

public class Rectangle : IShape
{
public int Width { get; set; }
public int Height { get; set; }

public int GetArea()
{
return Width * Height;
}
}

public class Square : IShape
{
public int SideLength { get; set; }

public int GetArea()
{
return SideLength * SideLength;
}
}


🤔 Объяснение

1️⃣ Интерфейс IShape: Определяем общий интерфейс для всех форм.

2️⃣ Реализация прямоугольника и квадрата: Классы Rectangle и Square реализуют интерфейс IShape, но теперь они не наследуются друг от друга и имеют свои собственные свойства и методы.

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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5👾1
🤔 Какое ключевое слово в C# используется для создания метода, который может быть переопределён в производном классе?
Anonymous Quiz
73%
virtual
14%
abstract
12%
override
1%
sealed
📌 Какие колекции знаешь?

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

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

1️⃣ Коллекции общего назначения

List<T>: Динамический массив, который автоматически изменяет свой размер по мере добавления элементов.
  List<int> numbers = new List<int> { 1, 2, 3, 4 };
numbers.Add(5);


Dictionary<TKey, TValue>: Коллекция пар ключ-значение. Обеспечивает быстрый доступ к значению по ключу.
  Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 }
};
int aliceAge = ages["Alice"];


HashSet<T>: Коллекция уникальных элементов. Используется для проверки наличия элемента и предотвращения дублирования.
  HashSet<string> fruits = new HashSet<string> { "Apple", "Banana" };
fruits.Add("Apple"); // Не добавит дубликат


Queue<T>: Очередь, работающая по принципу FIFO (First In, First Out).
  Queue<string> queue = new Queue<string>();
queue.Enqueue("first");
queue.Enqueue("second");
string item = queue.Dequeue(); // "first"


Stack<T>: Стек, работающий по принципу LIFO (Last In, First Out).
  Stack<string> stack = new Stack<string>();
stack.Push("first");
stack.Push("second");
string item = stack.Pop(); // "second"


2️⃣ Специализированные коллекции

LinkedList<T>: Двусвязный список, позволяющий быстро вставлять и удалять элементы.
  LinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddLast(1);
linkedList.AddLast(2);


SortedList<TKey, TValue>: Коллекция пар ключ-значение, отсортированная по ключам.
  SortedList<string, int> sortedList = new SortedList<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 }
};


SortedDictionary<TKey, TValue>: Похож на SortedList, но использует бинарное дерево для хранения элементов.
  SortedDictionary<string, int> sortedDict = new SortedDictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 }
};


SortedSet<T>: Отсортированное множество уникальных элементов.
  SortedSet<int> sortedSet = new SortedSet<int> { 3, 1, 2 };


3️⃣ Коллекции для параллельного программирования

ConcurrentDictionary<TKey, TValue>: Параллельная версия Dictionary, предназначенная для безопасного использования в многопоточных приложениях.
  ConcurrentDictionary<string, int> concurrentDict = new ConcurrentDictionary<string, int>();
concurrentDict.TryAdd("Alice", 30);


ConcurrentQueue<T>: Параллельная версия Queue.
  ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
concurrentQueue.Enqueue("first");


ConcurrentStack<T>: Параллельная версия Stack.
  ConcurrentStack<string> concurrentStack = new ConcurrentStack<string>();
concurrentStack.Push("first");


BlockingCollection<T>: Коллекция, поддерживающая операции добавления и извлечения с блокировкой и ограничением по емкости.
  BlockingCollection<int> blockingCollection = new BlockingCollection<int>(5);
blockingCollection.Add(1);


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

В C# есть множество коллекций для различных целей, включая List, Dictionary, HashSet, Queue, Stack, специализированные коллекции, такие как LinkedList, SortedList, а также коллекции для параллельного программирования, такие как ConcurrentDictionary и BlockingCollection.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
📌 Что такое DI(инъекция зависимости)?

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

Dependency Injection (DI), или инъекция зависимости, — это шаблон проектирования, который позволяет объектам получить свои зависимости от внешних источников, а не создавать их самостоятельно. Этот подход улучшает тестируемость, расширяемость и поддерживаемость кода, делая его более гибким и модульным.

🤔 Основные концепции

1️⃣ Зависимость: Любой объект или класс, от которого зависит другой объект или класс. Например, если класс A использует класс B для выполнения своих задач, то B является зависимостью для A.

2️⃣ Инъекция зависимости: Процесс предоставления зависимости объекту извне, обычно через конструктор, метод или свойство.

🤔 Преимущества DI

Улучшенная тестируемость: Легко заменять реальные зависимости на моки или заглушки, что упрощает модульное тестирование.

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

Расширяемость и поддерживаемость: Позволяет легко добавлять новые функциональные возможности и изменять существующие зависимости.

🤔 Виды инъекций зависимости

1️⃣ Конструкторная инъекция: Зависимости передаются через параметры конструктора.
   public class Service
{
private readonly IRepository _repository;

public Service(IRepository repository)
{
_repository = repository;
}

public void DoWork()
{
_repository.Save();
}
}


2️⃣ Инъекция через свойства: Зависимости устанавливаются через свойства класса.
   public class Service
{
public IRepository Repository { get; set; }

public void DoWork()
{
Repository.Save();
}
}


3️⃣ Инъекция через методы: Зависимости передаются через параметры метода.
   public class Service
{
private IRepository _repository;

public void SetRepository(IRepository repository)
{
_repository = repository;
}

public void DoWork()
{
_repository.Save();
}
}


🤔 Использование DI с IoC-контейнерами

IoC-контейнеры (контейнеры инверсии управления) управляют созданием и жизненным циклом зависимостей, а также автоматизируют процесс их инъекции. Пример использования популярного IoC-контейнера Autofac:

1️⃣ Установка Autofac: Добавляем пакет Autofac через NuGet Package Manager.

2️⃣ Настройка контейнера и регистрация зависимостей:
   using Autofac;

var builder = new ContainerBuilder();
builder.RegisterType<Repository>().As<IRepository>();
builder.RegisterType<Service>().As<IService>();
var container = builder.Build();


3️⃣ Разрешение зависимостей и использование сервиса:
   using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IService>();
service.DoWork();
}


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

Dependency Injection (DI) — это метод предоставления зависимостей объекту извне, что делает код более гибким, тестируемым и поддерживаемым. DI может осуществляться через конструкторы, свойства или методы, а IoC-контейнеры автоматизируют процесс управления зависимостями.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Какой модификатор доступа в C# используется для обеспечения доступа к члену класса только внутри его текущего сборочного контекста?
Anonymous Quiz
18%
private
9%
protected
61%
internal
13%
protected internal
📌 В чем разница между списком и массивом?

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

В C# списки (List) и массивы (Array) являются двумя основными типами коллекций, но они имеют различия в своих свойствах, возможностях и сценариях использования. Рассмотрим основные различия между ними.

🤔 Массивы (Array)

1️⃣ Размер: Массивы имеют фиксированный размер, который необходимо указать при создании. Размер массива не может быть изменен после его создания.
   int[] numbers = new int[5]; // Массив из 5 элементов


2️⃣ Тип данных: Массивы являются типобезопасными, что означает, что все элементы массива должны быть одного типа.
   string[] words = new string[] { "apple", "banana", "cherry" };


3️⃣ Быстродействие: Массивы обеспечивают очень быстрый доступ к элементам по индексу, так как они хранятся в непрерывном блоке памяти.
   int firstNumber = numbers[0]; // Быстрый доступ по индексу


4️⃣ Методы и свойства: Массивы имеют ограниченный набор методов и свойств. В основном это методы для работы с элементами, такие как Length.
   int length = numbers.Length; // Длина массива


🤔 Списки (List)

1️⃣ Размер: Списки имеют динамический размер, который автоматически изменяется по мере добавления или удаления элементов.
   List<int> numbersList = new List<int> { 1, 2, 3, 4, 5 };
numbersList.Add(6); // Добавление элемента увеличивает размер списка


2️⃣ Тип данных: Списки также являются типобезопасными и могут хранить элементы только одного типа.
   List<string> wordsList = new List<string> { "apple", "banana", "cherry" };


3️⃣ Быстродействие: Доступ к элементам списка по индексу также быстрый, но из-за динамической природы список может быть менее эффективен по памяти при частом изменении размера.
   int firstNumberInList = numbersList[0]; // Быстрый доступ по индексу


4️⃣ Методы и свойства: Списки обладают богатым набором методов и свойств, таких как Add, Remove, Find, Count и многие другие, что делает их более удобными для работы с динамическими данными.
   int count = numbersList.Count; // Количество элементов в списке
numbersList.Remove(3); // Удаление элемента


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

1️⃣ Размер: Массивы фиксированного размера, списки динамического размера.

2️⃣ Гибкость: Списки более гибкие и предоставляют больше методов для работы с элементами.

3️⃣ Производительность: Массивы могут быть более эффективны по памяти и быстрее при доступе к элементам, но менее гибкие в изменении размера.

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

Массив:
int[] numbersArray = new int[] { 1, 2, 3, 4, 5 };
int firstElement = numbersArray[0];
numbersArray[2] = 10;
Console.WriteLine(numbersArray.Length);


Список:
List<int> numbersList = new List<int> { 1, 2, 3, 4, 5 };
numbersList.Add(6);
int firstElementInList = numbersList[0];
numbersList[2] = 10;
Console.WriteLine(numbersList.Count);
numbersList.Remove(4);


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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Какое из следующих ключевых слов в C# используется для объявления метода, который не имеет реализации в базовом классе и должен быть переопределён в производных классах?
Anonymous Quiz
22%
virtual
73%
abstract
4%
sealed
1%
static
👍1
📌 Что такое post?

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

В C# post чаще всего ассоциируется с HTTP POST-запросами, которые используются для отправки данных на сервер. Это один из основных методов HTTP-протокола наряду с GET, PUT, DELETE и другими.

🤔 Основные понятия

1️⃣ HTTP POST-запрос: Метод HTTP, используемый для отправки данных на сервер. Обычно применяется для создания новых ресурсов или передачи данных, которые могут изменять состояние сервера.

2️⃣ Отправка данных: Данные могут быть отправлены в теле запроса в различных форматах, таких как JSON, XML или обычный текст.

3️⃣ Использование в веб-приложениях: POST-запросы широко используются в веб-приложениях для передачи данных от клиента к серверу, например, при отправке формы, загрузке файлов или выполнении AJAX-запросов.

🤔 Пример использования HTTP POST-запроса в C#

Для выполнения HTTP POST-запроса в C# часто используется класс HttpClient, который предоставляет удобные методы для взаимодействия с веб-сервисами.

🤔 Пример отправки JSON-данных

1️⃣ Настройка проекта: Убедитесь, что в вашем проекте установлен пакет System.Net.Http (обычно он включен по умолчанию в .NET Core проектах).

2️⃣ Отправка POST-запроса:
   using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
static async Task Main(string[] args)
{
// Создаем HttpClient
using (HttpClient client = new HttpClient())
{
// URL-адрес, на который отправляется запрос
string url = "https://example.com/api/resource";

// Данные для отправки
var data = new
{
Name = "John Doe",
Age = 30
};

// Сериализуем данные в JSON
string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(data);

// Создаем содержимое запроса
StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

// Отправляем POST-запрос
HttpResponseMessage response = await client.PostAsync(url, content);

// Проверяем успешность ответа
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Запрос выполнен успешно.");
}
else
{
Console.WriteLine($"Ошибка: {response.StatusCode}");
}
}
}
}


🤔 Объяснение кода

1️⃣ Создание HttpClient: Объект HttpClient используется для отправки HTTP-запросов и получения HTTP-ответов от ресурса, определенного по URI.

2️⃣ Определение URL: URL-адрес, на который будет отправлен POST-запрос.

3️⃣ Создание данных: Объект с данными, которые мы хотим отправить на сервер. В данном случае это анонимный объект с именем и возрастом.

4️⃣ Сериализация данных: Преобразование объекта в JSON-строку с использованием JsonConvert.SerializeObject.

5️⃣ Создание содержимого запроса: Объект StringContent, который содержит сериализованные данные, кодировку и тип содержимого.

6️⃣ Отправка POST-запроса: Метод PostAsync отправляет POST-запрос на указанный URL с указанным содержимым.

7️⃣ Проверка ответа: Проверка успешности ответа с использованием свойства IsSuccessStatusCode.

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

HTTP POST-запрос используется для отправки данных на сервер, обычно для создания новых ресурсов. В C# для выполнения POST-запросов часто используется класс HttpClient, который позволяет отправлять данные в формате JSON или других форматах.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
📌 Что такое put?

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

В C# и веб-программировании PUT обычно относится к HTTP PUT-запросам, которые используются для обновления ресурсов на сервере. Это один из основных методов HTTP-протокола наряду с GET, POST, DELETE и другими.

🤔 Основные понятия

1️⃣ HTTP PUT-запрос: Метод HTTP, который используется для обновления существующего ресурса или создания ресурса, если он не существует. В отличие от POST, который обычно используется для создания новых ресурсов, PUT применяется для замены текущего состояния ресурса новым состоянием.

2️⃣ Идемпотентность: PUT-запросы идемпотентны, что означает, что многократное выполнение одного и того же запроса с одинаковыми данными приведет к одному и тому же результату. Это важно для надежности сетевых операций.

3️⃣ Отправка данных: Как и в случае с POST-запросами, данные могут быть отправлены в теле запроса в различных форматах, таких как JSON, XML или обычный текст.

🤔 Пример использования HTTP PUT-запроса в C#

Для выполнения HTTP PUT-запроса в C# часто используется класс HttpClient, который предоставляет удобные методы для взаимодействия с веб-сервисами.

🤔 Пример обновления ресурса с помощью PUT-запроса

1️⃣ Настройка проекта: Убедитесь, что в вашем проекте установлен пакет System.Net.Http (обычно он включен по умолчанию в .NET Core проектах).

2️⃣ Отправка PUT-запроса:
   using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
static async Task Main(string[] args)
{
// Создаем HttpClient
using (HttpClient client = new HttpClient())
{
// URL-адрес, на который отправляется запрос
string url = "https://example.com/api/resource/1"; // Предполагается, что ресурс с ID 1 уже существует

// Данные для отправки
var data = new
{
Name = "John Doe",
Age = 31 // Обновляем возраст
};

// Сериализуем данные в JSON
string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(data);

// Создаем содержимое запроса
StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

// Отправляем PUT-запрос
HttpResponseMessage response = await client.PutAsync(url, content);

// Проверяем успешность ответа
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Ресурс успешно обновлен.");
}
else
{
Console.WriteLine($"Ошибка: {response.StatusCode}");
}
}
}
}


🤔 Объяснение кода

1️⃣ Создание HttpClient: Объект HttpClient используется для отправки HTTP-запросов и получения HTTP-ответов от ресурса, определенного по URI.

2️⃣ Определение URL: URL-адрес, на который будет отправлен PUT-запрос. В данном случае предполагается, что ресурс с ID 1 уже существует.

3️⃣ Создание данных: Объект с данными, которые мы хотим отправить на сервер для обновления ресурса. В данном случае это анонимный объект с обновленным именем и возрастом.

4️⃣ Сериализация данных: Преобразование объекта в JSON-строку с использованием JsonConvert.SerializeObject.

5️⃣ Создание содержимого запроса: Объект StringContent, который содержит сериализованные данные, кодировку и тип содержимого.

6️⃣ Отправка PUT-запроса: Метод PutAsync отправляет PUT-запрос на указанный URL с указанным содержимым.

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

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

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

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