🤔 Какие типы HTTP-запросов бывают и где в них передаются данные?
1. GET: данные передаются в URL как параметры.
2. POST: данные передаются в теле запроса.
3. PUT и PATCH: обновляют данные, передавая их в теле запроса.
4. DELETE: удаляет ресурс, данные могут передаваться в URL или теле.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. GET: данные передаются в URL как параметры.
2. POST: данные передаются в теле запроса.
3. PUT и PATCH: обновляют данные, передавая их в теле запроса.
4. DELETE: удаляет ресурс, данные могут передаваться в URL или теле.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Для чего нужны методы service configuration?
В ASP.NET Core методы Service Configuration используются для настройки и регистрации зависимостей в контейнере внедрения зависимостей (Dependency Injection, DI). Это позволяет управлять зависимостями в приложении, делая код более гибким, тестируемым и удобным для расширения.
🚩Где происходит настройка сервисов?
Настройка сервисов выполняется в методе
🚩Основные виды регистрации сервисов
🟠`AddSingleton<T>`
создаёт единственный экземпляр объекта на всё время работы приложения.
🟠`AddScoped<T>`
создаёт один экземпляр объекта на каждый HTTP-запрос.
🟠`AddTransient<T>`
создаёт новый экземпляр объекта при каждом запросе.
🚩Пример использования в контроллере
Ставь 👍 и забирай 📚 Базу знаний
В ASP.NET Core методы Service Configuration используются для настройки и регистрации зависимостей в контейнере внедрения зависимостей (Dependency Injection, DI). Это позволяет управлять зависимостями в приложении, делая код более гибким, тестируемым и удобным для расширения.
🚩Где происходит настройка сервисов?
Настройка сервисов выполняется в методе
ConfigureServices(IServiceCollection services), который находится в классе Program.cs или Startup.cs (в зависимости от версии .NET). public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(); // Добавление контроллеров для API
services.AddDbContext<ApplicationDbContext>(); // Регистрация контекста базы данных
services.AddScoped<IMyService, MyService>(); // Внедрение зависимости
}
🚩Основные виды регистрации сервисов
🟠`AddSingleton<T>`
создаёт единственный экземпляр объекта на всё время работы приложения.
services.AddSingleton<ILogger, ConsoleLogger>();
🟠`AddScoped<T>`
создаёт один экземпляр объекта на каждый HTTP-запрос.
services.AddScoped<IUserService, UserService>();
🟠`AddTransient<T>`
создаёт новый экземпляр объекта при каждом запросе.
services.AddTransient<IEmailSender, EmailSender>();
🚩Пример использования в контроллере
public class HomeController : Controller
{
private readonly IMyService _myService;
public HomeController(IMyService myService)
{
_myService = myService;
}
public IActionResult Index()
{
var data = _myService.GetData();
return View(data);
}
}
Ставь 👍 и забирай 📚 Базу знаний
💊2
🤔 Что такое reflection и для чего используется?
Это механизм, позволяющий исследовать и взаимодействовать с метаданными типов в рантайме. Используется для динамического вызова методов, получения информации о классах, их свойствах, конструкторах и атрибутах, а также для создания объектов во время выполнения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥2👍1
🤔 Что такое Dispose?
Dispose метод является частью паттерна управления ресурсами, известного как "Dispose Pattern". Этот метод реализуется в классах через интерфейс
🚩Неуправляемые и управляемые ресурсы
🟠Неуправляемые ресурсы
включают в себя ресурсы, которые не управляются средой CLR (Common Language Runtime), например, файловые дескрипторы, сетевые соединения или указатели на память, выделенную вне .NET среды.
🟠Управляемые ресурсы
это объекты .NET, которые занимают память и потенциально удерживают ссылки на неуправляемые ресурсы.
🚩Как он работает
Должен освобождать все неуправляемые ресурсы, занимаемые объектом, а также должен иметь возможность освобождать управляемые ресурсы, если это необходимо. Как правило, управляемые ресурсы освобождаются сами сборщиком мусора, но если управляемый ресурс включает в себя неуправляемые ресурсы, тогда
Пример использования Dispose
Ставь 👍 и забирай 📚 Базу знаний
Dispose метод является частью паттерна управления ресурсами, известного как "Dispose Pattern". Этот метод реализуется в классах через интерфейс
IDisposable. Цель — явное освобождение неуправляемых ресурсов и, по желанию, управляемых ресурсов, прежде чем сборщик мусора освободит объект. Это важно для эффективного управления памятью и другими системными ресурсами.🚩Неуправляемые и управляемые ресурсы
🟠Неуправляемые ресурсы
включают в себя ресурсы, которые не управляются средой CLR (Common Language Runtime), например, файловые дескрипторы, сетевые соединения или указатели на память, выделенную вне .NET среды.
🟠Управляемые ресурсы
это объекты .NET, которые занимают память и потенциально удерживают ссылки на неуправляемые ресурсы.
🚩Как он работает
Должен освобождать все неуправляемые ресурсы, занимаемые объектом, а также должен иметь возможность освобождать управляемые ресурсы, если это необходимо. Как правило, управляемые ресурсы освобождаются сами сборщиком мусора, но если управляемый ресурс включает в себя неуправляемые ресурсы, тогда
Dispose может быть вызван для их явного освобождения.public class ResourceHolder : IDisposable
{
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождение управляемых ресурсов
}
// Освобождение неуправляемых ресурсов
disposed = true;
}
}
~ResourceHolder()
{
Dispose(false);
}
}
Пример использования Dispose
using (var resource = new ResourceHolder())
{
// Использование ресурса
}
// Метод Dispose автоматически вызывается при выходе из блока using
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое IEnumerable?
IEnumerable — это интерфейс в .NET, представляющий коллекцию объектов, которые могут быть перечислены. Он предоставляет метод GetEnumerator(), который возвращает объект IEnumerator для перебора элементов коллекции, например, в цикле foreach. Этот интерфейс часто используется для реализации простых коллекций и позволяет ленивую (отложенную) обработку данных, что особенно полезно при работе с большими наборами данных или потоками данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 Что такое Redis?
Это система управления базами данных с открытым исходным кодом, работающая в памяти и поддерживающая множество типов данных, таких как строки, списки, множества, хеши и другие. Redis часто используется как кэш, брокер сообщений и база данных. Он известен своей высокой производительностью, низкой задержкой и простотой в использовании.
🚩Особенности
🟠Работа в памяти
Redis хранит все данные в памяти, что обеспечивает очень быструю скорость чтения и записи. Данные также могут периодически сохраняться на диск для обеспечения долговечности.
🟠Поддержка различных типов данных
Строки (Strings): Самый простой тип данных в Redis, который может содержать текст или двоичные данные.
Списки (Lists): Упорядоченные коллекции строк, которые можно использовать как очереди или стеки.
Множества (Sets): Неупорядоченные коллекции уникальных строк.
Упорядоченные множества (Sorted Sets): Коллекции уникальных строк, каждая из которых связана с числовым значением (score), определяющим порядок.
Хеши (Hashes): Коллекции пар "ключ-значение", где каждый хеш связан с ключом.
Bitmaps и HyperLogLogs: Для эффективного хранения и обработки больших объемов данных.
🟠Высокая производительность
Благодаря хранению данных в памяти и простому протоколу клиент-сервер, Redis обеспечивает очень высокую скорость операций.
🟠Поддержка репликации
Redis поддерживает мастер-слейв репликацию, что позволяет создать резервные копии данных и обеспечить отказоустойчивость.
🟠Кластеризация
Redis Cluster позволяет распределить данные по нескольким узлам, обеспечивая горизонтальную масштабируемость.
🟠Поддержка Lua-скриптов
Redis позволяет выполнять атомарные операции с помощью Lua-скриптов.
🟠Транзакции
Redis поддерживает транзакции, позволяя выполнить несколько команд атомарно.
🚩Примеры использования
🟠Кэширование
Redis часто используется для кэширования данных, что позволяет значительно уменьшить задержку доступа и снизить нагрузку на базу данных.
🟠Сессии
Хранение сессий пользователя для веб-приложений, что обеспечивает быстрое и эффективное управление состоянием.
🟠Очереди сообщений
Использование списков или упорядоченных множеств для организации очередей сообщений.
🟠Счетчики и рейтинги
Использование упорядоченных множеств для реализации счетчиков, рейтингов или систем рекомендаций.
Ставь 👍 и забирай 📚 Базу знаний
Это система управления базами данных с открытым исходным кодом, работающая в памяти и поддерживающая множество типов данных, таких как строки, списки, множества, хеши и другие. Redis часто используется как кэш, брокер сообщений и база данных. Он известен своей высокой производительностью, низкой задержкой и простотой в использовании.
🚩Особенности
🟠Работа в памяти
Redis хранит все данные в памяти, что обеспечивает очень быструю скорость чтения и записи. Данные также могут периодически сохраняться на диск для обеспечения долговечности.
🟠Поддержка различных типов данных
Строки (Strings): Самый простой тип данных в Redis, который может содержать текст или двоичные данные.
Списки (Lists): Упорядоченные коллекции строк, которые можно использовать как очереди или стеки.
Множества (Sets): Неупорядоченные коллекции уникальных строк.
Упорядоченные множества (Sorted Sets): Коллекции уникальных строк, каждая из которых связана с числовым значением (score), определяющим порядок.
Хеши (Hashes): Коллекции пар "ключ-значение", где каждый хеш связан с ключом.
Bitmaps и HyperLogLogs: Для эффективного хранения и обработки больших объемов данных.
🟠Высокая производительность
Благодаря хранению данных в памяти и простому протоколу клиент-сервер, Redis обеспечивает очень высокую скорость операций.
🟠Поддержка репликации
Redis поддерживает мастер-слейв репликацию, что позволяет создать резервные копии данных и обеспечить отказоустойчивость.
🟠Кластеризация
Redis Cluster позволяет распределить данные по нескольким узлам, обеспечивая горизонтальную масштабируемость.
🟠Поддержка Lua-скриптов
Redis позволяет выполнять атомарные операции с помощью Lua-скриптов.
🟠Транзакции
Redis поддерживает транзакции, позволяя выполнить несколько команд атомарно.
🚩Примеры использования
🟠Кэширование
Redis часто используется для кэширования данных, что позволяет значительно уменьшить задержку доступа и снизить нагрузку на базу данных.
using StackExchange.Redis;
using System;
class Program
{
static void Main()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
db.StringSet("key", "value");
string value = db.StringGet("key");
Console.WriteLine(value);
}
}
🟠Сессии
Хранение сессий пользователя для веб-приложений, что обеспечивает быстрое и эффективное управление состоянием.
🟠Очереди сообщений
Использование списков или упорядоченных множеств для организации очередей сообщений.
using StackExchange.Redis;
using System;
class Program
{
static void Main()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
db.ListLeftPush("queue", "task1");
db.ListLeftPush("queue", "task2");
string task = db.ListRightPop("queue");
Console.WriteLine(task);
}
}
🟠Счетчики и рейтинги
Использование упорядоченных множеств для реализации счетчиков, рейтингов или систем рекомендаций.
using StackExchange.Redis;
using System;
class Program
{
static void Main()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
// Add scores for users
db.SortedSetAdd("scores", "user1", 100);
db.SortedSetAdd("scores", "user2", 200);
// Retrieve scores with scores included
var scores = db.SortedSetRangeByRankWithScores("scores", 0, -1);
foreach (var score in scores)
{
Console.WriteLine($"{score.Element}: {score.Score}");
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое сборщик мусора?
Сборщик мусора — это механизм автоматического управления памятью, который отслеживает каждый объект в системе и удаляет те объекты, на которые больше нет ссылок, автоматически освобождая ресурсы и предотвращая утечки памяти.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что такое делегаты и зачем они нужны?
Делегаты — это типы, которые безопасно инкапсулируют методы, подобно указателям на функции в других языках программирования, но с проверкой типов во время компиляции. Могут ссылаться на метод, который принимает параметры и возвращает значение. Они используются для реализации обратных вызовов и событий, а также для определения пользовательских операций, которые могут быть выполнены методом, принимаемым в качестве параметра.
🚩Зачем они нужны?
🟠Обратные вызовы (Callbacks)
Делегаты предоставляют механизм для передачи методов в качестве аргументов другим методам. Это полезно для реализации обратных вызовов, позволяя вызывать методы в ответ на определенные события или условия.
🟠События
Являются основой системы событий. Они позволяют определять события и подписываться на них. Когда событие происходит, вызываются делегаты, связанные с этим событием, что позволяет реагировать на изменения или действия пользователя.
🟠Параметризация методами
Позволяют создавать более гибкие и масштабируемые приложения, поскольку методы могут быть переданы и использованы динамически в различных контекстах.
🟠Асинхронное программирование
Используются для асинхронного программирования, позволяя выполнять задачи в фоновом режиме, не блокируя основной поток приложения.
Ставь 👍 и забирай 📚 Базу знаний
Делегаты — это типы, которые безопасно инкапсулируют методы, подобно указателям на функции в других языках программирования, но с проверкой типов во время компиляции. Могут ссылаться на метод, который принимает параметры и возвращает значение. Они используются для реализации обратных вызовов и событий, а также для определения пользовательских операций, которые могут быть выполнены методом, принимаемым в качестве параметра.
🚩Зачем они нужны?
🟠Обратные вызовы (Callbacks)
Делегаты предоставляют механизм для передачи методов в качестве аргументов другим методам. Это полезно для реализации обратных вызовов, позволяя вызывать методы в ответ на определенные события или условия.
🟠События
Являются основой системы событий. Они позволяют определять события и подписываться на них. Когда событие происходит, вызываются делегаты, связанные с этим событием, что позволяет реагировать на изменения или действия пользователя.
🟠Параметризация методами
Позволяют создавать более гибкие и масштабируемые приложения, поскольку методы могут быть переданы и использованы динамически в различных контекстах.
🟠Асинхронное программирование
Используются для асинхронного программирования, позволяя выполнять задачи в фоновом режиме, не блокируя основной поток приложения.
public delegate int Operation(int x, int y);
public class Calculator
{
public int PerformOperation(int x, int y, Operation op)
{
return op(x, y);
}
}
class Program
{
static int Add(int x, int y)
{
return x + y;
}
static int Multiply(int x, int y)
{
return x * y;
}
static void Main()
{
Calculator calc = new Calculator();
// Создание делегата для метода Add и вызов через метод PerformOperation
Operation addOp = new Operation(Add);
int result = calc.PerformOperation(5, 6, addOp);
Console.WriteLine("Addition: " + result);
// Создание делегата для метода Multiply и вызов через метод PerformOperation
Operation mulOp = new Operation(Multiply);
result = calc.PerformOperation(5, 6, mulOp);
Console.WriteLine("Multiplication: " + result);
}
}
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое конкурентность в многопоточности?
Конкурентность — это способность нескольких потоков выполняться одновременно или чередоваться в выполнении. Даже если физически работает один процессор, задачи могут переключаться быстро, создавая ощущение одновременности. Важно при этом избегать конфликтов между потоками.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Конкурентность — это способность нескольких потоков выполняться одновременно или чередоваться в выполнении. Даже если физически работает один процессор, задачи могут переключаться быстро, создавая ощущение одновременности. Важно при этом избегать конфликтов между потоками.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Если в двух переменных хранится одинаковое значение, то будут ли они равны?
Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения.
🟠Примитивные типы (Value Types)
Для примитивных типов (например,
🟠Ссылочные типы (Reference Types)
Для ссылочных типов (например, классы, строки) переменные содержат ссылки на объекты в куче. Сравнение ссылочных типов по умолчанию выполняется по ссылке, а не по значению.
🟠Строки (Strings)
Строки являются ссылочными типами, но переопределяют операторы сравнения
🟠Кастомные классы
Для кастомных классов можно переопределить методы
Ставь 👍 и забирай 📚 Базу знаний
Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения.
🟠Примитивные типы (Value Types)
Для примитивных типов (например,
int, float, char, bool) значение хранятся непосредственно в переменных, и их сравнение выполняется по значению. int a = 5;
int b = 5;
bool areEqual = (a == b); // True
🟠Ссылочные типы (Reference Types)
Для ссылочных типов (например, классы, строки) переменные содержат ссылки на объекты в куче. Сравнение ссылочных типов по умолчанию выполняется по ссылке, а не по значению.
class Person
{
public string Name { get; set; }
}
Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };
bool areEqual = (person1 == person2); // False, потому что сравниваются ссылки
🟠Строки (Strings)
Строки являются ссылочными типами, но переопределяют операторы сравнения
== и Equals для сравнения по значению. string str1 = "Hello";
string str2 = "Hello";
bool areEqual = (str1 == str2); // True, строки сравниваются по значению
🟠Кастомные классы
Для кастомных классов можно переопределить методы
Equals и GetHashCode, чтобы сравнивать объекты по значению. class Person
{
public string Name { get; set; }
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
Person other = (Person)obj;
return Name == other.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };
bool areEqual = person1.Equals(person2); // True
Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Какие виды связей бывают у join`ов?
Связи бывают: один к одному, один ко многим, многие ко многим. Они определяют, как таблицы взаимодействуют друг с другом через ключи.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 Может ли абстрактный метод быть вне абстрактного класса?
Нет, абстрактный метод не может существовать вне абстрактного класса. В C# это ограничение встроено в язык, чтобы поддерживать строгую логику наследования и полиморфизма.
🚩Почему абстрактный метод требует абстрактного класса?
Абстрактный метод — это метод, который объявлен, но не имеет реализации. Он выступает как "контракт", который обязан быть реализован в производном классе.
Абстрактные методы имеют следующие особенности:
Они не могут содержать тело (реализацию).
Их цель — заставить производные классы реализовать конкретную функциональность.
Они всегда принадлежат абстрактным классам.
🚩Пример ошибки
Если попытаться объявить абстрактный метод в обычном классе, компилятор выдаст ошибку
🚩Логика дизайна
C# требует, чтобы абстрактные методы находились только в абстрактных классах, потому что:
Абстрактные классы могут содержать как абстрактные, так и обычные методы. Это позволяет определять базовое поведение в абстрактном классе и оставлять специфическую реализацию производным классам.
Обычные классы не могут содержать абстрактные методы, так как они предназначены для создания объектов, а объект не может содержать "незавершённый" метод.
Ставь 👍 и забирай 📚 Базу знаний
Нет, абстрактный метод не может существовать вне абстрактного класса. В C# это ограничение встроено в язык, чтобы поддерживать строгую логику наследования и полиморфизма.
🚩Почему абстрактный метод требует абстрактного класса?
Абстрактный метод — это метод, который объявлен, но не имеет реализации. Он выступает как "контракт", который обязан быть реализован в производном классе.
public abstract class Shape
{
public abstract double CalculateArea();
}
Абстрактные методы имеют следующие особенности:
Они не могут содержать тело (реализацию).
Их цель — заставить производные классы реализовать конкретную функциональность.
Они всегда принадлежат абстрактным классам.
🚩Пример ошибки
Если попытаться объявить абстрактный метод в обычном классе, компилятор выдаст ошибку
public class RegularClass
{
public abstract void SomeMethod(); // Ошибка: абстрактный метод может быть только в абстрактном классе
}
🚩Логика дизайна
C# требует, чтобы абстрактные методы находились только в абстрактных классах, потому что:
Абстрактные классы могут содержать как абстрактные, так и обычные методы. Это позволяет определять базовое поведение в абстрактном классе и оставлять специфическую реализацию производным классам.
Обычные классы не могут содержать абстрактные методы, так как они предназначены для создания объектов, а объект не может содержать "незавершённый" метод.
Ставь 👍 и забирай 📚 Базу знаний
🤔 Можно ли в рамках lock использовать await?
Нет, нельзя. Ожидание с await может привести к тому, что поток выйдет из текущего блока и продолжит выполнение в другом — это нарушает правила lock, который должен оставаться в одном потоке. Для асинхронного кода используют другие механизмы синхронизации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Нет, нельзя. Ожидание с await может привести к тому, что поток выйдет из текущего блока и продолжит выполнение в другом — это нарушает правила lock, который должен оставаться в одном потоке. Для асинхронного кода используют другие механизмы синхронизации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 Какие есть методы запросов жизненного цикла в asp.net Core?
В ASP.NET Core жизненный цикл запроса проходит несколько этапов — от получения HTTP-запроса до отправки ответа. В этом процессе участвуют Middleware, контроллеры, фильтры и обработчики событий.
🚩Основные этапы жизненного цикла запроса
Получение запроса (
Обработка через Middleware (передача запроса вниз)
Маршрутизация (Routing) — определение контроллера
Фильтры (например, аутентификация)
Вызов контроллера и метода (
Обратный проход через Middleware (формирование ответа)
Отправка ответа клиенту
🚩Методы Middleware (Промежуточное ПО)
Middleware — это основной механизм обработки запросов.
Где регистрируются? → В
Методы Middleware
🚩Методы в контроллерах (`Controller`)
Контроллер обрабатывает запросы после маршрутизации.
Основные методы
🚩Фильтры (`Filters`)
Фильтры выполняются до и после вызова контроллера.
Методы фильтров
🚩Методы жизненного цикла в `Program.cs`
В ASP.NET Core 6+ вся конфигурация находится в
Методы инициализации
Ставь 👍 и забирай 📚 Базу знаний
В ASP.NET Core жизненный цикл запроса проходит несколько этапов — от получения HTTP-запроса до отправки ответа. В этом процессе участвуют Middleware, контроллеры, фильтры и обработчики событий.
🚩Основные этапы жизненного цикла запроса
Получение запроса (
HttpContext создаётся) Обработка через Middleware (передача запроса вниз)
Маршрутизация (Routing) — определение контроллера
Фильтры (например, аутентификация)
Вызов контроллера и метода (
Action) Обратный проход через Middleware (формирование ответа)
Отправка ответа клиенту
🚩Методы Middleware (Промежуточное ПО)
Middleware — это основной механизм обработки запросов.
Где регистрируются? → В
Program.cs (в app.Use...) Методы Middleware
app.Use(async (context, next) =>
{
Console.WriteLine("Перед обработкой запроса");
await next(); // Передаём запрос дальше
Console.WriteLine("После обработки запроса");
});
🚩Методы в контроллерах (`Controller`)
Контроллер обрабатывает запросы после маршрутизации.
Основные методы
public class HomeController : Controller
{
// Метод вызывается при GET-запросе
public IActionResult Index()
{
return View();
}
// Метод вызывается при POST-запросе
[HttpPost]
public IActionResult SubmitForm(FormModel model)
{
return RedirectToAction("Index");
}
}
🚩Фильтры (`Filters`)
Фильтры выполняются до и после вызова контроллера.
Методы фильтров
public class MyActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("Перед вызовом метода контроллера");
}
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("После вызова метода контроллера");
}
}
🚩Методы жизненного цикла в `Program.cs`
В ASP.NET Core 6+ вся конфигурация находится в
Program.cs. Методы инициализации
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews(); // Подключаем MVC
var app = builder.Build();
app.UseRouting(); // Включаем маршрутизацию
app.UseAuthorization(); // Проверка прав
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Подключаем контроллеры
});
app.Run();
Ставь 👍 и забирай 📚 Базу знаний
👍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;
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое Box/Unbox и как этого можно избежать?
Boxing — это преобразование значимого типа (int, float и т.д.) в ссылочный тип (object), т.е. упаковка значения в объект.
Unboxing — это обратное преобразование: из object обратно в value-type.
Проблема: это создаёт накладные расходы на память и производительность.
Избежать можно следующим образом:
- Использовать обобщённые коллекции (List<int> вместо ArrayList).
- Не использовать object, если можно указать конкретный тип.
- Избегать приведения типов без необходимости.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Boxing — это преобразование значимого типа (int, float и т.д.) в ссылочный тип (object), т.е. упаковка значения в объект.
Unboxing — это обратное преобразование: из object обратно в value-type.
Проблема: это создаёт накладные расходы на память и производительность.
Избежать можно следующим образом:
- Использовать обобщённые коллекции (List<int> вместо ArrayList).
- Не использовать object, если можно указать конкретный тип.
- Избегать приведения типов без необходимости.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 В чем суть extension методов?
Extension-методы (методы расширения) — это способ добавить новые методы к существующим классам, не изменяя их код и не создавая наследников. Они позволяют расширять классы и интерфейсы, даже если у нас нет доступа к их исходному коду.
🚩Как работают extension-методы?
Это обычные статические методы, но объявленные внутри статического класса.
Первый параметр метода должен принимать тот тип, который мы хотим расширить, и перед ним ставится ключевое слово
После этого метод становится доступен как "встроенный" у этого типа.
🟠Добавляем метод к `string`
Допустим, у нас есть строка, и мы хотим добавить метод
🟠Расширяем `List<int>`
Добавим метод `SumEvenNumbers()`, который суммирует только четные числа в
🚩Когда использовать extension-методы?
Когда нужно добавить новый метод к существующему классу, но нельзя изменить его код (например,
Когда хочется сделать код более читаемым:
Когда нужно улучшить API без наследования и изменения структуры классов.
Ставь 👍 и забирай 📚 Базу знаний
Extension-методы (методы расширения) — это способ добавить новые методы к существующим классам, не изменяя их код и не создавая наследников. Они позволяют расширять классы и интерфейсы, даже если у нас нет доступа к их исходному коду.
🚩Как работают extension-методы?
Это обычные статические методы, но объявленные внутри статического класса.
Первый параметр метода должен принимать тот тип, который мы хотим расширить, и перед ним ставится ключевое слово
this. После этого метод становится доступен как "встроенный" у этого типа.
🟠Добавляем метод к `string`
Допустим, у нас есть строка, и мы хотим добавить метод
ToSnakeCase, который заменяет пробелы на нижние подчеркивания. using System;
public static class StringExtensions
{
public static string ToSnakeCase(this string str)
{
return str.Replace(" ", "_").ToLower();
}
}
class Program
{
static void Main()
{
string text = "Hello World";
Console.WriteLine(text.ToSnakeCase()); // hello_world
}
}
🟠Расширяем `List<int>`
Добавим метод `SumEvenNumbers()`, который суммирует только четные числа в
List<int>. using System;
using System.Collections.Generic;
using System.Linq;
public static class ListExtensions
{
public static int SumEvenNumbers(this List<int> numbers)
{
return numbers.Where(n => n % 2 == 0).Sum();
}
}
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
Console.WriteLine(numbers.SumEvenNumbers()); // 12 (2 + 4 + 6)
}
}
🚩Когда использовать extension-методы?
Когда нужно добавить новый метод к существующему классу, но нельзя изменить его код (например,
string, List<T>, DateTime). Когда хочется сделать код более читаемым:
numbers.SumEvenNumbers() лучше, чем MyExtensions.SumEvenNumbers(numbers). Когда нужно улучшить API без наследования и изменения структуры классов.
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое String?
String в C# — это класс, представляющий неизменяемую последовательность символов. Каждый раз, когда строка изменяется, создаётся новый объект String, а старый объект остаётся в памяти до сборки мусора. Строки поддерживают методы для работы с текстом, такие как конкатенация, сравнение и поиск подстрок. Так как строки неизменяемы, для частых изменений строк предпочтительнее использовать StringBuilder.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍4🔥1
🤔 Какие тесты бывают?
🚩Виды
🟠Юнит-тесты
Предназначены для проверки отдельных компонентов или модулей приложения в изоляции. Они помогают убедиться, что отдельные функции или методы работают правильно.
Цель: Проверка логики отдельных методов или классов.
Инструменты: xUnit, NUnit, MSTest.
🟠Интеграционные тесты
Проверяют взаимодействие между различными компонентами системы, убеждаясь, что они корректно работают вместе.
Цель: Проверка взаимодействия между модулями.
Инструменты: xUnit, NUnit, MSTest, плюс дополнительные библиотеки для тестирования баз данных или HTTP-запросов.
🟠Функциональные тесты
Проверяют, что приложение выполняет свои функции в соответствии с требованиями. Эти тесты проверяют конкретные сценарии использования.
Цель: Проверка функциональности приложения на уровне пользователя.
Инструменты: Selenium, Playwright, Cypress.
🟠Системные тесты
Проверяют приложение в целом, включая взаимодействие с внешними системами и проверку всех требований.
Цель: Проверка всей системы в интегрированном виде.
Инструменты: JUnit, TestNG для Java, или те же инструменты, что и для функциональных тестов.
🟠Приемочные тесты
Проводятся для проверки, что приложение соответствует требованиям и готово к использованию клиентом или конечным пользователем.
Цель: Подтверждение соответствия приложения требованиям.
Инструменты: Cucumber, SpecFlow (для BDD).
🟠Регрессионные тесты
Проверяют, что недавние изменения в коде не нарушили существующую функциональность.
Цель: Убедиться, что новые изменения не привели к новым багам.
Инструменты: Все инструменты для юнит-тестирования и функционального тестирования.
🟠Нагрузочные тесты
Проверяют, как приложение ведет себя под нагрузкой, например, при большом количестве одновременных пользователей или операций.
Цель: Оценка производительности и устойчивости приложения под нагрузкой.
Инструменты: JMeter, Gatling, Apache Bench.
Ставь 👍 и забирай 📚 Базу знаний
🚩Виды
🟠Юнит-тесты
Предназначены для проверки отдельных компонентов или модулей приложения в изоляции. Они помогают убедиться, что отдельные функции или методы работают правильно.
Цель: Проверка логики отдельных методов или классов.
Инструменты: 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.
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что занимает меньше памяти: класс или структура?
Структура (значимый тип) занимает меньше памяти, потому что:
- Хранится в стеке или внутри другого объекта, без дополнительной накладной информации.
- Не требует хранения метаданных о типе, как у класса.
- Не использует сборщик мусора (GC) для удаления.
Однако слишком большие или часто копируемые структуры могут быть менее эффективны.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Структура (значимый тип) занимает меньше памяти, потому что:
- Хранится в стеке или внутри другого объекта, без дополнительной накладной информации.
- Не требует хранения метаданных о типе, как у класса.
- Не использует сборщик мусора (GC) для удаления.
Однако слишком большие или часто копируемые структуры могут быть менее эффективны.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥4