Эшу быдлокодит
297 subscribers
135 photos
12 videos
7 files
170 links
Дневник C# разработчика.

Личка: @EshuMarabo
Гитхаб: https://github.com/vladzvx

Стек: C#, PostgreSQL
加入频道
На прошлых выходных был на конференции по экосистеме .Net, к которой относится мой основной язык - c#: DotNext.

В первый день прослушал 4 доклада, во второй - 5.

Далее будет серия постов по прослушанным докладам, с тегом #dotnext@eshu_coding

#conf
#dotnext, день 1, доклад 1.

Workflow архитектура сервисов в .Net

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

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

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

Также в докладе рассказали о готовых либах, реализующих workflow в c#. По случаю может и пригодится.

P.S. Отдельным бонусом к либам идёт возможность генерации блок схемы наших workflow

#conf
👍2
#dotnext, день 1, доклад 2.

Когда 100% cpu ничего не значит.

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

Основная полезная информация, которую я вынес - о механизме устройства конвейера виртуальных машин, за мощности которых мы платим хостерам.

Если наш сервис постоянно потребляет мизерное количество ресурсов, хостер, в рамках оптимизации, может засунуть его миллионной виртуалкой на запасной сервер.

И тут к нам приходит лавинообразная нагрузка. Реально выделенных (а не тех, за которые уполчено) выделенных ресурсов нам перестает хватать, автоматика хостера пытается как-то выдать нам оплаченное и теперь востребованное - и тратит на это время, в течение которого наш сервис может захлёбываться на ровном месте.

Другой интересный момент - взятие лишнего десятка ядер CPU, как раз таки на такой случай, не спасает, а наоборот делает хуже. Чем больше запрашиваемые нами ресурсы - тем сложнее приткнуть нашу виртуалку туда, где они есть.

Ещё было занятно про k8s и гармоничные настройки потребления памяти, но кубером я пока не проникся, потому прошло мимо.

#conf
👍1
#dotnext, день 1, доклад 3.

Кафка и распродажи в Озоне.

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

Из забавного - у них считается нормальным тестить на проде, точнее не тестить, а устраивать учения:)

#conf
😁3
#dotnext, день 1, доклад 4.

Dependecy Injection в тестах.

Автор из Яндекса пропагандировал использование стандартных практик написания кода внутри тестов, ну и рассказал об основных тестовых фреймворках в .Net (я и так знал, что использую самый дремучий - MSTest).

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

Пока наиболее оптимальным выглядит путь максимального говнокода с копипастой. И совсем чуть-чуть выноса повторяющихся простынь в отдельные методы.

#conf
#dotnext, день 2, доклад 1.

Экономия памяти в .Net.

Известно, что приложения на java/c# съедают память столько, сколько им дадут. Но если заморочиться - можно сократить потребление.

В докладе занимались загрузкой файлов со средним размером ~123 Мб. В среднем на загрузку такого файла уходило ~280 Мб памяти.

Путем разных непристойных действий с байтами автор ужал потребление памяти до ~2.7 Мб, т.е. в 100 раз. И даже не особо потерял в читаемости кода.

Во основном использовалось два подхода:
1. Пулинг объектов
2. Выделение памяти на стеке вместо кучи

В c# есть встроенный пул массивов, которые можно использовать как буферные объекты, не создавая новые и не забивая память новосоздаваемыми одноразовыми массивами.

А если таки надо создавать буферные короткоживущие объекты - можно попробовать разместить их на стеке. Использовать структуру. Или вообще аллоцировать кусочек стека и использовать его по своему усмотрению (главное не переусердствовать и не завалить все приложение со Stack Overflow Exception).

Список колдунств, применённых автором, просто чтобы не забыть:
1. stackalloc
2. ArrayPool
3. readonly ref struct
4. ValueStringBuilder (вытащенный внутренний класс из недр рантайма c#, базирующийся на стеке билдер строк).
5. TryFormat

Ещё была важная мысль - использовать бенчмарки в докере, чтобы сравнивать как работает код в целевой ОС, а не на Винде, где идёт разработка.

#csharp
#conf
👍1
#dotnext, день 2, доклад 2.

Убийцы производительности в c#.

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

1. Следить за логгером
2. Следить за использованием кучи больших объектов
3. Прежде чем тащить ArrayPool в проект - почитать Best practices по его использованию.

Ну и некоторые новые пакеты/инструменты для повышения производительности, просто чтобы не потерять:
RecyclableMemoryStream
Pipelines.Sockets.Unofficial
ArraySegment

#conf
👍1
#dotnext, день 2, доклад 3.

Знакомство с функциональной парадигмой и F#.

В целом, код в функциональной парадигме выглядит для привыкшего к ООП человека очень странно.

Но вообще, достаточно занятно, как вариант для читаемого клея для страшных многосоставных операций - вполне себе вариант.

Но острого желания вот прямо сейчас изучить F# не возникло.

#conf
#dotnext, день 2, доклад 4.

PureDI.

Человек рассказывал о своем пет-проекте - фреймворке для реализации Dependency Injection. В целом, довольно нишевая штука, хотя и интересная.

Обладает некоторыми преимуществами перед стандартными средствами.

Главная проблема на мой взгляд - чтобы подружить эту библиотеку и стандартные средства для реализации Dependency Injection требуются дополнительные приседания.

Ну и заодно доклад проиллюстрировал, для чего на практике нужен механизм SourceGen в .Net (при билде проекта запускается специальный инструмент и генерирует исходный код по сконфигурированным правилам, а потом собственно билдит проект с этим новргенеренным кодом).

#conf
#dotnext, день 2, доклад 5.

Linq: искусство запрашивать данные.

В c# принято общаться с базой через ORM - Entity Framework (EF). Он позволяет пропустить фазу написания sql запросов путем трансляции внутреннего шарпового языка написания запросов к коллекциям с данными - Linq - в sql запросы.

Но иногда эти запросы разрастаются и становятся нечитаемыми даже в c# даже без единой строки SQL.

В докладе давался обзор фреймворков, позволяющих сделать запросы читаемее. Вообще, подобная проблема передо мной уже стояла при создании сложных запросов к MongoDB. В итоге получилось редкостное уродство, ставшее легаси в момент коммита, так что я понимаю боль авторов. На случай возможного будущего погружения в те же дебри, но с EF, ниже приведу просто набор ключевых слов для поиска:

Подход к упрощению запросов - паттерн спецификация
AddHocSpecification
ReplaceVisitor
Linqkit
nein-linq
Projectable
EF7 - IQueryExpressionInterseptor
Sieve - для комбинации фильтров
AutoFilterer


#conf
👍1😁1