ch
Feedback
C# 1001 notes

C# 1001 notes

前往频道在 Telegram

Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого. admin - @haarrp

显示更多
6 617
订阅者
+124 小时
+537
+4730
帖子存档
Не знаешь, что ещё могут спросить на собеседовании по C#? Наш бот подскажет ⚡️ Просто напиши тему — например, C# — и @tiny_in
Не знаешь, что ещё могут спросить на собеседовании по C#? Наш бот подскажет ⚡️ Просто напиши тему — например, C# — и @tiny_interview_bot засыплет тебя вопросами. Ответы — "под катом", чтобы не подглядывать. ⚠️ Нужно точечно?Пиши узкую тему — хоть async/await, хоть dependency injection в ASP.NET, хоть LINQ internals — и бот будет гонять тебя только по ней. 📈 Повторяй десятки вопросов каждый день, по любой теме — от основ до продвинутых концепций. 🎯 Идеально для: Быстрой самопроверки Подготовки к техническим интервью Закрытия пробелов в знаниях 👉 Попробуй сам — @tiny_interview_bot И на собесе тебя уже ничем не удивят 😎 erid: 2W5zFHkYKDz

🚀 Вышел .NET 10 Preview 5 — с улучшениями на всех фронтах! 🛠️ В этом обновлении Microsoft прокачала: • Runtime — улучшена п
🚀 Вышел .NET 10 Preview 5 — с улучшениями на всех фронтах! 🛠️ В этом обновлении Microsoft прокачала: • Runtime — улучшена производительность и управление памятью • C# — новые языковые фичи для более выразительного кода • ASP.NET Core — оптимизация рендеринга и поддержки HTTP • Blazor — упрощена работа с интерактивными компонентами • MAUI — ускорены сборки и улучшена поддержка платформ • + расширены инструменты диагностики и безопасности ✅ Почему стоит обратить внимание Серьёзные улучшения в производительности и безопасность Новые фичи как в Runtime, так и в C#, веб-фреймворках и UI (MAUI) Продолжение активного развития с учётом обратной связи сообщества 📌 Подробности 📌 Скачать .NET 10 уже сейчас выглядит как одно из самых амбициозных обновлений в экосистеме. @csharp_ci

🧠 Задача для .NET разработчиков: «Загадочная утечка памяти в ASP.NET Core приложении» 🧩 Уровень: Senior .NET / Backend Engineer 🎯 Цель: Найти и устранить причину роста памяти без падений и исключений 📍 Ситуация: У вас — высоконагруженное API на ASP.NET Core (.NET 8), работающее под Linux в контейнере. Сервис обрабатывает тысячи запросов в минуту. Мониторинг показывает: - Память растёт стабильно, но не освобождается - GC работает, но не очищает выделенную память - dotnet-counters показывает рост в LOH (Large Object Heap) - Приложение не падает, но хост начинает свапать и тормозить - При перезапуске — память очищается, но через 2–3 часа снова заполняется ❗ В логах — тишина, ошибок нет. Библиотеки: Newtonsoft.Json, HttpClient, MemoryCache, EF Core. --- 🧩 Твоя задача: 1. Почему .NET GC может не освобождать LOH, даже при работе GC? 2. Какие действия вызывают накопление в LOH? 3. Как можно отследить, какие объекты скапливаются в памяти? 4. Чем опасен повторный вызов HttpClient или StringBuilder без очистки? 5. Как корректно использовать MemoryCache, чтобы избежать утечек? 💡 Подсказка: - LOH начинается с объектов > 85,000 байт - Часто виноваты: большие строки, сериализация, `ToString()`,🧠 Задача для .N🧠 Задача🧠 Задача -Задача для .NETможет хранить сильные ссылки бесконечно, если не задано время жизни - Частое создание 🧩 Уровень: S— может удерживать сокеты в TIME_WAIT и загонять GC в ступор 🛠 Решение: 1. Запускаем профилировщик:

   dotnet-gcdump collect -p <PID>
   dotnet-gcdump analyze dump.gcdump
   
2. Смотрим типы с самым большим retained size: List<string>, byte[], MemoryStream → В коде — сериализация в JSON огромных объектов без ограничения глубины 3. Находим участок с JsonConvert.SerializeObject(hugeObject) без MaxDepth 4. Исправления: - Добавить настройки сериализации:

     new JsonSerializerSettings { MaxDepth = 5, ReferenceLoopHandling = Ignore }
     
- Ограничить MemoryCache по размеру:

     new MemoryCache(new MemoryCacheOptions { SizeLimit = 100_000_000 });
     
- Использовать HttpClientFactory вместо new HttpClient() на каждый запрос 5. Альтернатива: перейти на System.Text.Json с Utf8JsonWriter — меньше аллокаций 📌 Вывод: Даже без явных ошибок .NET-приложение может стабильно "утекать" в LOH — через сериализацию, кэш или неправильную работу с потоками. Только анализ дампа памяти и правильная конфигурация GC и кешей помогут найти такие проблемы. @csharp_1001_notes

⚡️ SQL-шпаргалка, которая выручит в интервью, проекте и проде Полный мастер-гайд по SQL в одном PDF: практичные примеры, чёткие объяснения и никакой воды. Что внутри: • 💬 Создание баз, таблиц и изменение схем • 💬 Запросы любого уровня сложности: JOIN, GROUP BY, HAVING, PARTITION • 💬 Подзапросы, CTE, оконные функции: ROW_NUMBER, RANK, DENSE_RANK • 💬 VIEW, временные таблицы и работа с дубликатами • 💬 Даты, строки, преобразования и агрегации • 💬 Очистка данных, разбиение по разделителям • 💬 UNION, INTERSECT, EXCEPT — управление сложными выборками Затрагиваются и продвинутые кейсы: • Парсинг адресов • Кастомная сортировка • Использование ISNULL и COALESCE 🧠 Это не просто набор команд — это концентрат боевого SQL-опыта. Подходит для: ➡️ Подготовки к SQL-интервью ➡️ BI и аналитики ➡️ Web-разработки с базами ➡️ Встраивания SQL в проекты на Python, Go, Java и других языках

Какой язык более читаемый: C# или Python? Программисты забивают на безопасность? Обсуждаем эти и другие холиварные темы в шоу Контура «Согласен — не согласен», где сталкиваются два представителя разных IT-профессий, каждый со своим мнением и бэкграундом. Cмотрите самые горячие выпуски🔥 ➡️ С# vs Python-разработчики: какой язык круче ➡️ Джун vs cеньор-разработчики: нужны ли джуны в бигтехе ➡️ Бэкендер vs фронтендер: кто больше страдает ➡️ Программист vs учитель информатики: делать ли программирование обязательным в школе ➡️ Безопасник vs программист: кто должен думать об уязвимости продукта Новые дискуссии выходят в канале @KonturTech каждые две недели. Будет эмоционально, но с уважением. 16+. Реклама. АО «ПФ «СКБ Контур», ОГРН 1026605606620. 620144, Екатеринбург, ул. Народной Воли, 19А. Erid: 2SDnjcTtt77

🔥 From C# to Rust: 42-дневный челлендж от Chris Woody Woodruff Chris Woodruff, экспериментающий .NET-разработчик, объявил ст
🔥 From C# to Rust: 42-дневный челлендж от Chris Woody Woodruff Chris Woodruff, экспериментающий .NET-разработчик, объявил старт своего 42-дневного пути погружения в Rust — язык системного программирования, совмещающий производительность, безопасность и отсутствие null:contentReference[oaicite:0]{index=0}. 🎯 Цели проекта - Жить и дышать Rust — по одному уроку в день. - Противостоять строгому borrow checker. - Осознанно учиться и делиться выводами от лица C#-разработчика. 🛠 Что ожидается изучить - Владение памятью, шаблоны, трейты, времена жизни (`lifetimes`). - Яркие сравнения Rust и C#: синтаксис, ownership vs GC, ошибки компилятора:contentReference[oaicite:2]{index=2}. - Краткие ежедневные отражения из .NET-мира. 📅 Примерный план на 42 дня 1. День 1–7: Почему Rust? Установка, cargo new vs dotnet new, "Hello, World!", переменные, функции:contentReference[oaicite:4]{index=4}. 2. День 8–14: Неделя владения — темы: ownership, borrowing, borrow checker:contentReference[oaicite:5]{index=5}. 3. День 15–42: Структуры, перечисления (`enum`), match, Option<T>, Result<T, E>, модули, ошибки, трейты, дженерики, лямбды и многое другое. 💬 Голос из сообщества > «What happens when a C# dev swaps null for Option, garbage collection for ownership… You get 42 days of brain‑bending, compiler‑fighting…» ✨ Подытожим - Проект идёт с апреля 2025 года, уже опубликованы десятки дневных эссе. - Каждая запись по мотивам реального опыта: «why won’t this compile?!», сравнения с привычным C#. - В финале — обзор полученного опыта, личные инсайты и примеры рабочего CLI‑приложения на Rust:contentReference[oaicite:8]{index=8}. 🚀 Готовы бросить вызов себе и глубже понять Rust? Следите за дневником Woody и за входом в мир безопасных без‑GC систем прямо с .NET-опытов! 🔗 Подробнее: From C# to Rust: A 42-Day Developer Challenge https://woodruff.dev/from-c-to-rust-a-42-day-developer-challenge/

ХОЧЕШЬ ПОВЫСИТЬ ГРЕЙД В 2025 ГОДУ? 🚀 Чтобы стать Senior C# разработчиком сегодня, нужно не только знать язык программировани
ХОЧЕШЬ ПОВЫСИТЬ ГРЕЙД В 2025 ГОДУ? 🚀 Чтобы стать Senior C# разработчиком сегодня, нужно не только знать язык программирования и фреймворки. Нужно уметь строить гибкую архитектуру приложения, которую легко тестировать и менять под задачи бизнеса. Стань экспертом в построении гибкой архитектуры приложения! 👉 Стартуем 2 июня. Курс ведет действующий архитектор и Principal Engineer Кирилл Ветчинкин. Ты научишься: ✅ Разбивать приложение на слои в соответствии с Clean Architecture ✅ Формировать Domain Model и применять тактические паттерны DDD ✅ Реализовывать Use Case как Command/Query ✅ Делать синхронные и асинхронные интеграции, не загрязняя ядро приложения ✅ Писать 3 вида тестов для разных слоев приложения Полная программа ТУТ 👉 https://microarch.ru/courses/ddd?utm_source=posev&utm_medium=erid:2VtzqwTjbcd&utm_campaign=5 А главное — ты с нуля разработаешь и запустишь микросервис, который максимально приближен к реальности "Диспетчеризация заказов на курьеров". Это будет крутым проектом в портфолио или основой для рабочих задач. А еще: ✅ Проверим все домашки ✅ Поддержим в чате ✅ Проведем живые разборы ✅ Ответим на все вопросы 📕 Сертификат об участии по итогам прохождения курса. 🔥 Не откладывай свой рост на потом: https://microarch.ru/courses/ddd?utm_source=posev&utm_medium=erid:2VtzqwTjbcd&utm_campaign=5 Реклама. ИП Ветчинкин К.Е. ИНН: 773376451099 Erid: 2VtzqwTjbcd

🚀 Wissance.WebApiToolkit: Быстрое создание REST и GRPC API на .NET Если устал каждый раз писать одинаковый CRUD — этот toolk
🚀 Wissance.WebApiToolkit: Быстрое создание REST и GRPC API на .NET Если устал каждый раз писать одинаковый CRUD — этот toolkit тебя спасёт. С помощью [Wissance.WebApiToolkit](https://github.com/Wissance/WebApiToolkit) можно создать полноценный REST или GRPC API почти без усилий. ● Что умеет: - Минимум кода — CRUD-контроллер ≈ 10 строк - BULK-операции: обновление/удаление сразу нескольких объектов - Поддержка Entity Framework, EdgeDB и других хранилищ через IModelManager - Автогенерация GRPC-сервисов - Встроенная пагинация, фильтрация, сортировка - Поддержка Swagger (c версии 1.6.0) ● Архитектура построена на 5 слоях: EntityDTOFactoryManagerControllerПример CRUD-контроллера:

[ApiController]
public class BookController : BasicCrudController<BookDto, BookEntity, int, EmptyAdditionalFilters>
{
    public BookController(BookManager manager)
    {
        Manager = manager;
        _manager = manager;
    }

    private readonly BookManager _manager;
}
● Установка:

dotnet add package Wissance.WebApiToolkit
🔗 WeatherControl — полная интеграция с EF и EdgeDB ⭐ Проект open-source: github.com/Wissance/WebApiToolkit

Разработчики, девопсы, сисадмины: 📲 внимание, внимание! Похоже, эпоха открытого исходного кода идёт к концу: одна за одной н
Разработчики, девопсы, сисадмины: 📲 внимание, внимание! Похоже, эпоха открытого исходного кода идёт к концу: одна за одной наши любимые бесплатные C#-библиотеки становятся платными. И что же теперь делать? Давайте соберёмся вместе и подумаем. Приглашаем вас на открытую онлайн-дискуссию «Библиотеки C# уходят в платную сферу: конец эры опенсорса?» 📌Узнаете, какие библиотеки уже стали платными и что ждёт экосистему дальше 📌Узнаете, чем конкретно можно заменить ту или иную библиотеку 📌Сможете уменьшить лицензионные риски 📌Сможете вовремя изменить карьерный вектор или поменять архитектуру проектов 📌 Получите экспертные рекомендации по архитектуре и устойчивым решениям Спикеры: 👨‍💻Олег Голенищев – старший разработчик в Directum 👨‍💻Антон Герасименко – ведущий .NET-разработчик. Всем участникам – скидка 7% на любой курс OTUS и подборка альтернативных библиотек с открытым исходным кодом в подарок. 27 мая, 19:00 МСК Бесплатно по записи: https://tglink.io/a87663fba48d Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963. erid: 2W5zFG9Ybix

🧠 C# Задача: “Ловушка замыкания в цикле” 📜 Условие: Посмотри на этот код и скажи, что он выведет:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        var actions = new List<Action>();

        for (int i = 0; i < 5; i++)
        {
            actions.Add(() => Console.Write(i + " "));
        }

        foreach (var action in actions)
        {
            action();
        }
    }
}
❓ Вопросы: 1. Что напечатает программа? 2. Почему результат может удивить? 3. Как исправить код, чтобы получить 0 1 2 3 4? ⚠️ Подвох: - Переменная i захватывается по ссылке всеми лямбдами в List<Action>, а не копируется в момент добавления. - Когда цикл завершится, i == 5, и все лямбды обращаются к одному и тому же `i`, уже равному 5. --- ### ✅ Ожидаемый вывод:
5 5 5 5 5 
🛠️ Исправление: Чтобы каждая лямбда захватывала свою копию `i`, нужно добавить промежуточную переменную:

for (int i = 0; i < 5; i++)
{
    int copy = i;
    actions.Add(() => Console.Write(copy + " "));
}
Теперь вывод будет:
0 1 2 3 4 
🎯 Что проверяет задача: - Знание механики замыканий в C# - Понимание разницы между значениями и ссылками в замыкании - Умение отлаживать неожиданные результаты в LINQ и делегатах

Горизонтальное масштабирование СУБД на примере Greenplum Современные приложения работают с огромными объёмами данных, и рано
Горизонтальное масштабирование СУБД на примере Greenplum Современные приложения работают с огромными объёмами данных, и рано или поздно классические СУБД перестают справляться с нагрузкой. Выход — горизонтальное масштабирование, позволяющее эффективно распределять запросы и хранение по нескольким узлам. 📌 На вебинары вы: — Познакомитесь с концепцией горизонтального масштабирования и почему оно критически важно в высоконагруженных системах. — Разберёте архитектуру СУБД Greenplum — одного из самых мощных решений на базе PostgreSQL для работы с Big Data. — Узнаете, как устроены шардирование, партиционирование, репликация и управление кластерами в Greenplum. — Посмотрите реальные кейсы использования Greenplum в распределённых системах. 👉 Регистрация и подробности о курсе Highload Architect: https://otus.pw/zwUN/?erid=2W5zFGGPcs2 Бесплатное занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов. Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable` В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно. ⚠️ Проблема: токен есть, но он бесполезен Допустим, вы пишете такой метод:

public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
    foreach (var id in ids)
    {
        var item = await GetDataAsync(id);
        yield return item;
    }
}
Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel(). 💣 Последствия • Фоновая загрузка продолжается после отмены • Зависшие соединения, неосвобождённые ресурсы • Непредсказуемое поведение в await foreach • Сложные баги и плохая отзывчивость приложений ✅ Решение: [EnumeratorCancellation] Правильно будет вот так:

public async IAsyncEnumerable<string> FetchItems(
    [EnumeratorCancellation] CancellationToken cancellationToken)
{
    await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
    {
        cancellationToken.ThrowIfCancellationRequested();
        yield return item;
    }
}
📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется. 🧪 Как проверить

var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
    if (item == "stop") cts.Cancel();
}
Если метод реализован без [EnumeratorCancellation], цикл может не остановиться. Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно. 🛠 Best Practices ✔ Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken ✔ Внутри итератора: - Вызывайте ThrowIfCancellationRequested() - Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token) ✔ Не используйте токен «для галочки» — он должен влиять на поведение итератора ✔ Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных 📎 Заключение Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается. Одна строка — и вы защищены:

[EnumeratorCancellation] CancellationToken token
📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html 🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена. 📌 Читать @csharp_1001_notes

🎮 Unity-разработчик? Пора на новый уровень! Пройди тест, подтверди свои знания и стань студентом курса: https://otus.pw/WwBW
🎮 Unity-разработчик? Пора на новый уровень! Пройди тест, подтверди свои знания и стань студентом курса: https://otus.pw/WwBW/ Если ты уже знаком с Unity и хочешь систематизировать знания, углубиться в архитектуру и освоить профессиональные практики разработки игр, то это именно то, что тебе нужно. Мы стартуем уже 29 мая! 🧠 Что ты узнаешь: - Применение принципов SOLID и паттернов GRASP на практике - Навыки выявления и устранения антипаттернов в коде - Разработка модульной архитектуры и повторно используемого кода - Создание систем загрузки, сохранения и ИИ - Освоение фреймворков Zenject и LeoECS - Работа с Addressables и подходом Test Driven Development ⏰Скорее проходи вступительный тест и получи выгодное предложение: https://otus.pw/WwBW/ erid: 2W5zFK2mjNg

🧠 Задача на C#: "Сбалансированное стандартное отклонение" Условие Дан список чисел List<double> — это одномерное распределение значений. Нужно определить: существует ли такой индекс, при котором массив можно разделить на две части, и стандартные отклонения этих частей отличаются не более чем на `epsilon` (например, 0.1). Пример:

var data = new List<double> { 1.0, 2.0, 3.0, 6.0, 9.0 };
// Разделение после 2 → [1.0, 2.0], [3.0, 6.0, 9.0]
// std_left ≈ 0.707, std_right ≈ 3.0 → ❌ слишком большая разница
Формат функции:

public static bool HasBalancedStdSplit(List<double> data, double epsilon = 0.1)
Решение:

using System;
using System.Collections.Generic;
using System.Linq;

public class StatUtils
{
    public static bool HasBalancedStdSplit(List<double> data, double epsilon = 0.1)
    {
        int n = data.Count;
        if (n < 4) return false;

        for (int i = 2; i <= n - 2; i++)
        {
            var left = data.Take(i).ToList();
            var right = data.Skip(i).ToList();

            double stdLeft = StandardDeviation(left);
            double stdRight = StandardDeviation(right);

            if (Math.Abs(stdLeft - stdRight) <= epsilon)
                return true;
        }

        return false;
    }

    private static double StandardDeviation(List<double> values)
    {
        double mean = values.Average();
        double sumSquares = values.Sum(v => Math.Pow(v - mean, 2));
        return Math.Sqrt(sumSquares / (values.Count - 1));
    }
}
Пример использования:

class Program
{
    static void Main()
    {
        var data = new List<double> { 2, 4, 4, 4, 5, 5, 7, 9 };
        bool result = StatUtils.HasBalancedStdSplit(data, 0.5);
        Console.WriteLine($"Можно ли сбалансировать: {result}");
    }
}
Что проверяет задача: • знание статистики и работы со стандартным отклонением • навыки эффективной работы с коллекциями • аккуратность при вычислениях с double • понимание требований к длине выборки для корректной статистики @csharp_1001_notes

🚀 Silk.NET 3.0: грядущая революция в .NET-графике Сообщество Silk.NET анонсировало работу над третьей версией своего фреймво
🚀 Silk.NET 3.0: грядущая революция в .NET-графике Сообщество Silk.NET анонсировало работу над третьей версией своего фреймворка — амбициозным переосмыслением того, как должны работать низкоуровневые .NET-биндинги для графики и мультимедиа. Особенность проекта всегда заключалась в кроссплатформенности и минимальных накладных расходах при работе с GPU. В 3.0 разработчики обещают переработанную систему биндингов и улучшенную интеграцию с современными .NET-стэками. 🤖 GitHub @csharp_ci

1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟 ИТ-событие, которое нельзя пропустить. Участие бесплатное 6 июня разработчики из российских биг
1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟 ИТ-событие, которое нельзя пропустить. Участие бесплатное 6 июня разработчики из российских бигтехов на практических примерах покажут, как ИИ перестал быть экспериментом и стал частью разработки. В программе: — Больше 40 докладов от известных ученых и ИТ-компаний. — Выступления зарубежных спикеров с индексом Хирша более 50. — Концентрация практических кейсов: как создаются большие проекты с применением AI. — Доклады по архитектуре, бэкенд-разработке и построению ИТ-платформ. — AI-интерактивы и технологические квесты. — Пространство для нетворкинга, …а еще after-party со звездным лайн-апом. Когда: 6 июня Где: Москва, МТС Live Холл и онлайн Регистрация по ссылке

📌 Задача: "Высоконагружённый кэш с автоматической очисткой и конкурентным доступом" ❗️Условие: Реализуйте класс SmartCache<TKey, TValue> в .NET, который должен: - Позволять безопасно добавлять и получать элементы из кэша в многопоточной среде (`Get`, `Set`). - Автоматически удалять элементы через N секунд после их добавления (TTL). - Поддерживать высокую производительность при массовом доступе (тысячи операций в секунду). - Минимизировать блокировки (`lock`) или использовать неблокирующие структуры. - Корректно работать с истекшими элементами: - Не возвращать их через Get. - Не копить мусор в памяти. --- ▪️ Ограничения: - Можно использовать стандартные коллекции .NET (`ConcurrentDictionary`, Timer, Task, CancellationToken и т.д.). - Нельзя использовать внешние библиотеки типа MemoryCache, Redis, LazyCache и др. - Нужно поддерживать работу под большой нагрузкой (много ключей и операций параллельно). --- ▪️ Подсказки: - Для конкурентного доступа подойдёт ConcurrentDictionary<TKey, ValueWithExpiry>. - Для очистки устаревших данных: - Можно использовать фоновую задачу (`Task`) с таймером, которая периодически чистит старые записи. - Обратите внимание на гонки состояний: между проверкой срока жизни элемента и его удалением. --- ▪️ Что оценивается: - Умение проектировать потокобезопасные структуры данных. - Продуманность балансировки между скоростью операций и частотой очистки. - Правильная работа со временем жизни (`TTL`). - Чистота и лаконичность кода. --- ▪️ Разбор возможного решения: ▪️ Основная идея: - В кэше храним не просто значение, а пару (значение + время истечения). - При Get(key): - Проверяем, истёк ли элемент. - Если истёк — удаляем его и возвращаем null или default. - При Set(key, value): - Сохраняем значение с текущим временем + TTL. - Отдельная фоновая задача (`Task`) регулярно сканирует кэш и удаляет устаревшие элементы. ▪️ Мини-пример структуры:

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

