C# Portal | Программирование
13.3K subscribers
1.28K photos
131 videos
31 files
996 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Сотрудничество, реклама: @devmangx

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Docker тихо вырастил себе самого серьёзного конкурента.

Он называется Podman.

И всё больше Linux-разработчиков переходят на него.

Почему?

Потому что Podman убирает одну из самых спорных архитектурных особенностей Docker:

демон.

Никакого центрального фонового сервиса.
Никакого постоянно работающего процесса с повышенными привилегиями.
Никакой огромной поверхности атаки из-за привилегированного демона.

Взамен получаешь:

• rootless-контейнеры
• CLI, совместимый с Docker
• интеграцию с Kubernetes
• поддержку OCI
• pods
• интеграцию с systemd
• меньшее потребление ресурсов в простое

При этом большинство Docker-команд работают почти без изменений.

Самое интересное здесь даже не Podman.

Тренд в том, что разработчики всё чаще выбирают инфраструктурные инструменты, которые:

• легче
• работают без root-прав
• имеют открытый исходный код
• не требуют демона
• проще в защите и сопровождении

Экосистема Linux-инструментов сейчас развивается с очень высокой скоростью.

https://github.com/podman-container-tools/podman

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🐳8🔥4🍾2
This media is not supported in your browser
VIEW IN TELEGRAM
Появился новый IDE для .NET, написанный на .NET и Godot.

Называется SharpIDE - https://github.com/MattParkerDev/SharpIDE

Проект полностью open source и нацелен на .NET 10. Автор делает ставку на современный интерфейс, кроссплатформенность и быстрый цикл разработки.

Что выделяется:
• написан на .NET + Godot
• работает на Windows, Linux и macOS
• собственный отладчик SharpDbg
• открытый исходный код
• активно развивается перед релизом .NET 10

Недавно автор показал бенчмарк, где путь от Build + Debug до срабатывания breakpoint занимает около 350 мс против 1.28 с у Visual Studio и 9.22 с у Rider.

Любопытно видеть, как кто-то пытается построить полноценную .NET IDE с нуля, а не очередной VS Code-плагин.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥29👎1🍾1
Постмортемы, пожалуй, самый недооценённый способ изучать распределённые системы.

Можно смотреть доклады, читать книги и разбирать архитектурные диаграммы. Но настоящий опыт приходит, когда читаешь, как крупные компании сами уронили продакшен и потом подробно объяснили почему.

5 постмортемов, которые реально стоит прочитать:

1. GitLab — Database Outage of January 31

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

2. Slack — Incident on 2-22-22

Отличный кейс про каскадные сбои. Маленькая проблема превращается в цепочку отказов, которая начинает валить остальные компоненты системы.

3. Meta — October 4 Outage

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

4. Cloudflare — Control Plane and Analytics Outage

Хорошо показывает путь от первопричины к восстановлению сервиса и дальнейшим изменениям в архитектуре.

5. AWS — Post-Event Summaries

Целая коллекция разборов инцидентов от одной из крупнейших облачных платформ. Хороший источник для регулярного чтения.

После таких материалов начинаешь смотреть на системы иначе.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1🍾1
В .NET 11 продолжают тихо выпиливать причины писать unsafe.
Команда накидала пачку оптимизаций в JIT (и Native AOT тоже), которые убирают лишние проверки границ массива. В результате безопасный код всё чаще выдаёт ту же производительность, что и его unsafe аналог.

Если интересно следить за прогрессом, у них даже есть отдельный лейбл: https://github.com/dotnet/runtime/pulls?q=is%3Apr+label%3Areduce-unsafe
Пример: https://github.com/EgorBot/Benchmarks/issues/169

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🍾2
CQRS на самом деле намного проще, чем его обычно пытаются представить.

Я не делю систему на 15 слоёв, не тащу отдельные базы и не устраиваю культ Event Sourcing.

Просто организую код вокруг use case'ов.
Типичные примеры:
• получить профиль пользователя
• добавить товар в корзину
• оформить возврат средств

Каждый use case живёт в своей папке и отвечает за одну конкретную бизнес-задачу.
Дальше всё сводится к двум вещам:

Command
→ меняет состояние системы
→ пишет в БД
→ отправляет события
→ запускает сайд-эффекты

Query
→ ничего не изменяет
→ просто возвращает данные в том виде, в котором они нужны UI

Вот и весь CQRS.

Каждый раз, когда вижу очередную статью с отдельными read/write базами, Kafka, Event Store и диаграммой на полэкрана, вспоминаю, что CQRS изначально был просто про разделение чтения и записи.

