Последние посты

.NET Разработчик
22 сент., 10:02
День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Часть 2 1-34. GROUPING SETS, ROLLUP и CUBE Для отчёта часто требуется получить сразу несколько уровней агрегации: итоговые значения по перевозчику и статусу, промежуточные итоги по перевозчику и общий итог. Наивный подход предполагает объединение нескольких запросов с помощью оператора UNION ALL. Конструкции GROUPING SETS, ROLLUP и CUBE позволяют получить все эти уровни в рамках одного запроса: SELECT carrier, status, COUNT() AS shipment_count, SUM(si.quantity) AS total_quantity FROM shipments s LEFT JOIN shipment_items si ON s.id = si.shipment_id GROUP BY GROUPING SETS ( (carrier, status), -- по поставщику и статусу (carrier), -- подытог по поставщику (status), -- подытог по статусу () -- общий итог );SELECT carrier, status, DATE_TRUNC('month', created_at) AS month,
.NET Разработчик
21 сент., 10:12
🔍Тестовое собеседование с Senior C# разработчиком уже завтра22 сентября(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle C# разработчика.Как это будет: 📂 Александр Моргунов, старший C# разработчик с опытом 7+ лет в Европейских высоконагруженных сервисах, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Александр будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос АлександруЭто бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для C# разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.Переходи в нашего бота, чтобы получить


.NET Разработчик
21 сент., 05:03
День 2791. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Часть 1 Большинство разработчиков используют лишь 20% возможностей SQL. SELECT, JOIN, GROUP BY — и на этом останавливаются. Однако у SQL есть и «второй уровень» — функции, позволяющие превратить страницу кода приложения или три отдельных запроса в одну лаконичную и понятную инструкцию. При этом они не являются новыми или экзотическими: они уже доступны в используемой вами БД.Замечание: запросы были протестированы в БД PostgreSQL. Большинство описанных функций поддерживаются и другими СУБД, хотя синтаксис может различаться.1. Обобщённые табличные выражения (CTE) Сложный запрос, оформленный как единая инструкция, труден для чтения, а вносить в него изменения ещё сложнее. CTE позволяет разбить его на последовательные именованные этапы с помощью ключевого слова WITH. Каждый этап представляет собой
.NET Разработчик
20 сент., 08:15

.NET Разработчик
20 сент., 05:04
День 2790. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.46. AutoMapper, метод расширения или операторы неявного приведения «Сравните использование AutoMapper, методов расширения и операторов неявного приведения для преобразования (маппинга) объектов в приложениях .NET. Обсудите преимущества и сценарии, наиболее подходящие для каждого из этих подходов. Приведите примеры реализации для каждого метода в минимальных API».Хороший ответ В приложениях .NET, особенно при использовании многоуровневой архитектуры, часто возникает необходимость преобразования объектов одного типа в другой. Для решения этой задачи популярны три способа: использование AutoMapper, методов расширения и операторов неявного приведения. У каждого из них есть свои преимущества и оптимальные сценарии применения.Auto
.NET Разработчик
19 сент., 05:00
День 2789. #Оффтоп #AI Важно ли По-прежнему Качество Кода? Автор оригинала: Марк СиманПока мы используем LLM как инструмент для генерации кода, за который в итоге отвечают люди, качество кода остается важным. Людям приходится проверять этот код, работать с ним, исправлять ошибки и т.п. Но что произойдёт, если люди перестанут участвовать в этом процессе? Если в будущем весь код будут писать LLM, будет ли иметь значение качество кода?Почему качество кода имеет значение Выражение «писать код в стиле YOLO (You Only Look Once)» означает создание кода без оглядки на его качество — практика, которая, откровенно говоря, преобладала десятилетиями. И всё же компании-разработчики, позволяющие своим сотрудникам так работать, в итоге сталкиваются с проблемами. Они накапливают столько технического долга, что больше не могут своевременно реагировать на запросы бизнеса.Важно уточнить: качество
.NET Разработчик
18 сент., 05:01
День 2788. #ЗаметкиНаПолях #Middleware Что Такое Промежуточное ПО и Его Подводные Камни. Окончание НачалоИзменение ответа после начала его отправки В данном случае промежуточное ПО обновляет код ответа после возврата управления из вызова next(): public async Task InvokeAsync(HttpContext ctx) { Console.WriteLine(quot;Запрос: {ctx.Request.Path}"); await _next(ctx);// Изменение статуса и ответа ctx.Response.StatusCode = StatusCodes.Status503ServiceUnavailable; await ctx.Response.WriteAsync( "<p>Эта страница недоступна</p>");Console.WriteLine(quot;Ответ: {ctx.Response.StatusCode}"); } Это приводит к возникновению исключения: System.InvalidOperationException: StatusCode cannot be set because the response has already started. (StatusCode нельзя установить, так как отправка ответа уже началась)
.NET Разработчик
17 сент., 05:00
День 2787. #ЗаметкиНаПолях #Middleware Что Такое Промежуточное ПО и Его Подводные Камни. Начало В этой серии постов разберём, что представляет собой промежуточное ПО, как написать собственный компонент и с какими неожиданными проблемами могут столкнуться разработчики.Создание промежуточного ПО Промежуточное ПО добавляется в файле Program.cs с помощью метода app.Use(): app.Use(async (ctx, next) => { Console.WriteLine(quot;Запрос: {ctx.Request.Path}"); await next(ctx); Console.WriteLine(quot;Ответ: {ctx.Response.StatusCode}"); }); Промежуточное ПО выполняется при каждом HTTP-запросе. Каждый запрос проходит через него на входе, а ответ — на выходе. Вызов next() играет ключевую роль: он обеспечивает переход к следующему компоненту в конвейере обработки. Если забыть его добавить, выполнение конвейера остановится, и все последующие компоненты промежуточного ПО не будут запущены. Недостаток
.NET Разработчик
16 сент., 05:04
День 2786. #AI Пусть Copilot Поспорит с Вами Как разработчик или архитектор, вы ежедневно принимаете множество проектных решений. Вы выбираете Redis для кэширования, отдаете предпочтение REST вместо GraphQL и так далее. Приняв решение, вы движетесь дальше, но где-то на заднем плане звучит внутренний голос: «Стоит ли беспокоить коллегу и спрашивать его мнение?», «А вдруг я что-то упустил?», «Действительно ли это правильный выбор?» GitHub Copilot может помочь вам в этом с помощью новой команды: /spar.Что это? Команда /spar переключает Copilot из режима «помоги мне это создать» в режим «убеди меня, что это плохая идея». Вместо того чтобы просто принять ваш план и сгенерировать код, Copilot начинает ставить под сомнение ваши допущения, спрашивает о граничных случаях и указывает на компромиссы, которые вы могли не заметить.Примечание: это отличается от команды /plan, которая помогает
.NET Разработчик
15 сент., 12:34

.NET Разработчик
15 сент., 05:00
День 2785. #ЗаметкиНаПолях Обеспечиваем Изоляцию Тенантов с Помощью PostgreSQL Механизм защиты на уровне строк (Row-Level Security, RLS) в PostgreSQL добавляет проверку на стороне БД поверх фильтров запросов EF Core. Он контролирует операции чтения и записи при условии, что приложение подключается под ролью, не являющейся владельцем таблицы, и устанавливает идентификатор тенанта при каждом открытии соединения.Популярна рекомендация использовать глобальные фильтры запросов для реализации мультитенантности. EF Core добавляет условие WHERE tenant_id = @tenant к каждому генерируемому запросу, поэтому разработчикам не нужно помнить об этом предикате. Однако действие фильтра ограничено: SQL-команды, отправляемые через ExecuteSql, присоединённые сущности, а также запросы с вызовом IgnoreQueryFilters() остаются вне зоны его влияния.Требуется дополнительный уровень проверки, не зависящий от
.NET Разработчик
14 сент., 05:00
День 2784. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков Если это ходит как утка и крякает как утка — значит, это утка. Применим утиную типизацию и заставим это работать в C# с помощью перехватчиков!Примечание: этот пост написан в образовательных целях, но вы смело можете использовать описанный подход в проде 😉В TypeScript можно сделать вот так: class A { Do(): void { console.log("A.Do"); } }class B { Do(): void { console.log("B.Do"); } }function foo(a: { Do(): void }) { a.Do(); }Попробуем сделать что-то подобное в C#:
.NET Разработчик
13 сент., 05:00
День 2783. #ЗаметкиНаПолях Паттерн «Производитель-потребитель» c System.Threading.Channels. Окончание Начало ПродолжениеНастройка и запуск нескольких потребителей Зарегистрируйте канал как синглтон, чтобы производитель и потребитель использовали один и тот же экземпляр, а затем добавьте столько экземпляров потребителя, сколько требуется для обеспечения нужной пропускной способности: builder.Services.AddSingleton(_ => Channel.CreateBounded<WorkItem>( new BoundedChannelOptions(100) { FullMode = BoundedChannelFullMode.Wait }));// 3 потребителя одного канала builder.Services.AddHostedService<WorkConsumer>(); builder.Services.AddHostedService<WorkConsumer>(); builder.Services.AddHostedService<WorkConsumer>(); Количество потребителей — регулятор уровня параллелизма. Один потребитель обрабатывает задачи строго последовательно, а 3 — до трёх одновременно. Настраивайте их количество с учётом
.NET Разработчик
12 сент., 05:02изменён
День 2782. #ЗаметкиНаПолях Паттерн «Производитель-потребитель» c System.Threading.Channels. Продолжение НачалоПроизводитель: конечная точка, передающая задачи Производитель просто выполняет запись. Единственный важный нюанс — как поступить, если канал переполнен; метод WriteAsync берёт это на себя: он завершается немедленно, если есть свободное место, или ожидает, пока потребитель освободит слот. [ApiController] [Route("api/[controller]")] public class ProcessController : ControllerBase { private readonly ChannelWriter<WorkItem> _writer;public ProcessController(Channel<WorkItem> ch) => _writer = channel.Writer;[HttpPost] public async Task<IActionResult> Enqueue( WorkItem item, CancellationToken ct) { // Ждёт, если канал полный
.NET Разработчик
11 сент., 05:00
День 2781. #ЗаметкиНаПолях Паттерн «Производитель-потребитель» c System.Threading.Channels. Начало Представим эндпоинт, принимающий файлы, изменяющий их размер и возвращающий ответ. В демо-версии всё работает отлично. Но в проде нагрузка растёт, и эндпойнт получает сотни запросов в секунду. Каждый запрос запускает задачу по изменению размера прямо в потоке обработки; CPU загружается до 100%, а остальные функции приложения начинают завершаться по таймауту, т.к. пул потоков перегружен. Не обязательно обрабатывать запросы сразу. Достаточно принять данные и обработать их в удобном для системы темпе. Это классическая задача типа «производитель-потребитель»: одна сторона передает задачу, а другая выполняет её со скоростью, которую реально может поддерживать. Для простейшей её реализации не нужны брокеры сообщений, достаточно System.Threading.Channels. Далее рассмотрим реализацию.Каналы в
.NET Разработчик
10 сент., 05:03
День 2780. #ЧтоНовенького #VS Избегаем Путаницы при Переключении Между Окнами Visual Studio Если вы запускаете несколько экземпляров Visual Studio одновременно для нескольких решений, все они выглядят одинаково. Бывало ли, что вы переключались между окнами и начинали работать не в том? Было бы здорово, если бы для каждого решения можно было задать свою цветовую тему. Эта функция уже реализована, и не только в отношении цвета.Откройте меню Tools > Options (Инструменты > Параметры). В верхней части окна найдите выпадающий список Applies to (Применить к) и переключите его с профиля пользователя на текущее решение (Current solution). С этого момента любые изменения настроек будут применяться только к открытому решению. Если вы закроете его и откроете позже снова, тема сохранится. А при открытии другого решения вы увидите назначенную для него цветовую схему. Выбирайте цвета с заметным


.NET Разработчик
9 сент., 05:03
День 2779. #ЧтоНовенького #NET11 Потоковая Передача JSON в .NET 11. Окончание НачалоJSON-строки: один объект на строку JSON-строки (или NDJSON - Newline Delimited JSON) — формат, который уже используется большинством инструментов потоковой обработки данных — одно значение JSON на строку, разделённые символом \n: {"Id":1,"Total":42.0} {"Id":2,"Total":19.5} {"Id":3,"Total":88.25} Каждая строка представляет собой полный, независимый JSON-документ. Потребитель читает строку, разбирает её, обрабатывает и забывает о ней. Если соединение обрывается после второй строки, первые две строки остаются действительными и пригодными для использования. Вы можете добавить четвёртую строку в файл, не затрагивая первые три. Конвейеры обработки, логи, загрузчики данных, потоки событий используют этот формат.В .NET 11 System.Text.Json может создавать его напрямую. Новые перегрузки
.NET Разработчик
8 сент., 05:01
День 2778. #ЗаметкиНаПолях Потоковая Передача JSON в .NET. Начало Допустим, у вас есть конечная точка, которая возвращает список: все заказы за последний квартал или поток показаний датчиков. Код выглядит нормально: app.MapGet("/orders/export", async (OrderService service) => { List<Order> orders = await service.GetAllAsync(); return Results.Ok(orders); }); GetAllAsync извлекает все строки в List<Order>. Затем Results.Ok передаёт весь список сериализатору, который формирует JSON-массив в памяти. Т.е. вы храните две копии данных одновременно — объекты и их сериализованную форму, — а клиент ждёт, пока не будет сериализована последняя строка, прежде чем что-либо получить.Для пары сотен строк это не заметно. При паре десятков тысяч происходит скачок потребления памяти, начинает работать сборщик мусора, и время до получения первого байта растёт, как и нагрузка на процесс при увеличении
.NET Разработчик
7 сент., 05:04
День 2777. #ЗаметкиНаПолях Конечные Точки в ASP.NET Core не Имеют Таймаута ASP.NET Core по умолчанию не применяет таймаут приложения к входящим запросам. Встроенное промежуточное ПО для таймаута запроса добавляет дедлайн, но вызывает только HttpContext.RequestAborted. Конечная точка должна передать этот токен в операцию, которую вы хотите остановить.Медленный запрос к БД или зависший вызов API могут продолжать потреблять ресурсы даже после того, как ответ перестанет быть полезным. В .NET 8 было введено промежуточное ПО для таймаута запроса, чтобы обеспечить кооперативный дедлайн обработки.Зарегистрируем промежуточное ПО и установим тайм-аут в Program.cs: var builder = WebApplication.CreateBuilder(args);builder.Services.AddRequestTimeouts();var app = builder.Build();app.UseRequestTimeouts();app.MapGet("/reports", async ( CancellationToken ct) => { await Task.Delay(TimeSpan.Fro1,510Открыть в Telegram
.NET Разработчик
6 сент., 05:01
День 2776. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.45. Проверка работоспособности и мониторинг «Как бы вы реализовали проверку работоспособности и мониторинг .NET-сервиса? Опишите инструменты и методы, которые вы бы использовали для обеспечения надёжного управления работоспособностью приложения».Хороший ответ Реализация проверки работоспособности и мониторинга включает в себя настройку конечных точек, к которым могут обращаться балансировщики нагрузки или инструменты мониторинга для проверки состояния приложения.Можно добавить и настроить проверки работоспособности, используя встроенные функции ASP.NET Core: var builder = WebApplication.CreateBuilder(args);// Добавляем проверки builder.Services.AddHealthChecks() .AddCheck("Sample Health Check", () => HealthCheckResult.Heal
