C# | Вопросы собесов
5.02K subscribers
40 photos
1 file
1.37K links
Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy

Контакт для рекламы: @easyoffer_adv
Download Telegram
🤔 Абстракция более высокого уровня — это Task или Thread?

Task — это более высокоуровневая абстракция над Thread или ThreadPool.
- Thread — примитив, напрямую управляет потоком ОС.
- Task — обёртка над ThreadPool-ом, планирует выполнение, поддерживает отмену (CancellationToken), продолжения (ContinueWith) и await.
Использовать Task предпочтительно в большинстве случаев.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥2👍1
🤔 Какова цель ключевого слова lock?

lock используется для синхронизации доступа к разделяемым ресурсам в многопоточном коде. Он:
- Гарантирует, что только один поток войдёт в критическую секцию кода.
- Блокирует объект (монитор), пока другой поток не освободит его.
Это предотвращает состояние гонки и обеспечивает корректную работу с общей памятью.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Расскажи про конкурентные коллекции?

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

🟠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
}


🟠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
}


🟠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
}


🟠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
}


🟠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}");
}


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Зачем используется библиотека Moq?

Это библиотека для создания имитаций (mock) объектов в тестах.
1. Она позволяет подменять зависимости тестируемого кода фейковыми реализациями.
2. Используется для тестирования изолированных частей приложения без вызова реальных ресурсов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2
🤔 Интерполяция - это возможность использовать в строке переменные?

Да, интерполяция строк — это удобный способ вставки значений переменных в строку без использования конкатенации (+) или String.Format().

Простой пример интерполяции строк
string name = "Иван";
int age = 25;

string message = $"Привет, меня зовут {name}, и мне {age} лет.";
Console.WriteLine(message);


Вывод
Привет, меня зовут Иван, и мне 25 лет.


🚩Дополнительные возможности интерполяции

🟠Форматирование значений
Можно форматировать числа и даты прямо в строке:
double price = 99.99;
DateTime today = DateTime.Now;

string formatted = $"Цена: {price:C}, Дата: {today:dd.MM.yyyy}";
Console.WriteLine(formatted);


Вывод
Цена: 99,99 ₽, Дата: 01.03.2025


🟠Выполнение выражений
Можно вставлять даже арифметические операции и вызовы методов:
int a = 10, b = 5;
string mathResult = $"Сумма: {a + b}, Разница: {a - b}";
Console.WriteLine(mathResult);


Вывод
Сумма: 15, Разница: 5


🟠Экранирование фигурных скобок
Если нужно вывести {} в тексте, их надо удваивать:
Console.WriteLine($"JSON: {{ \"name\": \"Иван\" }}");


Вывод
JSON: { "name": "Иван" }


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Можно ли вызвать асинхронный код синхронно?

Да, асинхронный код можно вызвать синхронно, но это не рекомендуется. Использование .Result или .GetAwaiter().GetResult() позволяет получить результат синхронно, однако это может привести к блокировкам, дедлокам и снижению производительности, особенно в UI-приложениях или в серверных окружениях с синхронным контекстом.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2🔥1
🤔 Какие принципы и практики используешь для обеспечения безопасности приложений?

🟠Валидация и Санитизация Входных Данных
Валидация входных данных помогает предотвратить атаки, такие как SQL-инъекции, XSS (межсайтовый скриптинг) и другие. SQL-инъекции: Используйте параметризованные запросы или ORM (например, Entity Framework).
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE Username = @username", conn))
{
cmd.Parameters.AddWithValue("@username", username);
// Выполнение команды
}


XSS: Используйте библиотеку для экранирования HTML, например, AntiXSS.
string safeContent = Microsoft.Security.Application.Encoder.HtmlEncode(userInput);


🟠Использование Аутентификации и Авторизации
Обеспечьте надежную аутентификацию и разграничение доступа к ресурсам.
Аутентификация: Используйте современные методы аутентификации, такие как OAuth, OpenID Connect.
Авторизация: Применяйте ролевую или заявочную (claims-based) авторизацию.
[Authorize(Roles = "Admin")]
public IActionResult AdminOnly()
{
return View();
}


🟠Защита от CSRF (Межсайтовая подделка запросов)
Используйте анти-CSRF токены для защиты от CSRF атак.
<form asp-action="Create">
<input type="hidden" name="__RequestVerificationToken" value="@Antiforgery.GetTokens(HttpContext).RequestToken" />
<!-- Другие поля формы -->
</form>


