🤔 В чём разница между string и StringBuilder?
`string` в C# — это неизменяемый тип данных, что означает, что каждое изменение строки создаёт новый объект в памяти. `StringBuilder` — это изменяемый тип, который позволяет эффективно манипулировать строками без создания новых объектов, что улучшает производительность при частых изменениях строк. `StringBuilder` предпочтительнее использовать для конкатенации строк в циклах или при выполнении множества операций со строками. `string` лучше подходит для случаев, когда строка не меняется.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 Что такое IEnumerable?
IEnumerable — это интерфейс в базовой библиотеке классов .NET Framework, который определяет один метод:
🚩Зачем он нужен?
Используется для создания универсального метода перебора данных, не зависящего от типа коллекции. Это означает, что любой тип данных, который реализует
🚩Как он используется?
Когда вы реализуете интерфейс
Ставь 👍 и забирай 📚 Базу знаний
IEnumerable — это интерфейс в базовой библиотеке классов .NET Framework, который определяет один метод:
GetEnumerator(). Этот метод возвращает объект IEnumerator, который позволяет перебирать элементы коллекции (например, массива или списка) один за другим.🚩Зачем он нужен?
Используется для создания универсального метода перебора данных, не зависящего от типа коллекции. Это означает, что любой тип данных, который реализует
IEnumerable, можно перебирать с помощью цикла foreach в C#. Это упрощает работу с различными структурами данных, предоставляя единый механизм для итерации элементов.🚩Как он используется?
Когда вы реализуете интерфейс
IEnumerable в своём классе, вы обязуете этот класс предоставлять метод GetEnumerator(), который возвращает IEnumerator. IEnumerator, в свою очередь, имеет методы для перехода к следующему элементу (MoveNext) и для получения текущего элемента (Current), а также метод Reset(), который возвращает перечислитель в начальное состояние.using System;
using System.Collections;
public class DaysOfWeek : IEnumerable
{
private string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
public IEnumerator GetEnumerator()
{
for (int index = 0; index < days.Length; index++)
{
// Yield each day of the week.
yield return days[index];
}
}
}
public class Program
{
public static void Main()
{
DaysOfWeek daysOfWeek = new DaysOfWeek();
foreach (string day in daysOfWeek)
{
Console.WriteLine(day);
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Как предложить избежать deadlock'а?
1. Установить порядок захвата ресурсов и всегда придерживаться его.
2. Использовать таймауты при попытке захвата блокировок.
3. Применять неблокирующие конструкции (lock-free) или библиотеки с конкурентными коллекциями.
4. Минимизировать время удержания блокировок.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
2. Использовать таймауты при попытке захвата блокировок.
3. Применять неблокирующие конструкции (lock-free) или библиотеки с конкурентными коллекциями.
4. Минимизировать время удержания блокировок.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3💊1
🤔 Приведи пример паттерна строитель в С#
Паттерн "Строитель" (Builder) используется для пошагового создания сложных объектов. Он удобен, когда объект имеет много параметров и возможных конфигураций.
🚩Проблема без паттерна "Строитель"
Допустим, у нас есть класс
Создавать объект через конструкторы или инициализаторы становится неудобно, если у нас много параметров:
🚩Решение с использованием паттерна "Строитель"
Сделаем пошаговый процесс сборки объекта с помощью паттерна "Строитель".
Шаг 1: Создаём интерфейс строителя
Шаг 2: Реализуем конкретного строителя
Шаг 3: Используем строителя
Вывод в консоли
Ставь 👍 и забирай 📚 Базу знаний
Паттерн "Строитель" (Builder) используется для пошагового создания сложных объектов. Он удобен, когда объект имеет много параметров и возможных конфигураций.
🚩Проблема без паттерна "Строитель"
Допустим, у нас есть класс
Car, и мы хотим создавать машины с разными конфигурациями:public class Car
{
public string Engine { get; set; }
public int Wheels { get; set; }
public bool HasSunroof { get; set; }
public override string ToString()
{
return $"Car: Engine={Engine}, Wheels={Wheels}, Sunroof={HasSunroof}";
}
}
Создавать объект через конструкторы или инициализаторы становится неудобно, если у нас много параметров:
var car1 = new Car { Engine = "V8", Wheels = 4, HasSunroof = true };
var car2 = new Car { Engine = "V6", Wheels = 4, HasSunroof = false };🚩Решение с использованием паттерна "Строитель"
Сделаем пошаговый процесс сборки объекта с помощью паттерна "Строитель".
Шаг 1: Создаём интерфейс строителя
public interface ICarBuilder
{
ICarBuilder SetEngine(string engine);
ICarBuilder SetWheels(int wheels);
ICarBuilder SetSunroof(bool hasSunroof);
Car Build();
}
Шаг 2: Реализуем конкретного строителя
public class CarBuilder : ICarBuilder
{
private Car _car = new Car(); // Временный объект
public ICarBuilder SetEngine(string engine)
{
_car.Engine = engine;
return this; // Возвращаем самого себя для цепочки вызовов
}
public ICarBuilder SetWheels(int wheels)
{
_car.Wheels = wheels;
return this;
}
public ICarBuilder SetSunroof(bool hasSunroof)
{
_car.HasSunroof = hasSunroof;
return this;
}
public Car Build()
{
return _car; // Возвращаем готовый объект
}
}
Шаг 3: Используем строителя
class Program
{
static void Main()
{
ICarBuilder builder = new CarBuilder();
Car sportsCar = builder
.SetEngine("V8")
.SetWheels(4)
.SetSunroof(true)
.Build();
Car economyCar = builder
.SetEngine("V4")
.SetWheels(4)
.SetSunroof(false)
.Build();
Console.WriteLine(sportsCar);
Console.WriteLine(economyCar);
}
}
Вывод в консоли
Car: Engine=V8, Wheels=4, Sunroof=True
Car: Engine=V4, Wheels=4, Sunroof=False
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое паттерн разработки — Строитель (Builder)?
Строитель применяется, когда нужно пошагово создать сложный объект, избегая громоздкого конструктора с множеством параметров.
Он позволяет:
- Создавать разные представления одного и того же объекта.
- Разделить конструирование от представления.
- Собирать объект поэтапно и настраиваемо.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Строитель применяется, когда нужно пошагово создать сложный объект, избегая громоздкого конструктора с множеством параметров.
Он позволяет:
- Создавать разные представления одного и того же объекта.
- Разделить конструирование от представления.
- Собирать объект поэтапно и настраиваемо.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Как работает threadpool?
ThreadPool (пул потоков) — это механизм управления потоками в .NET, который позволяет повторно использовать созданные потоки для выполнения задач, уменьшая накладные расходы на их создание и уничтожение.
🚩Зачем нужен ThreadPool?
🟠Создание потоков — дорогостоящая операция
Каждый раз создавать новый поток — медленно и неэффективно.
🟠Пул потоков позволяет повторно использовать уже созданные потоки
вместо их постоянного создания и удаления.
🟠Автоматическое управление количеством потоков
в зависимости от нагрузки.
🟠Идеально подходит для небольших, кратковременных задач
Обработки HTTP-запросов
Выполнения задач в фоне
Асинхронного выполнения операций
🚩Как работает ThreadPool?
🟠Когда вы отправляете задачу в ThreadPool
он берет поток из пула и выполняет задачу.
🟠Если в пуле нет свободных потоков
создается новый (но их количество ограничено).
🟠Когда задача выполнена, поток не уничтожается
а возвращается в пул и может быть использован снова.
🟠ThreadPool сам регулирует количество потоков
в зависимости от загрузки системы.
🚩Пример использования ThreadPool
🚩Максимальное и минимальное количество потоков
ThreadPool управляет количеством потоков сам, но их можно настраивать
Ставь 👍 и забирай 📚 Базу знаний
ThreadPool (пул потоков) — это механизм управления потоками в .NET, который позволяет повторно использовать созданные потоки для выполнения задач, уменьшая накладные расходы на их создание и уничтожение.
🚩Зачем нужен ThreadPool?
🟠Создание потоков — дорогостоящая операция
Каждый раз создавать новый поток — медленно и неэффективно.
🟠Пул потоков позволяет повторно использовать уже созданные потоки
вместо их постоянного создания и удаления.
🟠Автоматическое управление количеством потоков
в зависимости от нагрузки.
🟠Идеально подходит для небольших, кратковременных задач
Обработки HTTP-запросов
Выполнения задач в фоне
Асинхронного выполнения операций
🚩Как работает ThreadPool?
🟠Когда вы отправляете задачу в ThreadPool
он берет поток из пула и выполняет задачу.
🟠Если в пуле нет свободных потоков
создается новый (но их количество ограничено).
🟠Когда задача выполнена, поток не уничтожается
а возвращается в пул и может быть использован снова.
🟠ThreadPool сам регулирует количество потоков
в зависимости от загрузки системы.
🚩Пример использования ThreadPool
using System;
using System.Threading;
class Program
{
static void Main()
{
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(DoWork, i);
}
Console.ReadLine(); // Ждём завершения потоков
}
static void DoWork(object? state)
{
Console.WriteLine($"Задача {state} выполняется в потоке {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(1000); // Симуляция работы
Console.WriteLine($"Задача {state} завершена");
}
}
🚩Максимальное и минимальное количество потоков
ThreadPool управляет количеством потоков сам, но их можно настраивать
int minWorker, minIOC;
ThreadPool.GetMinThreads(out minWorker, out minIOC);
Console.WriteLine($"Мин. количество потоков: {minWorker}");
ThreadPool.SetMinThreads(4, 4); // Устанавливаем минимум потоков
int maxWorker, maxIOC;
ThreadPool.GetMaxThreads(out maxWorker, out maxIOC);
Console.WriteLine($"Макс. количество потоков: {maxWorker}");
Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Что такое метод расширения?
Это статический метод, который добавляет новую функциональность к существующим классам без их изменения. Это позволяет улучшить читаемость и повторное использование кода.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Это статический метод, который добавляет новую функциональность к существующим классам без их изменения. Это позволяет улучшить читаемость и повторное использование кода.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Какие минусы есть у индексов с точки зрения оптимизации?
Индексы в базах данных, таких как SQL Server, MySQL или PostgreSQL, существенно улучшают производительность запросов, особенно для операций поиска, сортировки и фильтрации. Однако у индексов есть и минусы, которые могут негативно сказаться на производительности и других аспектах работы базы данных.
🟠Увеличение времени записи
Индексы замедляют операции вставки (
Вставка: При вставке новой записи нужно обновить все соответствующие индексы.
Обновление: При обновлении записи могут изменяться индексируемые колонки, что требует обновления индексов.
Удаление: При удалении записи нужно удалить соответствующие записи из индексов.
🟠Дополнительное использование памяти и дискового пространства
Индексы занимают дополнительное пространство на диске и в оперативной памяти. Чем больше индексов на таблице, тем больше требуется места для их хранения.
Дисковое пространство: Каждому индексу требуется место на диске для хранения его данных.
Память: Индексы занимают память при их использовании, особенно в случае часто запрашиваемых индексов, которые кэшируются в оперативной памяти.
🟠Замедление операций массовой загрузки данных
При массовой загрузке данных, например, при использовании операций
🟠Проблемы с фрагментацией
Индексы могут фрагментироваться, особенно если в таблице часто выполняются операции вставки, обновления и удаления. Фрагментация индексов приводит к ухудшению производительности запросов.
Фрагментация: При частых изменениях данных индексы могут становиться фрагментированными, что увеличивает время доступа к данным.
Реорганизация: Периодически индексы нужно реорганизовывать или перестраивать, что требует дополнительных ресурсов и времени.
🟠Сложность управления
Управление индексами требует дополнительного администрирования и мониторинга. Нужно следить за эффективностью индексов, удалять неиспользуемые индексы и создавать новые по мере изменения запросов и структуры данных.
🟠Перекрестные индексы
Наличие нескольких индексов на одной таблице может привести к конфликтам при планировании запросов. Оптимизатор запросов может выбирать менее эффективные индексы, что ухудшает производительность.
🟠Влияние на производительность при ошибках в проектировании
Плохо спроектированные индексы могут негативно повлиять на производительность запросов. Например, индексы на часто изменяемых колонках или слишком большое количество индексов могут привести к значительным издержкам при обновлении данных.
🚩Пример ситуации
🚩Минусы
➖Вставка данных
➖Обновление данных
Ставь 👍 и забирай 📚 Базу знаний
Индексы в базах данных, таких как 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;
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое DI (инъекция зависимости)?
Это способ передачи зависимостей в объект вместо их создания внутри объекта.
1. Позволяет строить слабо связанный код и облегчает тестирование.
2. Реализуется через конструкторы, свойства или методы.
3. Используется для улучшения гибкости и модульности приложений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. Позволяет строить слабо связанный код и облегчает тестирование.
2. Реализуется через конструкторы, свойства или методы.
3. Используется для улучшения гибкости и модульности приложений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Какие есть модификаторы доступа?
Есть модификаторы доступа, которые определяют, кто может использовать классы, методы и переменные. Они помогают скрыть внутренние детали кода и контролировать доступ к данным.
🚩Подробное объяснение с примерами
🟠`public` (Открытый доступ)
Открытый доступ означает, что элемент можно использовать везде.
🟠`private` (Только внутри класса)
Самый закрытый модификатор. Поля и методы невидимы за пределами класса.
🟠`protected` (Доступен в наследниках)
Доступен только внутри класса и его наследников.
🟠`internal` (Только внутри проекта)
Элементы с
🟠`protected internal` (В сборке и у наследников)
Этот модификатор разрешает доступ внутри сборки, а также в классах-наследниках за её пределами.
🟠`private protected` (Только в классе и наследниках из той же сборки)
Этот модификатор ещё жёстче, чем
- Доступ внутри класса – да
- В наследниках – только внутри той же сборки
- В других проектах – нет доступа!
Ставь 👍 и забирай 📚 Базу знаний
Есть модификаторы доступа, которые определяют, кто может использовать классы, методы и переменные. Они помогают скрыть внутренние детали кода и контролировать доступ к данным.
🚩Подробное объяснение с примерами
🟠`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` доступен только в наследниках из этой сборки
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Когда можно использовать using?
using используется для управления объектами, реализующими интерфейс IDisposable, чтобы гарантировать освобождение ресурсов. Это удобно для работы с файлами, потоками, базами данных и другими ресурсами, требующими явного закрытия. Код внутри блока using автоматически вызывает метод Dispose для объекта, даже если возникло исключение.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Какие объекты живут в нулевом поколении?
В C# и .NET память управляется сборщиком мусора (Garbage Collector, GC), который делит объекты на три поколения
🟠Generation 0 (Gen 0, нулевое поколение)
самые "молодые" объекты.
🟠Generation 1 (Gen 1, первое поколение)
промежуточные объекты.
🟠Generation 2 (Gen 2, второе поколение)
"долгоживущие" объекты.
🚩Какие объекты попадают в Generation 0?
В Gen 0 живут "короткоживущие" объекты которые создаются и быстро уничтожаются.
Это новые объекты, которые только что были выделены в управляемой куче (Heap).
Обычно это локальные переменные внутри методов, если они не выходят за их пределы.
Пример объектов в Gen 0
🚩Когда объекты остаются в Gen 0, а когда переходят в следующее поколение?
Если объект быстро умирает → удаляется из Gen 0 при первой же очистке.
Если объект выжил после первой очистки GC → переходит в Gen 1.
Если объект живёт долго → может попасть в Gen 2.
Ставь 👍 и забирай 📚 Базу знаний
В C# и .NET память управляется сборщиком мусора (Garbage Collector, GC), который делит объекты на три поколения
🟠Generation 0 (Gen 0, нулевое поколение)
самые "молодые" объекты.
🟠Generation 1 (Gen 1, первое поколение)
промежуточные объекты.
🟠Generation 2 (Gen 2, второе поколение)
"долгоживущие" объекты.
🚩Какие объекты попадают в Generation 0?
В Gen 0 живут "короткоживущие" объекты которые создаются и быстро уничтожаются.
Это новые объекты, которые только что были выделены в управляемой куче (Heap).
Обычно это локальные переменные внутри методов, если они не выходят за их пределы.
Пример объектов в Gen 0
class Program
{
static void Main()
{
for (int i = 0; i < 5; i++)
{
var obj = new object(); // Этот объект создаётся в Gen 0
}
GC.Collect(); // Принудительный запуск GC для проверки
}
}
🚩Когда объекты остаются в Gen 0, а когда переходят в следующее поколение?
Если объект быстро умирает → удаляется из Gen 0 при первой же очистке.
Если объект выжил после первой очистки GC → переходит в Gen 1.
Если объект живёт долго → может попасть в Gen 2.
Ставь 👍 и забирай 📚 Базу знаний
🤔 Какие типы шаблонов проектирования есть?
C# поддерживает все классические шаблоны проектирования (по GoF), включая:
- Порождающие: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
- Структурные: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
- Поведенческие: Strategy, Observer, Command, State, Visitor, Mediator, Chain of Responsibility, Memento, Interpreter, Iterator, Template Method.
А также часто используются:
- Dependency Injection
- Repository
- Unit of Work
- MVVM (в WPF) и MVC (в ASP.NET )
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Порождающие: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
- Структурные: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
- Поведенческие: Strategy, Observer, Command, State, Visitor, Mediator, Chain of Responsibility, Memento, Interpreter, Iterator, Template Method.
А также часто используются:
- Dependency Injection
- Repository
- Unit of Work
- MVVM (в WPF) и MVC (в
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍4🔥1
🤔 Что такое value-type?
Value Type (тип значения) – это тип данных, который хранит своё значение непосредственно в памяти (обычно в стеке), а не ссылку на объект в куче (heap), как это делает ссылочный тип (Reference Type).
🚩Какие типы данных являются Value Type?
Простые типы (
Структуры (
Перечисления (
Nullable-значения (
🚩Пример Value Type
🚩Где хранятся Value Type?
Value Type обычно хранятся в стеке (stack) – это быстрая область памяти.
Если структура (
🚩Когда использовать Value Type?
Если данные небольшие и часто изменяются –
Если объект недолговечный и не требует сложного поведения
Если производительность важна – Value Type быстрее из-за работы в стеке
Ставь 👍 и забирай 📚 Базу знаний
Value Type (тип значения) – это тип данных, который хранит своё значение непосредственно в памяти (обычно в стеке), а не ссылку на объект в куче (heap), как это делает ссылочный тип (Reference Type).
🚩Какие типы данных являются Value Type?
Простые типы (
int, double, bool, char, byte, float, decimal, etc.) Структуры (
struct) Перечисления (
enum) Nullable-значения (
int?, double?) 🚩Пример Value Type
int a = 10;
int b = a; // Значение копируется
b = 20;
Console.WriteLine(a); // 10 (остался неизменным)
Console.WriteLine(b); // 20
🚩Где хранятся Value Type?
Value Type обычно хранятся в стеке (stack) – это быстрая область памяти.
Если структура (
struct) является частью объекта (который хранится в куче), то её значение хранится внутри объекта в куче. struct Point
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
Point p1 = new Point { X = 5, Y = 10 };
Point p2 = p1; // Копирование структуры (создаётся новый экземпляр)
p2.X = 20;
Console.WriteLine(p1.X); // 5 (остался неизменным)
Console.WriteLine(p2.X); // 20
}
}
🚩Когда использовать Value Type?
Если данные небольшие и часто изменяются –
struct Если объект недолговечный и не требует сложного поведения
Если производительность важна – Value Type быстрее из-за работы в стеке
Ставь 👍 и забирай 📚 Базу знаний
💊1
🤔 Для чего используют асинхронность?
Асинхронность позволяет выполнять операции без блокировки основного потока, что особенно важно для долгих операций, таких как сетевые запросы или чтение/запись данных.
1. Улучшает отзывчивость пользовательского интерфейса.
2. Повышает производительность за счёт параллельного выполнения задач.
3. Экономит системные ресурсы, избегая создания лишних потоков.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. Улучшает отзывчивость пользовательского интерфейса.
2. Повышает производительность за счёт параллельного выполнения задач.
3. Экономит системные ресурсы, избегая создания лишних потоков.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3
🤔 Что такое .NET стандарт?
.NET Standard — это спецификация API, которая определяет набор базовых библиотек, доступных во всех реализациях .NET (например, .NET Framework, .NET Core, Xamarin, Unity и других). Она была создана для обеспечения совместимости между разными платформами .NET.
🚩Зачем нужен .NET Standard?
До появления .NET Standard существовало несколько отдельных реализаций .NET:
.NET Framework (для Windows-приложений)
.NET Core (кроссплатформенная версия .NET)
Mono/Xamarin (для мобильных и игровых приложений)
Каждая из них имела свои особенности и набор доступных API. Из-за этого разработчики, создавая библиотеку, сталкивались с проблемой совместимости: приходилось писать несколько версий кода под разные платформы или использовать Portable Class Library (PCL), которая имела ограниченный функционал.
.NET Standard решил эту проблему, введя единый набор API, который обязаны поддерживать все реализации .NET.
🚩Как это работает?
.NET Standard представляет собой абстрактную спецификацию API, которая реализуется разными версиями .NET. Например, .NET Standard 2.0 поддерживается в .NET Framework 4.6.1, .NET Core 2.0 и выше. Если библиотека написана под .NET Standard 2.0, её можно использовать во всех этих средах.
🚩Версии .NET Standard
Существуют разные версии .NET Standard, каждая из которых включает больше API, чем предыдущая. Чем выше версия, тем больше возможностей, но и тем меньше совместимость с более старыми реализациями .NET.
🚩Пример использования
Создаём Class Library с таргетом
Ставь 👍 и забирай 📚 Базу знаний
.NET Standard — это спецификация API, которая определяет набор базовых библиотек, доступных во всех реализациях .NET (например, .NET Framework, .NET Core, Xamarin, Unity и других). Она была создана для обеспечения совместимости между разными платформами .NET.
🚩Зачем нужен .NET Standard?
До появления .NET Standard существовало несколько отдельных реализаций .NET:
.NET Framework (для Windows-приложений)
.NET Core (кроссплатформенная версия .NET)
Mono/Xamarin (для мобильных и игровых приложений)
Каждая из них имела свои особенности и набор доступных API. Из-за этого разработчики, создавая библиотеку, сталкивались с проблемой совместимости: приходилось писать несколько версий кода под разные платформы или использовать Portable Class Library (PCL), которая имела ограниченный функционал.
.NET Standard решил эту проблему, введя единый набор API, который обязаны поддерживать все реализации .NET.
🚩Как это работает?
.NET Standard представляет собой абстрактную спецификацию API, которая реализуется разными версиями .NET. Например, .NET Standard 2.0 поддерживается в .NET Framework 4.6.1, .NET Core 2.0 и выше. Если библиотека написана под .NET Standard 2.0, её можно использовать во всех этих средах.
🚩Версии .NET Standard
Существуют разные версии .NET Standard, каждая из которых включает больше API, чем предыдущая. Чем выше версия, тем больше возможностей, но и тем меньше совместимость с более старыми реализациями .NET.
🚩Пример использования
Создаём Class Library с таргетом
.NET Standard 2.0:namespace MyLibrary
{
public class MathHelper
{
public static int Add(int a, int b)
{
return a + b;
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
🤔 Какие объекты можно использовать в foreach?
В foreach-цикле можно использовать любые объекты, которые реализуют интерфейс IEnumerable (в .NET) или Iterable (в Java).
Это могут быть:
- массивы;
- коллекции (List, Set, Dictionary, ArrayList, и др.);
- результат LINQ-запроса;
- пользовательские коллекции, если реализуют IEnumerable.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
В foreach-цикле можно использовать любые объекты, которые реализуют интерфейс IEnumerable (в .NET) или Iterable (в Java).
Это могут быть:
- массивы;
- коллекции (List, Set, Dictionary, ArrayList, и др.);
- результат LINQ-запроса;
- пользовательские коллекции, если реализуют IEnumerable.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥1💊1
🤔 Что такое медиатор?
Это паттерн проектирования поведенческих шаблонов, который позволяет уменьшить связанность между объектами, обеспечивая взаимодействие через центральный объект-посредник. Медиатор упрощает коммуникацию между компонентами системы, делая ее более модульной и легкой для сопровождения.
🚩Примеры использования
1⃣Определение интерфейса медиатора
2⃣Реализация медиатора
3⃣Компоненты, взаимодействующие через медиатора
4⃣Использование медиатора в приложении
🚩Плюсы и минусы
➕Снижение связанности
Компоненты не взаимодействуют напрямую, а используют медиатор.
➕Упрощение поддержки
Вся логика взаимодействия сосредоточена в одном месте.
➕Повышение модульности
Легко добавлять новые компоненты или изменять существующие.
➖Усложнение медиатора
Медиатор может стать сложным, если в него добавляется много логики.
➖Единая точка отказа
Если медиатор выходит из строя, это может повлиять на всю систему.
Ставь 👍 и забирай 📚 Базу знаний
Это паттерн проектирования поведенческих шаблонов, который позволяет уменьшить связанность между объектами, обеспечивая взаимодействие через центральный объект-посредник. Медиатор упрощает коммуникацию между компонентами системы, делая ее более модульной и легкой для сопровождения.
🚩Примеры использования
1⃣Определение интерфейса медиатора
public interface IMediator
{
void Notify(object sender, string ev);
}
2⃣Реализация медиатора
public class DialogMediator : IMediator
{
private Button _button;
private TextBox _textBox;
public DialogMediator(Button button, TextBox textBox)
{
_button = button;
_button.SetMediator(this);
_textBox = textBox;
_textBox.SetMediator(this);
}
public void Notify(object sender, string ev)
{
if (ev == "ButtonClick")
{
_textBox.Clear();
}
else if (ev == "TextBoxEnter")
{
_button.SetEnabled(true);
}
}
}
3⃣Компоненты, взаимодействующие через медиатора
public class Button
{
private IMediator _mediator;
public void SetMediator(IMediator mediator)
{
_mediator = mediator;
}
public void Click()
{
Console.WriteLine("Button clicked");
_mediator.Notify(this, "ButtonClick");
}
public void SetEnabled(bool enabled)
{
Console.WriteLine($"Button is {(enabled ? "enabled" : "disabled")}");
}
}
public class TextBox
{
private IMediator _mediator;
public void SetMediator(IMediator mediator)
{
_mediator = mediator;
}
public void EnterText()
{
Console.WriteLine("Text entered");
_mediator.Notify(this, "TextBoxEnter");
}
public void Clear()
{
Console.WriteLine("TextBox cleared");
}
}
4⃣Использование медиатора в приложении
var button = new Button();
var textBox = new TextBox();
var mediator = new DialogMediator(button, textBox);
textBox.EnterText(); // Ввод текста активирует кнопку
button.Click(); // Нажатие кнопки очищает текстовое поле
🚩Плюсы и минусы
➕Снижение связанности
Компоненты не взаимодействуют напрямую, а используют медиатор.
➕Упрощение поддержки
Вся логика взаимодействия сосредоточена в одном месте.
➕Повышение модульности
Легко добавлять новые компоненты или изменять существующие.
➖Усложнение медиатора
Медиатор может стать сложным, если в него добавляется много логики.
➖Единая точка отказа
Если медиатор выходит из строя, это может повлиять на всю систему.
Ставь 👍 и забирай 📚 Базу знаний
🤔1
🤔 Можно ли передать строку в lock?
Можно, но не рекомендуется. Строки могут быть разделяемыми между разными частями программы, даже если они написаны одинаково. Это может привести к неожиданным блокировкам. Лучше использовать уникальные объекты, специально созданные для блокировки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Можно, но не рекомендуется. Строки могут быть разделяемыми между разными частями программы, даже если они написаны одинаково. Это может привести к неожиданным блокировкам. Лучше использовать уникальные объекты, специально созданные для блокировки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊1
🤔 Какова концепция сборки мусора в С#?
Это автоматический процесс управления памятью, который освобождает память, занятую объектами, которые больше не используются приложением. Этот механизм помогает разработчикам избежать ошибок, связанных с управлением памятью вручную, таких как утечки памяти и неправильное использование освобожденных ресурсов.
🚩Основные концепции сборки мусора
🟠Управляемая куча (Managed Heap)
Управляемая куча — это область памяти, в которой размещаются объекты, созданные в управляемой среде .NET. Когда создается новый объект, память для него выделяется в управляемой куче.
🟠Корни (Roots)
Корни — это переменные и ссылки, которые являются начальными точками для сборки мусора. Они включают глобальные и статические переменные, локальные переменные в стеке, а также ссылки из регистров процессора.
🟠Алгоритм маркировки и сжатия (Mark-and-Compact)
GC использует алгоритм маркировки и сжатия для определения объектов, которые больше не используются. Сначала он помечает все доступные объекты (те, до которых можно добраться из корней), а затем удаляет все непомеченные объекты, освобождая их память.
🟠Поколения (Generations)
Память управляемой кучи разделена на три поколения: поколение 0, поколение 1 и поколение 2. Это позволяет оптимизировать процесс сборки мусора:
Поколение 0: Содержит новые объекты. Сборка мусора здесь происходит чаще всего, так как большинство объектов живут недолго.
Поколение 1: Содержит объекты, которые пережили одну сборку мусора.
Поколение 2: Содержит объекты, которые пережили несколько сборок мусора. Сборка мусора здесь происходит реже всего, так как такие объекты считаются долгоживущими.
🚩Этапы сборки мусора
🟠Инициализация сборки мусора
Когда выделяется новая память и управляемая куча достигает определенного порога, запускается процесс сборки мусора.
🟠Маркировка (Mark)
GC проходит по всем корням и помечает все объекты, которые могут быть достигнуты.
🟠Удаление (Sweep)
После маркировки все непомеченные объекты считаются недоступными и могут быть удалены.
🟠Сжатие (Compact)
Для улучшения производительности и уменьшения фрагментации памяти, сборщик мусора может переместить оставшиеся объекты, чтобы освободить блоки памяти.
Ставь 👍 и забирай 📚 Базу знаний
Это автоматический процесс управления памятью, который освобождает память, занятую объектами, которые больше не используются приложением. Этот механизм помогает разработчикам избежать ошибок, связанных с управлением памятью вручную, таких как утечки памяти и неправильное использование освобожденных ресурсов.
🚩Основные концепции сборки мусора
🟠Управляемая куча (Managed Heap)
Управляемая куча — это область памяти, в которой размещаются объекты, созданные в управляемой среде .NET. Когда создается новый объект, память для него выделяется в управляемой куче.
🟠Корни (Roots)
Корни — это переменные и ссылки, которые являются начальными точками для сборки мусора. Они включают глобальные и статические переменные, локальные переменные в стеке, а также ссылки из регистров процессора.
🟠Алгоритм маркировки и сжатия (Mark-and-Compact)
GC использует алгоритм маркировки и сжатия для определения объектов, которые больше не используются. Сначала он помечает все доступные объекты (те, до которых можно добраться из корней), а затем удаляет все непомеченные объекты, освобождая их память.
🟠Поколения (Generations)
Память управляемой кучи разделена на три поколения: поколение 0, поколение 1 и поколение 2. Это позволяет оптимизировать процесс сборки мусора:
Поколение 0: Содержит новые объекты. Сборка мусора здесь происходит чаще всего, так как большинство объектов живут недолго.
Поколение 1: Содержит объекты, которые пережили одну сборку мусора.
Поколение 2: Содержит объекты, которые пережили несколько сборок мусора. Сборка мусора здесь происходит реже всего, так как такие объекты считаются долгоживущими.
🚩Этапы сборки мусора
🟠Инициализация сборки мусора
Когда выделяется новая память и управляемая куча достигает определенного порога, запускается процесс сборки мусора.
🟠Маркировка (Mark)
GC проходит по всем корням и помечает все объекты, которые могут быть достигнуты.
🟠Удаление (Sweep)
После маркировки все непомеченные объекты считаются недоступными и могут быть удалены.
🟠Сжатие (Compact)
Для улучшения производительности и уменьшения фрагментации памяти, сборщик мусора может переместить оставшиеся объекты, чтобы освободить блоки памяти.
class Program
{
static void Main()
{
for (int i = 0; i < 1000; i++)
{
CreateObject();
}
// Явный вызов сборщика мусора (не рекомендуется для обычного использования)
GC.Collect();
}
static void CreateObject()
{
MyClass obj = new MyClass();
// Объект obj будет собран сборщиком мусора, когда он больше не будет использоваться
}
}
class MyClass
{
// Поля и методы класса
}
Ставь 👍 и забирай 📚 Базу знаний
👍3
Завтра последний день!
Успей купить пожизненный easyoffer PRO - по цене 1 года
Покупаешь один раз — пользуешься всю жизнь.
👉 Акция до 31 марта: https://easyoffer.ru/pro
Успей купить пожизненный easyoffer PRO - по цене 1 года
Покупаешь один раз — пользуешься всю жизнь.
👉 Акция до 31 марта: https://easyoffer.ru/pro