C# | Вопросы собесов
5.1K subscribers
36 photos
1 file
989 links
Download Telegram
Что такое абстракция ?
Спросят с вероятностью 22%

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

Основные аспекты:

1️⃣Сокрытие деталей реализации: Позволяет скрыть детали реализации объекта и предоставлять пользователям только те функциональности, которые необходимы для использования объекта. Это уменьшает сложность программы и увеличивает её удобство в использовании.

2️⃣Обобщение функционала: Позволяет создавать общие решения, которые можно легко адаптировать или расширить для решения специфических задач. Это достигается за счет определения общих интерфейсов или базовых классов, которые могут быть уточнены или расширены в производных классах.

3️⃣Уменьшение взаимозависимости компонентов: Поскольку она позволяет разделять интерфейс и реализацию, компоненты программы могут быть менее зависимы друг от друга. Это упрощает замену одних компонентов другими и делает код более модульным.
public abstract class Vehicle
{
public abstract void Move();

public void Start()
{
Console.WriteLine("Vehicle has started.");
}
}

public class Car : Vehicle
{
public override void Move()
{
Console.WriteLine("Car is moving.");
}
}

public class Airplane : Vehicle
{
public override void Move()
{
Console.WriteLine("Airplane is flying.");
}
}


В этом примере Vehicle является абстрактным классом, который определяет абстрактный метод Move() и конкретный метод Start(). Метод Move() абстрактен, потому что каждый вид транспорта перемещается по-своему: автомобиль едет, самолет летит. Класс Vehicle предоставляет абстракцию для всех видов транспортных средств, скрывая детали о том, как именно они перемещаются, и предоставляя общий интерфейс для их запуска.

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🤔1
🤔 Какая из следующих операций в C# не поддерживает перегрузку операторов?
Anonymous Quiz
32%
инкремент (++)
8%
деление (/)
56%
логическое И (&&)
4%
сложение (+)
Что такое сборщик мусора ?
Спросят с вероятностью 22%

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

Основные этапы работы:

1️⃣Маркировка (Marking): Сборщик мусора периодически проходит через все объекты в куче, начиная с "корней" (объектов, непосредственно доступных в программе, например, через переменные в стеке вызовов и глобальные переменные). Он отмечает все объекты, до которых можно добраться напрямую или косвенно.

2️⃣Очистка (Sweeping): После маркировки доступных объектов, сборщик мусора удаляет все непомеченные объекты, освобождая ресурсы, которые они занимали.

3️⃣Компактификация (Compacting): Некоторые сборщики мусора перемещают оставшиеся объекты, чтобы уменьшить фрагментацию памяти и улучшить производительность работы с памятью.

Почему он важен

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

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

Ограничения:

Несмотря на многие преимущества, сборщик мусора также имеет недостатки:

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

В среде .NET, например, сборщик мусора управляется CLR (Common Language Runtime) и работает автоматически, облегчая задачу управления памятью для разработчиков C# и других .NET-языков. Сборка мусора управляется JVM (Java Virtual Machine), которая предлагает разные типы сборщиков мусора, настраиваемых под различные типы приложений.

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое Action Executor и Action Executing ?
Спросят с вероятностью 22%

"Action Executor" и "Action Executing" относятся к компонентам и процессам, управляющим выполнением действий контроллера. Они являются частью жизненного цикла запроса в MVC и играют ключевую роль в обработке запросов и генерации ответов. Подробно рассмотрим каждый из этих терминов.

Action Executor

Это компонент, который отвечает за непосредственное выполнение метода действия контроллера. Когда запрос достигает контроллера, определённый метод действия должен быть вызван для обработки этого запроса. Задача Action Executor — обеспечить вызов этого метода с правильными параметрами, основываясь на данных запроса и конфигурации маршрутизации.

Обрабатывает логику выбора и вызова нужного метода действия, а также управляет привязкой данных запроса к параметрам метода. В случае ASP.NET Core, это может включать использование IActionInvoker или аналогичных интерфейсов, которые реализуют различные стратегии для вызова действий контроллера.

Action Executing

