CQS и CQRS — это одно и то же?
Не совсем.
CQS (разделение команд и запросов) — это принцип:
команды изменяют состояние, ничего не возвращают
запросы возвращают данные, не изменяют состояние
он применяется на уровне методов и относится к намерению, а не к жёстким правилам.
CQRS строится на этой идее уже на архитектурном уровне. Он разделяет модели чтения и записи ради масштабируемости, ясности и гибкости.
Хочешь посмотреть, как реализовать CQRS на практике?
Вот как: читать
Большинство приложений уже делают это, даже без прямого упоминания CQRS.
👉 @KodBlog
Не совсем.
CQS (разделение команд и запросов) — это принцип:
команды изменяют состояние, ничего не возвращают
запросы возвращают данные, не изменяют состояние
он применяется на уровне методов и относится к намерению, а не к жёстким правилам.
CQRS строится на этой идее уже на архитектурном уровне. Он разделяет модели чтения и записи ради масштабируемости, ясности и гибкости.
Хочешь посмотреть, как реализовать CQRS на практике?
Вот как: читать
Большинство приложений уже делают это, даже без прямого упоминания CQRS.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🍾2
azure-alphabet.pdf
2.5 MB
Хочешь уверенно работать с Azure как бэкенд-разработчик на .NET?
Кристи потратил 20+ часов, чтобы собрать «Алфавит Azure для тебя:
• Разобраться в 26 ключевых сервисах и концепциях Azure (без воды)
• Понимать, что делает каждый сервис, когда его использовать и зачем он нужен
• Стартовать путь разработки в Azure
Я его скачал и делюсь с вами!❤️ ❤️
👉 @KodBlog
Кристи потратил 20+ часов, чтобы собрать «Алфавит Azure для тебя:
• Разобраться в 26 ключевых сервисах и концепциях Azure (без воды)
• Понимать, что делает каждый сервис, когда его использовать и зачем он нужен
• Стартовать путь разработки в Azure
Я его скачал и делюсь с вами!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🍾1
Самый простой способ генерировать PDF-отчёты
Первый выбор — конвертация HTML → PDF.
В большинстве коммерческих проектов используется IronPDF.
Нужен бесплатный вариант:
- Puppeteer Sharp
- headless-версия Chrome
Но ключевая идея важнее конкретного инструмента.
Если есть HTML-шаблон, появляется полный контроль над форматированием.
Можно использовать современный CSS для стилизации HTML-разметки.
Общая схема реализации:
1. MVC-представления и Razor-синтаксис
2. Рендер динамического HTML-контента
3. Передача HTML в PDF-рендерер
Такой подход использовался в нескольких проектах с хорошими результатами.
Нужен пример реализации гибкой PDF-генерации?
Гайд: тут
👉 @KodBlog
Первый выбор — конвертация HTML → PDF.
В большинстве коммерческих проектов используется IronPDF.
Нужен бесплатный вариант:
- Puppeteer Sharp
- headless-версия Chrome
Но ключевая идея важнее конкретного инструмента.
Если есть HTML-шаблон, появляется полный контроль над форматированием.
Можно использовать современный CSS для стилизации HTML-разметки.
Общая схема реализации:
1. MVC-представления и Razor-синтаксис
2. Рендер динамического HTML-контента
3. Передача HTML в PDF-рендерер
Такой подход использовался в нескольких проектах с хорошими результатами.
Нужен пример реализации гибкой PDF-генерации?
Гайд: тут
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🍾1
Совет по LINQ:
Вызывай
Почему?
> В первом случае всё загружается в память до фильтрации
> Во втором — фильтрация происходит на источнике, что лучше для БД или больших коллекций
> Особенно важно при работе с EF Core или API, использующих
🎉 🎉
👉 @KodBlog
Вызывай
ToList() после фильтрации, а не до.Почему?
> В первом случае всё загружается в память до фильтрации
> Во втором — фильтрация происходит на источнике, что лучше для БД или больших коллекций
> Особенно важно при работе с EF Core или API, использующих
IQueryablePlease open Telegram to view this post
VIEW IN TELEGRAM
🥴12😁6🤯3🍾1
Что такое Queue<T>?
Queue<T> — это коллекция в C# с принципом FIFO (первым пришёл — первым ушёл).
То есть первый добавленный элемент будет извлечён первым.
Когда использовать?
> Планирование задач
> Очереди на печать
> Обработка сообщений
> Поиск в ширину (BFS) в графах
Пример прикрепил, с вас лайк❤️
👉 @KodBlog
Queue<T> — это коллекция в C# с принципом FIFO (первым пришёл — первым ушёл).
То есть первый добавленный элемент будет извлечён первым.
Когда использовать?
> Планирование задач
> Очереди на печать
> Обработка сообщений
> Поиск в ширину (BFS) в графах
Пример прикрепил, с вас лайк
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤1🍾1💋1
Ubuntu 26.04 поставляется с .NET 10 из коробки: новые контейнерные образы -resolute, готовность к Linux 7.0, постквантовая криптография и чистая поддержка cgroup v2.
Native AOT работает быстро: компактные бинарники + ~3 мс запуска. .NET 8/9 доступны через PPA с бэкпортами.
👉 @KodBlog
Native AOT работает быстро: компактные бинарники + ~3 мс запуска. .NET 8/9 доступны через PPA с бэкпортами.
Please open Telegram to view this post
VIEW IN TELEGRAM
Microsoft News
What’s new for .NET in Ubuntu 26.04
Ubuntu 26.04 (Resolute Raccoon) ships today with .NET 10. Here's how to install .NET 10 from the archive, use the new -resolute container tags, build Native AOT apps, and install .NET 8 and 9 from the dotnet-backports PPA.
👍10🔥5🍾4
EF Core имеет заметную просадку производительности при использовании колонок-идентификаторов.
Как это обычно решают ?
В большинстве проектов для первичных ключей используют либо автоинкремент из базы данных, либо GUID.
При вызове метода SaveChanges EF Core возвращает сгенерированное значение идентификатора, которое сформировала база.
В SQL Server EF Core применяет оператор MERGE с предложением OUTPUT, чтобы объединять множественные вставки в один запрос и возвращать новые значения идентификаторов.
Подход рабочий, но у него есть жёсткие ограничения:
- лимит в 2100 параметров: SQL Server допускает максимум 2100 параметров на один запрос. При 14 колонках это примерно 100–200 строк за одну партию. Для 10 000 строк Product это приводит к множеству обходных вызовов к базе.
- стоимость привязки параметров: каждый параметр создаётся, привязывается и отправляется по сети. Для больших объёмов это десятки тысяч параметров.
- нагрузка на отслеживание изменений: после каждой партии EF Core обновляет трекер изменений и присваивает возвращённые идентификаторы объектам.
Это заметно ухудшает производительность при массовых вставках.
При этом часто нет необходимости возвращать идентификаторы сразу после вставки.
Заявленный результат:
10 000 записей Product.
EF Core SaveChanges с возвратом идентификаторов: ~7000 мс.
Оптимизированная вставка: ~200 мс.
👉 @KodBlog
Как это обычно решают ?
В большинстве проектов для первичных ключей используют либо автоинкремент из базы данных, либо GUID.
При вызове метода SaveChanges EF Core возвращает сгенерированное значение идентификатора, которое сформировала база.
В SQL Server EF Core применяет оператор MERGE с предложением OUTPUT, чтобы объединять множественные вставки в один запрос и возвращать новые значения идентификаторов.
Подход рабочий, но у него есть жёсткие ограничения:
- лимит в 2100 параметров: SQL Server допускает максимум 2100 параметров на один запрос. При 14 колонках это примерно 100–200 строк за одну партию. Для 10 000 строк Product это приводит к множеству обходных вызовов к базе.
- стоимость привязки параметров: каждый параметр создаётся, привязывается и отправляется по сети. Для больших объёмов это десятки тысяч параметров.
- нагрузка на отслеживание изменений: после каждой партии EF Core обновляет трекер изменений и присваивает возвращённые идентификаторы объектам.
Это заметно ухудшает производительность при массовых вставках.
При этом часто нет необходимости возвращать идентификаторы сразу после вставки.
Заявленный результат:
10 000 записей Product.
EF Core SaveChanges с возвратом идентификаторов: ~7000 мс.
Оптимизированная вставка: ~200 мс.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🍾1
Использование нативной компиляции AOT в .NET для сборки DLL под Windows WinAPI: читать
Я пропустил один момент с AOT: через него можно собирать нативные библиотеки динамической компоновки. Проверил на практике — получаются небольшие стандартные DLL в стиле WinAPI, которые можно вызывать из легаси-приложений.
👉 @KodBlog
Я пропустил один момент с AOT: через него можно собирать нативные библиотеки динамической компоновки. Проверил на практике — получаются небольшие стандартные DLL в стиле WinAPI, которые можно вызывать из легаси-приложений.
Please open Telegram to view this post
VIEW IN TELEGRAM
West-Wind
Using .NET Native AOT to build Windows WinAPI Dlls
Did you know that you can use .NET AOT compilation to create native Windows DLLs to potentially replace traditional C/C++ compiled DLLs? It's now possible to build completely native DLLs that can be called from external applications and legacy applications…
👍5🍾2
.NET MAUI работает на Linux через GTK4. Команда экспериментирует с этим в maui-labs, и реализация уже выглядит очень полной. Есть Shell, Blazor Hybrid, CollectionView, жесты, анимации. Всё на нативных виджетах GTK4.
https://github.com/dotnet/maui-labs/tree/main/platforms/Linux.Gtk4
👉 @KodBlog
https://github.com/dotnet/maui-labs/tree/main/platforms/Linux.Gtk4
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15🍾5
SkiaSharp 4.0 Preview 1 вышел — более быстрый рендеринг, более чистые API и более умное формирование текста для .NET-приложений, которые рисуют… что угодно.
Попробуй и посмотри, на что теперь способны твои графические компоненты: https://ift.tt/k9wTbRv
👉 @KodBlog
Попробуй и посмотри, на что теперь способны твои графические компоненты: https://ift.tt/k9wTbRv
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🍾2
Я написал два почти одинаковых SQL-запроса.
Один из них оказался быстрее в 451 раз.
Я реализовывал постраничную навигацию через курсор.
И подумал: почему бы не добавить индекс, чтобы ускорить запрос?
Вот здесь всё пошло не по плану.
Есть сканирование индекса через составной индекс. На первый взгляд — всё нормально.
Но запрос стал даже медленнее, чем без индекса.
В чём причина?
Можно было бы подумать, что дело в слишком маленьком объёме данных, где индекс просто не даёт выгоды.
Но дело было не в этом…
А что если использовать сравнение кортежей в SQL?
В итоге индекс начал работать — 0.668 мс.
Оптимизатор запросов не смог корректно понять, можно ли применить составной индекс для построчного сравнения.
Но при сравнении кортежей индекс начал использоваться эффективно.
Если бы я не посмотрел план выполнения запроса, я бы это не понял.
👉 @KodBlog
Один из них оказался быстрее в 451 раз.
Я реализовывал постраничную навигацию через курсор.
И подумал: почему бы не добавить индекс, чтобы ускорить запрос?
Вот здесь всё пошло не по плану.
Есть сканирование индекса через составной индекс. На первый взгляд — всё нормально.
Но запрос стал даже медленнее, чем без индекса.
В чём причина?
Можно было бы подумать, что дело в слишком маленьком объёме данных, где индекс просто не даёт выгоды.
Но дело было не в этом…
А что если использовать сравнение кортежей в SQL?
В итоге индекс начал работать — 0.668 мс.
Оптимизатор запросов не смог корректно понять, можно ли применить составной индекс для построчного сравнения.
Но при сравнении кортежей индекс начал использоваться эффективно.
Если бы я не посмотрел план выполнения запроса, я бы это не понял.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤2🍾2
Стоит ли перестать использовать случайные UUID в .NET?
Классический UUID через
Из-за случайного порядка появляются:
- дорогие ребалансировки индексов;
- просадка скорости вставки;
- высокая фрагментация.
Поэтому многие перешли на ULID — 128-битный сортируемый идентификатор с сохранением уникальности.
ULID сохраняет временной порядок генерации, благодаря чему лучше работает с индексами.
Но начиная с .NET 9 появился более нативный вариант:
✅
UUID V7 — это time-ordered UUID с полной совместимостью с
Фактически получаете преимущества ULID, но уже встроенные в .NET.
👉 @KodBlog
Классический UUID через
Guid.NewGuid() генерируется случайным образом. Для уникальности это отлично, но для базы данных — не лучший вариант.Из-за случайного порядка появляются:
- дорогие ребалансировки индексов;
- просадка скорости вставки;
- высокая фрагментация.
Поэтому многие перешли на ULID — 128-битный сортируемый идентификатор с сохранением уникальности.
ULID сохраняет временной порядок генерации, благодаря чему лучше работает с индексами.
Но начиная с .NET 9 появился более нативный вариант:
Guid.CreateVersion7()UUID V7 — это time-ordered UUID с полной совместимостью с
Guid, без сторонних пакетов.Фактически получаете преимущества ULID, но уже встроенные в .NET.
Please open Telegram to view this post
VIEW IN TELEGRAM
👌8🔥3🍾1
This media is not supported in your browser
VIEW IN TELEGRAM
Каждый бэкенд-инженер должен уметь ответить на вопрос:
Что произойдёт, если база данных упадёт посреди транзакции?
Причины могут быть разные: отключение питания, сбой оборудования и т.д.
Чтобы не потерять данные, система должна сохранять их на энергозависимом хранилище, например, на диске.
Когда пользователь выполняет транзакцию, база данных делает две вещи:
> записывает данные в отдельный лог
> применяет обновление
Лог нужен для повторной обработки транзакции при перезапуске, чтобы восстановить консистентное состояние после сбоя.
Запись в лог быстрая, так как это бинарный файл с добавлением только в конец (append-only).
Это исключает затратные операции поиска по файлу.
А если база распределённая?
Тут сложнее — серверам базы нужно координироваться с помощью протокола двухфазной фиксации (2PC).
В этом процессе один из серверов выступает координатором:
> он отправляет всем участникам запрос на коммит
> ждёт подтверждения от всех
> затем сообщает коммитить или откатить транзакцию
👉 @KodBlog
Что произойдёт, если база данных упадёт посреди транзакции?
Причины могут быть разные: отключение питания, сбой оборудования и т.д.
Чтобы не потерять данные, система должна сохранять их на энергозависимом хранилище, например, на диске.
Когда пользователь выполняет транзакцию, база данных делает две вещи:
> записывает данные в отдельный лог
> применяет обновление
Лог нужен для повторной обработки транзакции при перезапуске, чтобы восстановить консистентное состояние после сбоя.
Запись в лог быстрая, так как это бинарный файл с добавлением только в конец (append-only).
Это исключает затратные операции поиска по файлу.
А если база распределённая?
Тут сложнее — серверам базы нужно координироваться с помощью протокола двухфазной фиксации (2PC).
В этом процессе один из серверов выступает координатором:
> он отправляет всем участникам запрос на коммит
> ждёт подтверждения от всех
> затем сообщает коммитить или откатить транзакцию
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3❤🔥2🍾1
REST API best practices в 2025
Антон Мартынов собрал опыт после 100+ реализованных API
1. уровни зрелости REST
уровень 0: один эндпоинт (лучше избегать)
уровень 1: несколько ресурсов
уровень 2: корректное использование HTTP-методов
уровень 3: HATEOAS (когда действительно нужно)
2. именование ресурсов
используются существительные:
не используются глаголы:
важна консистентность:
не смешивать стили:
3. HTTP-методы и коды статусов
методы:
- GET → чтение
- POST → создание
- PUT / PATCH → обновление
- DELETE → удаление
коды успеха:
- 200 → успех
- 201 → создано
- 202 → принято (асинхронная обработка)
- 204 → без тела ответа
коды ошибок клиента:
- 400 → некорректный запрос
- 401 → неавторизован
- 403 → доступ запрещён
- 404 → не найдено
- 422 → ошибка валидации
коды ошибок сервера:
- 500 → внутренняя ошибка
- 503 → сервис недоступен
4. версионирование API
варианты:
- через URI:
- через заголовок:
- через media type:
мчерез query string:
5. запросы и ответы
- всегда JSON
- единый формат ошибок
- поддержка фильтрации и пагинации
- документация через OpenAPI / Swagger
6. безопасность
- HTTPS везде
- OAuth2 / JWT авторизация
- ограничение частоты запросов
- валидация входных данных
- кэширование ответов
👉 @KodBlog
Антон Мартынов собрал опыт после 100+ реализованных API
1. уровни зрелости REST
уровень 0: один эндпоинт (лучше избегать)
уровень 1: несколько ресурсов
уровень 2: корректное использование HTTP-методов
уровень 3: HATEOAS (когда действительно нужно)
2. именование ресурсов
используются существительные:
/users, /ordersне используются глаголы:
/getUsers, /createOrderважна консистентность:
user-profiles или product-cartsне смешивать стили:
UserProfiles, userProfiles3. HTTP-методы и коды статусов
методы:
- GET → чтение
- POST → создание
- PUT / PATCH → обновление
- DELETE → удаление
коды успеха:
- 200 → успех
- 201 → создано
- 202 → принято (асинхронная обработка)
- 204 → без тела ответа
коды ошибок клиента:
- 400 → некорректный запрос
- 401 → неавторизован
- 403 → доступ запрещён
- 404 → не найдено
- 422 → ошибка валидации
коды ошибок сервера:
- 500 → внутренняя ошибка
- 503 → сервис недоступен
4. версионирование API
варианты:
- через URI:
/api/v1/users- через заголовок:
X-Api-Version- через media type:
application/vnd.api.v1+jsonмчерез query string:
?version=1 (не рекомендуется)5. запросы и ответы
- всегда JSON
- единый формат ошибок
- поддержка фильтрации и пагинации
- документация через OpenAPI / Swagger
6. безопасность
- HTTPS везде
- OAuth2 / JWT авторизация
- ограничение частоты запросов
- валидация входных данных
- кэширование ответов
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9🍾2
net-developer-resources.pdf
4.3 MB
Сборник 650+ отобранных ресурсов для прокачки C#, .NET, ASP .NET Core, EF Core и микросервисов
👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Если ты разработчик и пишешь код каждый день — помни 5 вещей:
1. Сначала сделай, чтобы работало
2. Потом сделай красиво
3. Добавь надёжность большим количеством тестов
4. Держись подальше от оверинжиниринга
5. Рефактори, если нужно (а обычно нужно)
Рефакторинг — твоя суперсила для очистки кода.
Вот несколько проверенных техник рефакторинга
👉 @KodBlog
1. Сначала сделай, чтобы работало
2. Потом сделай красиво
3. Добавь надёжность большим количеством тестов
4. Держись подальше от оверинжиниринга
5. Рефактори, если нужно (а обычно нужно)
Рефакторинг — твоя суперсила для очистки кода.
Вот несколько проверенных техник рефакторинга
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12🍾3
Проекция в LINQ на C#: Select, SelectMany и «сплющивание» коллекций
Разбор проекции в LINQ на C# с использованием селект, селектмани и метода Index() в .NET 9. Рассматриваются анонимные типы, записи, разворачивание вложенных коллекций и практические примеры.
Читать статью: https://bgh.st/vrpbm0
👉 @KodBlog
Разбор проекции в LINQ на C# с использованием селект, селектмани и метода Index() в .NET 9. Рассматриваются анонимные типы, записи, разворачивание вложенных коллекций и практические примеры.
Читать статью: https://bgh.st/vrpbm0
Please open Telegram to view this post
VIEW IN TELEGRAM
Dev Leader
LINQ Projection in C#: Select, SelectMany, and Flattening Collections
Learn LINQ projection in C# with Select, SelectMany, and the .NET 9 Index() method. Covers anonymous types, records, flattening nested collections, and real exa
🍾1
Тестовая пирамида была хорошим советом для 2009 года.
Я не думаю, что это хороший совет для современных .NET-систем.
Тогда интеграционные тесты были дорогими:
общие серверы баз данных, нестабильный CI, медленные сборки, болезненная настройка окружения.
Поэтому рекомендация имела смысл:
писать много модульных тестов, мокать всё подряд, держать интеграционные тесты в минимальном объёме.
Но экономика изменилась.
С Testcontainers можно поднять PostgreSQL, Redis и RabbitMQ за секунды.
С Aspire можно собрать граф приложения и протестировать реальные границы системы.
Это меняет само понятие «быстрой обратной связи».
Для меня набор тестов с высокой уверенностью сейчас выглядит так:
Тонкий слой модульных тестов для чистой доменной логики.
Толстый слой интеграционных тестов на реальной инфраструктуре.
Несколько критичных end-to-end тестов для сценариев, которые реально больно ломать.
И архитектурные/контрактные тесты, чтобы границы со временем не «плыли».
Я всё ещё пишу модульные тесты.
Просто не для всего.
Хендлеры, эндпоинты, репозитории, консьюмеры сообщений и API модулей обычно относятся к интеграционным тестам.
Именно там чаще всего и прячутся реальные баги.
👉 @KodBlog
Я не думаю, что это хороший совет для современных .NET-систем.
Тогда интеграционные тесты были дорогими:
общие серверы баз данных, нестабильный CI, медленные сборки, болезненная настройка окружения.
Поэтому рекомендация имела смысл:
писать много модульных тестов, мокать всё подряд, держать интеграционные тесты в минимальном объёме.
Но экономика изменилась.
С Testcontainers можно поднять PostgreSQL, Redis и RabbitMQ за секунды.
С Aspire можно собрать граф приложения и протестировать реальные границы системы.
Это меняет само понятие «быстрой обратной связи».
Для меня набор тестов с высокой уверенностью сейчас выглядит так:
Тонкий слой модульных тестов для чистой доменной логики.
Толстый слой интеграционных тестов на реальной инфраструктуре.
Несколько критичных end-to-end тестов для сценариев, которые реально больно ломать.
И архитектурные/контрактные тесты, чтобы границы со временем не «плыли».
Я всё ещё пишу модульные тесты.
Просто не для всего.
Хендлеры, эндпоинты, репозитории, консьюмеры сообщений и API модулей обычно относятся к интеграционным тестам.
Именно там чаще всего и прячутся реальные баги.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔3❤🔥1❤1🍾1
ИИ-агенты заменят джунов и мидлов .NET-разработки
Джун и мидл часто пропускают базовые принципы и начинают срезать углы на каждом шаге через ИИ.
ИИ усиливает уже имеющиеся знания.
Если фундамент слабый, сложно заметить, когда Claude или Copilot генерирует код с тонкими ошибками.
И такие ошибки будут.
Достаточно часто, чтобы это стало проблемой в продакшене.
Чем сильнее фундамент, тем лучше способность оценивать, что оставить, что исправить, а что выбросить.
Вот 5 базовых областей, которые определяют выживаемость в эпоху ИИ:
𝟭. 𝗛𝗧𝗧𝗣
→ Джун: выкатывает контроллер, сгенерированный ИИ.
→ Сеньор: замечает отсутствие идемпотентности у POST, некорректные коды ответов, утечку стектрейса в ошибках.
𝟮. Конкурентность
→ Джун: просто пишет асинхронный метод.
→ Сеньор: ловит отсутствие прокидывания CancellationToken по цепочке вызовов и .Result, который даёт дедлок под нагрузкой.
𝟯. 𝗘𝗙 𝗖𝗼𝗿𝗲 и БД
→ Джун: видит код, который компилируется.
→ Сеньор: замечает N+1 запрос, отсутствие AsNoTracking, IQueryable, который материализует миллионы строк в память.
𝟰. Архитектура 𝘁𝗿𝗲𝗶𝗱-𝗼𝗳𝗳𝘆
→ Джун: принимает микросервисы, потому что так предложил Claude.
→ Сеньор: задаёт вопрос, почему не начать с модульного монолита и не выделять сервисы позже при необходимости.
𝟱. Валидация и обработка ошибок
→ Джун: держит try/catch внутри эндпоинта.
→ Сеньор: понимает, что Result<T> лучше для бизнес-потока, а FluentValidation лучше, чем inline if-else.
👉 @KodBlog
Джун и мидл часто пропускают базовые принципы и начинают срезать углы на каждом шаге через ИИ.
ИИ усиливает уже имеющиеся знания.
Если фундамент слабый, сложно заметить, когда Claude или Copilot генерирует код с тонкими ошибками.
И такие ошибки будут.
Достаточно часто, чтобы это стало проблемой в продакшене.
Чем сильнее фундамент, тем лучше способность оценивать, что оставить, что исправить, а что выбросить.
Вот 5 базовых областей, которые определяют выживаемость в эпоху ИИ:
𝟭. 𝗛𝗧𝗧𝗣
→ Джун: выкатывает контроллер, сгенерированный ИИ.
→ Сеньор: замечает отсутствие идемпотентности у POST, некорректные коды ответов, утечку стектрейса в ошибках.
𝟮. Конкурентность
→ Джун: просто пишет асинхронный метод.
→ Сеньор: ловит отсутствие прокидывания CancellationToken по цепочке вызовов и .Result, который даёт дедлок под нагрузкой.
𝟯. 𝗘𝗙 𝗖𝗼𝗿𝗲 и БД
→ Джун: видит код, который компилируется.
→ Сеньор: замечает N+1 запрос, отсутствие AsNoTracking, IQueryable, который материализует миллионы строк в память.
𝟰. Архитектура 𝘁𝗿𝗲𝗶𝗱-𝗼𝗳𝗳𝘆
→ Джун: принимает микросервисы, потому что так предложил Claude.
→ Сеньор: задаёт вопрос, почему не начать с модульного монолита и не выделять сервисы позже при необходимости.
𝟱. Валидация и обработка ошибок
→ Джун: держит try/catch внутри эндпоинта.
→ Сеньор: понимает, что Result<T> лучше для бизнес-потока, а FluentValidation лучше, чем inline if-else.
Please open Telegram to view this post
VIEW IN TELEGRAM
👎7❤4🍾1