ch
Feedback

不要被骗子欺骗!Telemetrio 会找到并标记这些频道 👉 如果想查看标记,请订阅

C# 1001 notes

C# 1001 notes

前往频道在 Telegram

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

显示更多
6 687
订阅者
+224 小时
+37 天
+4030 天
帖子存档
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

❓Сталкиваетесь с задачами, когда вам нужно выбрать лучший алгоритм, но не понимаете, как анализировать их сложность? Ваш код
❓Сталкиваетесь с задачами, когда вам нужно выбрать лучший алгоритм, но не понимаете, как анализировать их сложность? Ваш код может быть медленным или неэффективным, и вы не знаете, как это исправить?  📗На открытом вебинаре 21 апреля в 20:00 мск вы освоите важные инструменты для анализа сложности алгоритмов, улучшите свой навык решения алгоритмических задач и на примере простых алгоритмов сортировки и увидите разницу при применении алгоритмов разной степени сложности. ➡️Регистрируйтесь прямо сейчас и получите скидку на большое обучение «C# Developer» по промокоду SHARP_SPEC_4: https://otus.pw/ph5R/?erid=2W5zFJYeybN Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

Вы используете локальные переменные в LINQ и используете let? 👇 Ключевое слово let позволяет вводить временную переменную пр
Вы используете локальные переменные в LINQ и используете let? 👇 Ключевое слово let позволяет вводить временную переменную прямо внутри запроса LINQ — как локальную переменную в цикле. Разбивайте сложные вычисления на части Делайте запрос модульнее и чище Меньше проходов по данным → выше производительность 👉 Простой пример: csharp

    from order in orders
    let total      = order.Items.Sum(i => i.Price * i.Quantity)
    where total > 1000
    let categories = order.Items.Select(i => i.Category).Distinct()
    select new
    {
        OrderId    = order.Id,
        Total      = total,
        Categories = categories
    };
let total = … — вычисляем сумму заказа только один раз where total > 1000 — фильтруем по готовому значению let categories = … — собираем уникальные категории

Улучшения API OrderedDictionary: новые перегрузки для TryAdd и TryGetValue возвращают позиции индексов для эффективного доступа. Обновление генерации исходного кода JSON: атрибут JsonSourceGenerationOptionsAttribute теперь поддерживает ReferenceHandler для расширенного управления сериализацией.​ Для получения более подробной информации сюда

В третьем предварительном выпуске .NET 10 Preview 3, Microsoft сосредоточила внимание на улучшении производительности, удобстве для разработчиков и современных облачных паттернах. Хотя этот выпуск не содержит значимых новых функций, он предлагает значительные усовершенствования в различных областях.​ 🔧 Основные нововведения 🐳 Нативная публикация контейнеров для консольных приложений Теперь консольные приложения могут создавать контейнерные образы с помощью команды:​ dotnet publish /t:PublishContainer Это стало возможным без необходимости устанавливать свойство <EnableSdkContainerSupport> в значение true в файле проекта. Если требуется отключить эту поддержку, можно установить это свойство в false. ​ 📦 Управление форматом контейнерных образов Разработчики получили возможность явно указывать формат контейнерного образа (.Docker или .OCI) с помощью нового свойства <ContainerImageFormat> в SDK. По умолчанию SDK выбирает формат на основе архитектуры контейнера и базового образа, но теперь это поведение можно переопределить, что особенно полезно для команд, стандартизирующихся на формате OCI. ​ 🌐 Обновления для облачных и веб-приложений ASP.NET Core: Добавлена поддержка OpenAPI 3.1, что обеспечивает лучшую интеграцию с современными API-шлюзами и инструментами проектирования. Также теперь можно обслуживать документы OpenAPI в формате YAML, что широко используется в инфраструктуре как код и DevOps-процессах.​ Blazor Web Apps: Введён новый компонент ReconnectModal для более плавной обработки отключений клиента. Улучшения также коснулись компонента QuickGrid, включая условное стилизование строк и управление пользовательским интерфейсом. Навигация стала более предсказуемой, избегая ненужной прокрутки страниц и лучше обрабатывая строки запроса. Кроме того, скрипт фреймворка Blazor теперь обслуживается как статический веб-ресурс с отпечатком, улучшая кэширование и производительность, особенно в средах с CDN или на периферии сети. ​ ⚙️ Дополнительные улучшения Оптимизация SDK: Автоматическое удаление неиспользуемых ссылок на пакеты, предоставляемые фреймворком, что снижает использование диска и улучшает производительность сборки.​ - Улучшения CLI: Введены новые алиасы команд, такие как dotnet package add, для повышения ясности и согласованности командной строки. Теперь можно генерировать скрипты автодополнения оболочки с помощью команды dotnet completions generate <SHELL> для bash, zsh, powershell и других. В интерактивных терминалах команды CLI теперь по умолчанию работают в интерактивном режиме, упрощая взаимодействие с пользователем.​ - Улучшения JIT-компилятора: Возможность деинлайнить и инлайнить методы интерфейса на массивах, улучшая производительность в коде с интенсивным использованием коллекций. Оптимизация перечисления массивов, позволяющая лучшую инлайнизацию JIT и размещение в стеке. Поддержка инлайнинга методов, которые становятся деинлайненными после предыдущих шагов инлайнинга. Разрешение размещения в стеке для небольших массивов фиксированного размера, состоящих из типов значений без указателей GC, снижая нагрузку на кучу.​ - Новые API и улучшения: Поддержка поиска сертификатов по отпечатку с использованием алгоритмов, отличных от SHA-1, таких как SHA-256. Улучшения в кодировании PEM: API PEM теперь поддерживают чтение ASCII/UTF-8 текста напрямую, упрощая кроссплатформенную работу с ключами и сертификатами. Поддержка DateOnly в ISOWeek: новые перегрузки для работы со значениями DateOnly в логике, основанной на неделях. Нормализация строк для Span<char> и ReadOnlySpan<char>: новые API позволяют выполнять нормализацию Unicode напрямую на этих типах, снижая количество выделений памяти. Для получения более подробной информации сюда

Что покажет код, представленный на картинке?
Anonymous voting

photo content

.NET митап в Нижнем Новгороде + трансляция Когда: 21 апреля, 19:00 (мск) Офлайн: КУПНО, регистрация обязательна, число мест о
.NET митап в Нижнем Новгороде + трансляция Когда: 21 апреля, 19:00 (мск) Офлайн: КУПНО, регистрация обязательна, число мест ограничено Онлайн: VK и Youtube, зарегистрируйтесь, чтобы получить ссылки на просмотр/запись. В программе доклады: • О построении распределенных систем и паттерне outbox от Андрея Цветцих (Т-Банк), • О расчете вероятности любого события инструментами .NET от Кирилла Панина (Altenar), • О миграции данных с MS SQL на Postgres SQL от Дмитрия Ершова (Рексофт).

🔧 Задача на C# для внимательных разработчиков Что выведет следующий код?

using System;
using System.Collections.Generic;

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

        for (int i = 0; i < 3; i++)
        {
            actions.Add(() => Console.WriteLine(i));
        }

        foreach (var action in actions)
            action();
    }
}
Варианты ответа: A)

1
2
B)

3
3
C)

0
0
D)

--- ✅ Правильный ответ: B Почему: Лямбда-функции захватывают переменную i по ссылке, а не её значение на каждой итерации. После завершения цикла i == 3, и все замыкания ссылаются на одно и то же i. Это классическая ловушка замыканий в C#.

🛡Хотите строить защищенные и масштабируемые микросервисы с помощью ASP.NET Core? Присоединяйтесь к открытому уроку 17 апреля
🛡Хотите строить защищенные и масштабируемые микросервисы с помощью ASP.NET Core? Присоединяйтесь к открытому уроку 17 апреля в 20:00 МСК и узнайте, как создать безопасные микросервисы с использованием JWT, OpenID Connect, и .NET Aspire. Мы разберем, как защитить API, оптимизировать производительность и внедрить современные подходы к аутентификации и авторизации. ❗️Что разберем: - Принципы и преимущества архитектуры микросервисов. - Защиту API с использованием JWT и OpenID Connect. - Инструменты .NET Aspire для оркестрации сервисов и настройки окружения. - Реальные шаги по созданию микросервисов, настройке безопасности и работе с Docker. 🚀 Урок пройдет в преддверии старта курса «C# ASP.NET Core разработчик». 🎁 Все участники получат скидку на обучение по промокоду: ASP_NET_04. Присоединяйтесь: https://otus.pw/M71Fp/?erid=2W5zFJ19jdJ Промокод действителен до 28.04.2025 Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

⚡️ .NET: валидация Minimal API В .NET 8 Preview 3 появилась встроенная поддержка валидации для Minimal API — теперь можно исп
⚡️ .NET: валидация Minimal API В .NET 8 Preview 3 появилась встроенная поддержка валидации для Minimal API — теперь можно использовать атрибуты Required, Range, StringLength и другие прямо в минималистичных контроллерах без лишнего кода. ⚙️ Microsoft добавила официальный пример: 🔗 github.com/captainsafia/minapi-validation-support 🧪 В проекте показано: - как включить AddValidation() в Program.cs - как использовать [ValidatableType] для ваших моделей - как обрабатывать ошибки валидации автоматически 🚀 Чтобы запустить пример: cd api dotnet run ✍️ Минимализм + строгая валидация = 🔥 для API! 📌 Github @csharp_1001_notes

