C# Portal | Программирование
15K subscribers
756 photos
86 videos
19 files
666 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Связь: @devmangx

РКН: https://clck.ru/3FocB6
Download Telegram
В .NET 10, который выйдет в ноябре этого года, значительно оптимизируют работу с небольшими массивами

Если JIT-компилятор определяет, что массив достаточно мал и не выходит за пределы области видимости метода, он размещает его в стеке, а не в куче. Это означает, что память не аллоцируется в heap, GC не задействуется, а производительность повышается почти в два раза. 😊

Например, в .NET 9 массив из 11 элементов занимал 72 байта и выполнялся за 7.7 наносекунды. В .NET 10 те же данные, но 0 байт аллокации и всего 3.9 наносекунды. И самое главное это работает автоматически

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥122
Стриминговые API в C# — используй IAsyncEnumerable

IAsyncEnumerable оптимизирован для потоковой передачи данных и полностью совместим с async/await.

> Производители используют IAsyncEnumerable<T> с yield return
> Потребители читают данные через await foreach

Зачем нужны стриминговые API?

В отличие от bulk-передачи, стриминг отправляет данные пакетами.

Сколько и когда передавать — зависит от кода, создающего IAsyncEnumerable.
Параметр T задаёт тип элемента, который будет возвращаться в потоке.

Где особенно полезно:

1. Отправка больших (или даже бесконечных) наборов данных

Пример: поливать сад из шланга вместо таскания вёдер с водой.
Вёдра тяжелее (ресурсоёмко) и требуют ожидания (блокировка).

2. Получение внешних данных — API, IoT-сенсоры, очереди сообщений

Когда нельзя предсказать, когда будет готов следующий элемент — IAsyncEnumerable идеально подходит.

3. Снижение потребления памяти

Данные проходят потоком и не накапливаются в памяти целиком.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥71
«Сначала фильтруй, потом объединяй» звучит умно. Но это не всегда быстрее.

В SQL порядок написания клауз не определяет порядок выполнения, этим занимается планировщик запросов.

Так что, хотя кажется, что ранняя фильтрация должна уменьшить объём данных перед JOIN — на практике это часто не так.

Планировщик может:

> Самостоятельно оптимизировать стратегии объединения
> Перестраивать порядок операций
> Использовать индексы

Реальный прирост производительности даёт понимание планов выполнения, а не следование «правилам на глазок».

Вот подробный разбор этого популярного мифа про SQL и того, что на самом деле влияет на производительность

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍3🔥3
Рекомендуемые расширения для работы с Copilot prompt-файлами:

🔹File Explorer for Visual Studio — даёт доступ к prompt-файлам прямо внутри Visual Studio.
🔹Open in Visual Studio Code — позволяет удобно создавать и редактировать prompt-файлы во внешнем редакторе (VS Code)

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
9
Хотите сделать HTTP-запросы в .NET более отказоустойчивыми?

Новая библиотека Microsoft HTTP Resilience предоставляет готовый пайплайн с поддержкой:

> ограничения частоты запросов (rate limiting)
> повторных попыток (retries)
> таймаутов (timeouts)
> предохранителей (circuit breakers)

И всё это настраивается всего одной строкой кода. 😐

Разработана в сотрудничестве с Polly, эта версия быстрее и эффективнее по памяти — готова для продакшен-нагрузок.

Вот как начать использовать resilience pipelines в .NET: ссылка

А вы уже используете ретраи или circuit breakers в своих сервисах?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
10🎉1
Временные сложности различных структур данных

Big O-нотация описывает, как производительность алгоритма растёт относительно размера входных данных (n). Она используется для оценки эффективности алгоритмов вне зависимости от оборудования или языка программирования. ✌️

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍73
Одна цитата, которая идеально описывает и паттерн Singleton, и Бэтмена:

«Ты либо умираешь героем, либо живёшь достаточно долго, чтобы стать злодеем».


Так же как и Бэтмен, Singleton изначально был «с благими намерениями».

Он защищает от создания более одного экземпляра класса.

Но с годами его начали чрезмерно использовать и неправильно применять.

В итоге это привело к:

> бессонным ночам из-за багов глобального состояния
> страданиям при юнит‑тестировании

В конце концов Singleton получил ярлык антипаттерна.

Сейчас его почти не встретишь на код‑ревью.
Но, иронично, он всё ещё повсюду.

Спрятан внутри .NET.

И ты взаимодействуешь с ним каждый раз, когда вызываешь:

services.AddSingleton<YourClass>();


Если ты пишешь на C#, учить Singleton в его «классическом» виде — бесполезно.

Но сам паттерн не умер.

Он просто похоронен на глубине шести футов под фреймворками и библиотеками, которые ты используешь каждый день.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
Это может быть полезно

WhatItPrints — это браузерная головоломка для разработчиков

Тебе показывают фрагмент кода, а ты должен угадать, что он выведет.

Поддерживает разные языки, включая C#, так что отлично прокачивает:

– понимание синтаксиса
– поведение компилятора
– нюансы типов, LINQ, boxing/unboxing и т.п.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3🐳31
Если ты используешь базу данных в памяти для «интеграционных» тестов, то ты на самом деле ничего не тестируешь

In-Memory-провайдер EF — это не полноценная база. Нет индексов. Нет ограничений. Нет реального поведения запросов.

Результат? Ложное чувство уверенности и нулевая проверка логики сохранения данных.

Настоящие интеграционные тесты требуют настоящей базы данных.

Подними локальный инстанс через Docker. А ещё лучше — используй Testcontainers для .NET и управляй окружением прямо из тестов.

Вот как сделать всё правильно: гайд

А как выглядит твоя интеграционная среда? 😨

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92🔥1
Вот реальные примеры применения SOLID из .NET-приложений.

Давайте честно:

Большинство онлайн-примеров SOLID — отстой.

Если ты не пишешь приложение для зоопарка, то объяснение принципа подстановки Барбары Лисков через Dog : Animal бесполезно.

Я тоже так думал. Считал, что SOLID — это что-то абстрактное и академическое. Пока не начал видеть его в своём реальном коде. И тогда дошло.

Как SOLID выглядит в реальном C#-коде:

1. SRP (Single Responsibility Principle)

Принцип единственной ответственности

Каждый класс должен отвечать только за одну задачу — и делать её хорошо. (смотри код на 1 фото)

🔴Нарушение: "Бог-класс" UserService, который делает всё подряд:
доступ к данным, валидация, отправка email и т.д.

Решение: Разделить на отдельные классы:

• UserValidator
• UserRepository
• EmailSender

2. OCP (Open/Closed Principle)

Принцип открытости/закрытости

Классы должны быть открыты для расширения, но закрыты для изменения.

🔴Нарушение: DbContext.OnModelCreating содержит конфигурацию для всех сущностей EF Core.
Добавляешь новую сущность — приходится лезть в DbContext.

Решение: Использовать IEntityTypeConfiguration<T>. (смотри код на 2 фото)

Новая сущность — просто новый конфигурационный класс.
DbContext остаётся нетронутым.

3. LSP (Liskov Substitution Principle)

Принцип подстановки Барбары Лисков

Дочерние классы должны заменять родительские без нарушения логики.

➡️Этот принцип касается наследования.

На практике: избегай наследования в C#. Всё.

4. ISP (Interface Segregation Principle)

Принцип разделения интерфейсов

Не заставляй классы реализовывать методы, которые им не нужны.

🔴Нарушение: Интерфейс IUserService, в котором всё подряд: валидация паролей, отправка писем, логирование и т.п.

Решение: Разделить на узкоспециализированные интерфейсы:

• IUserRepository
• IPasswordValidator
• IEmailSender
• ILogger

ISP — это SRP, но для интерфейсов.

5. DIP (Dependency Inversion Principle)

Принцип инверсии зависимостей

Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций.

➡️Слои бизнес-логики не должны зависеть от инфраструктуры (БД, файловой системы, внешних API и т.п.)

Решение: В Clean Architecture слои Entities и UseCases (доменная логика) не должны зависеть от инфраструктурных слоёв.

Совмести с Vertical Slices — получишь максимум пользы.

Вот и всё.

SOLID на реальном .NET-коде. Дай знать, стало ли понятнее.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥20👌6🔥5👀41
This media is not supported in your browser
VIEW IN TELEGRAM
В VS Code Insiders теперь по умолчанию включён IntelliSense в терминале

Попробуй — ты получишь плавные и динамичные подсказки прямо в терминале, например, при переключении на другую ветку 🥰

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
14🔥5
Тебе не нужно больше покрытия тестами. Тебе нужна лучше спроектированная система.

Большинство разработчиков винят недостаточное покрытие в том, что не чувствуют уверенности в коде.
Но это — лишь вершина айсберга.

В чём настоящие проблемы?

1. Бизнес-логика размазана по сервисам и хендлерам
2. Внешние зависимости разделены неправильно
3. Доменная модель содержит только свойства, но не поведение

Как команды пытаются это решать?

Добавляют больше интеграционных тестов.

Но это создаёт ложное чувство уверенности:

• Вы сильно полагаетесь на медленные, широкие интеграционные тесты
↳ Кажется, что они надёжны. Но на деле они лишь скрывают архитектурные проблемы за хрупкой обёрткой.

• Основная логика не покрыта быстрыми unit-тестами
↳ Уверенность должна приходить от быстрого фидбека, а не от 15-минутного пайплайна.

• Вы компенсируете плохой дизайн большим количеством тестов
↳ Количество тестов не решит проблему с хаосом между сервисами и анемичной моделью домена.

Что реально работает:

→ Вся ключевая логика должна быть в насыщенной доменной модели
→ Покрывать её быстрыми, изолированными и точечными unit-тестами
→ А более высокоуровневые тесты должны лишь дополнять

Больше тестов — не решение.
Хорошая архитектура — вот что нужно

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
💯52
Трудно отследить, что происходит внутри твоего .NET-приложения?

Вот базовая настройка OpenTelemetry, которую я использую в каждом проекте:

- ASP .NET Core instrumentation
- HttpClient instrumentation
- EF Core instrumentation
- Redis instrumentation
- Npgsql (или SqlClient)

Это даёт полноценные, сквозные трассировки — и всё это быстро.

Для визуализации можно использовать:

- Seq
- Jaeger
- Grafana
- Aspire Dashboard

Seq также поддерживает структурированные логи, что хорошо сочетается с трассировкой.

Вот практическое руководство: ссылка

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍2🔥2
Производительность критична для любого приложения.

Разработчики часто добавляют слой кэширования поверх медленных SQL-запросов. Тем самым они маскируют симптомы, вместо того чтобы устранить первопричину.

В этом мы разберёмся на практике: как оптимизировать медленный реальный запрос на EF Core. EF Core предоставляет мощные инструменты, но при неправильном использовании может приводить к медленным запросам.

Автор покажет, как пошагово оптимизировал запрос на EF Core — с неприемлемых 30 секунд до сверхбыстрых 30 миллисекунд. 😮

В приложении используются следующие сущности:

🔸Users (Пользователи): каждый пользователь может иметь много постов и комментариев.
🔸Comments (Комментарии): каждый комментарий принадлежит пользователю и связан с постом.
🔸Categories (Категории): посты имеют категории.
🔸Posts (Посты): каждый пост относится к категории и может иметь множество лайков.
🔸Likes (Лайки): каждый лайк относится к посту.

Условие задачи:

Выбрать топ-5 пользователей, которые оставили наибольшее число комментариев за последние 7 дней под постами в категории ".NET".

Для каждого пользователя вернуть:

🔸UserId
🔸Username
🔸Количество комментариев пользователя (только по постам из категории ".NET" за последние 7 дней)
🔸Топ-3 поста в категории ".NET" с наибольшим числом лайков, под которыми этот пользователь чаще всего комментировал (PostId, LikesCount)

Полное разбор задачи по оптимизации EF Core-запроса — читай тут

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥4
Самая большая ошибка джуниоров? Игнорировать SQL.

Невозможно по-настоящему понять, как работают базы данных, если полагаться только на ORM.

Реляционные базы данных существуют уже более 40 лет и не просто так.

Сфокусируйся на:

🔸основах SQL
🔸моделировании данных
🔸транзакциях
🔸индексировании

Окупается быстро. Недавно я оптимизировал два запроса:

> SELECT: с 70 мс до 1 мс
> UPDATE: с 300 мс до 52 мс


Как именно — cмотрите тут

Освой SQL и ты вырастешь как разработчик в 10 раз быстрее 📖

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥21😁1
𝟰𝟱 вопросов для подготовки к собеседованию по ASP.NET Core

→ Объясните, как работает маршрутизация в ASP . NET Core
→ Что такое middleware и в каком порядке они выполняются?
→ Как можно остановить выполнение последующих middleware?
→ В чём разница между MVC и Razor Pages?
→ Назовите 3 способа создания middleware
→ Объясните, как работает многослойная конфигурация в appsettings.json
→ В чём разница между сервисами Singleton, Scoped и Transient?
→ Как использовать Scoped-сервис внутри Singleton-сервиса?
→ Как выполнить код при запуске и остановке приложения?
→ Что такое BackgroundService?
→ Назовите несколько способов чтения данных из конфигурации appsettings.json
→ Что такое Options Pattern?
→ Назовите случаи использования ISnapshotMonitor и IOptionsMonitor
→ Как валидировать конфигурацию?
→ В чём разница между DataAnnotations и FluentValidation?
→ Какие бывают атрибуты фильтров у контроллеров?
→ Почему Minimal API работают быстрее, чем контроллеры?
→ Как добавить авторизацию в проект?
→ Как добавить авторизацию ко всем методам контроллера, кроме одного?
→ Как бы вы реализовали функциональность входа в систему (Log-In)?
→ Объясните, как работают JWT-токены
→ Объясните Refresh-токены и как они работают
→ Как бы вы реализовали доступ к ресурсам на основе прав пользователя?
→ Для чего используется HostedService?
→ Объясните разницу между PeriodicTimer и await Task.Delay()
→ Что такое HSTS?
→ Как вернуть файл из API-эндпойнта?
→ Как принять файл через API-эндпойнт?
→ Как получить параметры query string в API-эндпойнте?
→ Как получить информацию о текущем авторизованном пользователе?
→ Как внедрять зависимости в Minimal API?
→ Как структурировать эндпойнты в Minimal API?
→ Что такое Output Caching?
→ В чём разница между IMemoryCache и IDistributedCache?
→ Объясните, как работает HybridCache или FusionCache
→ Какие паттерны кэширования вы знаете?
→ Для чего используется Rate Limiting и какие его типы существуют?
→ Как инвалидировать данные в OutputCache?
→ Как реализовать версионирование API?
→ Как добавить версионирование в существующий API, если нельзя менять URL?
→ Для чего используется Swagger?
→ Как задокументировать эндпойнты, модели и поля в Swagger?
→ Как получить строку подключения из конфигурации?
→ Как развернуть приложение ASP. NET Core?
→ Как настроить логирование в ASP. NET Core?


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22
Минималистичные API + версионирование API = дублирующийся беспорядок?

Нет, если сделать правильно.

Вместо того чтобы помечать каждый endpoint через ApiVersionSet, можно определить группу маршрутов.

Версию указываешь один раз — и она применяется ко всем endpoint'ам внутри группы. Чище маршруты, меньше дублирования.

Отлично работает и для префиксов вроде /v1

Хочешь увидеть, как это реализуется (и для Minimal API, и для контроллеров)?

▶️Вот гайд: ссылка

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2
Что такое JSON Web Token (JWT)?

JWT — это компактный, безопасный для передачи по URL токен, предназначенный для безопасной передачи информации между двумя сторонами — обычно между клиентом и сервером.

Он широко используется для аутентификации и авторизации в современных веб-приложениях.

JWT выглядит так: xxxxx.yyyyy.zzzzz

Он состоит из трёх частей:

🔸Header: указывает тип токена и алгоритм подписи (например, HMAC или RSA)
🔸Payload: содержит claims — данные о пользователе, такие как userId, role и т. д.
🔸Signature: используется для проверки подлинности отправителя и гарантирует, что токен не был изменён

Как это работает:

1. Пользователь входит в систему, вводя логин и пароль.
2. Сервер проверяет учётные данные и генерирует JWT.
3. Сервер отправляет токен обратно клиенту.
4. Клиент сохраняет токен (обычно в localStorage или в cookie).
5. При последующих запросах клиент добавляет JWT в заголовок Authorization

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥42👏2🐳1