C# собеседования
753 subscribers
104 photos
222 links
Подготовка к собеседованиям на позицию C#-разработчик

Еще больше на сайте https://frontview-it.ru

Backend собеседования - @frontview_backend
C# работа - @frontview_csharp_vacancies
Все IT вакансии - @frontview_all_vacancies
Download Telegram
🔥 Как написать простой запрос LINQ для выборки элементов из списка?

LINQ (Language Integrated Query) позволяет удобно работать с коллекциями в C#. Для выборки элементов из списка можно использовать простой запрос LINQ.

Например, есть список чисел, и нужно выбрать только чётные числа:


List<int> numbers = new List<int> {1, 2, 3, 4, 5, 6};

// Выборка чётных чисел из списка
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();


Можно также использовать синтаксис запросов:


List<int> numbers = new List<int> {1, 2, 3, 4, 5, 6};

// Выборка чётных чисел с использованием синтаксиса запросов
var evenNumbers = (from n in numbers
where n % 2 == 0
select n).ToList();


В результате переменная evenNumbers будет содержать числа 2, 4 и 6.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🔥 Что такое утечка памяти и как ее избежать в C#?

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

Для предотвращения утечек памяти следует:

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


// Отписка от события
eventHandler -= EventMethod;


- Использовать using для IDisposable. Это гарантирует освобождение неуправляемых ресурсов.


// Использование using для IDisposable
using (var resource = new Resource())
{
// Работа с ресурсом
}


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

- Контролировать кэширование. Удалять устаревшие данные из кэша.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Что такое переменная и константа? В чем их отличие?

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


int number = 10; // Объявление переменной number типа int со значением 10
number = 20; // Изменение значения переменной number на 20


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


const double Pi = 3.1415; // Объявление константы Pi типа double со значением 3.1415
// Pi = 3.14; // Ошибка: значение константы нельзя изменить


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Как работает оператор null в C#?

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

Основные операторы, связанные с null:

1. Оператор ?? (null-объединение):

Возвращает левый операнд, если он не равен null, иначе возвращает правый операнд.


string name = null;
string displayName = name ?? "Unknown"; // Если name == null, то displayName будет "Unknown"


2. Оператор ?. (null-условный доступ):

Позволяет безопасно обращаться к членам объекта, который может быть null, предотвращая исключение NullReferenceException.


Person person = null;
string firstName = person?.FirstName; // Если person == null, то firstName будет null


3. Оператор ??= (присваивание при null):

Присваивает значение правого операнда левому только если левый операнд равен null.


int? number = null;
number ??= 10; // Если number == null, то number присваивается 10


4. Оператор switch с шаблоном null:

Позволяет выполнять специальные действия, если значение равно null.


object obj = null;

switch (obj)
{
case null:
// Обработка случая, когда obj == null
break;
default:
// Обработка остальных случаев
break;
}


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1
🔥 Чем отличаются абстрактные классы от интерфейсов?

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

Абстрактные классы:

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


public abstract class Animal
{
public string Name; // Поле имени животного

public abstract void Speak(); // Абстрактный метод

public void Sleep()
{
// Реализация метода сна
}
}


Интерфейсы:

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


public interface IMovable
{
void Move(); // Метод для перемещения
}


Основные отличия:

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Что такое IDisposable и как он помогает управлять памятью?

В C# интерфейс IDisposable определяет метод Dispose(), который используется для явного освобождения неуправляемых ресурсов, таких как файловые дескрипторы, соединения с базой данных и другие ресурсы, не управляемые сборщиком мусора.

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

Пример реализации IDisposable:


public class ResourceHolder : IDisposable
{
private bool disposed = false; // Флаг для отслеживания состояния освобождения

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // Отключение финализации
}

protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождение управляемых ресурсов
}
// Освобождение неуправляемых ресурсов

disposed = true;
}
}

~ResourceHolder()
{
Dispose(false);
}
}


При использовании такого класса рекомендуется применять using, что обеспечивает автоматический вызов Dispose():


// Использование using гарантирует вызов Dispose()
using (var resource = new ResourceHolder())
{
// Работа с ресурсом
}


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Что такое Action, Func и Predicate делегаты?

В C# делегаты Action, Func и Predicate широко используются для представления методов.

Action представляет метод, который не возвращает значение. Например:


Action<string> print = message => Console.WriteLine(message);
print("Hello");


Func представляет метод, который возвращает значение. Последний параметр указывает тип возвращаемого значения. Например:


Func<int, int, int> add = (a, b) => a + b;
int result = add(3, 4);


Predicate — специализированный делегат Func, возвращающий bool. Применяется для проверки условий:


Predicate<int> isEven = number => number % 2 == 0;
bool check = isEven(4); // возвращает true


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Что такое deferred execution в LINQ?

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

Пример:


List<int> numbers = new List<int> {1, 2, 3};
var query = numbers.Where(n => n > 1);

// Добавление элемента после определения запроса
numbers.Add(4);

foreach(var num in query)
{
Console.WriteLine(num);
}


В этом примере запрос Where не выполняется сразу. Он выполняется при итерации в foreach, учитывая добавленный элемент 4. Таким образом, вывод будет:


2 3 4


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Как обрабатывать исключения в асинхронных методах?

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

Пример:


public async Task<string> FetchDataAsync()
{
try
{
// Асинхронный вызов метода
return await GetDataFromServiceAsync();
}
catch (HttpRequestException ex)
{
// Обработка сетевых ошибок
Console.WriteLine($"Ошибка запроса: {ex.Message}");
throw;
}
catch (Exception ex)
{
// Обработка других исключений
Console.WriteLine($"Произошла ошибка: {ex.Message}");
throw;
}
}


При вызове метода важно использовать await внутри блока try-catch:


try
{
var data = await FetchDataAsync();
}
catch (Exception ex)
{
// Обработка исключений из FetchDataAsync
Console.WriteLine(ex.Message);
}


Кроме того, при работе с задачами можно использовать метод ContinueWith для обработки исключений, но использование async/await с try-catch считается более предпочтительным и читаемым подходом.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Что такое ORM и какие ORM фреймворки ты знаешь?

ORM (Object-Relational Mapping) упрощает взаимодействие между объектно-ориентированным кодом и реляционными базами данных, позволяя работать с данными как с объектами.

Популярные ORM-фреймворки в C#:

Entity Framework – стандартный ORM от Microsoft, предоставляет высокий уровень абстракции, поддерживает LINQ и миграции схем базы данных.

Dapper – микро-ORM, известен своей производительностью и простотой, идеально подходит для выполнения быстрых SQL-запросов с минимальными накладными расходами.

NHibernate – зрелый ORM с богатым функционалом, поддерживает различные базы данных, кэширование и сложные сценарии маппинга.

ServiceStack.OrmLite – облегченный ORM, фокусируется на простых и понятных SQL-запросах, обеспечивает высокую скорость работы.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥1
🔥 Как работать с текстовыми файлами с помощью StreamReader и StreamWriter?

Для работы с текстовыми файлами в C# используются классы StreamReader и StreamWriter. Они позволяют читать и записывать текстовые данные эффективно и удобно.

Чтение файла с помощью StreamReader:


using System.IO;

string filePath = "example.txt";

using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}


В данном примере файл example.txt читается построчно, каждая строка выводится в консоль.

Запись в файл с помощью StreamWriter:


using System.IO;

string filePath = "output.txt";

using (StreamWriter writer = new StreamWriter(filePath))
{
writer.WriteLine("Первая строка");
writer.WriteLine("Вторая строка");
}


Этот код записывает две строки в файл output.txt. Если файл не существует, он будет создан. При повторном запуске содержимое файла перезапишется.

Советы:
- Использование конструкции using гарантирует, что ресурсы будут освобождены автоматически.
- Для добавления содержимого в существующий файл используйте конструктор StreamWriter с параметром append:


using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("Дополнительная строка");
}


Понимание работы с StreamReader и StreamWriter позволяет эффективно управлять текстовыми данными в приложениях на C#.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Объясни паттерн Repository и расскажи про его преимущества

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

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

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

Пример интерфейса Repository:


public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
}


Реализация с Entity Framework:


public class Repository<T> : IRepository<T> where T : class
{
private readonly DbContext context;
private readonly DbSet<T> dbSet;

public Repository(DbContext context)
{
this.context = context;
dbSet = context.Set<T>();
}

public IEnumerable<T> GetAll() => dbSet.ToList();

public T GetById(int id) => dbSet.Find(id);

public void Add(T entity) => dbSet.Add(entity);

public void Update(T entity) => context.Entry(entity).State = EntityState.Modified;

public void Delete(T entity) => dbSet.Remove(entity);
}


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🔥 Что такое кроссплатформенность в .NET Core?

Кроссплатформенность в .NET Core означает возможность разработки и запуска приложений на различных операционных системах, таких как Windows, macOS и Linux.

Преимущества кроссплатформенности .NET Core:

- Гибкость развертывания: Приложения могут работать на любой поддерживаемой ОС без изменения кода.
- Широкий охват аудитории: Возможность создания приложений для различных платформ расширяет потенциальных пользователей.
- Поддержка контейнеризации: Отличная интеграция с Docker и другими технологиями контейнеров.
- Оптимизированная производительность: Высокая производительность на всех поддерживаемых платформах.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🔥 Как создать и запустить unit-тесты с использованием NUnit?

Для создания и запуска unit-тестов с использованием NUnit в C# выполняются следующие шаги.

Шаг 1: Установка NUnit

Пакеты NUnit и NUnit3TestAdapter устанавливаются через NuGet в тестовом проекте:


Install-Package NUnit
Install-Package NUnit3TestAdapter


Шаг 2: Создание тестового проекта

В Visual Studio выбирается Add > New Project, затем NUnit Test Project.

Шаг 3: Написание тестов

Создается класс для тестирования и добавляются тестовые методы с атрибутом [Test]:


using NUnit.Framework;

public class Calculator
{
public int Add(int a, int b) => a + b;
}

[TestFixture]
public class CalculatorTests
{
[Test]
public void Add_ShouldReturnSum()
{
var calculator = new Calculator();
Assert.AreEqual(5, calculator.Add(2, 3));
}
}


Шаг 4: Запуск тестов

Test Explorer в Visual Studio используется для обнаружения и запуска тестов. Тесты отображаются в окне Test Explorer, откуда они запускаются.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🔥 Объясни различия между IEnumerable<T>, IQueryable<T> и ICollection<T>

IEnumerable<T>, IQueryable<T> и ICollection<T> — основные интерфейсы для работы с коллекциями в C#.

IEnumerable<T>
Предназначен для перебора коллекций в памяти. Поддерживает только чтение данных и отложенное выполнение запросов.


IEnumerable<int> numbers = new List<int> {1, 2, 3};
foreach(var num in numbers)
{
Console.WriteLine(num);
}


IQueryable<T>
Расширяет IEnumerable<T>, позволяя строить запросы, которые могут выполняться на удалённых источниках данных, таких как базы данных. Поддерживает выражения LINQ, которые трансформируются в запросы к источнику данных.


IQueryable<User> users = dbContext.Users.Where(u => u.IsActive);


ICollection<T>
Наследуется от IEnumerable<T> и добавляет методы для изменения коллекции, такие как Add, Remove, Clear. Подходит для коллекций, требующих модификации элементов.


ICollection<string> names = new List<string>();
names.Add("Alice");
names.Remove("Bob");


Ключевые различия:
- IEnumerable<T> подходит для простого перебора.
- IQueryable<T> оптимален для запросов к удалённым источникам с поддержкой LINQ.
- ICollection<T> обеспечивает функциональность изменения коллекций.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Что такое runtime exceptions?

Runtime exceptions в C# — это ошибки, возникающие во время выполнения программы. Они не обнаруживаются компилятором и могут привести к аварийному завершению приложения, если не обработаны должным образом.

Примеры runtime exceptions:

- NullReferenceException — возникает при попытке обращения к объекту через null.


string text = null;
int length = text.Length; // Ошибка


- IndexOutOfRangeException — при доступе к несуществующему индексу в массиве или коллекции.


int[] numbers = {1, 2, 3};
int number = numbers[5]; // Ошибка


- DivideByZeroException — при попытке деления числа на ноль.


int a = 10;
int b = 0;
int result = a / b; // Ошибка


Обработка runtime exceptions:

Использование блоков try-catch позволяет перехватывать и обрабатывать такие исключения, предотвращая аварийное завершение программы.


try
{
int[] numbers = {1, 2, 3};
Console.WriteLine(numbers[5]);
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine($"Ошибка: {ex.Message}");
}


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🔥 Как инициализировать массив в C#?

В C# массивы можно инициализировать несколькими способами, в зависимости от потребностей.

Объявление массива с заданным размером:


int[] numbers = new int[5];


Создает массив из 5 элементов типа int, каждый из которых инициализируется значением по умолчанию (0).

Инициализация массива с элементами:


string[] fruits = { "Apple", "Banana", "Cherry" };


Позволяет сразу задать значения элементов массива.

Использование ключевого слова var:


var colors = new[] { "Red", "Green", "Blue" };


Компилятор автоматически определяет тип массива на основе предоставленных значений.

Многомерные массивы:


int[,] matrix = new int[3, 3];


Создает двумерный массив 3x3 типа int.

Массивы массивов:


int[][] jaggedArray = new int[2][];
jaggedArray[0] = new int[] {1, 2};
jaggedArray[1] = new int[] {3, 4, 5};


Позволяет создавать массивы разной длины внутри основного массива.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🔥 Что такое полиморфизм и как он реализуется в C#?

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

Виды полиморфизма:
1. Компиляционный (перегрузка методов): Методы с одинаковым именем, но разными параметрами.
2. Исполнительный (переопределение методов): Методы, которые могут иметь разную реализацию в производных классах.

Пример переопределения метода:


public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal sound");
}
}

public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Bark");
}
}

public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Meow");
}
}


В данном примере метод MakeSound объявлен как virtual в базовом классе Animal и переопределён в классах Dog и Cat. Это позволяет вызывать соответствующую реализацию метода в зависимости от типа объекта.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Что такое init-only свойства и как их использовать?

Init-only свойства — это свойства, которые могут быть установлены только во время инициализации объекта и становятся неизменяемыми после. Они были введены в C# 9.0 для поддержки создания иммутабельных объектов с удобным синтаксисом.

Как использовать init-only свойства:

Для объявления init-only свойства используется ключевое слово init вместо set.


public class Person
{
public string Name { get; init; }
public int Age { get; init; }
}


Инициализация объекта:


var person = new Person
{
Name = "Иван",
Age = 30
};

// Следующая строка вызовет ошибку компиляции
// person.Age = 31;


В данном примере свойства Name и Age могут быть установлены только при создании объекта Person. После инициализации попытка изменить значение свойства приведет к ошибке компиляции.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔥 Как работать с XML-документами с помощью XDocument и LINQ to XML?

Работа с XML-документами в C# осуществляется с помощью XDocument и LINQ to XML, они предоставляют удобные методы для чтения, запроса и изменения данных.

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


using System;
using System.Linq;
using System.Xml.Linq;

public class Example
{
public static void Main()
{
XDocument doc = XDocument.Load("data.xml");

var books = from b in doc.Descendants("Book")
where (int)b.Element("Price") > 20
select new
{
Title = b.Element("Title").Value,
Price = b.Element("Price").Value
};

foreach (var book in books)
{
Console.WriteLine($"{book.Title}: {book.Price}");
}
}
}


Добавление элемента:


doc.Root.Add(new XElement("Book",
new XElement("Title", "Новая книга"),
new XElement("Price", 25)));
doc.Save("data.xml");


Использование XDocument совместно с LINQ упрощает работу с XML, делая код более чистым и понятным.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6