🛠 Patroni + PostgreSQL: как обеспечить высокую доступность? Когда база данных — это сердце системы, её отказ может стоить до
🛠 Patroni + PostgreSQL: как обеспечить высокую доступность? Когда база данных — это сердце системы, её отказ может стоить дорого. Как сделать PostgreSQL отказоустойчивым и управляемым? Решение есть — Patroni! 📅 14 апреля в 20:00 (мск) 🎓 Открытый вебинар с Сергеем Кирьяковым 💡 Что разберём? ✅ Как работает Patroni и зачем он нужен для PostgreSQL ✅ Основные компоненты и архитектуру Patroni ✅ Как правильно настроить и конфигурировать Patroni ✅ Практические примеры управления кластером PostgreSQL ✅ Оптимизация, мониторинг и лучшие практики работы 🎯 Что получите? ✔️ Понимание работы Patroni и его роли в HA-кластерах PostgreSQL ✔️ Готовые практические решения по настройке и оптимизации ✔️ Навыки мониторинга и управления отказоустойчивыми базами Присоединяйтесь и узнайте, как обеспечить PostgreSQL надёжностью! 👉 Регистрируйтесь по ссылке: https://otus.pw/0sSi5/?erid=2W5zFJSpPZa Бесплатное занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов. Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

🔥 Awesome на GitHub Это курируемые подборки ресурсов (книг, статей, инструментов, библиотек и многое другое) по конкретным темам, созданные сообществом разработчиков и энтузиастов. Собрали подборку лучших из них. Сохраняйте, чтобы не потерять • C: awesome-c • C++: awesome-cpp • C#: awesome-dotnet • Хакинг: https://github.com/Hack-with-Github/Awesome-Hacking • Информационная безопасность: awesome-security • Базы данных: awesome-database-learning • JavaScript: awesome-javascript • React: awesome-react • Vue: awesome-vue • Angular: awesome-angular • Node.js: awesome-nodes • Typescript: awesome-typescript • Java: awesome-java • Go: awesome-go • Ruby: awesome-ruby • PHP: awesome-php • Kotlin: awesome-kotlin • Rust: awesome-rust • Swift: awesome-swift • iOS-разработка: awesome-ios • Android-разработка: awesome-android • Unreal Engine: awesome-unreal • Unity: awesome-unity3d • Python: awesome-python • Django: awesome-django • Data Science: awesome-datascience • TensorFlow: awesome-tensorflow • Linux: Awesome-Linux-Software • DevOps: awesome-devops • SysAdmins: awesome-sysadmin • Nginx: awesome-nginx • Kubernetes: awesome-kubernetes • Docker: awesome-docker • Автоматизация сетевой инфраструктуры: awesome-network-automation • QA: awesome-testing @cpluscsharp

Transaction Outbox: как избежать потери данных в распределённых системах В распределённых системах потеря данных — это не ред
Transaction Outbox: как избежать потери данных в распределённых системах В распределённых системах потеря данных — это не редкость. Как гарантировать целостность информации и обеспечить надёжную передачу сообщений? Transaction Outbox — шаблон, который решает проблему согласованности данных. 📅 7 апреля в 20:00 (мск) 🎓 Открытый вебинар с Олегом Мифле 💡 Что разберём? ✅ Проблемы согласованности данных в распределённых системах ✅ Как работает Transaction Outbox ✅ Как связать локальные базы данных с брокерами сообщений (Kafka, RabbitMQ) ✅ Реальные примеры внедрения шаблона в микросервисную архитектуру 🎯 Что получите? ✔️ Понимание принципов согласованности данных в распределённых системах ✔️ Практические навыки работы с Transaction Outbox ✔️ Готовые решения для построения надёжной микросервисной архитектуры 👉 Регистрация: https://otus.pw/N3xZ/?erid=2W5zFGkyYSk Занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов. Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

✔️ Визуализация алгоритмов сортировки Интерактивный инструмент, который поможет разобраться в работе ключевых алгоритмов сорт
✔️ Визуализация алгоритмов сортировки Интерактивный инструмент, который поможет разобраться в работе ключевых алгоритмов сортировки. Возможности: — сортирует массив трёхзначных чисел; — регулирует скорость; — запускает, останавливает, сбрасывает процесс; — создаёт случайный массив. 🔗 GitHub @csharp_1001_notes

💻Хотите быстро научиться строить интерактивные интерфейсы на C#? Присоединяйтесь к открытому уроку 8 апреля в 20:00 мск, где
💻Хотите быстро научиться строить интерактивные интерфейсы на C#?   Присоединяйтесь к открытому уроку 8 апреля в 20:00 мск, где мы покажем, как сделать ваш код живым и динамичным!  📖Вы научитесь использовать класс System.Console для создания простых, но интересных программ с текстовыми интерфейсами. Например, вы напишете свою версию игры "Крестики-нолики" прямо в консоли. Это легко и увлекательно!  🔥С этим знанием вы сможете не просто выводить данные, а создавать интерактивные приложения, которые смогут реагировать на действия пользователя. ➡️ Зарегистрируйтесь на вебинар и получите скидку по промокоду SHARP_SPEC_4 на большое обучение «C# Developer»: https://otus.pw/Lh8D/?erid=2W5zFJHnQcp Промокод действителен до 30.04.2025 Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.