P.S. Нет, CQRS не требует Event Sourcing.
P.P.S. Нет, CQRS не требует двух баз данных.
P.P.P.S. Да, большинство команд, которые внедряют CQRS, в итоге внедряют что-то гораздо сложнее самого CQRS. 😅

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍2😁1🍓1
Этот парень уместил RetroPad, свою версию Notepad из Windows XP с полным набором функций, всего в 2686 байт x86-ассемблера.

Да, меньше трёх килобайт.
Чтобы всем было проще запустить проект, он сразу закоммитил готовый .exe, так что возиться с MASM не придётся.
Скоро выйдет отдельный разбор того, как удалось так ужать приложение.

Код: https://github.com/PlummersSoftwareLLC/TinyRetroPad

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🍾1
Небольшой VS Code трюк для скриншотов и демонстраций.

Откройте Command Palette → Developer: Toggle Developer Tools.
Во вкладке Elements выберите body и добавьте:
filter: blur(5px);

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

Удобно, когда нужно показать IDE на скриншоте, записать видео или провести демонстрацию, не раскрывая содержимое проекта.
Чтобы вернуть всё обратно, просто перезагрузите VS Code.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6🍾1
Что такое API Gateway?

API Gateway — это «входная дверь» для ваших бэкенд-сервисов.
Он принимает запросы от клиентов и маршрутизирует их к нужным сервисам.
При этом клиенту не нужно знать, как устроена внутренняя архитектура бэкенда.
Можно рассматривать это как форму сокрытия деталей реализации.

Что обычно берёт на себя API Gateway:
• маршрутизацию запросов
• аутентификацию
• авторизацию
• балансировку нагрузки
• ограничение частоты запросов (rate limiting)

Если ищете хорошую технологию для построения API Gateway, обратите внимание на YARP. Это высокопроизводительный reverse proxy для .NET.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍53🍾2
Новичкам кажется, что хороший программист пишет быстро.

Быстро печатает. Быстро решает задачи. Быстро отвечает на вопросы.

Потом приходит опыт, и оказывается, что скорость переоценена.

Можно решить 500 задач на LeetCode и всё ещё теряться при первом реальном продакшен-инциденте. Можно знать пять языков и не понимать, почему система разваливается под нагрузкой. Можно наизусть помнить сложности алгоритмов и при этом проектировать хрупкую архитектуру.

Потому что программирование почти никогда не упирается в синтаксис.

Настоящие вопросы выглядят иначе:

• Почему это сломалось?
• Почему это решение не масштабируется?
• Почему этот крайний случай никто не учёл?
• Почему архитектура ощущается неправильной?

Хорошие разработчики отличаются не скоростью набора текста.

Они умеют сидеть с проблемой дольше остальных.

Они могут часами разбирать логическую ошибку. Переписывать решение несколько раз подряд. Удалять сотни строк кода и радоваться этому. Отказываться от «рабочего» решения в пользу правильного.

Со стороны это выглядит скучно.

На GitHub никто не выкладывает скриншот с подписью:

«Сегодня четыре часа искал одну гонку данных».

Никто не пишет:

«Шесть раз переделал архитектуру, прежде чем она начала нормально масштабироваться».

Хотя именно там и происходит рост.

Языки меняются.

Фреймворки меняются.

Тренды меняются.

Способность ясно мыслить остаётся.

Поэтому вопрос не в том, хорошо ли вы знаете программирование.

Вопрос в другом:

Можете ли вы разобраться в хаосе?

Можете ли вы построить систему из ничего?

Можете ли вы продолжать искать решение, когда ничего не работает?

Потому что программирование давно перестало быть соревнованием по скорости.

Это дисциплина мышления.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍7🍾2😁1
Вот 5 недооценённых методов LINQ, о которых стоит знать:

SequenceEqual
Aggregate
GroupJoin
ToLookup
Intersect

В LINQ есть немало полезных методов, которые помогают писать более чистый и эффективный код.
Какой метод LINQ, по твоему мнению, получает незаслуженно мало внимания?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93🍾2
This media is not supported in your browser
VIEW IN TELEGRAM
Визуализация того, как байты двигаются через память.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥54🍾1
Ты не делаешь integration tests, если тестируешь через in-memory database.

В лучшем случае это раздутый unit test.

Я видел кучу примеров с EF Core in-memory provider.

Но это не integration test, потому что настоящей базы данных там нет.

Хуже того, такие тесты не поймают баги в LINQ или SQL.

Лучший подход:

- использовать настоящую базу данных или Docker-контейнер
- подключаться к этой базе из тестов
- писать нормальные integration tests, от которых есть польза

Если хочешь использовать Docker, посмотри в сторону Testcontainers.

Он позволяет поднимать одноразовые контейнеры прямо из тестов.

А какие инструменты или подходы вы используете для integration testing?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥1🍾1
Как устроены логирование и мониторинг в Docker

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🍾1
Ваш lock в C# работает идеально.

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

В итоге два воркера могут одновременно:
→ запустить одну и ту же scheduled task
→ обновить один и тот же cache entry
→ обработать один shared resource
→ сгенерировать один и тот же отчёт
→ одновременно записать данные

А дальше начинается веселье: дубли, лишняя нагрузка, гонки и иногда сломанные данные.
Для этого и нужны distributed locks.

Они дают нескольким инстансам одно общее правило:
только один из вас делает эту работу прямо сейчас.
Не надо тащить это везде. Но если job должна выполниться один раз, или shared work не должен пересекаться, distributed lock может сэкономить много боли.

Если у вас уже есть PostgreSQL, можно начать с advisory locks.
А если нужен более чистый вариант поверх Postgres, Redis или SQL Server, можно взять готовую distributed locking library.
На одном сервере приложение может выглядеть нормально.
Настоящая проверка начинается со второго инстанса.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11🍾2😐1
Если вы программируете на Windows, стоит обратить внимание на Windows Developer Config от Microsoft.

Инструмент позволяет подготовить машину для разработки одной командой.

Что умеет:

✓ Настраивает WSL и Ubuntu
✓ Устанавливает Windows Terminal
✓ Ставит Node.js, Python, Rust, Go, Java, .NET, PHP и другие инструменты
✓ Автоматизирует настройку рабочего окружения

Проект полностью открытый и доступен на GitHub.

Удобный способ поднять новое окружение без ручной установки десятков компонентов.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣52🍾1
Фича дня в EF Core: алгоритм Hi/Lo.
С его помощью можно генерировать идентификаторы на стороне приложения и реже обращаться к базе данных.

Как это работает:
Вместо запроса нового ID для каждой записи приложение получает сразу диапазон идентификаторов.
База хранит значение hi_value, которое указывает на верхнюю границу текущего диапазона.
При запросе нового диапазона используется следующий блок ID, начиная с hi_value + 1.

Такой подход уменьшает количество запросов к базе и снижает конкуренцию за блокировки.
Есть и компромисс. Если приложение завершится до того, как использует весь диапазон, в последовательности ID появятся пропуски. На практике это редко становится проблемой.

В EF Core достаточно вызвать метод UseHiLo(). После этого EF Core создаст в базе последовательность и будет получать диапазоны идентификаторов автоматически. Дальше первичные ключи могут назначаться прямо на стороне клиента.
Особенно удобно при сохранении связанных сущностей, например родительских и дочерних записей.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾4
Большинство разработчиков неправильно понимают DRY.

Они думают, что DRY про устранение дублирующегося кода.

На самом деле DRY про дублирование знаний.

Повторяющийся код часто оказывается лишь симптомом. Настоящая проблема начинается тогда, когда одно и то же бизнес-правило разбросано по всей системе.

Если одно правило живёт в пяти местах, любое изменение становится рискованным. Исправили одно место, забыли про остальные четыре.

Где команды обычно ошибаются:

Слишком рано выносят код в общие хелперы

Создают универсальные утилиты, которые потом сложно поддерживать

Связывают между собой несвязанные части системы ради борьбы с дублированием

В итоге код становится сложнее.

Иногда дублирование вполне нормально.

Если два участка кода меняются по разным причинам, лучше оставить их отдельно. Часто это даже лучше соответствует принципу единственной ответственности.

DRY нарушается тогда, когда одна и та же причина для изменения присутствует в нескольких местах.

Примеры реальных нарушений DRY:

→ Правила валидации, скопированные между контроллерами

→ Логика ценообразования, продублированная в сервисах и фоновых задачах

→ Проверки авторизации, разбросанные по разным слоям приложения

А вот такие случаи обычно не проблема:

→ Похожие циклы, выполняющие разные задачи

→ Повторяющиеся маппинги рядом с местом использования

→ Небольшие дублирующиеся SQL или EF Core запросы

Неправильное понимание DRY часто приводит к «энтерпрайзному» коду:

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

Если один и тот же EF Core запрос из пары строк встречается в двух классах, это ещё не повод тащить в проект Repository.

Лично я придерживаюсь простого правила:

Если мне приходится копировать одну и ту же логику в третий раз, тогда стоит задуматься о выносе в отдельное место. До этого момента никакого преждевременного рефакторинга.

