ar
Feedback

لا تقع ضحية للمخادعين! تيليمتريو يكتشف ويُميّز هذه القنوات 👉 إذا كنت تريد رؤية العلامة، اشترك

C# | Вопросы собесов

C# | Вопросы собесов

الذهاب إلى القناة على Telegram
5 014
المشتركون
لا توجد بيانات24 ساعات
+47 أيام
+2230 أيام
أرشيف المشاركات
Яндекс Музыка до 360 дней бесплатно Яндекс Музыка для вас и 3-х ваших близких. Кинопоиск и Яндекс Книги тоже в мультиподписке
Яндекс Музыка до 360 дней бесплатно Яндекс Музыка для вас и 3-х ваших близких. Кинопоиск и Яндекс Книги тоже в мультиподписке Плюс. Попробуйте бесплатно❤️ Слушать #реклама 18+ music.yandex.ru О рекламодателе

🤔 Какие есть методы запросов жизненного цикла в asp.net Core? В 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();
Ставь 👍 и забирай 📚 Базу знаний

Бесплатно проверим, готово ли ваше ПО к реестру Минцифры Разрабатываете ПО и хотите НДС 0%, ИТ-аккредитацию и доступ к госзак
Бесплатно проверим, готово ли ваше ПО к реестру Минцифры Разрабатываете ПО и хотите НДС 0%, ИТ-аккредитацию и доступ к госзакупкам? Всё это даёт включение в реестр российского ПО Минцифры. Но самостоятельная подача часто заканчивается отказом из-за прав, документов или несоответствия сайта требованиям. ✅Проверим ПО и права ✅ Подготовим и подадим документы ✅ Сопроводим до внесения в реестр ✅ Все за 60 дней. Пройдите бесплатную проверку готовности вашего ПО и за пару минут поймёте, реально ли попасть в реестр уже этим летом. Получить консультацию #реклама registration.group О рекламодателе

🤔 Что такое аутентификация? Когда человек вводит логин и пароль, система аутентифицирует его, проверяя, действительно ли это тот, за кого он себя выдаёт. 🚩Как работает аутентификация? Пользователь вводит данные (например, логин и пароль). Система проверяет их в базе данных. Если данные верны → доступ разрешён. Если данные неверны → отказ в доступе.
public async Task<IActionResult> Login(string username, string password)
{
    var user = await _userManager.FindByNameAsync(username);
    if (user != null && await _userManager.CheckPasswordAsync(user, password))
    {
        await _signInManager.SignInAsync(user, isPersistent: false);
        return RedirectToAction("Index", "Home");
    }
    ModelState.AddModelError("", "Неверный логин или пароль");
    return View();
}
🚩Виды аутентификации 🟠По паролю Самый распространённый вариант. Минус: если пароль украден – доступ открыт. 🟠Двухфакторная (2FA) Например, SMS-код + пароль. Усложняет взлом аккаунта. 🟠Биометрическая Отпечаток пальца, Face ID. Удобно, но требует спецоборудования. 🟠OAuth (Google, Facebook, GitHub) Вход через соцсети. Удобно, не нужно запоминать пароль. 🟠Аутентификация по токену (JWT) Используется в API и микросервисах. Позволяет работать без сохранения сессий. Ставь 👍 и забирай 📚 Базу знаний

Услуги дата-центра в Москве Размещение и аренда серверного оборудования в дата-центре. 👍 4 современных дата-центра в Москве.
Услуги дата-центра в Москве Размещение и аренда серверного оборудования в дата-центре. 👍 4 современных дата-центра в Москве. 👍 Лицензированный оператор связи. 👍 Индивидуальные конфигурации выделенных серверов под задачи клиента. 👍 Круглосуточная техническая поддержка в Телеграм, без ботов. Узнать цену #реклама 16+ itsoft.ru О рекламодателе

🤔 Как работает 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}");
Ставь 👍 и забирай 📚 Базу знаний

Оценка проекта: от догадок к системному подходу Оценка проекта часто начинается с цифры, которую назвали на пресейле до полно
Оценка проекта: от догадок к системному подходу Оценка проекта часто начинается с цифры, которую назвали на пресейле до полноценного анализа задачи. Затем команда пытается уложить в неё реальные трудозатраты, сроки и риски. Эффект привязки, излишний оптимизм и ошибки памяти создают ложную уверенность в расчётах, а первоначальный бюджет в процессе работы может вырасти в несколько раз. На открытом уроке 5 августа в 20:00 в OTUS разберём, как перейти от интуитивных предположений к системной оценке проекта. Поговорим о том, как выстроить Presale, связать продажи с командой разработки и проверить решение до принятия обязательств перед заказчиком. Рассмотрим реальные причины перерасхода бюджета и способы выявлять риски ещё до старта проекта. Узнать больше #реклама 16+ otus.ru О рекламодателе

🤔 Может ли в абстрактном классе не быть ни одного абстрактного метода? Да, может. Абстрактный класс не обязан содержать абстрактные методы. Он может использоваться как нельзя инстанцируемая базовая структура с частичной или полной реализацией, предназначенной для наследования. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

Бесплатный курс: веб-дизайн, графика, интерфейсы Научись создавать дизайн сайтов и приложений, инфографику для карточек на маркетплейсах и работать в Figma! Студенты курса в среднем зарабатывают от 68 000 ₽ уже во время обучения💰 Этот курс для тебя, если ты: ✅ мечтаешь о новой профессии, но не знаешь, с чего начать; ✅ чувствуешь, что хочешь большего — свободы, самореализации, творчества; ✅ полный новичок и хочешь систему, а не хаос; ✅ хочешь начать зарабатывать удалённо. Зарегистрироваться #реклама 16+ ydaev.ru О рекламодателе

🤔 В чем суть extension методов? 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 без наследования и изменения структуры классов. Ставь 👍 и забирай 📚 Базу знаний

Kafka на практике: продюсеры, консьюмеры, Docker Хотите увидеть, как реально работает Kafka? 3 августа в 20:00 — вебинар с жи
Kafka на практике: продюсеры, консьюмеры, Docker Хотите увидеть, как реально работает Kafka? 3 августа в 20:00 — вебинар с живыми примерами кода. Поднимем кластер в Docker, создадим топики, напишем продюсеров на Python/Java, настроим консьюмеров с consumer groups. Разберем партиционирование, оффсеты и гарантии доставки. Для backend-разработчиков, DevOps и всех, кто любит практику. Узнать больше #реклама 16+ otus.ru О рекламодателе

🤔 Что такое метод Finalize? Метод Finalize() представляет собой специальный метод, который предназначен для выполнения финальной очистки ресурсов перед тем, как объект будет уничтожен сборщиком мусора. Это метод, который может быть определен в классе для очистки неуправляемых ресурсов, если класс не реализует интерфейс IDisposable. 🚩Особенности метода 🟠Автоматический вызов Сборщик мусора автоматически вызывает Finalize() на объекте, который не имеет других активных ссылок и который определяет финализатор. Это происходит непосредственно перед тем, как сборщик мусора освобождает память, занимаемую объектом. 🟠Определение в базовом классе `Object` Все объекты наследуют от базового класса Object, который предоставляет реализацию Finalize(). Однако в большинстве случаев Finalize() не имеет реализации и не делает ничего, пока не будет переопределен в производном классе. 🟠Замедление сборки мусора Наличие объектов с финализаторами может замедлить процесс сборки мусора, так как объекты, требующие финализации, должны быть обработаны дважды: сначала они помещаются в очередь финализации, а затем их память освобождается после выполнения Finalize().
class ResourceWrapper
{
    // Конструктор
    public ResourceWrapper() {
        // Инициализация ресурсов
    }