Относится к процессу, происходящему непосредственно перед выполнением метода действия в контроллере. В ASP.NET MVC это часто управляется с помощью фильтров действий, специально ActionExecutingContext.

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

Аутентификация и авторизация: Проверка того, имеет ли пользователь права на выполнение данного действия.
Валидация данных: Проверка входящих данных на корректность перед обработкой методом действия.
Кэширование: Определение, может ли ответ быть извлечён из кэша, чтобы избежать выполнения метода действия.
Логирование и аудит: Запись информации о запросе и его обработке.

Фильтры действий в ASP.NET MVC реализуются через реализацию интерфейсов IActionFilter или IAsyncActionFilter и могут быть применены глобально или на уровне отдельных контроллеров или действий.
public class LogActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика перед выполнением действия
Log.Information("Action {ActionName} is executing.", context.ActionDescriptor.DisplayName);
}

public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
Log.Information("Action {ActionName} executed.", context.ActionDescriptor.DisplayName);
}
}


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

Action Executor и Action Executing являются важными аспектами в управлении жизненным циклом запроса, позволяя контролировать, как запросы обрабатываются и ответы генерируются в их веб-приложениях.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Какой интерфейс используется для асинхронных потоков данных в C#?
Anonymous Quiz
46%
IAsyncEnumerable<T>
40%
IAsyncResult<T>
10%
IQueryable<T>
4%
IObservable<T>
Какие преимущества представляет C# 12 ?
Спросят с вероятностью 22%

Вот некоторые из функций и улучшений в C# 12:

1️⃣List Patterns
Списочные шаблоны позволяют упростить и сделать более интуитивно понятными проверки списков и массивов. Это расширение существующих возможностей сопоставления с образцом и позволяет разработчикам легко проверять содержимое коллекций.

2️⃣Required Properties
Обязательные свойства улучшат обработку данных, делая явным требование наличия значения для свойств во время создания объекта. Это облегчит создание более безопасных по типам и предсказуемых приложений, уменьшая вероятность ошибок, связанных с отсутствием данных.

3️⃣Improved Pattern Matching
Повышение возможностей сопоставления с образцом продолжает развиваться, обеспечивая более мощные и гибкие способы деконструкции и проверки данных без необходимости писать многословный и ошибочный код.

4️⃣Enhanced Lambdas
Улучшения в лямбда-выражениях, включая новые возможности типизации и возможно улучшения по производительности. Это делает лямбда-выражения еще более мощным инструментом для разработчиков.

5️⃣UTF-8 String Literals
Поддержка литералов строк в UTF-8 может быть добавлена для улучшения обработки текстовых данных, что особенно важно в приложениях, работающих с многими языками и большими объемами текстовых данных.

6️⃣Record Improvements
Записи (records) были введены в C# 9 и представляют собой неизменяемый тип данных, идеально подходящий для создания компактных объектов данных. Улучшения в записях могут включать новые способы работы с ними или расширение их функциональности.

7️⃣Static Virtual Members in Interfaces
Статические виртуальные члены в интерфейсах позволят создавать более гибкие и мощные абстракции, давая разработчикам больше контроля над реализацией и наследованием в их программных структурах.

C# 12 продолжает развивать язык в направлениях, улучшающих безопасность типов, производительность, и удобство программирования. Каждое новое обновление C# старается сделать язык более мощным и удобным для создания разнообразных приложений, от веб-сервисов до крупномасштабных систем. На момент вашего запроса полный список функций C# 12 еще может быть в стадии определения, и для точных деталей стоит обратить внимание на официальные ресурсы Microsoft и сообщества.NET.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81🔥1
👀8👍1
Какие механизмы позволяют не нарушать принцип dependency inversion ?
Спросят с вероятностью 22%

Принцип инверсии зависимостей (Dependency Inversion Principle, DIP) является одним из пяти принципов SOLID, который играет важную роль в проектировании гибкой и устойчивой к изменениям архитектуры программного обеспечения. Этот принцип утверждает, что:

1️⃣Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба типа модулей должны зависеть от абстракций.
2️⃣Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

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

Механизмы для реализации принципа:

1️⃣Использование интерфейсов и абстрактных классов
Позволяют определять контракты для функционала, которые должны реализовать конкретные классы, не указывая, каким образом эта функциональность будет выполнена. Такой подход позволяет компонентам общаться друг с другом через абстракции, а не конкретные реализации.

2️⃣Внедрение зависимостей (Dependency Injection, DI)
Это техника, при которой один объект предоставляет зависимости другому объекту. Это может быть реализовано через конструктор, методы установки или прямое внедрение через свойства. Frameworks like Spring for Java, .NET Core’s built-in DI container, or Google Guice help manage dependencies at runtime, allowing for more flexible and decoupled code architectures.

3️⃣Инверсия управления (Inversion of Control, IoC) контейнеры
IoC контейнеры управляют созданием объектов и их жизненным циклом, а также реализуют DI для передачи зависимостей. Примеры таких контейнеров включают Autofac, Unity в .NET, или Spring IoC в Java.

4️⃣Фабричные методы
Этот шаблон проектирования используется для создания объектов без спецификации конкретных классов объектов. Класс Фабрика обычно возвращает объект базового типа или интерфейса, позволяя программе быть гибкой в отношении создаваемых объектов.

5️⃣Сервис-локатор
Хотя это менее предпочтительный способ по сравнению с DI (так как вводит глобальную зависимость), сервис-локатор может использоваться для управления зависимостями в приложении. Он позволяет извлекать экземпляры компонентов по запросу, используя конфигурацию, определённую в одном центральном месте.
public interface IDataRepository
{
void Save(string data);
}

public class DataRepository : IDataRepository
{
public void Save(string data)
{
Console.WriteLine("Data saved: " + data);
}
}

public class BusinessLogic
{
private readonly

IDataRepository _dataRepository;

// Constructor injection
public BusinessLogic(IDataRepository dataRepository)
{
_dataRepository = dataRepository;
}

public void ProcessData(string data)
{
_dataRepository.Save(data);
}
}

class Program
{
static void Main(string[] args)
{
IDataRepository repo = new DataRepository();
BusinessLogic logic = new BusinessLogic(repo);
logic.ProcessData("Example data");
}
}


В этом примере зависимость IDataRepository внедряется в BusinessLogic через конструктор, что обеспечивает слабую связанность и упрощает тестирование компонентов.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21👀1
Как сделать миграцию методов ?
Спросят с вероятностью 22%

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

1️⃣Планирование

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

2️⃣Разработка стратегии миграции

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

3️⃣Выбор инструментов и технологий

Выбор языка программирования и платформы: В зависимости от целей миграции, выберите наиболее подходящие инструменты и технологии. Например, если вы мигрируете веб-сервисы, возможно, вы захотите перейти с PHP на Node.js или с .NET Framework на .NET Core.
Использование библиотек и фреймворков: Использование сторонних библиотек может значительно ускорить процесс миграции и упростить реализацию сложных функций.

4️⃣Реализация миграции

Тестирование: На каждом этапе миграции важно проводить тщательное тестирование, чтобы убедиться, что мигрированные методы работают как ожидается. Автоматизированные тесты могут значительно упростить этот процесс.
Документирование: Поддерживайте актуальной документацию на протяжении всего процесса миграции. Это важно для понимания изменений в коде и облегчения будущей поддержки и разработки.

5️⃣Деплоймент и мониторинг

Постепенный деплоймент: Если это возможно, используйте стратегии постепенного внедрения, такие как canary releases или blue-green deployments, чтобы минимизировать риски.
Мониторинг: После внедрения изменений активно мониторьте приложение для выявления любых проблем в работе, производительности или других неожиданных поведений.

Синхронный метод:
public string GetDataFromDb()
{
// Предположим, что это вызов к базе данных
Thread.Sleep(1000); // Имитация задержки
return "Data";
}


Асинхронный метод:
public async Task<string> GetDataFromDbAsync()
{
await Task.Delay(1000); // Имитация асинхронной задержки
return "Data";
}


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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1
Что такое Signalr ?
Спросят с вероятностью 22%

SignalR — это библиотека, разработанная для облегчения добавления функциональности "реального времени" в веб-приложения. Она позволяет серверу автоматически отправлять обновления клиентам в режиме реального времени, не требуя от клиентов периодически опрашивать сервер на предмет изменений.

Ключевые особенности:

1️⃣Двусторонняя связь: В отличие от традиционного HTTP, который является односторонним (клиент отправляет запрос, сервер отправляет ответ), SignalR позволяет обоюдный обмен данными между клиентом и сервером в реальном времени.

2️⃣Абстракция транспорта: Автоматически выбирает наилучший доступный способ транспорта данных между клиентом и сервером в зависимости от возможностей клиентского устройства и сервера. Он поддерживает различные технологии, включая WebSockets, Server-Sent Events и Long Polling.

3️⃣Масштабируемость: Поддерживает масштабируемость веб-приложений через использование внешних компонентов, таких как Redis или Azure Service Bus, для управления подключениями через несколько серверов.

4️⃣Управление подключениями: Автоматически управляет подключениями, обработкой переподключений и обеспечивает групповую отправку сообщений, позволяя сообщениям быть отправленными к выбранным пользователям или группам.

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

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

На сервере (C#):
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}


На клиенте (JavaScript):
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.build();

connection.on("ReceiveMessage", function(user, message) {
const msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
const encodedMsg = user + " says " + msg;
const li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
});

connection.start().catch(function(err) {
return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function(event) {
const user = document.getElementById("userInput").value;
const message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function(err) {
return console.error(err.toString());
});
event.preventDefault();
});


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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Что такое интерфейс ?
Спросят с вероятностью 22%

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

Основные аспекты:

1️⃣Определение поведения: Интерфейс определяет "контракт" или спецификацию, которой должен следовать класс. Этот контракт включает методы и, иногда, свойства, которые реализующий класс обязан предоставить.

2️⃣Абстракция: Интерфейсы помогают отделить определение того, что класс должен делать, от деталей того, как класс выполняет эти задачи. Это позволяет разрабатывать программы, опираясь на абстракции, а не конкретные реализации.

3️⃣Множественное наследование: В языках, где классы не могут наследовать поведение нескольких классов напрямую (например, в C# и Java), интерфейсы предоставляют способ реализовать множественное наследование на уровне поведения.

4️⃣Интероперабельность: Интерфейсы облегчают взаимодействие различных частей программы или даже различных программ, поскольку они могут взаимодействовать через общий интерфейс, не заботясь о внутренних деталях каждого компонента.
public interface IAnimal
{
void Eat();
void Move();
}

public class Dog : IAnimal
{
public void Eat()
{
Console.WriteLine("Dog is eating.");
}

public void Move()
{
Console.WriteLine("Dog is running.");
}
}


В этом примере, IAnimal — это интерфейс с методами Eat и Move. Класс Dog реализует интерфейс IAnimal, предоставляя конкретную реализацию для каждого из методов интерфейса.

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41👾1
📌 Расскажи про конкурентные коллекции?

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

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

1️⃣ ConcurrentDictionary<TKey, TValue>:

Это словарь, который позволяет безопасно добавлять, удалять и изменять элементы из нескольких потоков одновременно. Он реализует интерфейс IDictionary<TKey, TValue>.

Пример:
var concurrentDictionary = new ConcurrentDictionary<int, string>();
concurrentDictionary.TryAdd(1, "value1");
concurrentDictionary.TryAdd(2, "value2");

string value;
if (concurrentDictionary.TryGetValue(1, out value))
{
Console.WriteLine(value); // Output: value1
}


2️⃣ ConcurrentQueue<T>:

Это очередь, которая обеспечивает безопасное добавление элементов в конец и извлечение из начала в многопоточной среде. Она реализует интерфейс IProducerConsumerCollection<T>.

Пример:
var concurrentQueue = new ConcurrentQueue<int>();
concurrentQueue.Enqueue(1);
concurrentQueue.Enqueue(2);

int result;
if (concurrentQueue.TryDequeue(out result))
{
Console.WriteLine(result); // Output: 1
}


3️⃣ ConcurrentStack<T>:

Это стек, который обеспечивает безопасное добавление и извлечение элементов в многопоточной среде. Он также реализует интерфейс IProducerConsumerCollection<T>.

Пример:
var concurrentStack = new ConcurrentStack<int>();
concurrentStack.Push(1);
concurrentStack.Push(2);

int result;
if (concurrentStack.TryPop(out result))
{
Console.WriteLine(result); // Output: 2
}


4️⃣ ConcurrentBag<T>:

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

Пример:
var concurrentBag = new ConcurrentBag<int>();
concurrentBag.Add(1);
concurrentBag.Add(2);

int result;
if (concurrentBag.TryTake(out result))
{
Console.WriteLine(result); // Output: 1 или 2
}


5️⃣ BlockingCollection<T>:

Это коллекция, которая поддерживает ограниченную емкость и блокировку потоков при добавлении или извлечении элементов. Она особенно полезна для реализации паттернов продюсер-потребитель.

Пример:
var blockingCollection = new BlockingCollection<int>(boundedCapacity: 5);
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
blockingCollection.Add(i);
Console.WriteLine($"Added {i}");
}
blockingCollection.CompleteAdding();
});

foreach (var item in blockingCollection.GetConsumingEnumerable())
{
Console.WriteLine($"Consumed {item}");
}


Заключение:

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

Кратко:

Конкурентные коллекции в C# позволяют безопасно работать с данными в многопоточной среде, избегая проблем с синхронизацией. Примеры включают ConcurrentDictionary, ConcurrentQueue, ConcurrentStack, ConcurrentBag и BlockingCollection.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
🤔 Какой из методов интерфейса IEnumerator должен быть реализован для поддержки итерации в C#?
Anonymous Quiz
90%
MoveNext()
2%
MovePrevious()
3%
ResetCurrent()
6%
Advance()
Forwarded from Идущий к IT
10$ за техническое собеседование на английском языке:

1. Отправьте запись технического собеседования на английском языке файлом на этот аккаунт
2. Добавьте ссылку на вакансию или пришлите название компании и должность
3. Напишите номер кошелка USDT (Tether) на который отправить 10$

🛡 Важно:

– Запись будет использована только для сбора данных о вопросах
– Вы останетесь анонимны
– Запись нигде не будет опубликована

🤝 Условия:

– Внятный звук, различимая речь
– Допустимые профессии:
• Любые программисты
• DevOps
• Тестировщики
• Дата сайнтисты
• Бизнес/Системные аналитики
• Прожекты/Продукты
• UX/UI и продукт дизайнеры
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
📌 Что такое групповые делегаты?

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

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

1️⃣ Основные понятия:

1. Делегат — это тип, который представляет ссылку на метод с определенной сигнатурой.
2. Групповой делегат — это делегат, который содержит ссылки на несколько методов и вызывает их по очереди.

2️⃣ Как создаются групповые делегаты:

Объединение делегатов.

Чтобы создать групповой делегат, нужно объединить несколько делегатов с помощью оператора + или метода Delegate.Combine.

Пример:
using System;

public delegate void MyDelegate();

public class Program
{
public static void Method1()
{
Console.WriteLine("Method1");
}

public static void Method2()
{
Console.WriteLine("Method2");
}

public static void Main()
{
MyDelegate del1 = Method1;
MyDelegate del2 = Method2;

// Объединяем делегаты
MyDelegate groupDel = del1 + del2;

// Вызов группового делегата
groupDel();
}
}


Вывод:
Method1
Method2


Удаление делегатов.

Для удаления метода из группового делегата используется оператор - или метод Delegate.Remove.

Пример:
using System;

public delegate void MyDelegate();

public class Program
{
public static void Method1()
{
Console.WriteLine("Method1");
}

public static void Method2()
{
Console.WriteLine("Method2");
}

public static void Main()
{
MyDelegate del1 = Method1;
MyDelegate del2 = Method2;

// Объединяем делегаты
MyDelegate groupDel = del1 + del2;

// Удаляем делегат
groupDel -= del1;

// Вызов группового делегата
groupDel();
}
}


Вывод:
Method2


3️⃣ Использование в событиях:

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

Пример:
using System;

public delegate void Notify(); // делегат для события

public class ProcessBusinessLogic
{
public event Notify ProcessCompleted; // событие

public void StartProcess()
{
Console.WriteLine("Process Started!");
// Какое-то логика процесса...
OnProcessCompleted();
}

protected virtual void OnProcessCompleted()
{
// Если есть подписчики
if (ProcessCompleted != null)
ProcessCompleted.Invoke();
}
}

public class Program
{
public static void Main()
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += bl_ProcessCompleted; // подписка на событие
bl.ProcessCompleted += bl_ProcessCompleted2; // подписка на событие
bl.StartProcess();
}

public static void bl_ProcessCompleted()
{
Console.WriteLine("Process Completed!");
}

public static void bl_ProcessCompleted2()
{
Console.WriteLine("Process Completed Again!");
}
}


Вывод:
Process Started!
Process Completed!
Process Completed Again!


Заключение:

Групповые делегаты в C# позволяют объединять несколько методов в один делегат и вызывать их последовательно. Они часто используются в событиях для уведомления нескольких подписчиков.

Кратко:

Групповые делегаты в C# позволяют объединять несколько методов в один делегат и вызывать их последовательно. Это полезно для уведомления нескольких подписчиков в событиях.

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2🎉1
📌 Что такое Inversion of control и dependency injection?

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

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

1️⃣ Inversion of Control (Инверсия управления)

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

IoC часто реализуется с помощью таких паттернов, как Dependency Injection, Event, Strategy.

2️⃣ Dependency Injection (Внедрение зависимостей)

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

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

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

public class Application
{
private readonly ILogger _logger;

// Внедрение зависимости через конструктор
public Application(ILogger logger)
{
_logger = logger;
}

public void Run()
{
_logger.Log("Приложение запущено");
}
}

// Где-то в другом месте приложения
ILogger logger = new ConsoleLogger();
Application app = new Application(logger);
app.Run();


В этом примере Application зависит от абстракции ILogger. Вместо того чтобы создавать конкретный экземпляр ConsoleLogger внутри Application, мы передаём его через конструктор, что позволяет легко заменить реализацию логгера без изменения кода класса Application.

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

Инверсия управления — это когда ваш код не управляет потоком выполнения, а подчиняется внешнему "руководителю". Внедрение зависимостей — это когда ваш код не создает то, что ему нужно для работы сам, а получает это "снаружи".

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
📌 Какие преимущества у LinQ?

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

LINQ (Language Integrated Query) — это компонент .NET Framework, который добавляет возможности запроса данных из различных источников (таких как коллекции, базы данных, XML и другие) прямо в код C#. LINQ обеспечивает единообразный способ работы с данными, позволяя использовать одни и те же методы для различных типов данных. Вот основные преимущества LINQ:

1️⃣ Унифицированный синтаксис:
LINQ предоставляет единый и последовательный способ работы с данными, будь то массивы, списки, базы данных или XML. Это снижает необходимость изучения различных API для работы с разными источниками данных.
    // Пример запроса к массиву
int[] numbers = { 1, 2, 3, 4, 5 };
var evenNumbers = from num in numbers
where num % 2 == 0
select num;


2️⃣ Читабельность кода:
Запросы LINQ легко читаются и понимаются, так как они используют знакомые конструкты языка программирования. Это упрощает поддержку и развитие кода.
    // Пример запроса к списку объектов
List<Person> people = GetPeopleList();
var adults = from person in people
where person.Age >= 18
select person;


3️⃣ Типобезопасность:
LINQ предоставляет строгую проверку типов на этапе компиляции, что помогает избежать многих ошибок, связанных с неправильным использованием типов данных. Это делает код более надежным.
    // Пример использования LINQ с типизированными данными
var adults = people.Where(p => p.Age >= 18);


4️⃣ Упрощение сложных запросов:
LINQ позволяет легко составлять сложные запросы, которые могут включать сортировку, группировку и объединение данных. Это позволяет сосредоточиться на логике запроса, а не на низкоуровневых деталях его выполнения.
    // Пример группировки данных с использованием LINQ
var groupedPeople = from person in people
group person by person.Age into ageGroup
select new { Age = ageGroup.Key, People = ageGroup };


5️⃣ Ленивые вычисления:
LINQ поддерживает ленивые вычисления, что означает, что данные не извлекаются из источника до тех пор, пока это не потребуется. Это может существенно повысить производительность, особенно при работе с большими объемами данных.
    // Пример ленивых вычислений
var query = people.Where(p => p.Age >= 18); // Запрос еще не выполнен
foreach (var person in query)
{
Console.WriteLine(person.Name); // Запрос выполняется здесь
}


6️⃣ Поддержка различных источников данных:
LINQ работает с различными источниками данных, включая массивы, списки, базы данных (через LINQ to SQL или Entity Framework), XML и даже сторонние сервисы.
    // Пример запроса к базе данных с использованием Entity Framework
using (var context = new MyDbContext())
{
var users = from user in context.Users
where user.IsActive
select user;
}


🤔 Краткое резюме:

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какой модификатор доступа в C# делает класс или член доступным только внутри своей сборки?
Anonymous Quiz
1%
public
10%
private
15%
protected
74%
internal
👍4
📌 Garbage collectior что это?

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

Garbage Collector (GC) — это механизм управления памятью в среде выполнения .NET, который автоматически освобождает память, занимаемую объектами, которые больше не используются приложением. Это важная часть управления ресурсами в .NET, так как она предотвращает утечки памяти и улучшает общую производительность приложения. Вот основные аспекты работы Garbage Collector и его преимущества:

🤔 Основные функции Garbage Collector

1️⃣ Автоматическое управление памятью:

GC автоматически отслеживает объекты, создаваемые в управляемой куче (managed heap), и освобождает память, занимаемую объектами, которые больше не достижимы или не используются приложением. Это снижает необходимость ручного управления памятью и уменьшает вероятность утечек памяти.

2️⃣ Сборка мусора:

GC выполняет сборку мусора (garbage collection) в несколько этапов:

Маркировка (Marking): GC определяет, какие объекты все еще достижимы и используются.

Очистка (Sweeping): Память, занимаемая недостижимыми объектами, освобождается.

Компактирование (Compacting): Память, занимаемая достижимыми объектами, перемещается для сокращения фрагментации.

3️⃣ Поколения объектов:

Объекты в управляемой куче делятся на поколения (Generation):

Generation 0: Новые объекты, которые недавно созданы. Сборка мусора для этого поколения выполняется чаще.

Generation 1: Объекты, которые пережили хотя бы одну сборку мусора.

Generation 2: Объекты, которые живут достаточно долго и пережили несколько сборок мусора.

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

4️⃣ Сборка в фоновом режиме:
.NET GC поддерживает сборку мусора в фоновом режиме, что позволяет минимизировать паузы в работе приложения за счет выполнения сборки мусора параллельно с основной работой приложения.

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

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

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

3️⃣ Оптимизация использования памяти:
GC периодически выполняет компактирование памяти, что снижает фрагментацию и улучшает производительность приложения.

🤔 Пример работы Garbage Collector

Рассмотрим пример создания объектов в C# и как GC их обрабатывает:
class Program
{
static void Main()
{
// Создание объектов
for (int i = 0; i < 100; i++)
{
MyClass obj = new MyClass();
}

// Вызов сборки мусора вручную (обычно не рекомендуется)
GC.Collect();
GC.WaitForPendingFinalizers();
}
}

class MyClass
{
~MyClass()
{
// Финализатор, который вызывается перед удалением объекта
Console.WriteLine("Объект удален");
}
}


В этом примере создается 100 объектов класса MyClass. Когда они выходят из области видимости, GC может освободить память, занимаемую этими объектами.

🤔 Краткое резюме:

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

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

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