🟠Шифрование и Защита Данных
Шифруйте чувствительные данные как при передаче, так и при хранении.
При передаче: Используйте HTTPS для шифрования данных, передаваемых через сеть.
При хранении: Используйте библиотеки для шифрования, такие как System.Security.Cryptography.
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
// Шифрование данных
}


🟠Логирование и Мониторинг
Внедрите логирование и мониторинг для обнаружения и анализа подозрительной активности.
Логирование: Логируйте важные действия, такие как входы в систему, изменения данных.
Мониторинг: Используйте инструменты мониторинга, такие как Application Insights, для отслеживания состояния приложения.
_logger.LogInformation("User {UserId} logged in.", userId);


🟠Управление Ошибками и Исключениями
Не показывайте подробные сообщения об ошибках пользователям, чтобы не раскрывать внутреннюю структуру приложения.
Обработка исключений: Ловите и корректно обрабатывайте исключения, предоставляя пользователю дружелюбные сообщения.
try
{
// Код, который может вызвать исключение
}
catch (Exception ex)
{
_logger.LogError(ex, "Произошла ошибка.");
return View("Error");
}


🟠Обновления и Патчи
Регулярно обновляйте используемые библиотеки и фреймворки, чтобы закрывать уязвимости.

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

🟠Защита Конфигурации
Защитите конфигурационные файлы, содержащие чувствительную информацию.
Секреты и ключи: Используйте секреты и безопасное хранилище для конфиденциальной информации.
var connectionString = Configuration["ConnectionStrings:DefaultConnection"];


Ставь 👍 и забирай 📚 Базу знаний
👍1🔥1
🤔 Есть ли разница в какой последовательности писать catch-и?

Да, порядок catch-блоков имеет значение.
Блоки catch проверяются сверху вниз, и первый подходящий будет выполнен.
Если более общий catch (например, Exception) находится выше специфического (например, IOException), то последний никогда не выполнится, и компилятор выдаст ошибку.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3💊1
🤔 Если мы используем Ref & out, то становится ли эта структура ссылочным типом?

Нет, структура (struct) не становится ссылочным типом, даже если мы передаём её через ref или out. Однако, когда структура передаётся с ref или out, передаётся сама структура (по ссылке), а не её копия. Это позволяет изменять исходный объект напрямую, избегая копирования.

🚩Разница между обычной передачей и передачей через `ref`

Передача структуры без ref (по значению, копируется)
struct Point
{
public int X;
public int Y;
}

void ChangePoint(Point p)
{
p.X = 100;
}

Point myPoint = new Point { X = 10, Y = 20 };
ChangePoint(myPoint);

Console.WriteLine(myPoint.X); // 10 (НЕ изменилось, потому что была копия)


Передача структуры с ref (по ссылке, изменения сохраняются)
void ChangePointRef(ref Point p)
{
p.X = 100;
}

ChangePointRef(ref myPoint);

Console.WriteLine(myPoint.X); // 100 (значение изменилось)


🚩Что насчёт `out`?

out работает так же, как ref, но требует обязательной инициализации внутри метода.
void InitPoint(out Point p)
{
p = new Point { X = 50, Y = 50 }; // Обязательно присвоить значение
}

Point newPoint;
InitPoint(out newPoint);

Console.WriteLine(newPoint.X); // 50


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Что такое инкапсуляция?

Инкапсуляция в объектно-ориентированном программировании — это механизм упаковки данных (переменных) и кода, работающего с данными (методов), в один объект и ограничение доступа к некоторым компонентам объекта, что способствует безопасности и упрощению интерфейса.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥1
🤔 Что такое IEnumerable?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3
🤔 Что такое Dispose?

Dispose метод является частью паттерна управления ресурсами, известного как "Dispose Pattern". Этот метод реализуется в классах через интерфейс IDisposable. Цель — явное освобождение неуправляемых ресурсов и, по желанию, управляемых ресурсов, прежде чем сборщик мусора освободит объект. Это важно для эффективного управления памятью и другими системными ресурсами.

🚩Неуправляемые и управляемые ресурсы

🟠Неуправляемые ресурсы
включают в себя ресурсы, которые не управляются средой CLR (Common Language Runtime), например, файловые дескрипторы, сетевые соединения или указатели на память, выделенную вне .NET среды.
🟠Управляемые ресурсы
это объекты .NET, которые занимают память и потенциально удерживают ссылки на неуправляемые ресурсы.

🚩Как он работает

Должен освобождать все неуправляемые ресурсы, занимаемые объектом, а также должен иметь возможность освобождать управляемые ресурсы, если это необходимо. Как правило, управляемые ресурсы освобождаются сами сборщиком мусора, но если управляемый ресурс включает в себя неуправляемые ресурсы, тогда Dispose может быть вызван для их явного освобождения.
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);
}
}


Пример использования Dispose
using (var resource = new ResourceHolder())
{
// Использование ресурса
}
// Метод Dispose автоматически вызывается при выходе из блока using


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Что такое полиморфизм?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2🔥1
🤔 Что такое многопоточность и библиотека TPL?

Это способность приложения выполнять несколько операций одновременно с использованием потоков.
• TPL (Task Parallel Library) — библиотека в .NET для упрощения работы с асинхронным и параллельным программированием.
• Она предоставляет классы, такие как Task и Parallel, которые позволяют управлять потоками, синхронизацией и обработкой задач.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥1
🤔 Какие шаблоны проектирования используешь во front- и back-end?

Front-end:
- MVVM (Model-View-ViewModel) — используется во фреймворках вроде WPF, Angular.
- MVC (Model-View-Controller) — в JavaScript-приложениях (например, с Backbone).
- Observer — реактивные библиотеки (RxJS).
- Strategy — динамическое поведение компонентов.
- Factory — динамическое создание UI-компонентов.
Back-end (на .NET):
- Repository — изолирует работу с базой данных.
- Unit of Work — объединяет операции изменения данных в одну транзакцию.
- Dependency Injection — внедрение зависимостей (широко используется в
ASP.NET Core).
- Factory Method — для создания объектов с гибкой конфигурацией.
- Adapter/Decorator — обёртки над внешними API или логикой.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что бывает, когда количества подключений не хватает?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔2
🤔 Когда можно использовать using?

Ключевое слово using используется в двух основных контекстах: для управления областью видимости объектов, реализующих интерфейс IDisposable, и для включения пространств имён.

🟠Управление областью видимости объектов (IDisposable)
Можно использовать для создания блока кода, внутри которого объекты, реализующие интерфейс IDisposable, автоматически освобождаются по завершении блока. Это удобно для управления ресурсами, такими как файловые потоки, базы данных или другие ресурсы системы, которые требуют явного освобождения.
using (StreamWriter writer = new StreamWriter("example.txt"))
{
writer.WriteLine("Hello, world!");
}
// Здесь объект writer уже автоматически закрыт и освобожден.


🟠Включение пространств имён
Также используется для объявления пространств имен, которые будут использоваться в коде, позволяя обращаться к классам внутри этих пространств без полного указания их имён.
using System;
using System.IO;
using System.Text;

// Теперь можно использовать классы из System, System.IO и System.Text без полного указания имени.


🟠using для статических классов (C# 6.0 и выше)
Для включения статических классов, что позволяет обращаться к статическим членам класса напрямую без указания имени класса.
using static System.Console;
using static System.Math;

class Program
{
static void Main()
{
WriteLine(Sqrt(144)); // Использование метода WriteLine и Sqrt без указания классов Console и Math
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍3
🤔 Что такое reflection и для чего используется?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2🔥1
🤔 В чём разница между списком и массивом?

1. Список (List): динамическая структура данных, которая может менять размер. Поддерживает методы для работы с элементами (добавление, удаление).
2. Массив: фиксированная структура данных, размер задаётся при создании. Более эффективен в использовании памяти, но менее гибок.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Зачем нужны операторы?

Операторы в C# позволяют:
- Выполнять арифметические, логические и побитовые операции (+, -, &&, |, <<, ++).
- Сравнивать значения (==, !=, >, <).
- Управлять потоком исполнения (??, ?:, is, as, await).
- Создавать собственные операторы перегрузки (например, operator + для собственного класса).
Операторы — важная часть языка, они позволяют делать код лаконичным, выразительным и типобезопасным.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что такое ORM?

Это технология для работы с базами данных, преобразующая данные между объектами приложения и реляционной БД.
1. Упрощает выполнение CRUD-операций без написания SQL-запросов.
2. Примеры: Entity Framework, Hibernate, SQLAlchemy.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний