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
🔥 Объясни паттерн 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
🔥 Чем отличаются абстрактные классы от интерфейсов?

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

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

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

Пример абстрактного класса:

public abstract class Animal {
public abstract void MakeSound();
public void Sleep() {
Console.WriteLine("Sleeping");
}
}


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

public interface IMovable {
void Move();
}


Выбор между абстрактным классом и интерфейсом зависит от архитектурных требований и необходимости в общей реализации.

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

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

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

Пример объявления делегата:

public delegate void Notify(string message);


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

public class Process {
public event Notify OnProcessCompleted;

public void StartProcess() {
// Процесс выполняется
OnProcessCompleted?.Invoke("Process completed");
}
}


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

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

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

При создании пользовательского исключения рекомендуется:

1. Унаследовать класс от Exception.
2. Определить конструкторы, которые вызывают базовые конструкторы Exception.
3. Переопределить метод GetObjectData, если требуется сериализация.

Пример пользовательского класса исключения:

public class InvalidUserInputException : Exception {
public InvalidUserInputException() { }

public InvalidUserInputException(string message) : base(message) { }

public InvalidUserInputException(string message, Exception inner) : base(message, inner) { }
}


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

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

XPath — это язык запросов, используемый для навигации по элементам и атрибутам в XML-документах. Он позволяет извлекать данные из XML, используя выражения, которые описывают путь к нужным элементам.

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

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

using System;
using System.Xml;

public class XPathExample {
public static void Main() {
string xml = "<books><book><title>C# Basics</title></book></books>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

XmlNode node = doc.SelectSingleNode("/books/book/title");
Console.WriteLine(node.InnerText); // Output: C# Basics
}
}


В этом примере используется метод SelectSingleNode для извлечения элемента <title> из XML-документа. XPath выражение "/books/book/title" указывает путь к нужному элементу. XPath упрощает извлечение и обработку данных из сложных XML-структур.

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

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

В C# кэширование можно реализовать с помощью различных подходов, включая использование MemoryCache из пространства имен System.Runtime.Caching.

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

using System;
using System.Runtime.Caching;

public class CacheExample {
public static void Main() {
MemoryCache cache = MemoryCache.Default;
string cacheKey = "dataKey";
string data = cache[cacheKey] as string;

if (data == null) {
data = "Expensive Data";
CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(10) };
cache.Set(cacheKey, data, policy);
}

Console.WriteLine(data);
}
}


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

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

CI/CD — это практика непрерывной интеграции и непрерывного развертывания (или доставки), которая автоматизирует процесс сборки, тестирования и развертывания программного обеспечения. Она помогает командам разработчиков быстро и надежно выпускать изменения в коде.

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

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

CI/CD способствует улучшению качества кода, сокращению времени выхода на рынок и повышению гибкости разработки. Инструменты, такие как Jenkins, GitLab CI/CD и GitHub Actions, часто используются для реализации этих практик.

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

Top-level statements в C# позволяют писать программы без явного объявления класса или метода Main, упрощая синтаксис для небольших приложений и скриптов. Эта возможность появилась в C# 9.0 и делает код более читаемым и компактным.

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

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

using System;

Console.WriteLine("Hello, World!");

int Add(int a, int b) => a + b;

Console.WriteLine(Add(3, 4));


В этом примере код выполняется без явного объявления класса и метода Main. Top-level statements удобны для простых приложений и быстрого прототипирования, позволяя сосредоточиться на логике, а не на структуре программы.

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

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

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

Основные отличия структур от классов:

1. Наследование: Структуры не поддерживают наследование, но могут реализовывать интерфейсы.

2. Конструкторы: Структуры не могут иметь явных конструкторов без параметров. Компилятор автоматически создает конструктор по умолчанию.

3. Инициализация: Поля структуры должны быть инициализированы до использования.

4. Семантика копирования: При присваивании структуры создается копия всех данных, в то время как при присваивании класса копируется только ссылка.

Пример структуры:

public struct Point {
public int X { get; set; }
public int Y { get; set; }

public Point(int x, int y) {
X = x;
Y = y;
}
}


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

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

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

Основные преимущества Docker:

1. Портативность: Контейнеры Docker работают одинаково в любой среде, что упрощает перенос приложений между различными системами и платформами.

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

3. Эффективность: Контейнеры используют ресурсы более эффективно по сравнению с виртуальными машинами, так как они разделяют ядро операционной системы.

4. Скорость: Запуск и остановка контейнеров происходит быстрее, чем виртуальных машин, что ускоряет разработку и тестирование.

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

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

Target-typed new expressions в C# — это синтаксический сахар, введенный в C# 9.0, который позволяет опустить тип объекта при создании экземпляра, если компилятор может вывести его из контекста. Это упрощает код и делает его более читаемым.

Когда используется target-typed new, тип объекта определяется из контекста, например, из типа переменной, свойства или параметра метода, которому присваивается новый объект.

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

Point point = new(3, 4);


В этом примере компилятор выводит, что new(3, 4) создает экземпляр типа Point, основываясь на типе переменной point.

Target-typed new expressions особенно полезны в случаях, когда тип уже очевиден из контекста, что позволяет избежать дублирования информации и улучшает читаемость кода.

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

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

Основные способы реализации DI:

1. Конструкторная инъекция: Зависимости передаются через параметры конструктора.

2. Сеттерная инъекция: Зависимости устанавливаются через свойства или методы.

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

Пример конструкторной инъекции:

public interface ILogger {
void Log(string message);
}

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

public class Service {
private readonly ILogger _logger;

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

public void Execute() {
_logger.Log("Executing service");
}
}


В этом примере Service получает зависимость ILogger через конструктор. Это позволяет легко заменять реализацию ILogger для тестирования или изменения логики без изменения кода Service. DI часто реализуется с помощью контейнеров, таких как Microsoft.Extensions.DependencyInjection.

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