C# | Вопросы собесов
5.1K subscribers
34 photos
1 file
990 links
Download Telegram
🤔 Какие типы 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
🤔 Какие минусы есть у индексов с точки зрения оптимизации?

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

🟠Увеличение времени записи
Индексы замедляют операции вставки (INSERT), обновления (UPDATE) и удаления (DELETE), так как при каждом изменении данных необходимо также обновлять индексы.
Вставка: При вставке новой записи нужно обновить все соответствующие индексы.
Обновление: При обновлении записи могут изменяться индексируемые колонки, что требует обновления индексов.
Удаление: При удалении записи нужно удалить соответствующие записи из индексов.

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

🟠Замедление операций массовой загрузки данных
При массовой загрузке данных, например, при использовании операций LOAD DATA или BULK INSERT, наличие индексов замедляет процесс, так как индексы должны обновляться по мере добавления каждой записи.

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

🟠Сложность управления
Управление индексами требует дополнительного администрирования и мониторинга. Нужно следить за эффективностью индексов, удалять неиспользуемые индексы и создавать новые по мере изменения запросов и структуры данных.

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

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

🚩Пример ситуации

CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
DepartmentID INT,
Salary DECIMAL(10, 2)
);

CREATE INDEX idx_firstname ON Employees(FirstName);
CREATE INDEX idx_lastname ON Employees(LastName);
CREATE INDEX idx_department ON Employees(DepartmentID);


🚩Минусы

Вставка данных
INSERT INTO Employees (EmployeeID, FirstName, LastName, DepartmentID, Salary)
VALUES (1, 'John', 'Doe', 10, 60000.00);


Обновление данных
UPDATE Employees
SET Salary = Salary * 1.05
WHERE DepartmentID = 10;


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

Если член класса (метод, свойство, поле) имеет модификатор public, то:
- Он доступен отовсюду — из любого другого класса, файла, сборки или проекта.
- Это означает полное отсутствие ограничений на его использование.


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

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

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

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

🟠Отложенное выполнение (Deferred Execution)
Запросы IQueryable не выполняются, пока не будут перечислены. Это позволяет системе строить более сложные запросы перед их выполнением.

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

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

using (var context = new MyDbContext()) // MyDbContext — это контекст Entity Framework
{
IQueryable<Product> query = context.Products.Where(p => p.Price > 100);

// Запрос еще не выполнен, можно добавить другие условия
query = query.OrderBy(p => p.Name);

// Запрос выполняется только при перечислении
foreach (var product in query)
{
Console.WriteLine($"{product.Name}: {product.Price}");
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍1💊1