    // Финализатор
    ~ResourceWrapper() {
        // Код очистки ресурсов
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Автоматизация бизнеса аренды серверов DCImanager. Скачай и попробуй бесплатно 30 дней. Для хостинга и сервис-провайдеров! ✅ В
Автоматизация бизнеса аренды серверов DCImanager. Скачай и попробуй бесплатно 30 дней. Для хостинга и сервис-провайдеров! ✅ Выдача сервера за 10 мин Автоматическая подготовка серверов к выдаче ✅ Мультифункциональность Платформа имеет встроенные дополнительные инструменты ✅ IPAM Управление IPv4/IPv6 и учет адресного пространства ✅ Поддержка 24/7 Техподдержка - сетевые инженеры, системные администраторы ✅ Получить доступ к демостенду Тестовый демостенд, на котором установлена платформа Узнать больше #реклама 16+ ispsystem.ru О рекламодателе

🤔 Что такое 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
Ставь 👍 и забирай 📚 Базу знаний

Получи грант до 1,35 млн руб. на обучение в магистратуре Хочешь развиваться в сфере ИТ и получить фундаментальные знания с пр
Получи грант до 1,35 млн руб. на обучение в магистратуре Хочешь развиваться в сфере ИТ и получить фундаментальные знания с практикой? Поступай в магистратуру Центрального университета! — 4 офлайн программы по востребованным направлениям ИТ — 2 онлайн-программы: машинное обучение и продуктовый менеджмент — 550 грантов до 75% — Вечерние занятия и учеба по выходным — удобно совмещать с работой — Обучение по модели STEM-образования: на стыке науки, технологий и бизнеса — Возможность стажировок и трудоустройства в ведущих компаниях — Государственный диплом за 2 года Магистратура в Центральном университете — это современный подход к образованию, сильный преподавательский состав и актуальные кейсы от индустрии. Оставляй заявку на грант уже сейчас! Зарегистрироваться #реклама 16+ cu.ru О рекламодателе

🤔 Как браузер отправляет запрос и получает ответ от 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);
});
Ставь 👍 и забирай 📚 Базу знаний

Онлайн-магистратура для IT: ИТМО, МИФИ + Яндекс Программы онлайн-магистратуры ИТМО и МИФИ в партнёрстве с Яндексом. Актуальны
Онлайн-магистратура для IT: ИТМО, МИФИ + Яндекс Программы онлайн-магистратуры ИТМО и МИФИ в партнёрстве с Яндексом. Актуальные знания, практическое обучение и гибкий график. Учитесь, совмещая с работой. Доступна господдержка оплаты, отсрочка от армии Перейти на сайт #реклама 16+ practicum.yandex.ru О рекламодателе

🤔 Что такое 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}");
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Yandex Ecom Open Air — летнее событие про онлайн-продажи Yandex Ecom Open Air 2026 объединяет деловую программу, живое общение и атмосферу фестиваля в одном потоке. Здесь обсуждают технологии, которые становятся частью среды. Исследуют силы, которые влияют на весь рынок. Находят новые связи, идеи и точки роста. В течение дня пространство фестиваля наполняют выступления, дискуссии, встречи, специальные форматы, музыка и активности партнёров. Присоединиться к происходящему можно из любой точки — на площадке фестиваля или через онлайн-трансляцию. Зарегистрироваться #реклама 18+ ecomfest.ru О рекламодателе

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

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

    public void Withdraw(decimal amount)
    {
        lock (balanceLock)
        {
            if (balance >= amount)
            {
                balance -= amount;
            }
        }
    }
}
🚩Зачем это нужно? Без использования lock или других методов синхронизации, программы с многопоточным доступом к общим данным могут испытывать проблемы, такие как гонки и условия гонки (race conditions), когда порядок или время доступа к данным может привести к ошибкам или неожиданным результатам. lock гарантирует, что только один поток может исполнять определенный блок кода, работающий с критическими ресурсами, в любой момент времени. Ставь 👍 и забирай 📚 Базу знаний