Обновить
128K+

C# *

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

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

Глобальные константы в DATAREON Platform: как убрать хардкод из интеграций

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

С вами снова Илья Вязников, инженер сопровождения SOFROS. Продолжаю делиться практическими приёмами, которые упрощают жизнь при эксплуатации и доработке интеграций.

Не так давно я рассказывал, как вынести повторяющуюся логику в C# функции, но в любом серьёзном проекте со временем накапливаются не только функции, но и куча параметров: адреса сервисов, таймауты и т.д. Сначала их прописывают прямо в коде, но очень быстро это превращается в проблему.

Сегодня расскажу про глобальные константы — один из полезных инструментов платформы для централизованного хранения таких параметров.

Читать далее

redb.Route 3.0.1 — плоская навигация по DSL, рефакторинг CRTP и тихий null

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

Продолжаем серию про redb.Route — вводная и разбор четырёх in-memory каналов уже вышли. Сегодня не статья серии, а релизная заметка: в 3.0.1 три конкретных изменения в DSL, каждое с боевым примером из демо.

До 3.0.1 глубоко вложенные scope-ы требовали закрывать себя в строго обратном порядке — утомительно и легко ошибиться. Три вещи изменились.

Читать далее

Rust внутри .NET: как упаковать native-библиотеку в один NuGet-пакет

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

FFI, P/Invoke, EmbeddedResource, DllImportResolver и кроссплатформенная доставка без ручного копирования .dll.so и .dylib.

Когда .NET-коду нужно вызвать Rust-библиотеку, первый прототип обычно заводится быстро:

Rust собирается как cdylib;

функции экспортируются через extern "C";

C# вызывает их через DllImport;

результат возвращается через указатель.

Читать далее

Eventual Consistency: как мы починили тормоза апрува и сломали бюджет

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

Мы убрали одну блокировку, чтобы апрувы перестали тормозить. Через несколько недель из‑за этого клиент пробил квартальный бюджет — а наша система этого даже не заметила.

Полгода после MVP, первые крупные клиенты. B2B travel SaaS, конец 2016-го. Компании начали подключать не по 15–20 человек, а по 80–100.

Один из новых клиентов оказался кратно крупнее остальных — финансовый департамент почти на сотню человек с фиксированным квартальным бюджетом на командировки порядка нескольких сотен тысяч рублей. К середине квартала большая часть бюджета уже потрачена, остаток — заметно меньше половины. Два руководителя — в разных городах, в разных браузерах — одновременно открывают форму апрува командировок. Оба видят один и тот же остаток. Один одобряет крупную поездку, другой почти в то же время — ещё одну, сопоставимую по сумме; каждая по отдельности в остаток вписывалась. Оба получают подтверждение. Вместе две поездки пробили лимит — перерасход, которого ни один из руководителей в одиночку не допускал.

Обнаружили через 3–4 часа — когда финансовый менеджер клиента открыл квартальную сводку и позвонил нам.

Читать далее

redb.Route изнутри: четыре in-memory канала и Exchange, который их связывает

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

Прошлая статья была обзорной — что такое redb.Route, зачем нам понадобился свой Apache Camel под .NET, как выглядит боевой маршрут. Если не читали, коротко: это fluent C# DSL для интеграции — 22 коннектора (~30 URI-схем, если считать https/wss/es-варианты), ~30 паттернов EIP нативно через 41 процессор8 in-process компонентов, компилируемый expression-движок. Сегодня заходим внутрь. Не список фич, а рабочий разбор.

Серия будет длинной, поэтому сразу скажу, что и в каком порядке:

Читать далее

Создаём DSL на C#: Пишем парсер

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

Создаю собственный DSL на C#: рассказываю о том, как написать парсер, и как его оптимизировать. Так же покажу как работает обещанный DFA.

Читать далее

redb.Route — Apache Camel для .NET, который мы написали потому что выхода другого не было

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

У вас не 5 микросервисов — у вас десятки. Бэкенд, который рос три года: монолит, расколотый на куски, GPS-фид от автопарка, мобильное приложение водителя, веб-кабинет диспетчера, интеграции с SAP / 1С / регуляторами / маркетплейсами, отдельный SMTP-воркер, отдельный PDF-генератор, отдельный шедулер ночных пересчётов. Между ними — Kafka (несколько кластеров, по топику на домен), RabbitMQ (RPC + pub/sub + DLQ), Redis (кэш, last-known-state, pub/sub-каналы), пара HTTP-эндпоинтов наружу, SFTP с поставщиком, SQL-polling outbox-таблицы старого монолита, MQTT с трекеров, IBM MQ для одного древнего банковского контура, SignalR-хабы для real-time-дашбордов. На каждом стыке — свой ретрай, свой DLQ (или нет DLQ), своя сериализация, свои метрики (или нет метрик), своя бойлерплейт-обвязка из консьюмеров и try/catch.

Каждый из этих стыков живёт своей жизнью в Program.cs соответствующего сервиса. Каждый — это hand-rolled цикл:

Читать далее

redb — типизированное хранилище для .NET поверх Postgres/MSSQL: без миграций, без Include, с полным LINQ

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

Типизированное хранилище для .NET поверх Postgres и MSSQL. C#-класс как схема — без миграций, без Include, с полным LINQ. Работает в проде.

LoadAsync вместо 40 Include →

Основной алгоритм повторной обработки

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

Не так давно, я писал, о том как автоматизировать повторную обработку сообщений из архива в DATAREON Platform.

Было несколько вопросов и уточнений, поэтому хочу дополнительно разобрать код C# для повторной обработки.

Для ЛЛ: Полный алгоритм с комментариями в конце поста

Читать далее

KeyboardHook: кроссплатформенный глобальный перехват клавиатуры и мыши для .NET

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

Рассказываю, как написал кроссплатформенную .NET-библиотеку для глобального перехвата клавиатуры и мыши. Под капотом: WH_KEYBOARD_LL на Windows, CGEventTap на macOS и polling через XQueryKeymap на Linux. Один интерфейс, три реализации, ноль внешних зависимостей.

Читать далее

Одна строчка .Result роняет ваш ASP.NET Core при CPU 8 %: разбор hill-climbing в .NET 9

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

TL;DR. Один «безобидный» foo.GetAsync().Result в middleware способен превратить ASP.NET Core, державший 50k RPS с p99 = 40 мс, в сервис с 12k RPS и p99 = 4 с — при CPU 8 %.

Виноват не сам blocking call, а hill-climbing — фидбэк-луп в ThreadPool, в недрах которого живёт дискретное преобразование Фурье. Разбираем по исходникам CoreCLR, почему это вообще возможно, воспроизводим эффект на ~80 строках кода и разбираемся, почему SetMinThreads — не решение, а анестезия.

Читать далее

Самодельный elgato-like макропад. Часть 2, софтовая

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

Так как в первой статье я сосредоточился на схемотехнике, в этой хотелось бы пройтись по разработке ПО и прошивки.

Напомню, я решил, что вместо прошивки мне подойдёт и нейрослоп - в конце концов это не серийное устройство, а поделка для себя. И тут, как обычно, в процессе работы пошли фейерверки.

ESP32-S3 имеет два USB выхода - обычный через микросхему CH340, которая конвертирует USB в UART, и второй USB OTG, который подключен к чипу напрямую. То есть чип может управлять тем, какое "устройство" он предоставит хостовой ОС! Более того, он может предоставлять несколько устройств одновременно. Это было как раз то, что надо: одним устройством будет USB HID клавиатура для "сырого" ввода в консоль, например, а вторым - USB RAW устройство, которое будет слушать софт бекенда - запускать приложения по ярлыкам, регулировать громкость, отправлять в устройство настройки. И всё это минуя тормознутый UART. Сказка. Но, как оказалось, для взрослых.

Казалось бы, полный интернет примеров того, как это настраивать. Даже в самом фреймворке esp-idf есть пример композитного устройства, значит, информация уж точно легкодоступная, бери да пользуйся. Я попросил ИИ добавить это в прошивку и... Оно не смогло. То есть вообще. Два дня и токенов примерно на 30 баксов - и я взял дело в свои руки, потому что ИИ выдумывал всё более и более изобретательные причины того, почему прошивка не компилируется, но вот выдумать компилирующуся прошивку не мог никак.

Читать далее

Пишем Third Person Controller на MonoGame. Часть I

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

В этой серии туториалов мы реализуем простой Third Person Controller на базе MonoGame.

Серия рассчитана на читателей, уже знакомых с основами MonoGame и 3D-графики.

Читать далее

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

Создал свой генератор случайных чисел на потоках

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

Я создал свой генератор случайных чисел, забудь про семена и формулы. Этот способ будет бесконечно генерировать случайные числа, не повторяясь...

Читать далее

Idempotency keys: 5 граблей, которые мы поймали на проде

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

Пятница, 23:47. PagerDuty: “Платёж AmEx, провайдер вернул 5xx три раза подряд, билеты не зарезервированы.” Открываю логи – действительно три ответа провайдера 5xx, ни одной успешной транзакции по нашей базе. Закрываю как временный сбой на стороне провайдера, пишу короткую сводку в дежурный чат и иду досматривать. Через 40 минут второй алерт – уже от ночной поддержки: клиент прислал скрин выписки, 3 списания подряд за одну бронь. У клиента рейс через 6 часов, ему нужна действующая бронь и подтверждение, что он завтра нормально улетит, а не тикет в поддержку.

