tgindex
C# Short Posts 🔞

C# Short Posts 🔞

Статистика
@dimasshortpostsрусский

Здесь я, Дима Афонченко @Undermove1, публикую короткие заметки о разработке (и около). Я не претендую на правильность высказываний и открыт к дискуссиям, исправлениям и конструктивной критике. С любыми деструктивными вещами можно приходить в комменты)

Последний пост
12 авг.
Последнее чтение
08:48
Постов за неделю
3
Всего постов
44
Тип
открытый
Язык
русский
В каталоге с
12 авг.
Подписчики
306
0 за 4 дн.
Сутки
+1
+0,33%
Неделя
 
Месяц
 
Просмотров на пост
321
40 постов
Вовлечённость
104,9%
к подписчикам
Постов в день
0,4
всего 44
Упоминаний
1
каналов
Охват размещения
оценка
1/24сутки в ленте
200
1/48двое суток
229
1/72трое суток
247

Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.

Посты

  • без подписи

  • 🚀 Новая серия: от кода до железа Когда в мою жизни пришла #ИИшница, я понял, что с ней можно очень глубоко погрузиться в любую тему: как в устройство баз данных, так и в устройство программ😣 Мне стало интересно разложить прям по байтикам максимально простой однострочный "Hello world!"🖥 Оказалось, что он как торт 🎂 (или как лук🧅, или как огр 🤥), состоит из нескольких слоёв 🔥 Между строкой, которую ты пишешь, и транзистором, который её исполняет, ещё целая стопка: компилятор, рантайм, операционная система, и процессор. Давай вместе пройдём через все эти слои сверху вниз🔽 Начнём с самого начала. Вот файл hello.cs: Console.WriteLine("Hello, World!"); Вот команда запуска: dotnet run hello.cs ⚙️ Что происходит под капотом Код на C# не исполняется напрямую на процессоре. Сначала компилятор (его зовут Roslyn) переводит наш код в промежуточный байт-код — IL (Intermediate Language). Это ещё не инструкции процессора, а переносимый «полуфабрикат». Потом стартует рантайм — CoreCLR, движок .NET. Он берёт IL и уже на лету, прямо во время работы, до-компилирует его в настоящие инструкции процессора. Это называется JIT (Just-In-Time): метод компилируется в момент первого вызова. Важная деталь про масштаб: IL-код нашей строки весит 11 байт, а рантайм, который его исполняет, весит 77 МБ. То есть наш с тобой код — это тонкая надстройка над огромным механизмом, который работает задолго до первой инструкции нашего кода и делает всё необходимое, чтобы мы увидели заветные строки на экране⚙️ Что именно он делает? Создаёт потоки Поток (thread) — это отдельная линия исполнения внутри процесса нашей программу, которую операционная система раскладывает по ядрам процессора. В одном процессе их может быть достаточно много. Сколько? Правильный ответ, конечно, «зависит». При отладке их можно получить целых 7! 7️⃣ И число это не фиксированное, его можно регулировать 🔧 А что ещё? Занимает память 🫡 Физически процесс держит около 24 МБ, но нашей программы там почти нет: больше 20 МБ — это сам рантайм (движок CLR, JIT-компилятор, библиотека базовых типов). Из нашего там два места: 🔲стеки потоков: у каждого из семи потоков свой стек под локальные переменные и кадры вызовов функций. Под него резервируется несколько мегабайт адресов, но физически занято по паре килобайт на поток 🕳 GC-куча (heap): здесь живут объекты, созданные через new. За этим простым словом скрывается целый мир со своими регионами: 👶gen0/👨‍🦱gen1/👴gen2 — здесь хранятся разные поколения «обычных» объектов (размером до 85 000 байт) 🌾 LOH — большие объекты (от 85 000 байт) 📍 POH — закреплённые (pinned) объекты 🧊 FOH — литералы и «вмороженные» объекты И это далеко не всё! 🅰️ Что с этим делать 🟢 Программы работают на целой стопке слоёв: от кода и компилятора до операционной системы и процессора 🟢 За классическим «Hello world» стоит огромный механизм — рантайм, который делает всё необходимое, что наша программа сработала в том окружении, в котором оказалась Если тебе что-то не понятно из вышесказанного👆 — не страшно, мне тоже многое не понятно, так что будем разбираться вместе🫂 Постепенно углубимся в каждую тему и разберёмся, как это всё работает💪 🧑‍💻dp🥁 #dotnet #csharp #инженерныештучки #heavywednesday

  • Оу, наконец мой доклад с Dotnext 2025 выложили! Теперь можно побороть страх k8s в любом месте в любое время! #k8s #dotnext

  • без подписи

  • без подписи

  • без подписи

  • без подписи

  • без подписи

  • без подписи

  • без подписи

  • Модный dev'ан @dimasshortposts #http #модныйdevан

  • 🔎 У HTTP появился новый метод QUERY Двадцать лет индустрия пытается ответить на главный вопрос жизни, вселенной и всего такого. А именно: как посылать сложные запросы? Потому что если посылать GET, то у него есть ограничения по длине. К примеру Nginx по умолчанию рубит строку запроса на 8 КБ. Плюс тело у GET семантически не определено: ты можешь его положить, но его по дороге могут не передать. Двадцать лет индустрия отвечала на этот вопрос: 4️⃣ 2️⃣ И вот наконец в этом году стала отвечать 6️⃣7️⃣ Ладно, это все шутки. На самом деле предлагалось взять метод POST, который создан совсем для другого, и заворачивать все в него, и в общем это так и работает. Минусы у этого подхода вот такие. POST по своей сути не идемпотентный. Словил таймаут, повторить не можешь (ну если следовать правилам): вдруг оно там уже что-то создало. Закэшировать тоже нельзя. На редиректе метод может схлопнуться в GET вместе с телом. Ну и в логах с трейсами твой поиск по каталогу выглядит как запись в БД. 📬 Но! НО! буквально на днях мы дожили. В июне 2026 приняли RFC 10008, и стал доступен новый метод: QUERY. Тело как у POST, семантика как у GET. Идемпотентный и кэшируемый. Вообще, для меня это шок. Я вообще такого, мне кажется, никогда не видел. Может, я просто не следил и новые методы появляются постоянно? Не знаю, но я вижу это в первый раз. И это прикольно. Теперь про дотнет. Десятка метод уже поддерживает: HttpMethod.Query на клиенте, HttpMethods.Query и IsQuery() на сервере, Kestrel умеет его парсить. На пояснительно дикпике можно ознакомиться с тем, как выглядит все это на посылку и на прием 🍆 Пока что MapQuery() для minimal API и [HttpQuery] для контроллеров недоступны, обещают вернуться в .NET 11-й. Но мне кажется что не проблема написать свой экстеншен метод, если будет нужно. Это все круто, но как вы понимаете в этой бочке дёгтя все вышеперечисленной было лишь чайной ложечкой мёда. 🔞 Использовать не получится еще лет 20: не все маршрутизаторы, устройства, вафы и прочие промежуточные узлы умеют правильно понимать QUERY. Незнакомый метод обычно скорее всего закэнселят по по allowlist'у. Но кое-что можно придумать: 1️⃣ Во-первых, можно делать фоллбэк на обычный стандартный POST: не получилось QUERY, ловишь 405 или сетевую ошибку и повторяешь POST'ом на тот же эндпоинт. Собрал демку, где это видно вживую: тумблер включает злой прокси, тот режет QUERY, фронт молча уезжает на POST. 2️⃣ Во-вторых, если хочется общаться между сервисами, то QUERY можно брать уже сейчас: там вы контролируете среду выполнения целиком. Так что в межсервисных взаимодействиях ни в чем себе не отказывайте. Если вы, конечно, еще отказываете. Есть идейка попробовать реализовать схемку с фоллбэком на рабочем проекте: сначала QUERY, не получилось, фоллбэк на POST. А потом посмотреть статистику, сколько запросов реально проходит с QUERY, а сколько нет. Но это если будет свободное время, а его, скорее всего, не будет. 🍾 Но вдруг кто-то поставит такой эксперимент, было бы очень интересно посмотреть на цифры. Кстати, у нас есть технопосиделка и для нее я быстренько навайбкодил презу про QUERY. Делюсь с вами. Вдруг удобнее пролистать всё это слайдами. 👋 Ну и заделитесь постом с коллегами, мне кажется что среди дотнетных каналов мало как-то уделено времени столь легендарному событию! #csharp #dotnet #http

  • без подписи

  • Почти всё лето мы с тобой изучали внутрянку БД на примере #postgresql: от индексов мы спустились по Б+-деревьям до work mem и узнали насколько глубока восьмиикилобайтовая страница 📄 Теперь поплывём дальше 🛳 На нашей steam state machine мы пойдём по бурным рабочим потокам (worker thread), воочию увидим их освобождение на асинхронном водопаде, который приведёт нас к бескрайнему озеру памяти 🫡 Там мы увидим, как различные объекты сбились в несколько поколений кучи (heap), сдерживаемой лишь DOTNET_GCHeapHardLimitPercent. Некоторые из них довольно глубоко пустили корни, так что финализировать их приходится в несколько проходов, а некоторые оказались настолько холодными, что образовали свои айсберги Frozen object heap 🧊 В концов концов мы увидим, как, параллельно с другими, наша программа последовательно впадает в океан ЦПУ🤩 и выполняет своё предназначение в этом круговороте исполнения, печатая у тебя на экране заветные слова: Hello, world! По крайней мере таков горизонт нашего планирования, к которому мы стремимся 🌅 Возможно шторма жизни и обратной связи изменят наш с тобой курс, но мы всё равно будем стремиться к общей цели: лучше узнать платформу, на которой работаем 🗼и прочие #инженерныештучки 🧑‍💻dp🥁 Это #heavywednesday, мои чюваки

  • 🗞 Что почитать за июль — мой топ-3 для ASP.NET-щика Возвращаюсь к нерегулярной рубрике (в мае был такой же топ за апрель). Как и всегда июль вышел с перекосом в AI-инструменты для дотнетчика, но и обычного бэкендерского добра завезли. 1️⃣ Много хайпа вокруг .NET 11 Preview 6. Там много чего завезли, но лично мне нравятся вот эти штуки: 🟢 CSRF-защита теперь работает по умолчанию. Приложение теперь само отбивает небезопасные кросс-origin запросы, глядя на заголовки Sec-Fetch-Site и Origin. Никаких токенов и никакой конфигурации. Завезли в minimal API, MVC, Razor Pages и Blazor. Отключается через .DisableAntiforgery() на эндпоинте или ключом DisableCsrfProtection на всё приложение. Это довольно круто, так как раньше можно было и не знать, что такую штуку надо включать. 🟢 Асинхронная валидация наконец нормальная: приехали AsyncValidationAttribute и IAsyncValidatableObject, и Microsoft.Extensions.Validation умеет их гонять при валидации запроса. То есть «проверь, не занят ли этот email» пишется своим атрибутом, который спокойно дёргает сервис через DI и await. Это полный топчик! 🔝 Так как раньше приходилось чутка изголяться. 🟢 Union-типы. Про них я уже говорил в прошлый раз. Но я по чатикам вижу, что народ прям обсуждает. Кто-то не понимает для чего оно, а кто-то наоборот люто хайпит. Мне оно скорее средне. 🟢 Четыре новых стрима: ReadOnlyMemoryStream, WritableMemoryStream, ReadOnlySequenceStream и StringStream. Это вот тоже неплохо. Мне вот особенно инетересен StringStream в контексте работы с текстами Базы Знаний. 2️⃣ MCP C# SDK v2.0 Главное — HTTP-транспорт стал stateless по умолчанию. Раньше сессия жила в памяти конкретного инстанса, значит нужны sticky-сессии или общее хранилище. Теперь сервер масштабируется горизонтально как обычный стейтлес-сервис. Чтобы не потерять интерактивные сценарии, придумали Multi Round-Trip Requests: сервер не дёргает клиента по живой сессии, а возвращает InputRequiredResult с непрозрачным блобом состояния, и клиент переспрашивает тем же вызовом уже с ответами. Плюс появился [McpHeader] — параметр можно поднять в HTTP-заголовок, чтобы балансировщик роутил по нему, не заглядывая в тело запроса. С первой версией обе стороны договариваются, ломается только расширение Tasks — его перепроектировали. 3️⃣ Binlog Analyzer прямо в VS Code Это прикольная штука. Я потыкал в июне Binlog MCP Server, чтобы попробовать оптимизнуть билд проекта на работе. Но к сожалению ничего драматически крутого агент с помощью MCP не нашел. Предложил кэшировать пакеты, что у нас и так было сделано. И был таков. Но у нас не очень сложный билд, так что может просто не подошло по применению. Однако для сложных билдов самое то. Теперь вот и Copilot в VS Code будет уметь в аналитику 🅰️ Итого: Вообще мне видится, что вот эта CSRF-защита по умолчанию делается в первую очередь для агентов. Чтобы те не могли забыть ее включить и тем самым не подставили начинающего вайб-кодера. В целом эта вся агентная история сместила фокус с “разраб сам должен думать головой” в сторону “а давайте сразу за него подумаем о базовой безопасности” И мне кажется это круто! Потому что надеяться на дисциплину — это всегда самая идиотская тактика из всех. Что на дорогах, что в разработке. А у вас в июле что зашло? Кидайте в комменты, если я что-то важное проспал. #dotnet #aspnet #mcp #digest

  • без подписи

  • 🩺 Диагностика — как понять, на что ушла оперативка (часть 2, work_mem наносит ответный удар) 👈 Часть инструментов рассмотрели в прошлом посте, а в этом рассмотрим ещё парочку: 🧰 Что лежит в кэше прямо сейчас Расширение pg_buffercache (мы его уже видели в посте про shared_buffers) показывает поимённо, какие страницы заняли кэш Postgres в данный момент. Удобно, когда надо понять, чем именно забиты те самые 128 MB, выданные под shared_buffers 👥 Кто сейчас активен (дикпик 3) Кроме shared_buffers можно проверить и work_mem, чтобы узнать, сколько соединений работает и что они выполняют. Это показывает представление pg_stat_activity: оно построчно показывает каждое соединение, и там видно текущий запрос от клиента (app) и его состояние. Дальше пользуемся арифметикой work_mem × число операций × число активных соединений, чтобы получить объём памяти, занятый данными для операций Чтобы при этом явно понять, какой клиент выполняет запрос, важно передавать его читаемое название через строку подключения или в запросе, тогда его название отобразится в app 🧠 ⚠️ Ловушка при подсчёте памяти процессов Если помнишь, каждое соединение в Postgres обслуживает отдельный процесс. Казалось бы, сложи память всех процессов и получишь общий расход. Но есть подвох: shared_buffers общий, и операционная система засчитывает его в память каждого процесса. Этот объём называют RSS (resident set size — объём оперативки, занятый процессом). Если просто сложить RSS всех бэкендов, общий shared_buffers посчитается много раз, и итог окажется сильно завышенным. Для суммирования правильнее брать PSS (proportional set size): он делит общую память поровну между процессами, которые ею пользуются 🧯 Если work_mem чересчур раздут Если арифметика подтвердит, что в основном память выделена под обработку запросов, рецепт простой: уменьшить work_mem, сократить число соединений, или поставить перед базой пулер соединений. Пулер (например, PgBouncer) — это прослойка, которая держит небольшой набор постоянных соединений к Postgres и раздаёт их клиентам, что позволяет избежать выделение процесса на подключение каждого клиента. А отдельному тяжёлому запросу можно задать work_mem прямо в нём командой SET LOCAL (она меняет параметр в пределах текущей транзакции). 🅰️ Что унести с собой 🟢 Состав кэша показывает pg_buffercache. Кто сейчас активен, видно в pg_stat_activity 🟢 Складывать RSS процессов не стоит: общий shared_buffers задвоится. Для суммы есть PSS 🧑‍💻dp🥁 #бд #postgresql #инженерныештучки #heavywednesday

  • 🍁 Уже этой осенью я буду выступать на DotNEXT 2026! Мне нравится .NET, AI и рассказывать доклады. И что может быть лучше чем рассказать доклад про AI в .NET? Агенты — это относительно новая штука, и мы привыкли пользоваться ими в разработке. Но вот как писать своих агентов и главное зачем? Об этом особо никто не говорит. Так что в этом году буду рассказывать с большого экрана про Microsoft Agent Framework и про то, как именно мы его применяем у себя в повседневных задачах. Поэтому переходите на сайт конфы, изучайте программу и до встречи на площадке! А за билетами по специальным спикерским условиям — всегда можно прийти ко мне в личку @Undermove1 😌

  • 🤩 Пятничное. Начал тут читать “Войну и Мир” Был значительно ошарашен (в ахуе) от того, сколкьо персонажей можно ввести за раз. В первой главе аж 9 основных. Ну и там еще около 10 второстепенных перечисляется. Сначала чутка фрустировал. Потом пытался вести конспект. А потом вдург вспомнил, что сейчас же есть клодчанский! Попросил его накидать по-быстрому доску-расследование, как в Alan Wake 2. Типа я читаю главу, а потом могу посмотреть, кто и что в ней делал, какие у кого были мотивы + по каждому персонажу могу посмотреть короткую сводку – как выглядит, чем знаменит, и чего хочет. По ходу прочтения буду расширять. Так что можете следить за моим прогрессом))) Кстати, в виде аудиокниги слушать значительно проще. На x2 все вот эти затянутые описания люстр воспринимаются сильно полегче. И бля, из приколов, там в самом начале мужика сравнивают, то с куском говядины, то с ростбифом, то еще с какой-то кулинарией. Я б такое читать устал. А на x2 это ощущается так, как и задумывалось автором – как ирония. Так что даже есть где посмеяться. А, ну и французские вставки там сразу переведены на русский. Так что не приходится скакать глазами между ебучими сносками. #ai #devlife #petproject

  • ⚡️ Еще быстрый факт про серверный MCP сервер Сегодня поймали еще одну проблемку-дилемку, которую можно было бы добавить в TOP-11 вопросов которые возникли при проектировании MCP: ⚠️ Не очень удобно через серверный MCP отправлять файлы. Дело в том, что по сути есть два пути как передать файл. 1️⃣ Inline base64 прям в Body запроса. 2️⃣ Передать ссылку на точку где лежит ресурс и загрузить самому на сервере. Путь 1 проще, но упирается в разнообразные лимиты сервера – body size и прочее. Путь 2 замороченнее для клиента, так как ему нужно сначала закгрузить куда-то на отдельный сервер файл, и только потом уже передать его нам, чтобы мы могли его прикопать. С локальным MCP появляется третий путь: клиент передаёт в тул просто путь к файлу, а сервер сам читает его с диска и стримит нам обычным multipart-запросом — хоть 500 MB, никакого base64 и лимитов на body. 🅰️ Итого: при проектировании MCP и выборе между серверным и клиентским вариантами, хорошо бы подумать о том, как вы будете пересылать вот такие крупные куски. PS: Есть еще такой прикол. Что если модельке дать возможность пихнуть инлайновый base64, то нужно как-то ей говорить, чтобы она его руками не генерила. Нейронки конечно сейчас умные, но не факт, что клиент использует самую умную и есть риск наткнуться на то, что при передаче картинки в 1Мб моделька внезапно сожрет пол-ляма дорогущих выходных токенов. Что есть полная жесть. Но тут непонятно, мы как поставщик MCP об этом должны заботиться или сам пользователь? Со своей стороны мы дескрипшен добавили, чтобы такого не случилось. #mcp #ai #agents #devtools

C# Short Posts 🔞 — tgindex