public class SmartCache<TKey, TValue>
{
    private readonly ConcurrentDictionary<TKey, (TValue Value, DateTime Expiry)> _cache = new();
    private readonly TimeSpan _ttl;
    private readonly CancellationTokenSource _cts = new();
    
    public SmartCache(TimeSpan ttl)
    {
        _ttl = ttl;
        StartCleanupTask();
    }

    public void Set(TKey key, TValue value)
    {
        _cache[key] = (value, DateTime.UtcNow.Add(_ttl));
    }

    public TValue Get(TKey key)
    {
        if (_cache.TryGetValue(key, out var entry))
        {
            if (entry.Expiry > DateTime.UtcNow)
            {
                return entry.Value;
            }
            else
            {
                _cache.TryRemove(key, out _);
            }
        }
        return default;
    }

    private void StartCleanupTask()
    {
        Task.Run(async () =>
        {
            while (!_cts.Token.IsCancellationRequested)
            {
                foreach (var key in _cache.Keys)
                {
                    if (_cache.TryGetValue(key, out var entry) && entry.Expiry <= DateTime.UtcNow)
                    {
                        _cache.TryRemove(key, out _);
                    }
                }
                await Task.Delay(TimeSpan.FromSeconds(30), _cts.Token); // периодическая очистка
            }
        });
    }

    public void Dispose()
    {
        _cts.Cancel();
    }
}
📌 Важные моменты: - Кэш конкурентный (`ConcurrentDictionary`) — доступ без явных блокировок. - Периодическая чистка не мешает основным операциям. - Удаление истёкших элементов происходит "мягко" (через проверку срока жизни). - Фоновая задача корректно завершается через CancellationToken.

- ❗ Нельзя полагаться только на фоновую очистку — нужно проверять срок жизни прямо при Get. - ❗ При огромном количестве ключей (`100k+`) может быть узким местом полное сканирование всех записей каждые 30 секунд. - ❗ Нужно уметь корректно завершать работу фонового потока при остановке приложения (`Dispose`). --- ▪️ Вопросы на собеседовании: - Как бы вы модифицировали SmartCache для ограничения размера кэша (например, максимум 10_000 элементов)? - Как сделать очистку более масштабируемой, чтобы не перебирать все ключи сразу? - Как бы вы реализовали приоритетное вытеснение устаревших элементов? ---

🖥Задача: "Высоконагружённый кэш с автоматической очисткой и конкурентным доступом" 📌 Условие: Реализуйте класс SmartCache<TKey, TValue> в .NET, который должен: - Позволять безопасно добавлять и получать элементы из кэша в многопоточной среде (`Get`, `Set`). - Автоматически удалять элементы через N секунд после их добавления (TTL). - Поддерживать высокую производительность при массовом доступе (тысячи операций в секунду). - Минимизировать блокировки (`lock`) или использовать неблокирующие структуры. - Корректно работать с истекшими элементами: - Не возвращать их через Get. - Не копить мусор в памяти. --- ▪️ Ограничения: - Можно использовать стандартные коллекции .NET (`ConcurrentDictionary`, Timer, Task, CancellationToken и т.д.). - Нельзя использовать внешние библиотеки типа MemoryCache, Redis, LazyCache и др. - Нужно поддерживать работу под большой нагрузкой (много ключей и операций параллельно). --- ▪️ Подсказки: - Для конкурентного доступа подойдёт ConcurrentDictionary<TKey, ValueWithExpiry>. - Для очистки устаревших данных: - Можно использовать фоновую задачу (`Task`) с таймером, которая периодически чистит старые записи. - Обратите внимание на гонки состояний: между проверкой срока жизни элемента и его удалением. --- ▪️ Что оценивается: - Умение проектировать потокобезопасные структуры данных. - Продуманность балансировки между скоростью операций и частотой очистки. - Правильная работа со временем жизни (`TTL`). - Чистота и лаконичность кода. --- ▪️ Разбор возможного решения: ▪️ Основная идея: - В кэше храним не просто значение, а пару (значение + время истечения). - При Get(key): - Проверяем, истёк ли элемент. - Если истёк — удаляем его и возвращаем null или default. - При Set(key, value): - Сохраняем значение с текущим временем + TTL. - Отдельная фоновая задача (`Task`) регулярно сканирует кэш и удаляет устаревшие элементы. ▪️ Мини-пример структуры:

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

public class SmartCache<TKey, TValue>
{
    private readonly ConcurrentDictionary<TKey, (TValue Value, DateTime Expiry)> _cache = new();
    private readonly TimeSpan _ttl;
    private readonly CancellationTokenSource _cts = new();
    
    public SmartCache(TimeSpan ttl)
    {
        _ttl = ttl;
        StartCleanupTask();
    }

    public void Set(TKey key, TValue value)
    {
        _cache[key] = (value, DateTime.UtcNow.Add(_ttl));
    }

    public TValue Get(TKey key)
    {
        if (_cache.TryGetValue(key, out var entry))
        {
            if (entry.Expiry > DateTime.UtcNow)
            {
                return entry.Value;
            }
            else
            {
                _cache.TryRemove(key, out _);
            }
        }
        return default;
    }

    private void StartCleanupTask()
    {
        Task.Run(async () =>
        {
            while (!_cts.Token.IsCancellationRequested)
            {
                foreach (var key in _cache.Keys)
                {
                    if (_cache.TryGetValue(key, out var entry) && entry.Expiry <= DateTime.UtcNow)
                    {
                        _cache.TryRemove(key, out _);
                    }
                }
                await Task.Delay(TimeSpan.FromSeconds(30), _cts.Token); // периодическая очистка
            }
        });
    }

    public void Dispose()
    {
        _cts.Cancel();
    }
}
--- ▪️ Важные моменты: - Кэш конкурентный (`ConcurrentDictionary`) — доступ без явных блокировок. - Периодическая чистка не мешает основным операциям. - Удаление истёкших элементов происходит "мягко" (через проверку срока жизни). - Фоновая задача корректно завершается через CancellationToken. --- ▪️ Возможные подводные камни:

⚡️Легкий способ получать свежие обновления и следить за трендами в разработке на вашем языке. Находите свой стек и подписывайтесь: Python: t.me/pythonl Linux: t.me/linuxacademiya Собеседования DS: t.me/machinelearning_interview Нерйросети t.me/ai_machinelearning_big_data C++ t.me/cpluspluc Docker: t.me/DevopsDocker Хакинг: t.me/linuxkalii Devops: t.me/DevOPSitsec Data Science: t.me/data_analysis_ml Javascript: t.me/javascriptv C#: t.me/csharp_ci Java: t.me/javatg Базы данных: t.me/sqlhub Python собеседования: t.me/python_job_interview Мобильная разработка: t.me/mobdevelop Golang: t.me/Golang_google React: t.me/react_tg Rust: t.me/rust_code ИИ: t.me/vistehno PHP: t.me/phpshka Android: t.me/android_its Frontend: t.me/front Big Data: t.me/bigdatai МАТЕМАТИКА: t.me/data_math Kubernets: t.me/kubernetc Разработка игр: https://t.me/gamedev Haskell: t.me/haskell_tg Физика: t.me/fizmat 💼 Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy Папка ML: https://t.me/addlist/2Ls-snqEeytkMDgy Папка FRONTEND: https://t.me/addlist/mzMMG3RPZhY2M2Iy 😆ИТ-Мемы: t.me/memes_prog 🇬🇧Английский: t.me/english_forprogrammers 🧠ИИ: t.me/vistehno 🎓954ГБ ОПЕНСОРС КУРСОВ: @courses 📕Ит-книги бесплатно: https://t.me/addlist/BkskQciUW_FhNjEy