10-11 октября проходил Positive Security Day, где я был стендистом. Это новый для меня опыт - я почувствовал себя настоящим сейлом.
В задачи стендиста входило рассказывать заинтересованным людям (потенциальным заказчикам) про продукт - желательно так чтобы:
1. Люди поняли, что это и зачем
2. Люди захотели это купить
И сначала я был просто в ступоре... у нас не было заготовленных речей, надо было вывозить на импровизации. Но к счастью мои коллеги это дело подхватили и у них всё получилось! Тогда я послушал ребят, дообучил свою нейронку в голове, набрался смелости и присоединился к общению с людьми, которые интересовались продуктом. Было прикольно! Реально новый опыт, интересные вопросы, интересные люди из интересных компаний - всё это драйвило меня, и с каждым новым человеком я общался всё увереннее и увереннее.
Конечно же были и сложности, но по более сложным вопросам всегда можно попросить помощи у коллег - поэтому всё прошло хорошо.
А что такое мы разработали???
А это настоящий автопентестер! Я пришёл в команду чуть больше месяца назад и принял участие в разработке "мозгов" программы - непосредственной реализации техник и тактик, которые используют хакеры в рамках своих атак. За этот месяц я очень сильно погрузился в продукт, в ИБ и пентест - ведь чтобы его автоматизировать, надо понимать как это всё делается вручную. Супер интересная область, супер сложная задача эмулировать действия хакера - фактически нелинейное мышление человека перекладывать в программный код.
Но к счастью, у нас драйвовая команда, готовая принять этот вызов!
Кстати, запись мероприятия доступна тут (Зал Молекула, есть таймкоды, PT Dephaze на 05:23:00): https://psd.ptsecurity.com/#live
Flexible Coding
В задачи стендиста входило рассказывать заинтересованным людям (потенциальным заказчикам) про продукт - желательно так чтобы:
1. Люди поняли, что это и зачем
2. Люди захотели это купить
И сначала я был просто в ступоре... у нас не было заготовленных речей, надо было вывозить на импровизации. Но к счастью мои коллеги это дело подхватили и у них всё получилось! Тогда я послушал ребят, дообучил свою нейронку в голове, набрался смелости и присоединился к общению с людьми, которые интересовались продуктом. Было прикольно! Реально новый опыт, интересные вопросы, интересные люди из интересных компаний - всё это драйвило меня, и с каждым новым человеком я общался всё увереннее и увереннее.
Конечно же были и сложности, но по более сложным вопросам всегда можно попросить помощи у коллег - поэтому всё прошло хорошо.
А что такое мы разработали???
А это настоящий автопентестер! Я пришёл в команду чуть больше месяца назад и принял участие в разработке "мозгов" программы - непосредственной реализации техник и тактик, которые используют хакеры в рамках своих атак. За этот месяц я очень сильно погрузился в продукт, в ИБ и пентест - ведь чтобы его автоматизировать, надо понимать как это всё делается вручную. Супер интересная область, супер сложная задача эмулировать действия хакера - фактически нелинейное мышление человека перекладывать в программный код.
Но к счастью, у нас драйвовая команда, готовая принять этот вызов!
Кстати, запись мероприятия доступна тут (Зал Молекула, есть таймкоды, PT Dephaze на 05:23:00): https://psd.ptsecurity.com/#live
Flexible Coding
1🔥9👏3👍2
Итак, коллеги, важный опрос - я в смятении.
Чем отличается Acceptance Test Driven Development от Behaviour Driven Development c точки зрения технической реализации (написания тестов на основе бизнес-требований)?
Судя по тому, что читал в интернете - на практике это буквально одно и то же под разными названиями. Конечно есть уверждения, что одно это процесс взаимодействия с заказчиком, а другое это написание тестов... А с технической точки зрения это те же тесты на Gherkin Language... или нет?
Короче, го в комменты!
Чем отличается Acceptance Test Driven Development от Behaviour Driven Development c точки зрения технической реализации (написания тестов на основе бизнес-требований)?
Судя по тому, что читал в интернете - на практике это буквально одно и то же под разными названиями. Конечно есть уверждения, что одно это процесс взаимодействия с заказчиком, а другое это написание тестов... А с технической точки зрения это те же тесты на Gherkin Language... или нет?
Короче, го в комменты!
🤔2
Akka .NET
По производственной необходимости я сейчас изучаю фреймворк Akka. Это реализация акторной модели - архитектура приложения строится на некоторых единицах исполнения заданий, которые общаются друг с другом посредством сообщений. Реактивная модель, получается (кстати, можете почитать про неё в Reactive Manifesto).
Сами акторы появились в Erlang и часто используются в телекоммуникационной индустрии. И так получилось, что они отлично ложатся на задачи в рамках моей текущей предметной области.
Как изучать?
По материалам именно по дотнету - всё плохо, поэтому тут я советую почитать оригинальные доки с примерами на Scala и Java.
(Но если что - вот документация и по Akka.NET)
Послушать можно доклады от автора порта акки на .NET - https://www.youtube.com/watch?v=MY1iPY78_fs. Ну или поискать другие.
Но самое главное
Я наткнулся на отличный курс от Petabridge - Akka Bootcamp. Он доступен на гитхабе - https://github.com/petabridge/akka-bootcamp. Тут гораздо более понятные и реальные примеры использования акторной модели - и есть практика, которую можно выполнять, а затем сравнивать свой результат с эталоном. Русификации нет, но я всё равно рекомендую изучать акку именно по этому курсу.
Flexible Coding
По производственной необходимости я сейчас изучаю фреймворк Akka. Это реализация акторной модели - архитектура приложения строится на некоторых единицах исполнения заданий, которые общаются друг с другом посредством сообщений. Реактивная модель, получается (кстати, можете почитать про неё в Reactive Manifesto).
Сами акторы появились в Erlang и часто используются в телекоммуникационной индустрии. И так получилось, что они отлично ложатся на задачи в рамках моей текущей предметной области.
Как изучать?
По материалам именно по дотнету - всё плохо, поэтому тут я советую почитать оригинальные доки с примерами на Scala и Java.
(Но если что - вот документация и по Akka.NET)
Послушать можно доклады от автора порта акки на .NET - https://www.youtube.com/watch?v=MY1iPY78_fs. Ну или поискать другие.
Но самое главное
Я наткнулся на отличный курс от Petabridge - Akka Bootcamp. Он доступен на гитхабе - https://github.com/petabridge/akka-bootcamp. Тут гораздо более понятные и реальные примеры использования акторной модели - и есть практика, которую можно выполнять, а затем сравнивать свой результат с эталоном. Русификации нет, но я всё равно рекомендую изучать акку именно по этому курсу.
Flexible Coding
🔥7👍4
Ради эксперимента поставил заметочник affine.pro. Однако у него довольно плохая мобильная версия, поэтому для быстрых записей я захотел написать телеграм-бота. А уже об этом - моя новая статья :)
вАЙТИ
Автоматизируем сервис без API
DIY-медиа для ИТ-специалистов. Практические истории про решение самых разных задач из ИТ и смежных областей.
👍6
Behaviour Driven Development && Dotnet
Так получилось, что в рамках своего опыта работы я не встречал проектов с хорошими юнит-тестами и большим покрытием ими проектов.
Зато на всех проектах использовался подход Behaviour Driven Development, в рамках которого писались интеграционные тесты.
Behaviour Driven Development - это подход к разработке, при котором вы пишете интеграционные тесты на основе User Story, используя язык Gherkin как со стороны бизнеса, так и со стороны разработки. Чем-то похоже на ATDD
Каждый тест состоит из трех этапов:
- Given (дано) - подготовка окружения (может быть несколько)
- When (когда) - выполнение действия, которое как-то это окружение меняет (желательно, чтобы этот шаг был только один)
- Then (тогда) - проверка того, что окружение изменилось так как надо (тоже может быть несколько)
Например
- Дано: созданный аккаунт пользователя с ролью администратор
- Когда пользователь авторизуется в системе
- Тогда пользователь видит страницу администратора
Такие тесты более сложны в сопровождении, дольше пишутся и дольше прогоняются, однако имеют очень важное преимущество - они не просто тестируют изолированный кусок логики, как юнит-тесты, а фактически подтверждают выполнение бизнес-требований.
В дотнете есть много популярных фреймворков для написания таких тестов - LightBDD, SpecFlow, MSpec. Однако наиболее популярны первые два - о них и поговорим в следующих постах
Flexible Coding
Так получилось, что в рамках своего опыта работы я не встречал проектов с хорошими юнит-тестами и большим покрытием ими проектов.
Зато на всех проектах использовался подход Behaviour Driven Development, в рамках которого писались интеграционные тесты.
Behaviour Driven Development - это подход к разработке, при котором вы пишете интеграционные тесты на основе User Story, используя язык Gherkin как со стороны бизнеса, так и со стороны разработки. Чем-то похоже на ATDD
Каждый тест состоит из трех этапов:
- Given (дано) - подготовка окружения (может быть несколько)
- When (когда) - выполнение действия, которое как-то это окружение меняет (желательно, чтобы этот шаг был только один)
- Then (тогда) - проверка того, что окружение изменилось так как надо (тоже может быть несколько)
Например
- Дано: созданный аккаунт пользователя с ролью администратор
- Когда пользователь авторизуется в системе
- Тогда пользователь видит страницу администратора
Такие тесты более сложны в сопровождении, дольше пишутся и дольше прогоняются, однако имеют очень важное преимущество - они не просто тестируют изолированный кусок логики, как юнит-тесты, а фактически подтверждают выполнение бизнес-требований.
В дотнете есть много популярных фреймворков для написания таких тестов - LightBDD, SpecFlow, MSpec. Однако наиболее популярны первые два - о них и поговорим в следующих постах
Flexible Coding
🔥5👍1😐1
SLNX-формат или как Microsoft меня расстроили
Всем привет! Сегодня поговорим про "решения" проектов на .NET.
Как мы знаем, приложение на дотнете - это некоторое решение (Solution) с набором проектов. В одном из проектов может быть слой бизнес-логики, в другом - инфраструктурный, ну и так далее. Всё это может быть и в одном проекте, но это редкость.
Так вот, проекты объединяются в решение через sln-файлы - файлы решений. Внутри этого файла находится страшный сплошной текст с информацией о проектах, их расположением в Solution Folders и прочими метаданными. И его довольно трудно читать - там довольно странные GUID-ы, куча каких-то маппингов, повторов...
А проблемы начинаются, когда разработчики параллельно в разных ветках добавляют много проектов, а потом надо решать merge-конфликты. И после очередного разбора конфликтов на работе, итогом которого стала отвязка части проектов и ручная их перепривязка к решению, стало понятно, что так дальше продолжаться не может.
В .NET8 был представлен новый формат файлов решений - slnx. Данные в нём уже структурированы и довольно удобно читаются - xml-формат, там нет GUID-ов и прочего мусора, который мешает пониманию содержимого файла - то, что надо!
И вот мы уже перешли на новый формат решений, счастливы - конфликты в этом файле решаются просто, коллизий нет... и тут выясняется, что dotnet cli этот формат полностью не поддерживает. То есть dotnet restore, dotnet build в нашем dockerfile тупо не отрабатывает и мы не можем задеплоиться!
Собственно, благодаря тому, что xml удобно парсить, не составило труда написать скрипт, который парсит список проектов в решении и выполняет dotnet restore для них по отдельности, но это не так удобно. Вместо
> Да, я написал F#-скрипт для парсинга slnx-файла
А ещё забавно, что даже последняя версия Visual Studio 2022 отказалась открывать этот файл :)
Какой же статус работы по slnx?
- Для dotnet cli - выйдет в .net9.0.2
- Для vs code - есть открытый issue
- Для Visual Studio - да вроде уже работает, но у меня не работает :(
- И только JetBrains Rider стабильно открывает и понимает новый формат солюшнов
Морали не будет, просто будьте внимательнее при переходе на что-то новое и крутое :)
Flexible Coding
Всем привет! Сегодня поговорим про "решения" проектов на .NET.
Как мы знаем, приложение на дотнете - это некоторое решение (Solution) с набором проектов. В одном из проектов может быть слой бизнес-логики, в другом - инфраструктурный, ну и так далее. Всё это может быть и в одном проекте, но это редкость.
Так вот, проекты объединяются в решение через sln-файлы - файлы решений. Внутри этого файла находится страшный сплошной текст с информацией о проектах, их расположением в Solution Folders и прочими метаданными. И его довольно трудно читать - там довольно странные GUID-ы, куча каких-то маппингов, повторов...
А проблемы начинаются, когда разработчики параллельно в разных ветках добавляют много проектов, а потом надо решать merge-конфликты. И после очередного разбора конфликтов на работе, итогом которого стала отвязка части проектов и ручная их перепривязка к решению, стало понятно, что так дальше продолжаться не может.
В .NET8 был представлен новый формат файлов решений - slnx. Данные в нём уже структурированы и довольно удобно читаются - xml-формат, там нет GUID-ов и прочего мусора, который мешает пониманию содержимого файла - то, что надо!
И вот мы уже перешли на новый формат решений, счастливы - конфликты в этом файле решаются просто, коллизий нет... и тут выясняется, что dotnet cli этот формат полностью не поддерживает. То есть dotnet restore, dotnet build в нашем dockerfile тупо не отрабатывает и мы не можем задеплоиться!
Собственно, благодаря тому, что xml удобно парсить, не составило труда написать скрипт, который парсит список проектов в решении и выполняет dotnet restore для них по отдельности, но это не так удобно. Вместо
dotnet restore
мы выполнеяем команду
dotnet fsi list-projects.fsx | sed 's|\\|/|g' | xargs -I {} sh -c 'if [ -f "{}" ]; then dotnet restore "{}"; fi'
> Да, я написал F#-скрипт для парсинга slnx-файла
А ещё забавно, что даже последняя версия Visual Studio 2022 отказалась открывать этот файл :)
Какой же статус работы по slnx?
- Для dotnet cli - выйдет в .net9.0.2
- Для vs code - есть открытый issue
- Для Visual Studio - да вроде уже работает, но у меня не работает :(
- И только JetBrains Rider стабильно открывает и понимает новый формат солюшнов
Морали не будет, просто будьте внимательнее при переходе на что-то новое и крутое :)
Flexible Coding
😨5👍3
Итак, 2025 год (с наступившим!), автор вышел из цепочки событий разной степени безумия и готов с вами познакомиться!
Меня зовут Дмитрий Бахтенков, уже несколько лет я занимаюсь коммерческой разработкой на .NET, а также увлекаюсь различными аспектами саморазвития - очень много времени уделяю тому, как быть продуктивным, организованным, эффективным и т.д.
Этот канал я создал, чтобы делиться с вами своими мыслями, идеями и личным опытом, непосредственно связанным с программированием и IT в целом.
Что здесь есть?
- Статьи. Последнее время я публикую их на портале вАЙТИ
- Обзоры книг. Я много читаю, в том числе техническую литературу. Об интересных книгах я пишу отзывы, и думаю о том, чтобы делать более развёрнутые конспекты
- Интересные технические кейсы. Что-то непонятное, занятное и странное
- Обучающие посты
- Личный опыт, публичные выступления, советы по организации и многое другое
А ещё я завёл бусти. Он пока пустой, но в ближайшее время я буду его наполнять по чуть чуть. Подписывайтесь, если хотите меня поддержать, я буду рад!
Меня зовут Дмитрий Бахтенков, уже несколько лет я занимаюсь коммерческой разработкой на .NET, а также увлекаюсь различными аспектами саморазвития - очень много времени уделяю тому, как быть продуктивным, организованным, эффективным и т.д.
Этот канал я создал, чтобы делиться с вами своими мыслями, идеями и личным опытом, непосредственно связанным с программированием и IT в целом.
Что здесь есть?
- Статьи. Последнее время я публикую их на портале вАЙТИ
- Обзоры книг. Я много читаю, в том числе техническую литературу. Об интересных книгах я пишу отзывы, и думаю о том, чтобы делать более развёрнутые конспекты
- Интересные технические кейсы. Что-то непонятное, занятное и странное
- Обучающие посты
- Личный опыт, публичные выступления, советы по организации и многое другое
А ещё я завёл бусти. Он пока пустой, но в ближайшее время я буду его наполнять по чуть чуть. Подписывайтесь, если хотите меня поддержать, я буду рад!
1👍7🎉4🔥3❤2🍓2
Зависимости зависимостей зависимостей
Всем привет! Сегодня - немного про nuget-пакеты.
В процессе развития проекта в него устанавливается все больше пакетов, и надо как-то успевать следить за их версиями, своевременно их обновлять или удалять неактуальные.
В IDE JetBrains Rider (а уж тем более в vs code) следить за неявными зависимостями довольно неудобно, в особенности когда на третьем или четвёртом уровне зависимостей мы сталкиваемся с конфликтами версий.
Представьте ситуацию:
Как предотвратить такие ситуации?
🚚 Централизованное управление пакетами
Это подход, при котором версии всех nuget-пакетов для всех проектов указываются в одном файле, который называется Directory.Packages.props со следующим содержанием:
Не всегда идеально помогает, но если у вас множество проектов, то организовать такое управление пакетами - Must Have.
Подробнее можно прочитать тут: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management
👀 Ручной анализ зависимостей, включая транзитивные
Если у вас уже случились проблемы с зависимостями, с помощью волшебного ctrl+f и специальных файлов можно посмотреть информацию о них.
Во-первых, можно воспользоваться командой
Пример файла:
Во-вторых, можно использовать файл по пути
📦 Использование Paket
Paket - это open-source менеджер пакетов, который может упростить работу с ними. Сама утилита написана на F#, и несмотря на удобство, имеет один недостаток: поддержка собственных nuget-источников реализована очень слабо, как и поддержка файлов slnx. Встречаются неприятные баги и недоработки, которые не позволяют удобно использовать этот инструмент.
А как вы управляете пакетами в своих проектах?
Flexible Coding
Всем привет! Сегодня - немного про nuget-пакеты.
В процессе развития проекта в него устанавливается все больше пакетов, и надо как-то успевать следить за их версиями, своевременно их обновлять или удалять неактуальные.
В IDE JetBrains Rider (а уж тем более в vs code) следить за неявными зависимостями довольно неудобно, в особенности когда на третьем или четвёртом уровне зависимостей мы сталкиваемся с конфликтами версий.
Представьте ситуацию:
Пакет А зависит от Пакета Б определённой версии, а Пакет Б зависит от Пакета В определённой версии. Вы ставите Пакет Г, а он зависит от Пакета В версии выше, чем позволено в дереве зависимостей Пакета А. Всё ломается, IDE сигнализирует об ошибке, а проект не собирается. Тем временем у вас в решении 5 проектов, куда установлены пакеты с одним названием и разными версиями... в общем, УДАЧИ. 🫡🫡🫡
Как предотвратить такие ситуации?
🚚 Централизованное управление пакетами
Это подход, при котором версии всех nuget-пакетов для всех проектов указываются в одном файле, который называется Directory.Packages.props со следующим содержанием:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Akka" Version="1.5.22" />
<PackageVersion Include="FluentCommandLineParser" Version="1.4.3" />
</ItemGroup>
</Project>
Не всегда идеально помогает, но если у вас множество проектов, то организовать такое управление пакетами - Must Have.
Подробнее можно прочитать тут: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management
👀 Ручной анализ зависимостей, включая транзитивные
Если у вас уже случились проблемы с зависимостями, с помощью волшебного ctrl+f и специальных файлов можно посмотреть информацию о них.
Во-первых, можно воспользоваться командой
dotnet list package --include-transitive --format json > packages.json
. Эта команда сгенерирует json-файл, в котором будут указаны абсолютно все зависимости проекта.Пример файла:
{
"version": 1,
"parameters": "--include-transitive",
"projects": [{
"path": "",
"frameworks": [{
"framework": "net8.0",
"topLevelPackages": [{
"id": "Akka",
"requestedVersion": "1.5.22",
"resolvedVersion": "1.5.22"
}],
"transitivePackages": [{
"id": "Newtonsoft.Json",
"resolvedVersion": "13.0.3"
}]
}]
}]
}
Во-вторых, можно использовать файл по пути
./Project/obj/project.assets.json
. В нём тоже расписаны зависимости пакетов, установленных в рамках проекта.📦 Использование Paket
Paket - это open-source менеджер пакетов, который может упростить работу с ними. Сама утилита написана на F#, и несмотря на удобство, имеет один недостаток: поддержка собственных nuget-источников реализована очень слабо, как и поддержка файлов slnx. Встречаются неприятные баги и недоработки, которые не позволяют удобно использовать этот инструмент.
А как вы управляете пакетами в своих проектах?
Flexible Coding
👍8❤2🔥1
💵 FluentAssertions стал платным
Недавно вышла версия библиотеки FluentAssertions 8.0.0, в которой изменилась лицензия. Теперь использование этой библиотеки в коммерческих проектах стоит $130 с человека в год.
🔗 Подробнее на Reddit
❓Что за библиотека?
FluentAssertions — это набор методов расширения для тестов, делающих их более лаконичными и читаемыми.
Примеры
FluentAssertions:
Assert:
Ну или
FluentAssertions:
Assert:
💰Лицензия и цена
- С одной стороны, разработчики библиотеки тоже хотят зарабатывать.
- Но $130 в год за набор методов расширения? Для сравнения, IDE Rider стоит примерно столько же — и это полноценная среда разработки.
🤔 Просто подумайте, вы готовы платить за это?
Вопросы о контроле лицензий остаются открытыми, а также использование большого количества библиотек - всегда риск. Помните это!
Ну а альтернативой может быть библиотека Shouldy
Flexible Coding
Недавно вышла версия библиотеки FluentAssertions 8.0.0, в которой изменилась лицензия. Теперь использование этой библиотеки в коммерческих проектах стоит $130 с человека в год.
🔗 Подробнее на Reddit
❓Что за библиотека?
FluentAssertions — это набор методов расширения для тестов, делающих их более лаконичными и читаемыми.
Примеры
FluentAssertions:
actual.Should().BeGreaterThan(40).And.BeLessThan(50);
Assert:
Assert.IsTrue(actual > 40 && actual < 50);
Ну или
FluentAssertions:
actual.Should().StartWith("Hello").And.EndWith("Assertions!");
Assert:
Assert.IsTrue(actual.StartsWith("Hello") && actual.EndsWith("Assertions!"));
💰Лицензия и цена
- С одной стороны, разработчики библиотеки тоже хотят зарабатывать.
- Но $130 в год за набор методов расширения? Для сравнения, IDE Rider стоит примерно столько же — и это полноценная среда разработки.
🤔 Просто подумайте, вы готовы платить за это?
Free: Assert.True(result);
$130 per person: result.Should().Be().A().Value().Of().True().For().Sure().Bro().Ok().Please;
Вопросы о контроле лицензий остаются открытыми, а также использование большого количества библиотек - всегда риск. Помните это!
Ну а альтернативой может быть библиотека Shouldy
Flexible Coding
😭5💔4❤2
Лучший скриптовый язык для C#-разработчика (и не только)
Недавно мой коллега опубликовал пост, в котором сказано, что F# - лучший скриптовый язык для дотнетчика. И я не совсем с этим согласен.
Для чего мы пишем скрипты? Для маленьких автоматизаций своей рутины. И пока эта рутина только своя, вопросов нет, F# действительно хорош. Я сам иногда пишу на нём, язык прикольный, функциональное программирование мне интересно.
Однако, большинство скриптов:
1. Шарятся с командой
2. Являются кандидатами на внедрение в пайплайны силами девопса
И эти два пункта, на мой взгляд, перекрывают все преимущества F# в качестве скриптового языка. Поясню.
Надёжность
В процессе работы с F#-скриптами я столкнулся с двумя проблемами.
1. Для того, чтобы IDE (Rider) поддерживал запуск скриптов не через консоль, пришлось потратить время на поиск причин, установку каких-то версий MSBuild и прочие настройки окружения.
2. Запуск через IDE и через консоль могут работать по-разному. Вероятно, что-то не так с моим окружением, но когда скрипт падает со случайной ошибкой - это бесит. И ты тратишь время даже не на изучение новой парадигмы программирования или синтаксиса F#, а на попытки разобраться с какими-то странными нюансами.
Например, при запуске через консоль F# не понял, 2 это int или float. А на ПК коллеги - понял!
Шаринг с командой
Допустим, у вас маленькая команда без девопса, и вы упрощаете себе деплой приложения с помощью F#-скриптов.
Команда растёт, девопса нанимают, и представьте его лицо, когда ему (знающему максимум bash, Python или Go) говорят - вот тебе F#-скрипт деплоя, нам нужно улучшить его под новые требования и сделать CI/CD в гитлабе. У девопса возникнет справедливый вопрос"Что это за хня?" "Я понимаю, что вы писали на чём умеете, не против, если я перенесу это на bash?"
Какой вывод можно сделать про F#?
Это классический холивар про совмещение новых модных технологий с кровавым энтерпрайзом. Где-то это работает, где-то нет. Но на мой взгляд, если мы говорим про работу в команде, F# - не лучший скриптовый язык.
А какой скриптовый язык лучше?
Ну а я пользуюсь следующими:
Bash
Да-да, тот самый. Нативно работает под nix-ос, можно писать консольные команды, которые по большей степени знают все, идеально интегрируется в любые CI-системы. И да, синтаксис не самый приятный по части работы с аргументами и ветвлениями, но это дело привычки. F# на самом деле тоже дело привычки - там есть свои особенности синтаксиса.
Мне норм.
Python
Именно в контексте скриптов, а не кровавого энтерпрайза, питон вполне неплох. Там есть свои сложности с библиотеками и виртуальными окружениями (нет, для скриптов всё изи), и он должен быть установлен на ПК всех участников команды. Однако он более универсален и знаком, чем тот же F#. По крайней мере, гугл и ChatGPT о нём точно больше знают.
Flexible Coding
Недавно мой коллега опубликовал пост, в котором сказано, что F# - лучший скриптовый язык для дотнетчика. И я не совсем с этим согласен.
Для чего мы пишем скрипты? Для маленьких автоматизаций своей рутины. И пока эта рутина только своя, вопросов нет, F# действительно хорош. Я сам иногда пишу на нём, язык прикольный, функциональное программирование мне интересно.
Однако, большинство скриптов:
1. Шарятся с командой
2. Являются кандидатами на внедрение в пайплайны силами девопса
И эти два пункта, на мой взгляд, перекрывают все преимущества F# в качестве скриптового языка. Поясню.
Надёжность
В процессе работы с F#-скриптами я столкнулся с двумя проблемами.
1. Для того, чтобы IDE (Rider) поддерживал запуск скриптов не через консоль, пришлось потратить время на поиск причин, установку каких-то версий MSBuild и прочие настройки окружения.
2. Запуск через IDE и через консоль могут работать по-разному. Вероятно, что-то не так с моим окружением, но когда скрипт падает со случайной ошибкой - это бесит. И ты тратишь время даже не на изучение новой парадигмы программирования или синтаксиса F#, а на попытки разобраться с какими-то странными нюансами.
Например, при запуске через консоль F# не понял, 2 это int или float. А на ПК коллеги - понял!
Конечно же, это единичные кейсы, но от скриптов ждёшь надёжности и удобства для всех, а не только для окружения автора (если скрипты, конечно, шарятся с командой)
Шаринг с командой
Допустим, у вас маленькая команда без девопса, и вы упрощаете себе деплой приложения с помощью F#-скриптов.
Команда растёт, девопса нанимают, и представьте его лицо, когда ему (знающему максимум bash, Python или Go) говорят - вот тебе F#-скрипт деплоя, нам нужно улучшить его под новые требования и сделать CI/CD в гитлабе. У девопса возникнет справедливый вопрос
Какой вывод можно сделать про F#?
Это классический холивар про совмещение новых модных технологий с кровавым энтерпрайзом. Где-то это работает, где-то нет. Но на мой взгляд, если мы говорим про работу в команде, F# - не лучший скриптовый язык.
А какой скриптовый язык лучше?
Наиболее знакомый вашей команде. Всей, а не только разработчикам.
Ну а я пользуюсь следующими:
Bash
Да-да, тот самый. Нативно работает под nix-ос, можно писать консольные команды, которые по большей степени знают все, идеально интегрируется в любые CI-системы. И да, синтаксис не самый приятный по части работы с аргументами и ветвлениями, но это дело привычки. F# на самом деле тоже дело привычки - там есть свои особенности синтаксиса.
Покажите мне хотя бы одного человека, которому нравится читать чужие скрипты командной оболочки.
Мне норм.
Python
Именно в контексте скриптов, а не кровавого энтерпрайза, питон вполне неплох. Там есть свои сложности с библиотеками и виртуальными окружениями (нет, для скриптов всё изи), и он должен быть установлен на ПК всех участников команды. Однако он более универсален и знаком, чем тот же F#. По крайней мере, гугл и ChatGPT о нём точно больше знают.
Flexible Coding
Telegram
PICO
Лучший скриптовый язык для .NET разработчика
Наверняка всем знакома история с bash/poweshell-скриптами для деплоя приложения на окружение.
Приходишь в проект, а там ЭТО: сотни строк кода вперемешку с магическими константами, циклы и условные конструкции…
Наверняка всем знакома история с bash/poweshell-скриптами для деплоя приложения на окружение.
Приходишь в проект, а там ЭТО: сотни строк кода вперемешку с магическими константами, циклы и условные конструкции…
❤5👍5🤩4🔥2🤔2
Проверяем, существует ли документ в коллекции MongoDB
Всем привет! Сегодня взглянем на интересные детали работы с MongoDB.
Итак, задача: написать метод, который проверяет, существует ли документ в БД по фильтру.
Вроде всё просто, однако у Mongo нет операции Exist на уровне документов и коллекций. А это значит, что мы можем выполнить задачу двумя способами:
1. Сделать запрос
2. Сделать запрос
Если рассуждать логически, не вникая в детали монги, то вызов
Собственно, в проекте мы думали также, поэтому изначально для проверки существования документа в коллекции использовали
И тут уже возникает вопрос:
Я решил провести небольшой бенчмарк с локальной монгой для того, чтобы проверить разницу этих методов. Код бенчмарка тут, в Readme есть описание происходящего, а выводы сделаны следующие:
- Разница минимальна - наносекунды для фильтров по идентификатору и милисекунды для фильтров без индексов
- В случае поиска по индексу (по
- В случае поиска без индекса - быстрее будет
Flexible Coding
Всем привет! Сегодня взглянем на интересные детали работы с MongoDB.
MongoDB - это документная база данных, которая позволяет хранить неструктурированные данные в json-like формате под названием bson.
Итак, задача: написать метод, который проверяет, существует ли документ в БД по фильтру.
Вроде всё просто, однако у Mongo нет операции Exist на уровне документов и коллекций. А это значит, что мы можем выполнить задачу двумя способами:
1. Сделать запрос
find
с фильтром и параметром limit=1
- чтобы получить первый документ по фильтру. Если он не null - значит такой документ есть.2. Сделать запрос
countDocuments
по фильтру и получить количество документов. Если их больше нуля - значит документ существуетЕсли рассуждать логически, не вникая в детали монги, то вызов
countDocuments
кажется наиболее быстрой операцией - ведь нам по сети надо гонять только число (4 или 8 байт), а не целый bson-документ, у которого есть как минимум идентификатор. Да и можно предположить, что у метода countDocuments
есть ещё какие-то оптимизации...Собственно, в проекте мы думали также, поэтому изначально для проверки существования документа в коллекции использовали
countDocuments
. Однако выяснилось, что эта операция внутри монги раскрывается в агрегацию следующего формата:
db.collection.aggregate(
[
{ $match: <query> },
{ $group: { _id: null, n: { $sum: 1 }}}
])
И тут уже возникает вопрос:
А точно ли это быстрее, чем find с лимитом и проекцией?
Я решил провести небольшой бенчмарк с локальной монгой для того, чтобы проверить разницу этих методов. Код бенчмарка тут, в Readme есть описание происходящего, а выводы сделаны следующие:
- Разница минимальна - наносекунды для фильтров по идентификатору и милисекунды для фильтров без индексов
- В случае поиска по индексу (по
_id
) - быстрее будет find
с проекцией- В случае поиска без индекса - быстрее будет
countDocuments
Flexible Coding
👍8🔥2
Всем привет!
Начал писать цикл статей про многопоточность на разных уровнях абстракции. И представляю вам первую статью из этой серии - про процессор!
Начал писать цикл статей про многопоточность на разных уровнях абстракции. И представляю вам первую статью из этой серии - про процессор!
вАЙТИ
Многопоточность. Снизу вверх. Процессор
DIY-медиа для ИТ-специалистов. Практические истории про решение самых разных задач из ИТ и смежных областей.
🔥13
Интеграционное тестирование MongoDB. Точки отказа
Всем привет! Сегодня рассмотрим тему настроек MongoDB для интгерационного тестирования и узнаем, что такое FailPoint и как он может помочь проверить нашу логику в нестандартных ситуациях.
Часто нам приходится писать интеграционные тесты. Интеграционные тесты — это тесты, которые проверяют взаимодействие нашего кода с внешними системами (БД, внешние API и т. д.) в как можно более приближённых к реальности условиях.
Зачем нужны такие тесты? Ну, например, чтобы убедиться, что наша логика корректно обрабатывает ситуации, когда база данных возвращает ошибку создания индекса или отказывает в записи. Юнит-тесты здесь уже не справятся, ведь они не покрывают фактическое взаимодействие с “живой” MongoDB.
Test Commands в MongoDB
MongoDB поддерживает набор специальных команд для тестирования (testCommands), которые обычно отключены в продакшене. Среди них есть конфигурация FailPoint — «точка отказа», позволяющая искусственно вызывать сбои и ошибки в различных операциях.
Чтобы включить testCommands, достаточно при запуске MongoDB задать параметр enableTestCommands=1. Вот пример docker-compose для этой задачи:
Для запуска команд нужно выбрать базу данных (для
Определение
1.
2.
3.
Пример использования для команды
А когда тесты будут завершены, точку отказа можно отключить:
В следующем посте мы рассмотрим пример интеграционного теста, который использует данную функциональность, а пока что можете погрузиться в вики-страничку про данный механизм.
Всем спасибо, с вами был Flexible Coding!
Всем привет! Сегодня рассмотрим тему настроек MongoDB для интгерационного тестирования и узнаем, что такое FailPoint и как он может помочь проверить нашу логику в нестандартных ситуациях.
Часто нам приходится писать интеграционные тесты. Интеграционные тесты — это тесты, которые проверяют взаимодействие нашего кода с внешними системами (БД, внешние API и т. д.) в как можно более приближённых к реальности условиях.
Зачем нужны такие тесты? Ну, например, чтобы убедиться, что наша логика корректно обрабатывает ситуации, когда база данных возвращает ошибку создания индекса или отказывает в записи. Юнит-тесты здесь уже не справятся, ведь они не покрывают фактическое взаимодействие с “живой” MongoDB.
Test Commands в MongoDB
MongoDB поддерживает набор специальных команд для тестирования (testCommands), которые обычно отключены в продакшене. Среди них есть конфигурация FailPoint — «точка отказа», позволяющая искусственно вызывать сбои и ошибки в различных операциях.
Чтобы включить testCommands, достаточно при запуске MongoDB задать параметр enableTestCommands=1. Вот пример docker-compose для этой задачи:
services:
mongo:
image: mongo:6.0
command: mongod --setParameter enableTestCommands=1
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
Для запуска команд нужно выбрать базу данных (для
ConfigureFailPoint
это база данных admin) и вызвать метод db.runCommand({})
.Определение
ConfigureFailPoint
состоит из следующих полей:1.
configureFailPoint
- название точки отказа, которую мы настраиваем. Чаще всего встречается значение failCommand
для настройки отказа конкретной команды2.
mode
: определяет режим срабатывания точки отказа: alwaysOn
, off
, {times: n}
и другие3.
data
- является вложенным объектом, в котором указываются детали и условия сбояПример использования для команды
createIndexes
:
use admin;
db.runCommand({
configureFailPoint: "failCommand",
mode: { times: 1 },
data: {
failCommands: ["createIndexes"],
errorCode: 100,
closeConnection: false
}
});
А когда тесты будут завершены, точку отказа можно отключить:
use admin;
db.runCommand({
configureFailPoint: "failCommand",
mode: "off"
});
В следующем посте мы рассмотрим пример интеграционного теста, который использует данную функциональность, а пока что можете погрузиться в вики-страничку про данный механизм.
Всем спасибо, с вами был Flexible Coding!
🔥4👍2❤1🤔1
Flexible Coding
Всем привет! Начал писать цикл статей про многопоточность на разных уровнях абстракции. И представляю вам первую статью из этой серии - про процессор!
Тем временем готова следующая статья из цикла про многопоточность - сегодня залезем на уровень операционной системы
вАЙТИ
Многопоточность. Снизу вверх. ОС
DIY-медиа для ИТ-специалистов. Практические истории про решение самых разных задач из ИТ и смежных областей.
🔥7👀2❤1
Интеграционное тестирование MongoDB. Точки отказа. .NET
Всем привет! Продолжаем тему точек отказа у MongoDb. С основами разобрались, а теперь приступим к написанию тестов на .NET.
Тесты разделяются на три этапа: Given (Arrange), When (Act) и Then (Assert). Так же в рамках теста может происходит подготовка окружения -
В рамках конкретного теста точку отказа удобнее всего настраивать на этапе Setup. В NUnit это будет выглядеть следующим образом:
Далее - сама логика теста:
А затем возвращаем MongoDB в исходное состояние:
Таким образом можно настраивать необходимое поведение БД в рамках теста.
Flexible Coding
Всем привет! Продолжаем тему точек отказа у MongoDb. С основами разобрались, а теперь приступим к написанию тестов на .NET.
Тесты разделяются на три этапа: Given (Arrange), When (Act) и Then (Assert). Так же в рамках теста может происходит подготовка окружения -
Setup
и очистка - TearDown
.В рамках конкретного теста точку отказа удобнее всего настраивать на этапе Setup. В NUnit это будет выглядеть следующим образом:
[SetUp]
public void Setup()
{
// Подключаемся к локальной монге, где включены testCommands
var client = new MongoClient("mongodb://root:password@localhost:27017");
_database = client.GetDatabase("testDb");
_collection = _database.GetCollection<BsonDocument>("testCollection");
_adminDatabase = client.GetDatabase("admin");
// Включаем FailPoint для команды createIndexes
var enableFailPoint = new BsonDocument
{
{ "configureFailPoint", "failCommand" },
{ "mode", new BsonDocument("times", 1) },
{
"data", new BsonDocument
{
{ "failCommands", new BsonArray { "createIndexes" } },
{ "errorCode", 100 }, // код ошибки (для проверки)
{ "closeConnection", false } // соединение не рвём
}
}
};
_adminDatabase.RunCommand<BsonDocument>(enableFailPoint);
}
Далее - сама логика теста:
[Test]
public void CreateIndexes_ShouldThrowException_WhenFailPointEnabled()
{
var ex = Assert.Throws<MongoCommandException>(() =>
{
_collection.Indexes.CreateOne(
new CreateIndexModel<BsonDocument>(
Builders<BsonDocument>.IndexKeys.Ascending("someField")));
});
Assert.That(ex.Code, Is.EqualTo(100));
}
А затем возвращаем MongoDB в исходное состояние:
[TearDown]
public void TearDown()
{
// Выключаем FailPoint, чтобы вернуть MongoDb в исходное состояние
var disableFailPoint = new BsonDocument
{
{ "configureFailPoint", "failCommand" },
{ "mode", "off" }
};
_adminDatabase.RunCommand<BsonDocument>(disableFailPoint);
}
Таким образом можно настраивать необходимое поведение БД в рамках теста.
Flexible Coding
🔥3✍2
💵 Open-Source становится платным (опять)
Всем привет! Сегодня поговорим о том, как open-source проекты собираются переходить на коммерческие модели. В прошлый раз была библиотека FluentAssertions, а на этот раз речь идёт о MassTransit, MediatR и AutoMapper.
🔗 Ссылки на анонсы:
- MassTransit
- MediatR и AutoMapper
К медиатору и автомапперу у меня довольно предвзятое отношение, а за MassTransit немного печально. Это действительно мощная библиотека для работы с сообщениями, и переход на коммерческую модель заставляет задуматься о будущем её использования.
🤔 Какие есть альтернативы MassTransit?
Из того, с чем работал я, могу предложить следующие варианты:
- EasyNetQ для RabbitMQ
- KafkaFlow для Apache Kafka
Flexible Coding
Всем привет! Сегодня поговорим о том, как open-source проекты собираются переходить на коммерческие модели. В прошлый раз была библиотека FluentAssertions, а на этот раз речь идёт о MassTransit, MediatR и AutoMapper.
🔗 Ссылки на анонсы:
- MassTransit
- MediatR и AutoMapper
К медиатору и автомапперу у меня довольно предвзятое отношение, а за MassTransit немного печально. Это действительно мощная библиотека для работы с сообщениями, и переход на коммерческую модель заставляет задуматься о будущем её использования.
Надеюсь, в старых версиях MassTransit не найдут какую-нибудь страшную уязвимость, которую пофиксят только в платной версии
🤔 Какие есть альтернативы MassTransit?
Из того, с чем работал я, могу предложить следующие варианты:
- EasyNetQ для RabbitMQ
- KafkaFlow для Apache Kafka
Flexible Coding
🤬5❤1👍1
Flexible Coding
Тем временем готова следующая статья из цикла про многопоточность - сегодня залезем на уровень операционной системы
Слегка прошёлся по Thread в дотнете в новой статье из цикла про многопоточность. Приятного чтения!
Flexible Coding
Flexible Coding
вАЙТИ
Многопоточность. Снизу вверх. Потоки в языке C#
DIY-медиа для ИТ-специалистов. Практические истории про решение самых разных задач из ИТ и смежных областей.
🔥7👍3👀2❤1
🤖 Заметки ИИ-юзера. Qwen-coder, continue и VS Code
Всем привет! С недавних пор я начал пользоваться плагином Continue, который предоставляет некоторые ИИ-возможности для вашей IDE. Среди них:
- Чат с возможностью положить в контекст файлы, папки и т.д.
- Tab-автокомплит (как в GitHub Copilot)
- Автоматическое редактирование файла на основе промпта
- Создание и использование своих провайдеров контекста (например на основе браузера или БД) - пока не пробовал, но знаю что есть
Начал я с чего-то попроще: для чата настроил модель GPT-4o, а для автокомплита поднял локальную модель qwen-coder. Подключил это дело в файлах конфигурации и пошёл тестить - сразу на большом проекте.
Вот мои промежуточные выводы.
😡 Сначала плохое
- Во-первых, КАК ЖЕ QWEN-CODER ЛЮБИТ ФИГУРНЫЕ СКОБКИ!!! Я писал некоторе большое switch-выражение, и он постоянно добавлял мне эти скобки, игнорируя их наличие ниже. По итогу я выключил автокомплит, пока писал этот свич, потому что это невозможно
- Во-вторых - qwen как будто бы ничего не знает про ValueTask, и даже когда метод в сигнатуре содержит его, локальная модель всё равно предлагает использовать Task.CompletedTask или другие методы класса Task.
🥹А теперь хорошее
Это прекрасный генератор json! Когда мне надо было подготовить тестовые переменные для сериализации, я просто открыл нужный класс-dto, написал
И автокомплит сам мне предложил корректный json на базе класса. Тема классная, пользуйтесь)
А модель ChatGPT в чате и в задачах авторедактирования файла действительно неплоха - главное добавить в промпт пример, так как эти модели лучше понимают задачи с примерами и аналогиями.
❓ Что дальше?
- Я хочу попробовать Codestral от Mistral - судя по документации Continue это лучшее решение для автокомплита
- Тестирование IDE Cursor - это вызывает у меня скептицизм и сомнения относительно большого проекта на миллион строк, но попробовать можно
- Возможно, использование GitHub Copilot и Jetbrains AI Assistant
Flexible Coding
TLDR: Он поднял локальную модель, которая хуже облачных и теперь ругает её. А плагин норм.
Всем привет! С недавних пор я начал пользоваться плагином Continue, который предоставляет некоторые ИИ-возможности для вашей IDE. Среди них:
- Чат с возможностью положить в контекст файлы, папки и т.д.
- Tab-автокомплит (как в GitHub Copilot)
- Автоматическое редактирование файла на основе промпта
- Создание и использование своих провайдеров контекста (например на основе браузера или БД) - пока не пробовал, но знаю что есть
Начал я с чего-то попроще: для чата настроил модель GPT-4o, а для автокомплита поднял локальную модель qwen-coder. Подключил это дело в файлах конфигурации и пошёл тестить - сразу на большом проекте.
Вот мои промежуточные выводы.
😡 Сначала плохое
- Во-первых, КАК ЖЕ QWEN-CODER ЛЮБИТ ФИГУРНЫЕ СКОБКИ!!! Я писал некоторе большое switch-выражение, и он постоянно добавлял мне эти скобки, игнорируя их наличие ниже. По итогу я выключил автокомплит, пока писал этот свич, потому что это невозможно
}}}}}}}
- Во-вторых - qwen как будто бы ничего не знает про ValueTask, и даже когда метод в сигнатуре содержит его, локальная модель всё равно предлагает использовать Task.CompletedTask или другие методы класса Task.
🥹А теперь хорошее
Это прекрасный генератор json! Когда мне надо было подготовить тестовые переменные для сериализации, я просто открыл нужный класс-dto, написал
var json = """
"""
И автокомплит сам мне предложил корректный json на базе класса. Тема классная, пользуйтесь)
А модель ChatGPT в чате и в задачах авторедактирования файла действительно неплоха - главное добавить в промпт пример, так как эти модели лучше понимают задачи с примерами и аналогиями.
Внедрение ИИ в повседневную работу с кодом - это отличный повод вкачать промпт-инженирнг - чтобы не оказаться в ситуации, когда тестирование промптов в поисках подходящего становится дольше, чем написание кода самостоятельно.
❓ Что дальше?
- Я хочу попробовать Codestral от Mistral - судя по документации Continue это лучшее решение для автокомплита
- Тестирование IDE Cursor - это вызывает у меня скептицизм и сомнения относительно большого проекта на миллион строк, но попробовать можно
- Возможно, использование GitHub Copilot и Jetbrains AI Assistant
Flexible Coding
🔥6👍1