Мы делали B2B-платформу для деловых поездок: бронь авиа, отели, трансфер, страховка, в финале – оплата корпоративной картой через платежный шлюз. С этой ночи началась история, которая закончилась переписыванием всего платёжного слоя нашего booking-сервиса. По дороге мы поймали 5 граблей.

Читать далее

Миграция микросервисов на Python с помощью LLM: экономим месяцы для разработчиков

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

Привет, Хабр! Меня зовут Михаил, в Циане я занимаюсь развитием культуры и developer experience. Архитектура у нас микросервисная, за каждый микросервис отвечает конкретная команда. В любой команде обычно есть микросервисы, которые помогают ей достигать собственных целей, и микросервисы, которые достались по наследству — поскольку архитектура наша не всегда развивалась достаточно последовательно. Бывает, что сервис приходит с каким-нибудь разработчиком из другой команды. Бывает, что сервис когда-то отдали команде, потому что больше некому было отдать.

Наш бэкенд написан на Python и C#. Иногда в одной команде могут быть микросервисы и на Python, и на C#. Я считаю, что это нНе самый удобный расклад, я считаю: лучше все-таки иметь один стек в рамках одной команды. Если, например, в команде с питонистами и единственным шарпистом последний уходит в отпуск, то при поломке сервиса на C# остальной команде придется этого шарписта ждать. Либо срочно вызывать на подмогу другого шарписта.

Можно переписать все микросервисы на один язык. Довольно трудоемкая задача, если заниматься этим вручную. Разработчику нужно погрузиться в микросервис, максимально покрыть тестами бизнес-логику и аккуратно все переписать. Не забывая, что делать один в один нужно не всегда, поскольку архитектурные паттерны Python и C# различаются.

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

Читать далее

Программные модули в DATAREON Platform: выносим повторяющуюся логику в C# функции

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

В интеграционных проектах на DATAREON довольно быстро появляется одна и та же проблема: код бизнес-алгоритмов разрастается, а повторяющаяся логика начинает копироваться между процессами.

В DATAREON Platform эту проблему можно решить через программные модули — механизм для хранения и повторного использования собственных функций на C#.

В статье покажу как создавать такие функции и использовать в ваших процессах.

Читать далее

Самодельный elgato-like макропад. Часть 1, железная

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

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

Я пользуюсь MAD CATZ S.T.R.I.K.E. 7, которая всем чудо как хороша, кроме того, что вышла больше 10 лет назад, её производитель обанкротился в 2014 и её софт на Win 11 уже надо ставить с бубном. Все мы смертны, клавиатуры - тем более, так что я стал задумываться над заменой. Но проблема в том, что я привык к россыпи макроклавиш, которые позволяют одним нажатием, не задействуя мозг, переключать ветки гита, исправлять криво введённые команды или вбивать пароли в окошки по 15 раз за день (о боги хаоса, как я "люблю" параноиков-безопасников). А современные клавы имеют в лучшем случае 4-5 макроклавиш (что вдвое меньше, чем нужно), а некоторые ещё и стоят как приватный остров. И тут в унынии я наткнулся на это...

Читать далее

C# мне нравится больше Java. Но в банковском enterprise мне всё равно понадобилась Java

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

C# я до сих пор считаю одним из самых удобных языков для backend разработки. В нём много вещей к которым быстро привыкаешь: свойства, LINQ, async/await, generics без type erasure, хороший tooling и понятная модель разработки.

Но банковский enterprise редко выбирает стек только по удобству языка. На практике важны не только синтаксис и экосистема, но и инфраструктура, сопровождение, безопасность, регламенты, legacy, найм, CI/CD, требования к платформам и долгосрочная стратегия организации.

Так я оказался в ситуации где C# мне субъективно нравится больше, но Java объективно стала полезнее в конкретном банковском контуре.

Эта статья не про холивар C# vs Java. Это попытка спокойно разобрать почему backend разработчику в enterprise иногда приходится расширять стек, даже если текущий язык его полностью устраивает.

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

Content Pipeline в MonoGame: почему я его не использую

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

Введение

Content Pipeline — это официальный способ работы с ассетами в MonoGame. Однако в сообществе уже давно существует немалая группа разработчиков, которые его не любят и предпочитают загружать ассеты в «сыром» виде. Особенно это заметно в сообществе FNA(ещё одной реализации XNA4) — там такой подход используют практически все.

Я тоже давно в этой «партии» и в этой статье объясню, почему…

Читать далее