Когда в следующий раз увидите дублирование, задайте себе вопрос:

«Это действительно одно и то же знание или просто похожий код?»

От ответа зависит архитектура всей системы.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🍾2
Завязал с Clean Architecture.

Перешёл на Vertical Slices. И назад пока не тянет

Чтобы добавить один endpoint, приходится лазить по 4 проектам и 5 слоям
Controllers, Services, Repositories, DTOs — папок больше, чем логики
Любая мелкая правка расползается по всему решению
AI-агенты сжигают токены, пока добираются до нужной фичи

Vertical Slice Architecture.

Весь код фичи лежит в одной папке.

Что это даёт:

1. Фича = папка

Для Create Shipment:

→ CreateShipment.Endpoint.cs
→ CreateShipment.Handler.cs
→ CreateShipment.Mapping.cs
→ CreateShipment.Validators.cs

Нужно изменить фичу — открываешь одну папку и работаешь.

2. В 2026 маленькие классы реально решают

Про это почему-то редко говорят в архитектурных статьях.

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

3. Clean Architecture никто не отменял

Я не говорю, что она плохая.

Просто подключать её стоит тогда, когда проект реально дорос до этого: сложная доменная модель, несколько инфраструктурных адаптеров или жёсткие требования к изоляции слоёв.

4. Между слайсами всё равно нужны границы

VSA — не про «пусть все вызывают всех».

В модульном монолите я обычно выделяю отдельный PublicApi-проект для каждого модуля:

→ Снаружи видны только интерфейсы и DTO
→ Реализация остаётся скрытой через internal sealed
→ Если модуль однажды переедет в отдельный сервис, контракт менять не придётся

5. Побочные эффекты через события

Если Create Shipment должен обновить остатки и уведомить перевозчика, handler не дёргает их напрямую.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83🍾2
Виды Классов в C#

Абстрактный
Базовый класс, экземпляр которого нельзя создать. Он может содержать абстрактные и неабстрактные члены и предназначен для наследования от него.
public abstract class Vehicle
{
public abstract int Wheels { get; }
public abstract void TurnOn();
public bool Started { get; protected set; }
}

Создать экземпляр класса Vehicle нельзя, поэтому унаследуем от него. При этом класс-наследник обязан переопределить абстрактные члены:
public class Car : Vehicle
{
public override int Wheels => 4;
public override void TurnOn()
=> Started = true;
}


Запечатанный (sealed)
Специальный тип класса, который ограничивает иерархию наследования. Это предотвращает создание производных типов, что повышает безопасность кода и позволяет компилятору применять оптимизации производительности.
public sealed class Vehicle
{
}


Статический
Экземпляр статического класса нельзя создать, и от статического класса нельзя унаследовать. Все члены должны быть помечены статическими.
public static class SpeedConverter
{
public static decimal ToMph(decimal kph)
=> return kph / 1.6093m;
}


Частичный
В одном и том же пространстве имён нельзя создавать несколько классов с одним именем. Частичный класс позволяет разделить объявление класса на несколько файлов. При компиляции объявления объединяются в один класс. Нельзя дублировать члены с одной сигнатурой в разных объявлениях частичного класса:
public partial class Team
{
public Team() { }
public string Name { get; set; }
}

public partial class Team
{
public int Players { get; set; }
}


Небезопасный
Небезопасный класс позволяет использовать код с указателями:
public unsafe class MemoryReader
{
public void Read(int* value)
{
Console.WriteLine(*value);
}
}

Если вам необходимо работать с указателями, нужно включить небезопасный код в файле .csproj, установив параметр AllowUnsafeBlocks в значение true.

Запись
Запись — ссылочный тип, предназначенный для данных, а не для поведения, и по умолчанию является неизменяемой:
public record class Team(string Name, int Players);


Модификаторы доступа
- public – доступен отовсюду;
- internal – доступен внутри сборки;
- private – доступен только внутри включающего его типа;
- protected – доступен внутри включающего его типа и всех его наследников;
- file – доступен только внутри содержащего его файла исходного кода.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥94🍾2😁1🤯1
This media is not supported in your browser
VIEW IN TELEGRAM
Чилловый разработчик сделал “чёрную дыру” прямо в терминале, чтобы заставить себя делать перерывы.

Чем дольше работаешь без остановки, тем больше она растёт и начинает искажать код, как гравитационная линза.
Отдохнул — она уменьшается.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍81👎1🍾1
microservices-2025-roadmap.pdf
1.8 MB
roadmap по .NET-микросервисам с подборкой полезных материалов

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾6