C# | Вопросы собесов
5.1K subscribers
35 photos
1 file
989 links
Download Telegram
🤔 Что такое cancellation token в многопоточности?

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

🚩Зачем нужен `CancellationToken`?

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

🚩Как работает `CancellationToken`?

🟠Создание `CancellationTokenSource`
Источник токена (CancellationTokenSource) управляет токеном (CancellationToken), который передаётся в задачи.

🟠Передача токена в выполняемую операцию
Код регулярно проверяет cancellationToken.IsCancellationRequested, чтобы определить, нужно ли остановиться.

🟠Запрос на отмену
Если вызывается cts.Cancel(), все методы, использующие этот токен, получают сигнал об отмене.

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

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static async Task Main()
{
using var cts = new CancellationTokenSource();

// Отменяем операцию через 3 секунды
cts.CancelAfter(3000);

try
{
await DoWorkAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Операция отменена!");
}
}

static async Task DoWorkAsync(CancellationToken cancellationToken)
{
for (int i = 0; i < 10; i++)
{
cancellationToken.ThrowIfCancellationRequested(); // Проверка отмены

Console.WriteLine($"Работаем... {i}");
await Task.Delay(1000, cancellationToken); // Ожидание с проверкой отмены
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
🤔 Что бывает, когда количества подключений не хватает?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
🤔 Что такое lock-еры?

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

🚩Как это работает?

Принимает в качестве параметра объект, который используется в качестве мьютекса (взаимоисключающего объекта). Во время выполнения блока кода внутри lock, текущий поток "захватывает" мьютекс. Если другой поток попытается войти в заблокированный участок кода, используя тот же мьютекс, он будет приостановлен до тех пор, пока первый поток не завершит выполнение блока lock и не освободит мьютекс.
public class Account
{
private decimal balance;
private readonly object balanceLock = new object();

public void Deposit(decimal amount)
{
lock (balanceLock)
{
balance += amount;
}
}

public void Withdraw(decimal amount)
{
lock (balanceLock)
{
if (balance >= amount)
{
balance -= amount;
}
}
}
}


🚩Зачем это нужно?

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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1🤔1
🤔 Какие типы HTTP-запросов бывают и где в них передаются данные?

1. GET: данные передаются в URL как параметры.
2. POST: данные передаются в теле запроса.
3. PUT и PATCH: обновляют данные, передавая их в теле запроса.
4. DELETE: удаляет ресурс, данные могут передаваться в URL или теле.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как браузер отправляет запрос и получает ответ от API?

Когда браузер отправляет запрос и получает ответ от API, это включает несколько шагов, которые следуют HTTP-протоколу. Этот процесс включает в себя создание и отправку HTTP-запроса, обработку на сервере и получение HTTP-ответа.

🚩Отправка запроса

🟠Инициация запроса
Обычно запрос инициируется через JavaScript с использованием встроенных функций, таких как XMLHttpRequest, fetch или сторонние библиотеки, такие как Axios.
   fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));


🟠Формирование HTTP-запроса
Метод: Указывает тип запроса (например, GET, POST, PUT, DELETE). URL: Указывает на какой URL отправляется запрос. Заголовки (Headers): Включают информацию о типе содержимого, авторизации и других метаданных. Тело (Body): Содержит данные, которые отправляются с запросом (для методов POST, PUT и PATCH).

🟠Отправка запроса
Браузер использует сетевые протоколы для отправки сформированного HTTP-запроса на указанный сервер через интернет.

🚩Обработка запроса на сервере

1⃣Получение запроса
Сервер получает HTTP-запрос.

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

3⃣Формирование ответа
Статус код (Status Code): Указывает результат обработки запроса (например, 200 OK, 404 Not Found, 500 Internal Server Error). Заголовки (Headers): Могут включать метаданные о содержимом ответа, кэшировании и других параметрах. Тело (Body): Содержит данные, которые отправляются обратно клиенту, часто в формате JSON или XML.
   HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 85

{
"id": 1,
"name": "Example",
"description": "This is an example response"
}


🚩Получение ответа

1⃣Получение ответа
Браузер получает HTTP-ответ от сервера.

2⃣Обработка ответа
Статус код: Браузер или JavaScript-код проверяет статус код, чтобы определить, был ли запрос успешным. Заголовки: Заголовки могут быть использованы для получения дополнительной информации о ответе. Тело: Браузер разбирает тело ответа, если это необходимо, например, преобразует JSON-данные в объект JavaScript.

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

🚩Пример полного цикла запроса и ответа

Отправка запроса
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
console.log('Data received:', data);
// Используем данные для обновления UI или других целей
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
🤔 В чём отличие реализации взаимодействия с БД через ORM и нативный SQL?

- ORM (Object-Relational Mapping):
- Автоматически связывает объекты и таблицы.
- Позволяет писать код на C#/Java вместо SQL.
- Повышает читаемость, уменьшает boilerplate.
- Меньше контроля над SQL.
- Нативный SQL:
- Полный контроль над запросами.
- Производительность выше в сложных сценариях.
- Требует ручной работы с соединениями, маппингом, транзакциями.
Выбор зависит от проекта: ORM — быстрее в разработке, SQL — гибче и мощнее при оптимизации.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊2
🤔 Какие тесты бывают?

🚩Виды

🟠Юнит-тесты
Предназначены для проверки отдельных компонентов или модулей приложения в изоляции. Они помогают убедиться, что отдельные функции или методы работают правильно.
Цель: Проверка логики отдельных методов или классов.
Инструменты: xUnit, NUnit, MSTest.
using Xunit;

public class CalculatorTests
{
[Fact]
public void Add_SimpleValues_ReturnsSum()
{
var calculator = new Calculator();
var result = calculator.Add(2, 3);
Assert.Equal(5, result);
}
}

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


🟠Интеграционные тесты
Проверяют взаимодействие между различными компонентами системы, убеждаясь, что они корректно работают вместе.
Цель: Проверка взаимодействия между модулями.
Инструменты: xUnit, NUnit, MSTest, плюс дополнительные библиотеки для тестирования баз данных или HTTP-запросов.
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

public class IntegrationTests
{
private readonly HttpClient _client;

public IntegrationTests()
{
var appFactory = new CustomWebApplicationFactory<Startup>();
_client = appFactory.CreateClient();
}

[Fact]
public async Task Get_EndpointReturnsSuccessAndCorrectContentType()
{
var response = await _client.GetAsync("/api/values");
response.EnsureSuccessStatusCode();
Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString());
}
}


🟠Функциональные тесты
Проверяют, что приложение выполняет свои функции в соответствии с требованиями. Эти тесты проверяют конкретные сценарии использования.
Цель: Проверка функциональности приложения на уровне пользователя.
Инструменты: Selenium, Playwright, Cypress.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Xunit;

public class UiTests
{
[Fact]
public void LoadPage_CheckTitle()
{
using (IWebDriver driver = new ChromeDriver())
{
driver.Navigate().GoToUrl("https://example.com");
Assert.Equal("Example Domain", driver.Title);
}
}
}


🟠Системные тесты
Проверяют приложение в целом, включая взаимодействие с внешними системами и проверку всех требований.
Цель: Проверка всей системы в интегрированном виде.
Инструменты: JUnit, TestNG для Java, или те же инструменты, что и для функциональных тестов.

🟠Приемочные тесты
Проводятся для проверки, что приложение соответствует требованиям и готово к использованию клиентом или конечным пользователем.
Цель: Подтверждение соответствия приложения требованиям.
Инструменты: Cucumber, SpecFlow (для BDD).

🟠Регрессионные тесты
Проверяют, что недавние изменения в коде не нарушили существующую функциональность.
Цель: Убедиться, что новые изменения не привели к новым багам.
Инструменты: Все инструменты для юнит-тестирования и функционального тестирования.

🟠Нагрузочные тесты
Проверяют, как приложение ведет себя под нагрузкой, например, при большом количестве одновременных пользователей или операций.
Цель: Оценка производительности и устойчивости приложения под нагрузкой.
Инструменты: JMeter, Gatling, Apache Bench.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какие различия между абстрактными и обычными методами?

- Абстрактный метод:
- Не имеет реализации.
- Должен быть переопределён в наследнике.
- Объявляется только внутри абстрактного класса.
- Обычный метод:
- Имеет реализацию.
- Может вызываться напрямую.
- Может быть переопределён или нет — по ситуации.
Абстрактный метод задаёт обязательную реализацию, а обычный — реальную логику.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое GVT?

Это аббревиатура, которая может иметь разные значения в зависимости от контекста. В программировании и IT чаще всего GVT используется в специфических областях.

🚩Global Virtual Time (Глобальное виртуальное время)

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

🟠Симуляторы дискретного времени
например, при моделировании сетей или физических систем.
🟠Алгоритмы для снятия состояния
Или управления памятью (garbage collection).

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

🚩Google Virtual Tables

В контексте баз данных и SQL, GVT может использоваться как обозначение для виртуальных таблиц, предоставляемых Google (например, в Google BigQuery).

Пример
Если вы работаете с Google BigQuery, виртуальные таблицы используются для создания временных представлений данных, которые могут быть обработаны SQL-запросами.

🚩Generic Virtualization Technology

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

🟠Серверы с виртуальными машинами
Которые требуют доступа к ускоренной графике.
🟠Облачные сервисы
Предоставляющие GPU как услугу.

Пример
Intel GVT-g — технология, которая позволяет нескольким виртуальным машинам совместно использовать один GPU, обеспечивая каждому виртуальному окружению необходимую производительность.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊7
🤔 Что такое String?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Какие типы данных можно использовать у Dictionary в качестве ключа?

В C# ключ (TKey) в Dictionary<TKey, TValue> должен быть уникальным и поддерживать сравнение.
Лучше всего использовать неизменяемые (immutable) типы, такие как:
Примитивные типы (int, string, char, bool, Guid, enum)
Кортежи (Tuple, ValueTuple)
Неизменяемые структуры (struct, если переопределён Equals и GetHashCode)

🚩Какие типы подходят в качестве ключа?

Числовые типы (int, double, long)
var dict = new Dictionary<int, string>
{
{1, "Один"},
{2, "Два"}
};
Console.WriteLine(dict[1]); // Вывод: Один


string (лучший выбор)
var dict = new Dictionary<string, int>
{
{"apple", 10},
{"banana", 5}
};
Console.WriteLine(dict["apple"]); // 10


Guid (уникальные идентификаторы)
var dict = new Dictionary<Guid, string>
{
{Guid.NewGuid(), "User1"},
{Guid.NewGuid(), "User2"}
};


enum (хороший вариант)
enum Status { New, Processing, Completed }

var dict = new Dictionary<Status, string>
{
{Status.New, "Заказ создан"},
{Status.Processing, "Заказ в обработке"}
};


Можно использовать несколько значений в качестве ключа:
var dict = new Dictionary<(int, string), string>
{
{(1, "apple"), "Красное яблоко"},
{(2, "banana"), "Жёлтый банан"}
};
Console.WriteLine(dict[(1, "apple")]); // Красное яблоко


🚩Какие типы нельзя использовать в качестве ключа?

List<T> (и другие изменяемые коллекции)
var dict = new Dictionary<List<int>, string>(); // Ошибка при использовании в качестве ключа!


class, если не переопределён Equals и GetHashCode
class Person { public string Name; }
var dict = new Dictionary<Person, string>(); // Плохо!


Нужно переопределить Equals и GetHashCode
class Person
{
public string Name { get; }

public Person(string name) => Name = name;

public override bool Equals(object? obj)
{
return obj is Person other && Name == other.Name;
}

public override int GetHashCode() => Name.GetHashCode();
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Что такое asp.net?

ASP.NET — это фреймворк для веб-разработки, предоставляемый Microsoft, который позволяет разработчикам строить динамичные веб-сайты, веб-приложения и веб-сервисы. Он основан на .NET Framework и поддерживает языки программирования, такие как C#, VB.NET и другие. ASP.NET отличается от простого HTML тем, что сервер выполняет код и отправляет результаты клиенту, позволяя создавать интерактивные и динамически обновляемые веб-страницы.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какие есть модификаторы доступа?

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

🚩Подробное объяснение с примерами

🟠`public` (Открытый доступ)
Открытый доступ означает, что элемент можно использовать везде.
public class Car
{
public string Model = "Tesla";
}

class Program
{
static void Main()
{
Car car = new Car();
Console.WriteLine(car.Model); // Доступ открыт
}
}


🟠`private` (Только внутри класса)
Самый закрытый модификатор. Поля и методы невидимы за пределами класса.
class Car
{
private string model = "Tesla";

private void PrintModel()
{
Console.WriteLine(model);
}
}

class Program
{
static void Main()
{
Car car = new Car();
// car.model = "BMW"; Ошибка! Поле `model` — private
// car.PrintModel(); Ошибка! Метод `PrintModel` — private
}
}


🟠`protected` (Доступен в наследниках)
Доступен только внутри класса и его наследников.
class Car
{
protected string Model = "Tesla";
}

class ElectricCar : Car
{
public void ShowModel()
{
Console.WriteLine(Model); // Можно, потому что наследуемый класс
}
}

class Program
{
static void Main()
{
ElectricCar eCar = new ElectricCar();
// eCar.Model Ошибка! Поле `Model` доступно только в наследниках
}
}


🟠`internal` (Только внутри проекта)
Элементы с internal можно использовать только внутри одной сборки (проекта).
internal class Engine
{
public void Start() => Console.WriteLine("Двигатель запущен");
}

class Program
{
static void Main()
{
Engine engine = new Engine();
engine.Start(); // Работает, потому что внутри того же проекта
}
}


🟠`protected internal` (В сборке и у наследников)
Этот модификатор разрешает доступ внутри сборки, а также в классах-наследниках за её пределами.
public class Car
{
protected internal string Model = "Tesla";
}

class ElectricCar : Car
{
public void ShowModel()
{
Console.WriteLine(Model); // Можно, потому что наследник
}
}


🟠`private protected` (Только в классе и наследниках из той же сборки)
Этот модификатор ещё жёстче, чем protected internal:
- Доступ внутри класса – да
- В наследниках – только внутри той же сборки
- В других проектах – нет доступа!
class Car
{
private protected string Model = "Tesla";
}

class ElectricCar : Car
{
public void ShowModel()
{
Console.WriteLine(Model); // Можно, потому что наследник в той же сборке
}
}

class Program
{
static void Main()
{
ElectricCar eCar = new ElectricCar();
// eCar.Model Ошибка! `Model` доступен только в наследниках из этой сборки
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1
🤔 Для чего нужен интерфейс IDisposable?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какие проблемы могут быть при многопоточности и как их избежать?

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

🚩Основные проблемы

🟠Гонки данных (Race Conditions)
Проблема: Два или более потоков пытаются одновременно изменить общие данные или один поток читает данные во время их изменения другим потоком, что приводит к непредсказуемым результатам.
Решение: Использование механизмов синхронизации, таких как блокировки (locks), мьютексы (mutexes) и семафоры (semaphores), для контроля доступа к общим ресурсам.

🟠Взаимная блокировка (Deadlock)
Проблема: Два или более потоков бесконечно ожидают ресурсы, заблокированные друг другом, в результате чего они не могут продолжить выполнение.
Решение: Разработка программы таким образом, чтобы потоки запрашивали ресурсы всегда в одном и том же порядке, использование таймаутов для блокировок, чтобы потоки могли выйти из состояния ожидания.

🟠Голодание (Starvation)
Проблема: Один или несколько потоков не могут получить доступ к необходимым ресурсам, потому что другие потоки постоянно занимают их.
Решение: Применение справедливых блокировок (fair locks) или алгоритмов планирования, которые обеспечивают всем потокам равный доступ к ресурсам.

🟠Переключение контекста (Context Switching)
Проблема: Частое переключение контекста между потоками может значительно снизить производительность системы, особенно если потоки часто блокируются и разблокируются.
Решение: Оптимизация количества потоков, уменьшение зависимостей между потоками и уменьшение использования блокировок.

🟠Проблемы с проектированием
Проблема: Неправильное проектирование многопоточной архитектуры может привести к сложностям в поддержке и расширении программного обеспечения.
Решение: Использование абстракций высокого уровня для работы с потоками, таких как пулы потоков, параллельные библиотеки (например, TPL в .NET) и модели акторов.

private static readonly object _lock = new object();
private static int _sharedResource;

public static void UpdateResource()
{
lock (_lock)
{
_sharedResource++;
// Выполнение некоторой работы с общим ресурсом
}
}


Избегание взаимной блокировки
private static readonly object _lock1

= new object();
private static readonly object _lock2 = new object();

public static void Method1()
{
lock (_lock1)
{
// Некоторые действия
lock (_lock2)
{
// Дополнительные действия
}
}
}

public static void Method2()
{
lock (_lock1)
{
// Аналогичные действия
lock (_lock2)
{
// Дополнительные действия
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Как происходит запрос интерфейса?

Когда компоненту нужен другой класс (зависимость), он объявляет интерфейс в своём конструкторе, а контейнер DI:
- Ищет зарегистрированную реализацию этого интерфейса.
- Создаёт экземпляр и передаёт его в зависимый класс.
Такой механизм называется инъекция через конструктор, и он наиболее распространён.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5💊1
🤔 Что такое hashset?

HashSet<T> — это коллекция уникальных элементов, которая обеспечивает быстрый поиск, добавление и удаление. В основе HashSet<T> лежит хеш-таблица, что делает операции очень быстрыми (почти за O(1) в среднем случае).

🚩Создание и использование `HashSet<T>`

Простой пример
HashSet<int> numbers = new HashSet<int> { 1, 2, 3, 4, 5 };

// Добавление элементов (дубликаты не добавляются)
numbers.Add(3); // Уже есть в HashSet, не добавится
numbers.Add(6); // Добавится

// Вывод всех элементов
foreach (int num in numbers)
{
Console.Write(num + " ");
}


Вывод
1 2 3 4 5 6


🚩Основные операции

Пример работы с Contains и Remove
if (numbers.Contains(3))
{
numbers.Remove(3);
}

Console.WriteLine(string.Join(", ", numbers));


Вывод
1, 2, 4, 5, 6


🚩Операции над множествами

HashSet<T> поддерживает математические операции над множествами, такие как пересечение, объединение и разность.

Пересечение (IntersectWith)
HashSet<int> set1 = new HashSet<int> { 1, 2, 3, 4 };
HashSet<int> set2 = new HashSet<int> { 3, 4, 5, 6 };

set1.IntersectWith(set2); // Оставит только {3, 4}
Console.WriteLine(string.Join(", ", set1));


Вывод
3, 4


Объединение (UnionWith)
set1 = new HashSet<int> { 1, 2, 3 };
set2 = new HashSet<int> { 3, 4, 5 };

set1.UnionWith(set2); // set1 = {1, 2, 3, 4, 5}
Console.WriteLine(string.Join(", ", set1));


Вывод
1, 2, 3, 4, 5


Разность (ExceptWith)
set1 = new HashSet<int> { 1, 2, 3, 4, 5 };
set2 = new HashSet<int> { 3, 4 };

set1.ExceptWith(set2); // Удалит {3, 4}, останется {1, 2, 5}
Console.WriteLine(string.Join(", ", set1));


Вывод
1, 2, 5


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 В чём разница между string и StringBuilder?

`string` в C# — это неизменяемый тип данных, что означает, что каждое изменение строки создаёт новый объект в памяти. `StringBuilder` — это изменяемый тип, который позволяет эффективно манипулировать строками без создания новых объектов, что улучшает производительность при частых изменениях строк. `StringBuilder` предпочтительнее использовать для конкатенации строк в циклах или при выполнении множества операций со строками. `string` лучше подходит для случаев, когда строка не меняется.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
🤔 Как сделать связь один к одному?

В реляционных базах данных связь "один к одному" (one-to-one) подразумевает, что каждая запись в одной таблице соответствует ровно одной записи в другой таблице. Для реализации связи "один к одному" в SQL можно использовать несколько подходов, в зависимости от требований и архитектуры базы данных.

🚩Основные подходы

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

🚩Уникальные внешние ключи

Таблицы
Users (пользователи)
UserId (Primary Key)
UserName
Profiles (профили)
ProfileId (Primary Key)
UserId (Foreign Key, Unique)
ProfileData
Создание таблиц
CREATE TABLE Users (
UserId INT PRIMARY KEY,
UserName VARCHAR(100)
);

CREATE TABLE Profiles (
ProfileId INT PRIMARY KEY,
UserId INT UNIQUE,
ProfileData VARCHAR(255),
FOREIGN KEY (UserId) REFERENCES Users(UserId)
);


Вставка данных
INSERT INTO Users (UserId, UserName) VALUES (1, 'John Doe');
INSERT INTO Profiles (ProfileId, UserId, ProfileData) VALUES (1, 1, 'Profile data for John Doe');


Запрос данных
SELECT Users.UserName, Profiles.ProfileData
FROM Users
JOIN Profiles ON Users.UserId = Profiles.UserId;


🚩Одинаковые первичные ключи

Таблицы
Users (пользователи)
UserId (Primary Key)
UserName
Profiles (профили)
UserId (Primary Key, Foreign Key)
ProfileData
Создание таблиц
CREATE TABLE Users (
UserId INT PRIMARY KEY,
UserName VARCHAR(100)
);

CREATE TABLE Profiles (
UserId INT PRIMARY KEY,
ProfileData VARCHAR(255),
FOREIGN KEY (UserId) REFERENCES Users(UserId)
);


Вставка данных
INSERT INTO Users (UserId, UserName) VALUES (1, 'John Doe');
INSERT INTO Profiles (UserId, ProfileData) VALUES (1, 'Profile data for John Doe');


Запрос данных
SELECT Users.UserName, Profiles.ProfileData
FROM Users
JOIN Profiles ON Users.UserId = Profiles.UserId;


🚩Плюсы и минусы

🟠Уникальные внешние ключи
Четкая семантика внешнего ключа.
Легкость добавления дополнительных данных в связанную таблицу.
Необходимо следить за уникальностью внешнего ключа.

🟠Одинаковые первичные ключи
Единый идентификатор для связанных данных.
Простота конструкции при обеспечении связи.
Необходимость синхронизации идентификаторов в обеих таблицах.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Абстракция более высокого уровня — это Task или Thread?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7