Обновить
128K+

C# *

Объектно-ориентированный язык программирования

78,59
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Архитектура движка подбора билетов: три GDS, железная дорога и маршрут, который меняют в дороге

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели7.8K

Референсная архитектура движка подбора билетов на redb: канонная модель, Scatter-Gather по трём GDS и ж/д, дерево-маршрут и saga-переоформление в дороге.

Сотруднику нужно долететь до одного города, доехать поездом до другого и вернуться тем же путём. Одна командировка, билеты из разных систем бронирования. А потом он уже в дороге пишет в телеграм: «планы изменились, летим не туда, перебронируй».

Три системы под самолёты (Amadeus, Sabre, Travelport) исторически несовместимы: разные XML-диалекты одного и того же понятия перелёта, выросшие из мейнфреймов 60–80-х, каждый со своими причудами и полями, которых нет у соседа. Плюс отдельная, никак не связанная с ними система бронирования под железную дорогу: свой формат, своя логика мест и классов, ничего общего по структуре с авиационными GDS. Запросить всё это параллельно, свести разноформатные ответы в одно и собрать валидный маршрут по стыковкам уже само по себе задача не для россыпи if и ручных мапперов.

А дальше человек в дороге меняет ...

Читать далее

Новости

Shadow AI — почему инженеры скрывают, что пользуются ИИ

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели6.7K

Слушал подкаст Code of Leadership, выпуск про AI-assisted engineering. Полтора часа про то, как правильно встроить ИИ в разработку: копайлоты, MCP, метрики, место ИИ в SDLC. Разговор хороший, по делу. И где-то в середине проскочил термин, за который я зацепился и с которым хожу уже неделю — shadow AI. Проскочил сноской, в ряду прочих ИБ-рисков, между утечками и комплаенсом.

А я на этой сноске завис. Потому что мне кажется, что она интереснее основного разговора...

Читать далее...

Бенчмаркая try/finally: один finally — и метод в 6,45 раза медленнее

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6K

Один try/finally внутри метода — и он работает в разы медленнее. Сам блок тут ни при чём, он не выполняет ни одной лишней инструкции.

Причина в решении JIT. В .NET 10 его поменяли — но не для всех методов и не при любых настройках.

Читать далее

AS2 в .NET без отдельного Java-гейтвея: EDI-обмен с партнёрами прямо в маршруте

Уровень сложностиСложный
Время на прочтение15 мин
Охват и читатели11K

Если вы поставляете товар в крупную розницу, возите грузы для 3PL-оператора, шлёте платёжные извещения банку или обмениваетесь медицинскими транзакциями X12 — вы почти наверняка обмениваетесь этими документами по AS2. Заказ (EDI 850), счёт (810), уведомление об отгрузке (856), платёжное авизо (820) уходят партнёру не почтой и не через REST, а как подписанный и зашифрованный S/MIME-конверт поверх HTTP, с подписанной квиткой-распиской в ответ. Так работает регламентированный B2B-документооборот в рознице, логистике, финансах, производстве и здравоохранении уже двадцать лет: Walmart, Amazon и их сети поставщиков, банки с host-to-host каналом, автопром, дистрибьюторы — все требуют AS2.

В .NET до сих пор было два пути. Либо коммерческий AS2-шлюз — Cleo, Seeburger, BizTalk — отдельная коробка, отдельная лицензия, отдельная команда сопровождения. Либо Java-сервер с открытым кодом — OpenAS2, Mendelson Community — отдельный JVM-процесс рядом с вашим .NET-бэкендом, со своим inbox-каталогом, откуда документы надо ещё забирать джобой. В обоих случаях AS2 живёт сбоку от вашей интеграции, а не внутри неё.

redb.Route.AS2закрывает этот разрыв: AS2 становится обычным шагом маршрута в вашем .NET-процессе. Приняли конверт от партнёра, расшифровали, проверили подпись, отдали документ в pipeline — провалидировали, трансформировали, положили в Kafka или SQL — и вернули партнёру подписанную расписку. Один процесс, один деплой, одна панель наблюдаемости. Разберём, как это выглядит в коде, где применяется и почему нативный коннектор в ESB выигрывает у отдельного шлюза.

Читать далее

VLAN и одна старая мечта: как я начал делать Visual IDE для сетей

Время на прочтение12 мин
Охват и читатели16K

Кстати, хочу поблагодарить сообщество за обратную связь по EvertyDesk. Я увидел огромное количество замечаний, идей и реальных проверок. Много ребят запускали проект у себя, ковыряли его, находили проблемы, и вместе мы дотащили всё до версии 2.0.1. Да, я перепрыгнул с 0.0.1 почти сразу. Иногда нумерация версий тоже хочет жить быстрее разработчика.

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

Некоторые спрашивали про Contributor в виде cloud. Ребят, было бы стыдно этого не указать. Значительная часть работы действительно идёт в диалоге с нейросетями. Я фанат технологий, и иногда меня в хорошем смысле удивляет, насколько круто они умеют делать рутинную работу.

В целом я считаю, что мы живём в удивительное время.

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

Поэтому я решил начать параллельную серию статей. Помимо своего VST3-плагина для сведения я хочу наконец сделать то, о чём мечтал годами, пока работал ведущим инженером у частного интернет-провайдера.

Читать далее

Ваш кэш в Redis неэффективен, что с этим делать?

Уровень сложностиСредний
Время на прочтение21 мин
Охват и читатели8.3K

Однажды в проде контейнеры одного из сервисов начали падать по OutOfMemory. Контейнерам было выделено по 4 ГБ оперативной памяти, нагрузка была вполне обычной: десятки страниц в секунду.

Расследование показало, что проблема была в JSON-конфиге.

Схема была стандартная. В базе данных хранился JSON. При запросе приложение доставало его из базы, выполняло дополнительную обработку — заполнение вычисляемых полей, обогащение справочниками — и сохраняло результат в Redis. Подавляющее большинство пользователей запрашивало один и тот же JSON и ходило за ним в Redis.

Из-за ошибки в обработке закэшированный JSON распухал до десятков мегабайт. В кэш писались не только нужные поля, но и вложенные коллекции, история изменений, сериализованные справочники.

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

Но всё оказалось интереснее…

Читать далее

Локальная база на клиенте: Blazor WebAssembly и MAUI на SQLite — без EF DbContext, Include и миграций

Уровень сложностиСредний
Время на прочтение21 мин
Охват и читатели8.4K

Офлайн-хранилище со сложным графом и outbox: быстрый старт в MAUI и в браузере, базовые операции и почему в этой роли EF Core только мешает.

Курьер спустился в подвал склада — связи нет. Кладовщик третий час принимает поставку в зоне, где вайфай добивает через раз. Пользователь заполнил форму на четыре экрана и нажал «Сохранить» в момент, когда сервер уехал на деплой.

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

И вот тут начинается знакомое.

Читать далее

Пишем Zero‑Allocation конвейер обработки G‑кода на C# (.NET 10): как выжать максимум из железа без GC‑пауз

Уровень сложностиСложный
Время на прочтение19 мин
Охват и читатели9.1K

Если в современных реалиях у разработчика возникает необходимость собрать надежное решение для обработки G‑кода, он обычно смотрит в сторону готовых вариантов (GRBL/FluidNC/Linux‑CNC), либо пишет свой кастомный парсер на С/С++ или Rust и для таких проектов вариант реализации на.NET даже не рассматривается ввиду того, что платформа является управляемой и потому недостаточно надежной (заслуженно или нет — разберем далее).

Читать далее

Как пишут базы данных на C#: RavenDb

Уровень сложностиСредний
Время на прочтение50 мин
Охват и читатели12K

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

Ознакомиться

Бенчмаркая Enumerable.Chunk: почему батчей меньше, а проход до ×2,7 дольше

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели9.3K

Chunk делит коллекцию на массивы — одна строка кода. Но есть размер чанка, после которого он замедляется в разы при тех же данных и той же памяти. А на массиве и на List<int> внутри разный код, и в самой строке этого не видно.

Читать далее

Месяц, 500M токенов и симулятор завода: как мы с ИИ-агентом построили имитационную модель производства чипов

Время на прочтение18 мин
Охват и читатели7.9K

Когда я прочёл о том, что Андрей Карпати больше не пишет код руками, а перешёл на агентное программирование, я, честно говоря призадумался. Скажи об этом кто-то другой, пропустил бы мимо ушей, но именно его слова стали сигналом - в своей работе, и в группе разработчиков придётся что-то менять. Как известно, личный пример - лучший способ убедить коллектив и повести за собой, поэтому пришлось пробовать.

Первой же пробой пера стал вовсе не Todo-app, а самый что ни на есть хардкорный энтерпрайз. Задача - создать полноценный аналог интеграционной шины CellWorks MBX. Это ключевой элемент автоматизации завода по производству полупроводников: она связывает в единое целое MES-систему и сотню единиц технологического оборудования. Мы как раз начинали перенос легаси-стека с PA-RISC-серверов на x64, и вопрос портирования старого транспорта стоял остро.

Вторым проектом стала имитационная модель этого производства. Нет-нет, это не аналог factorio, в ней ни намёка на 3D или игровые механики. Это симулятор реального цеха: с моделями оборудования, технологическими маршрутами, реальным незавершённым производством, производственным планом на годы вперёд (при желании). Эта модель отвечает на вопрос: какую продукцию и в какой срок я потенциально смогу выпустить, если запущу в работу вот столько-то сырья, и оборудование не встанет надолго из-за поломки или отсутствия материалов. Результат превзошёл ожидания. Софт, который раньше создавался большими коллективами, благодаря ИИ и open-source, теперь можно создавать практически в одиночку, и активно внедрять в реальное производство!

Читать далее

Бенчмаркая StringBuilder: подстава на длинном тексте

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели10K

StringBuilder делит текст на чанки по 8000 символов — вчетверо ниже порога кучи больших объектов. Запас такой, что попасть туда невозможно.

Но чанк на 400 КБ в этой куче возможен и получить его можно разными способами.

Читать далее

Три паттерна написания Agent Skills

Время на прочтение16 мин
Охват и читатели10K

Еще год-два лет назад большинство разработчиков даже не задумывались о том, что будут программировать агентами с помощью обычных Markdown-файлов. Сегодня ситуация изменилась буквально за несколько месяцев.

Практически каждый современный AI-агент, будь то Claude Code, Cursor, Codex, Gemini CLI или OpenCode, предлагает один и тот же механизм расширения своих возможностей - напишите Skill, опишите процесс решения задачи, добавьте примеры, подключите документацию и агент начнет выполнять эту работу значительно лучше.

Десятилетиями мы учили разработчиков, что Markdown - это документация. Средство общения между людьми. Формат, который не исполняется и никак не влияет на поведение программы, а затем неожиданно оказалось, что один Markdown-файл способен изменить проект сильнее, чем сотни строк кода и здесь индустрия практически мгновенно наступила на старые грабли.

Читать далее

Ближайшие события

Создаём DSL на C#: Диагностика

Уровень сложностиПростой
Время на прочтение11 мин
Охват и читатели8.7K

Создаю собственный DSL на C#: в этой части добавим инструменты диагностики. Построим инспектор дерева компонентов, научимся изменять состояния и параметры прямо во время работы приложения, подключим метрики через System.Diagnostics и настроим #line, чтобы исключения указывали на исходный .akbura-файл, а не на сгенерированный C#.

Читать далее

Бенчмаркая ArrayPool: подстава при копировании потоков — 131 072 байта в LOH

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели13K

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

Один такой размер зашит в .NET по умолчанию — им копируются потоки. Проверил на четырёх машинах и трёх рантаймах.

Читать далее

Бенчмаркая ZLinq: один IEnumerable в сигнатуре — и .NET 10 быстрее библиотеки в 3,9 раза

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6.5K

ZLinq — замена LINQ без аллокаций. На .NET 8 и .NET 9 время одинаковое. На .NET 10 иначе: массив тот же, но если параметр объявлен как IEnumerable, foreach перебирает его в 2,58–3,89 раза быстрее ZLinq. Причина видна в машинном коде, память замерена отдельно.

Читать далее

Бенчмаркая System.Text.Json: те же данные, те же настройки, до ×4,3 разницы

Уровень сложностиСложный
Время на прочтение14 мин
Охват и читатели12K

В документации к PropertyNameCaseInsensitive есть предупреждение про накладные расходы, но не сказано, когда они появятся. Замерил на четырёх машинах, трёх рантаймах и трёх размерах входного JSON: пока через настройки идёт один регистр ключей, флаг не добавляет ничего — 0,92–1,09. Политика именования camelCase тоже.

Разницу до ×4,3 даёт другое: какие ещё написания этих ключей прошли через настройки раньше. Два экземпляра JsonSerializerOptions, созданные через new с одинаковыми полями, делят один кеш имён.

Внутри: пять историй с таблицами по четырём машинам, листинги из dotnet/runtime, предел кеша в 64 записи и веб-настройки, на которых эта разница не видна.

Читать далее

Почему мы разделили UI, бизнес-логику и ядро: архитектура платформы «Галактика Сверхновая»

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели11K

Большинство корпоративных платформ, которые сегодня работают на крупных предприятиях, проектировались 15-20 лет назад. С тех пор сменились языки программирования, подходы к разработке, требования к интеграциям и интерфейсам. Архитектура же во многих случаях осталась прежней.

Мы задумались – можно ли сохранить проверенную бизнес-логику, не переписывая накопленный за десятилетия код, и одновременно сделать платформу открытой для современных технологий?

Эту задачу мы и хотели решить при разработке «Галактики Сверхновой». Заглядывайте под кат и узнаете, как устроено это разделение: почему ядро осталось консервативным, а расширения можно писать на Python, Java и C#, и как метаданные стали основой для интеграций и ИИ.

Читать далее

Background jobs в.NET: retry есть, а exactly‑once никто не завозил

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели11K

Сегодня про background jobs в .NET: Hangfire, Quartz.NET, Worker Service и тот неловкий момент, когда job “почти точно выполнилась”, но система не уверена.

Снаружи все выглядит спокойно: задача ушла в фон, worker что-то сделал, retry настроен, lock вроде есть. А внутри остается неприятный вопрос: внешний эффект уже произошел или job просто упала до записи статуса?

Разберем без магии: почему retry не равен идемпотентности, чем lock отличается от dedup, зачем нужен operationId и что делать, когда повторный запуск может превратиться во второй счет, второе письмо или повторное изменение статуса.

Читать далее

Ваш агент не тупой — ему просто неудобно

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели12K

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

Читать про Agent Comfort
1
23 ...