Source Generators in C#
Спустя несколько лет после релиза, наконец, добрался до этих знаменитых сорс генераторов, и теперь могу записать себя в ряды метапрограммистов.
Интересно, а постметапрограммисты будут?
Поделюсь своими впечатлениями от использования.
В первую очередь, что бросается в глаза - действительно хорошая гибкость инструмента. Он развязывает руки настолько, что кажется любой компонент разрабатываемого проекта можно так или иначе сделать модульным и расширять на основе внешних понятных конфигов или ещё чего покруче.
Поскольку эта штука compile-time, а все генерируемые файлы можно посмотреть прямиком в solution explorer - инструмент крайне прозрачен. Он делает все явно и без "магии", любой сгенерированный файлик можно увидеть и применить к нему IntelliSense вашей IDE.
Hot Reload. Ну это вообще бомба. Любой файл, связанный с сорс генератором, подвергнувшись изменению, оповещает сорс генератор и можно в реальном времени увидеть новый сгенерированный код без перекомпиляции. Супер удобно.
Из минусов отмечу отсутствие встроенного инструментария для написания кода. Ну могли бы какой-то fluent-интерфейс сделать за столько-то лет. А то как в мезозое, пишем код через StringBuilder. Вот с этого прям негодую. Не смотрел в сторону готовых библиотек, но уверен, что open-source умельцы уже наделали с десяток таких.
Также, в какой-то момент поймал себя на мысли, что с помощью сорс генераторов можно делать динамические провайдеры типов как в F#, но поспешил с выводами. Не-а, так сделать не получится (только может совсем чуть чуть), на это Майкрософт фокус не брали, а жаль.
Итого, крайне полезный инструмент, когда нужно написать миллиард строчек boilerplate-кода, быстрый и надежный. Единственное, что нужно - это чуть пристальнее контролировать сложность и чистоту генераторов, чтобы облегчить себе будущую поддержку. Рекомендую!
C# Source Generators
👾 PICO
Программистов, хорошо пишущих код, мало, а программистов, хорошо пишущих код, который пишет код, и подавно.
Спустя несколько лет после релиза, наконец, добрался до этих знаменитых сорс генераторов, и теперь могу записать себя в ряды метапрограммистов.
Интересно, а постметапрограммисты будут?
Поделюсь своими впечатлениями от использования.
В первую очередь, что бросается в глаза - действительно хорошая гибкость инструмента. Он развязывает руки настолько, что кажется любой компонент разрабатываемого проекта можно так или иначе сделать модульным и расширять на основе внешних понятных конфигов или ещё чего покруче.
Поскольку эта штука compile-time, а все генерируемые файлы можно посмотреть прямиком в solution explorer - инструмент крайне прозрачен. Он делает все явно и без "магии", любой сгенерированный файлик можно увидеть и применить к нему IntelliSense вашей IDE.
Hot Reload. Ну это вообще бомба. Любой файл, связанный с сорс генератором, подвергнувшись изменению, оповещает сорс генератор и можно в реальном времени увидеть новый сгенерированный код без перекомпиляции. Супер удобно.
Из минусов отмечу отсутствие встроенного инструментария для написания кода. Ну могли бы какой-то fluent-интерфейс сделать за столько-то лет. А то как в мезозое, пишем код через StringBuilder. Вот с этого прям негодую. Не смотрел в сторону готовых библиотек, но уверен, что open-source умельцы уже наделали с десяток таких.
Также, в какой-то момент поймал себя на мысли, что с помощью сорс генераторов можно делать динамические провайдеры типов как в F#, но поспешил с выводами. Не-а, так сделать не получится (только может совсем чуть чуть), на это Майкрософт фокус не брали, а жаль.
Итого, крайне полезный инструмент, когда нужно написать миллиард строчек boilerplate-кода, быстрый и надежный. Единственное, что нужно - это чуть пристальнее контролировать сложность и чистоту генераторов, чтобы облегчить себе будущую поддержку. Рекомендую!
C# Source Generators
👾 PICO
👍5👾1
GigaCode - AI Assistant
JetBrains выкатили своего AI ассистента, который под капотом ломится вЧАТДЖИПИТИ. У Microsoft есть Copilot. Чтобы данные AI ассистенты успешно завелись - нужен или постоянно включенный польский VPN либо польский VPN + хитрая маршрутизация (нет, спасибо). А пощупать то хочется, посмотреть, каково это, иметь в паре постоянного недоджуна.
И вот недавно я получил доступ к AI-ассистенту от Сбера - GigaCode.
Этот парень ещё в преальфе, доступ по вайт листу, но зато бесплатный и НАШ, СИБИРСКИЙ, без впнов и танцев с бубном. И так, на что же он способен...
Первое, что бросается в глаза - список поддерживаемых IDE: продукты JB и VSCode в списке, похвально, ребята нацелены серьезно.
Гигакод пока что может только в дополнение кода, поболтать про ужасную архитектуру или "а вот бы все с нуля переписать" прямо в IDE не получится.
Но когда ты вводишь свою первую строчку кода... Тут то и начинается веселье. Автодополнение до конца строки, написание методов по комментариям, и даже... даже... ничего больше.
Вот такой вот скромняга гигакод, больше ничего не умеет. Ну, зато личный ассистент, статусно. Ладно, что на счет качества? Помогает при разработке?
Знаете, в целом да. Функциональность автодополнения до конца строки помогает в написании повторяющегося boiletplate-кода. Анализирует контекст текущего открытого файла (или всех открытых файлов, есть настройка) и дописывает твой код. Получается красиво и быстро. Кстати скорость генерации кода практически моментальная.
Бывает я трачу больше времени на анализ кода, который он предлагает мне написать, чем на код, который написал бы сам, но на первый взгляд кажется, что это просто дело привычки. Написание функций по комментариям вообще бомба (когда контекста хватило)
Резюмировать могу так, с помощью ассистента я стал писать код быстрее на 10-20%, это достаточно непривычно, требует времени на освоение,а также есть вероятность что вы сливаете код ребятам из сбера, но попробовать определенно точно стоит!
👾 PICO
JetBrains выкатили своего AI ассистента, который под капотом ломится в
И вот недавно я получил доступ к AI-ассистенту от Сбера - GigaCode.
Этот парень ещё в преальфе, доступ по вайт листу, но зато бесплатный и НАШ, СИБИРСКИЙ, без впнов и танцев с бубном. И так, на что же он способен...
Первое, что бросается в глаза - список поддерживаемых IDE: продукты JB и VSCode в списке, похвально, ребята нацелены серьезно.
Гигакод пока что может только в дополнение кода, поболтать про ужасную архитектуру или "а вот бы все с нуля переписать" прямо в IDE не получится.
Но когда ты вводишь свою первую строчку кода... Тут то и начинается веселье. Автодополнение до конца строки, написание методов по комментариям, и даже... даже... ничего больше.
Вот такой вот скромняга гигакод, больше ничего не умеет. Ну, зато личный ассистент, статусно. Ладно, что на счет качества? Помогает при разработке?
Знаете, в целом да. Функциональность автодополнения до конца строки помогает в написании повторяющегося boiletplate-кода. Анализирует контекст текущего открытого файла (или всех открытых файлов, есть настройка) и дописывает твой код. Получается красиво и быстро. Кстати скорость генерации кода практически моментальная.
Бывает я трачу больше времени на анализ кода, который он предлагает мне написать, чем на код, который написал бы сам, но на первый взгляд кажется, что это просто дело привычки. Написание функций по комментариям вообще бомба (когда контекста хватило)
Резюмировать могу так, с помощью ассистента я стал писать код быстрее на 10-20%, это достаточно непривычно, требует времени на освоение,
👾 PICO
🔥6👍2❤1🤡1
Последние несколько лет не вылезаю из бекенд разработки, поднадоело.
Решил освежить в памяти и заодно узнать, какого это, пилить приложухи под виндовый десктоп в 2к24.
Из технологий у нас все так же есть WinForms и WPF - (не) стареющая классика. К ним добавились UWP (который за 3 года успел устареть и откиснуть) и MAUI (позиционирующий себя как эволюция Xamarin.Forms)
Трогать новые технологии от Майкрософта себе дороже, поэтому решил взять старый добрый WPF и проверить, а как же дела сейчас у старичка. Спойлер: все у него круто!
Во-первых, наконец, прислушались к сообществу и вместо необходимости использовать тысячи тысяч сторонних MVVM фреймворков нас встречает дружелюбный CommunityToolkit.Mvvm - официальный фреймворк от Майков.
Его снабдили полноценной документацией, большим количеством примеров и, что самое приятное, в него также встроили современные фичи языка, а именно Source Generators. Теперь писать ViewModel для XAML разметки стало на порядки быстрее и проще.
Пару слов про IDE. Я пользуюсь JetBrains Rider, и по сравнению с тем, какая поддержка WPF была в нем 5 лет назад - ощущение от разработки сейчас - это небо и земля.
Джеты подтянули XAML дизайнер, оптимизировали навигацию между разметкой и code-behind, надо проверить, есть ли hot-reload, а то руки не дошли посмотреть.
Делаю вывод, что инструментарий разработки под десктоп развивается, причем достаточно стремительно. Писать приложения стало проще, хотя и отсутствуют некоторые давно желанные мною фичи, но легко подключаются сторонними либами.
Может, стоит попробовать MAUI?..
👾 PICO
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2❤1
Кекекек, тут десериализация в .NET стала второй топовой хакерской техникой рейтинга PortSwigger.
Ало, я думал .NET одна из самых безопасных сред для разработки ПО, а в документе на 100+ страниц перечислили просто нереальное количество векторов, как же можно ломануться из-вне на машинки, где крутятся .NET приложухи через бреши во внешних библиотеках. В страшное время живем...
👾 PICO
Ало, я думал .NET одна из самых безопасных сред для разработки ПО, а в документе на 100+ страниц перечислили просто нереальное количество векторов, как же можно ломануться из-вне на машинки, где крутятся .NET приложухи через бреши во внешних библиотеках. В страшное время живем...
👾 PICO
PortSwigger Research
Top 10 web hacking techniques of 2023
Welcome to the Top 10 Web Hacking Techniques of 2023, the 17th edition of our annual community-powered effort to identify the most innovative must-read web security research published in the last year
😁5🤔2❤1🔥1
Data Oriented Design
Мы живём в мире, ориентированном на объекты. Есть сущности, они обладают определенными свойствами, поведением. Часть свойств можно увидеть из-вне, часть только при углубленном изучении, какие-то системы могут быть скрыты, поведение объектов может меняться в зависимости от обстоятельств...
Чистой воды объектно ориентированное программирование. Именно поэтому оно так популярно в айтишной среде, из-за своей обыденной простоты. "Ближе к народу", так сказать.
Мы уже давно отошли от процедурного программирования, перешли на следующей уровень абстракции, моделируем целые предметные области через призму реального мира (DDD), чтобы запускать успешные продукты. И это работает.
Но будучи сфокусированными на разработке конкретного проекта по устоявшейся методологии - упускаем очень много чего интересного вокруг.
Например, существует целое направление, пришедшее к нам из игровой индустрии под названием Data Oriented Design (DOD).
Если коротко - то это набор практик, позволяющих добиться наибольшей производительности и при этом сохранить гибкость и расширяемость в разработке продукта. Этот подход полностью базируется на анемичной модели, когда логика и данные разделены, в противовес богатой, когда логика и данные находятся вместе.
Как часто вы наблюдаете тормоза при работе с современными продуктами? Они, к сожалению, часто являются следствием неоптимального применения DDD, где используется богатая модель, когда надо, допустим, собрать объект из 10 таблиц для выполнения операции, занимающей 1 наносекунду.
Современные игры, однако, строят в основном с использованием подхода DOD, именно благодаря ему мы получаем 144 кадра в секунду при огромном количестве происходящих действий на экране. Вот это я понимаю, мощь.
DOD заставляет посмотреть на ООП под другим углом, а после прочтения информации об архитектурах, применяемых в DOD, например об Entity Component System (тема одного из следующих постов, кстати), трудно не воскликнуть "А что, так можно было?"
Про DOD на Хабре
Книга по DOD
👾 PICO
Мы живём в мире, ориентированном на объекты. Есть сущности, они обладают определенными свойствами, поведением. Часть свойств можно увидеть из-вне, часть только при углубленном изучении, какие-то системы могут быть скрыты, поведение объектов может меняться в зависимости от обстоятельств...
Чистой воды объектно ориентированное программирование. Именно поэтому оно так популярно в айтишной среде, из-за своей обыденной простоты. "Ближе к народу", так сказать.
Мы уже давно отошли от процедурного программирования, перешли на следующей уровень абстракции, моделируем целые предметные области через призму реального мира (DDD), чтобы запускать успешные продукты. И это работает.
Но будучи сфокусированными на разработке конкретного проекта по устоявшейся методологии - упускаем очень много чего интересного вокруг.
Например, существует целое направление, пришедшее к нам из игровой индустрии под названием Data Oriented Design (DOD).
Если коротко - то это набор практик, позволяющих добиться наибольшей производительности и при этом сохранить гибкость и расширяемость в разработке продукта. Этот подход полностью базируется на анемичной модели, когда логика и данные разделены, в противовес богатой, когда логика и данные находятся вместе.
Как часто вы наблюдаете тормоза при работе с современными продуктами? Они, к сожалению, часто являются следствием неоптимального применения DDD, где используется богатая модель, когда надо, допустим, собрать объект из 10 таблиц для выполнения операции, занимающей 1 наносекунду.
Современные игры, однако, строят в основном с использованием подхода DOD, именно благодаря ему мы получаем 144 кадра в секунду при огромном количестве происходящих действий на экране. Вот это я понимаю, мощь.
DOD заставляет посмотреть на ООП под другим углом, а после прочтения информации об архитектурах, применяемых в DOD, например об Entity Component System (тема одного из следующих постов, кстати), трудно не воскликнуть "А что, так можно было?"
Про DOD на Хабре
Книга по DOD
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3🤔3👍2💩1
Безграничная фильтрация в MongoDB (нет)
Люблю монгу. Правда, отличная СУБД для повседневных задач. Когда начинаешь работу с этим инструментом - как будто попадаешь в сказку. Все удобно, быстро, что ни захочешь - будет.
И вроде бы все зашибись, но как и всегда бывает, в каждой бочке меда есть ложка дегтя.
Стоит простейшая задача - фильтрация с пагинацией. Ну практически каждому продукту в том или ином виде эта функциональность нужна. Есть пара миллиончиков документов, надо их постранично отображать с применением кучи фильтров, при этом показывать количество всех документов, удовлетворяющих фильтру.
Как это сделать на монге? Подержите мое пиво, берём документ, денормализуем все входящие в него поля в один массив, например, props, следующим образом:
Пишем механизм синхронизации этого поля, и все, что остается сделать - повесить индекс
В чем загвоздка? Хе-хе-хе, а вот это нифига не очевидно. Как только вы попробуете посчитать количество документов, удовлетворяющих фильтру, вы будете неприятно удивлены скоростью работы этой операции.
Внезапно, монга не хранит метаданные в индексах и для того, чтобы посчитать количество документов, ей нужно все эти документы достать из базы. Итого мы получаем, что запрос за количеством документов может падать по таймауту и крашить нашу пагинацию.
В общем случае решить эту проблему (с сохранением первоначальных требований) на монге просто невозможно. Такие "тупые" ограничения и становятся причиной появления технологических "зоопарков", в данном случае можно внедрять ElasticSearch и поддерживать еще тонну кода.
Печально.
Пока что единственная СУБД, которая ни разу не подводила в таких вещах - это PostgreSQL.
👾 PICO
Люблю монгу. Правда, отличная СУБД для повседневных задач. Когда начинаешь работу с этим инструментом - как будто попадаешь в сказку. Все удобно, быстро, что ни захочешь - будет.
И вроде бы все зашибись, но как и всегда бывает, в каждой бочке меда есть ложка дегтя.
Стоит простейшая задача - фильтрация с пагинацией. Ну практически каждому продукту в том или ином виде эта функциональность нужна. Есть пара миллиончиков документов, надо их постранично отображать с применением кучи фильтров, при этом показывать количество всех документов, удовлетворяющих фильтру.
Как это сделать на монге? Подержите мое пиво, берём документ, денормализуем все входящие в него поля в один массив, например, props, следующим образом:
{
"_id": "000",
"DisplayName": "Label",
// ...
"props": [
{ "k": "_id", "v": "000" },
{ "k": "DisplayName", "v": "Label" }
// ...
]
}
Пишем механизм синхронизации этого поля, и все, что остается сделать - повесить индекс
{ "props.k": 1, "props.v": 1 } и перенацелить фильтрацию. В итоге мы получаем очень быстрый поиск по любой комбинации полей, при относительно небольших трудозатратах.В чем загвоздка? Хе-хе-хе, а вот это нифига не очевидно. Как только вы попробуете посчитать количество документов, удовлетворяющих фильтру, вы будете неприятно удивлены скоростью работы этой операции.
Внезапно, монга не хранит метаданные в индексах и для того, чтобы посчитать количество документов, ей нужно все эти документы достать из базы. Итого мы получаем, что запрос за количеством документов может падать по таймауту и крашить нашу пагинацию.
В общем случае решить эту проблему (с сохранением первоначальных требований) на монге просто невозможно. Такие "тупые" ограничения и становятся причиной появления технологических "зоопарков", в данном случае можно внедрять ElasticSearch и поддерживать еще тонну кода.
Печально.
Пока что единственная СУБД, которая ни разу не подводила в таких вещах - это PostgreSQL.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍3🔥2💯2🤔1👾1
Entity Component System
Как-то года 4 назад я вбил в поиск гугла "хорошая архитектура". Вот так просто, без заморочек. Не "идеальная", чтобы не кликбейт, а вот просто "хорошая". Открыл вкладку с видео и начал смотреть.
На первой странице находился доклад Кирилла Надеждина про "архитектуру для всех" - ECS.
Доклад был про то, как спроектировать кодовую базу для безболезненного развития и масштабирования игр. Я не особо был погружен в аспекты геймдева, но его доклад настолько меня вдохновил, что я решил тут же попробовать применить этот подход на практике (спойлер: мало что из этого получилось).
Так о чем эта архитектура?
Концепт достаточно прост, есть три типа "объектов":
- Сущность (entity). Это абстрактный объект, у которого есть только одно свойство - идентификатор (гуид, число - не важно). Можно представить, что это просто строка в базе данных с одним единственным полем - ID.
- Компонент. Это маркер, которым можно пометить сущность. На сущности могут находиться сколь угодно много компонентов самых разных типов. Если сущность можно было представить как строку в бд, то компонент - это колонка для этой строки.
- Система. Это логика, которая взаимодействует с сущностями, меняет набор их компонентов, а также изменяет их. Собственно, системы - это просто функции бизнес-логики, меняющие данные (компоненты) у сущностей.
Комбинация взаимодействий этих трёх объектов позволяет развивать сложные проекты достаточно большого масштаба. Overwatch, Operation Flashpoint, Raid: Shadow Legends, Baldur's Gate 3 - все эти проекты стали следствием применения паттерна ECS.
Но чтобы научиться грамотно им управлять - нужно сломать свой ООПшный мозг (что-то похожее чувствуешь, когда начинаешь писать в функциональном стиле, но в ECS эффект намного сильнее).
В ECS из коробки вы получаете data-oriented design, а следовательно, и performance. Наличие малого количества составных частей архитектуры (всего лишь три) гарантирует, что ваш код не превратится в ball of mud (хотя, если постараться, - все возможно)
Но паттерн подойдёт не всем. Я делал как минимум два подхода в попытке применить его к стандартным backend-сервисам, ориентированным на CRUD-операции. И каждый раз получается шляпа, все-таки не подходит ECS для стандартных бизнес-приложений, очередной "не silver bullet".
С другой стороны, в нестандартных задачах эта технология может раскрыться с очень положительной стороны. Например, если взять из ECS только концепт, связанный с хранением данных (entity и component), то оказывается, что подход идеально ложится на ситуации, когда вы не знаете доменную область на момент начала разработки. Динамические связи компонентов и сущностей позволяют менять доменную область "на лету", формируя ее по ходу разработки, а впоследствии закрепить стандартной реляционной схемой, когда вся доменная область будет "разведана" и понятна для команды.
Прямо сейчас применяю этот подход в рабочей деятельности и очень кайфую от результата. Помимо этого, слом мышления даёт реально крутой буст техническим скилам. Рекомендую ознакомиться.
Отличная статья на хабре про ECS - базовые концепции и overview
Dev Talk разработчиков Overwatch про ECS и сетевой код на backend'e
Доклад от разработчика Larian (Baldur's Gate 3) про правильное применение ECS
👾 PICO
Как-то года 4 назад я вбил в поиск гугла "хорошая архитектура". Вот так просто, без заморочек. Не "идеальная", чтобы не кликбейт, а вот просто "хорошая". Открыл вкладку с видео и начал смотреть.
На первой странице находился доклад Кирилла Надеждина про "архитектуру для всех" - ECS.
Доклад был про то, как спроектировать кодовую базу для безболезненного развития и масштабирования игр. Я не особо был погружен в аспекты геймдева, но его доклад настолько меня вдохновил, что я решил тут же попробовать применить этот подход на практике (спойлер: мало что из этого получилось).
Так о чем эта архитектура?
Концепт достаточно прост, есть три типа "объектов":
- Сущность (entity). Это абстрактный объект, у которого есть только одно свойство - идентификатор (гуид, число - не важно). Можно представить, что это просто строка в базе данных с одним единственным полем - ID.
- Компонент. Это маркер, которым можно пометить сущность. На сущности могут находиться сколь угодно много компонентов самых разных типов. Если сущность можно было представить как строку в бд, то компонент - это колонка для этой строки.
- Система. Это логика, которая взаимодействует с сущностями, меняет набор их компонентов, а также изменяет их. Собственно, системы - это просто функции бизнес-логики, меняющие данные (компоненты) у сущностей.
Комбинация взаимодействий этих трёх объектов позволяет развивать сложные проекты достаточно большого масштаба. Overwatch, Operation Flashpoint, Raid: Shadow Legends, Baldur's Gate 3 - все эти проекты стали следствием применения паттерна ECS.
Но чтобы научиться грамотно им управлять - нужно сломать свой ООПшный мозг (что-то похожее чувствуешь, когда начинаешь писать в функциональном стиле, но в ECS эффект намного сильнее).
В ECS из коробки вы получаете data-oriented design, а следовательно, и performance. Наличие малого количества составных частей архитектуры (всего лишь три) гарантирует, что ваш код не превратится в ball of mud (хотя, если постараться, - все возможно)
Но паттерн подойдёт не всем. Я делал как минимум два подхода в попытке применить его к стандартным backend-сервисам, ориентированным на CRUD-операции. И каждый раз получается шляпа, все-таки не подходит ECS для стандартных бизнес-приложений, очередной "не silver bullet".
С другой стороны, в нестандартных задачах эта технология может раскрыться с очень положительной стороны. Например, если взять из ECS только концепт, связанный с хранением данных (entity и component), то оказывается, что подход идеально ложится на ситуации, когда вы не знаете доменную область на момент начала разработки. Динамические связи компонентов и сущностей позволяют менять доменную область "на лету", формируя ее по ходу разработки, а впоследствии закрепить стандартной реляционной схемой, когда вся доменная область будет "разведана" и понятна для команды.
Прямо сейчас применяю этот подход в рабочей деятельности и очень кайфую от результата. Помимо этого, слом мышления даёт реально крутой буст техническим скилам. Рекомендую ознакомиться.
Отличная статья на хабре про ECS - базовые концепции и overview
Dev Talk разработчиков Overwatch про ECS и сетевой код на backend'e
Доклад от разработчика Larian (Baldur's Gate 3) про правильное применение ECS
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2👾1
PT Dephaze
Фух, мы это сделали.
На прошедшем мероприятии Positive Security Day наша команда продемонстрировала крупнейшим компаниям РФ первого автопентестера компании Positive Technologies - Dephaze.
Мы начали активную разработку продукта весной 2024 года, за несколько месяцев разработали базу продукта и громко заявили о себе, пообещав выпустить коммерческий релиз уже в феврале 25-ого года.
Собственно, это основная причина изменений в частоте публикаций на канале. Я по уши в работе💃
Перед нами стоит непростая задача - программно сэмулировать действия хакера внутри инфраструктуры, не попасться при этом средствам защиты и успешно захватить как можно большее количество машин сами разными способами.
После нескольких месяцев проектирования и проверки концепций различных архитектур (+ работы по выходным), кажется, мне удалось найти баланс и создать достаточно гибкое и масштабируемое технологическое ядро, на котором может стоять весь тот функционал, который мы собираемся внедрить.
Это невероятно интересная и увлекательная область, которая не только является большим челленджем, но и с огромной скоростью прокачивает технологические скиллы. Машинное обучение, эксплуатация уязвимостей, сетевые коммуникации по экзотическим протоколам, разнообразие инфраструктуры - и это только малая часть того, с чем приходится сталкиваться буквально каждый день.
У нас прекрасная, драйвовая команда. На мероприятии мы сами продавали наш продукт. Ни одного сейла - только команда разработки. Наш продакт в ночь перед событием просто накупил для нас белых футболок и написал на них черным маркером название продукта (так как иконки еще нет👍 ). И в таком эпатажном, без преувеличения, формате, мы общались с представителями крупнейшего бизнеса, слушали их боли и записывали потенциальные решения, которые без сомнений окажутся в продукте в ближайшее время.
Мы точно очень скоро вас удивим✌️
А запись мероприятия доступна тут (Зал Молекула, есть таймкоды, PT Dephaze на 05:23:00):
https://psd.ptsecurity.com/#live
Обязательно посмотрите вступительную заставку в самом начале (00:30:00), она очень кайфовая.
👾 PICO
Фух, мы это сделали.
На прошедшем мероприятии Positive Security Day наша команда продемонстрировала крупнейшим компаниям РФ первого автопентестера компании Positive Technologies - Dephaze.
Мы начали активную разработку продукта весной 2024 года, за несколько месяцев разработали базу продукта и громко заявили о себе, пообещав выпустить коммерческий релиз уже в феврале 25-ого года.
Собственно, это основная причина изменений в частоте публикаций на канале. Я по уши в работе
Перед нами стоит непростая задача - программно сэмулировать действия хакера внутри инфраструктуры, не попасться при этом средствам защиты и успешно захватить как можно большее количество машин сами разными способами.
После нескольких месяцев проектирования и проверки концепций различных архитектур (+ работы по выходным), кажется, мне удалось найти баланс и создать достаточно гибкое и масштабируемое технологическое ядро, на котором может стоять весь тот функционал, который мы собираемся внедрить.
Это невероятно интересная и увлекательная область, которая не только является большим челленджем, но и с огромной скоростью прокачивает технологические скиллы. Машинное обучение, эксплуатация уязвимостей, сетевые коммуникации по экзотическим протоколам, разнообразие инфраструктуры - и это только малая часть того, с чем приходится сталкиваться буквально каждый день.
У нас прекрасная, драйвовая команда. На мероприятии мы сами продавали наш продукт. Ни одного сейла - только команда разработки. Наш продакт в ночь перед событием просто накупил для нас белых футболок и написал на них черным маркером название продукта (так как иконки еще нет
Мы точно очень скоро вас удивим
А запись мероприятия доступна тут (Зал Молекула, есть таймкоды, PT Dephaze на 05:23:00):
https://psd.ptsecurity.com/#live
Обязательно посмотрите вступительную заставку в самом начале (00:30:00), она очень кайфовая.
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥7👍2❤1
Microsoft News
Copy files across instances of Visual Studio
Discover how Visual Studio 2022's new feature allows you to seamlessly copy and paste code files and folders between different instances, streamlining your workflow and enhancing efficiency.
Разработчики Visual Studio написали отдельный блог пост про то, что теперь в этой IDE можно КОПИРОВАТЬ ФАЙЛЫ между разными окнами приложения.
Шел 2024 год.
https://devblogs.microsoft.com/visualstudio/copy-files-across-instances-of-visual-studio/
👾 PICO
Шел 2024 год.
https://devblogs.microsoft.com/visualstudio/copy-files-across-instances-of-visual-studio/
Please open Telegram to view this post
VIEW IN TELEGRAM
👾4🔥1
Приколы межпроцессной буферизации
В операционных системах существует традиционное разделение потоков консольного вывода программ на stdout и stderr.
Stderr - поток для сигналов, что что-то идёт не так. Обычно туда попадают ошибки, исключения и различного рода крэши.
Stdout в свою очередь - это место, куда летит оставшийся вагон логов исполняемой программы.
Но кроме концептуальных различий между ними есть ещё кое-что. Буферизация.
Буферизация - механизм, оптимизирующий доставку информации от источника к потребителю с целью минимизации количества исполняемых операций над данными.
Короче говоря, буфер - это пакет с мусором, который время от времени выносят на помойку (выгружают в консоль). Если бы не было буфера - приходилось бы бегать до контейнера с каждым фантиком от конфетки.
Стандартный поток вывода по-умолчанию буферизируется, а вот поток ошибок - нет.
В целом, это логично. Сообщения о проблемах мы хотим получить максимально быстро, ошибок в программе (по сравнению с объемами остальной информации) кратно меньше - и видеть их нужно срочно. А вот логи можно выгружать в консоль когда удобно.
Да только вот в настройках операционных систем на Unix взято за правило, в случае, если программа не ассоциирована с запуском из терминала, то выгружать буфер по-умолчанию она будет не построчно (как мы привыкли видеть), а только при завершении работы.
Это значит, что если запускать утилиту из другой программы через код, мы увидим лог исполнения дочернего процесса только после завершения его работы.
А если речь идёт о процессе, который нужно повесить в фоновое исполнение надолго... То из родительской программы в реальном времени мы увидим логи примерно никогда.
Такое поведение можно переопределить, и в языках высокого уровня (например в dotnet) это "исправлено" из коробки: мы увидим построчный вывод даже из другого процесса. Но на низкоуровневых языках типа C/C++ разработчики сами принимают решение о "выносе мусора".
И если они не подумали об этом и оставили поведение по-умолчанию, и уж тем более не дали возможность этим управлять - придется наслаждаться пустым аутпутом в дочерних процессах или городить костыли, эмулируя подключение терминала, либо же запускать программу через прокси-процесс для контроля буферизации.
Так и живем.
👾 PICO
В операционных системах существует традиционное разделение потоков консольного вывода программ на stdout и stderr.
Stderr - поток для сигналов, что что-то идёт не так. Обычно туда попадают ошибки, исключения и различного рода крэши.
Stdout в свою очередь - это место, куда летит оставшийся вагон логов исполняемой программы.
Но кроме концептуальных различий между ними есть ещё кое-что. Буферизация.
Буферизация - механизм, оптимизирующий доставку информации от источника к потребителю с целью минимизации количества исполняемых операций над данными.
Короче говоря, буфер - это пакет с мусором, который время от времени выносят на помойку (выгружают в консоль). Если бы не было буфера - приходилось бы бегать до контейнера с каждым фантиком от конфетки.
Стандартный поток вывода по-умолчанию буферизируется, а вот поток ошибок - нет.
В целом, это логично. Сообщения о проблемах мы хотим получить максимально быстро, ошибок в программе (по сравнению с объемами остальной информации) кратно меньше - и видеть их нужно срочно. А вот логи можно выгружать в консоль когда удобно.
Да только вот в настройках операционных систем на Unix взято за правило, в случае, если программа не ассоциирована с запуском из терминала, то выгружать буфер по-умолчанию она будет не построчно (как мы привыкли видеть), а только при завершении работы.
Это значит, что если запускать утилиту из другой программы через код, мы увидим лог исполнения дочернего процесса только после завершения его работы.
А если речь идёт о процессе, который нужно повесить в фоновое исполнение надолго... То из родительской программы в реальном времени мы увидим логи примерно никогда.
Такое поведение можно переопределить, и в языках высокого уровня (например в dotnet) это "исправлено" из коробки: мы увидим построчный вывод даже из другого процесса. Но на низкоуровневых языках типа C/C++ разработчики сами принимают решение о "выносе мусора".
И если они не подумали об этом и оставили поведение по-умолчанию, и уж тем более не дали возможность этим управлять - придется наслаждаться пустым аутпутом в дочерних процессах или городить костыли, эмулируя подключение терминала, либо же запускать программу через прокси-процесс для контроля буферизации.
Так и живем.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤2👾1
PT Dephaze - наш первый вебинар
Приглашаю всех заценить какой же все-таки кайф мы делаем 17 декабря в 14.00 (МСК) на вебинаре, посвященном Dephaze - флагманскому атакующему продукту Positive Technologies по автоматическому пентесту корпоративных инфраструктур!
А еще, мы запустили обратный отсчет до коммерческого запуска и старта первых пилотов. Смотрю на этот таймер и страшно становится. Но! Придуманная нами технология настолько перспективная, что приходится вырабатывать механизмы "сдерживания" этого монстра, чтобы он не сделал то, что не должен (а может он огого).
Кароч, завтра, 14.00 по мск, покажем реальную инфру, реальные атаки, без ерунды, будет интересно, залетай😎
https://dephaze.ptsecurity.com/
👾 PICO
Приглашаю всех заценить какой же все-таки кайф мы делаем 17 декабря в 14.00 (МСК) на вебинаре, посвященном Dephaze - флагманскому атакующему продукту Positive Technologies по автоматическому пентесту корпоративных инфраструктур!
А еще, мы запустили обратный отсчет до коммерческого запуска и старта первых пилотов. Смотрю на этот таймер и страшно становится. Но! Придуманная нами технология настолько перспективная, что приходится вырабатывать механизмы "сдерживания" этого монстра, чтобы он не сделал то, что не должен (а может он огого).
Кароч, завтра, 14.00 по мск, покажем реальную инфру, реальные атаки, без ерунды, будет интересно, залетай
https://dephaze.ptsecurity.com/
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥8
Лучший скриптовый язык для .NET разработчика
Наверняка всем знакома история с bash/poweshell-скриптами для деплоя приложения на окружение.
Приходишь в проект, а там ЭТО: сотни строк кода вперемешку с магическими константами, циклы и условные конструкции, которые несут для разработчика, читающего этот код, только одно - страдание.
Покажите мне хотя бы одного человека, которому нравится читать чужие скрипты командной оболочки.
Есть универсальное решение этой задачи - грамотно выстроенный CI, но иногда без скриптов обойтись действительно нельзя ввиду различных ограничений, или просто нужен быстрый fallback-вариант автоматизации.
C# обладает скриптовым диалектом, но жесткость синтаксических конструкций может приводить к появлению лишнего кода, а лишний код мы писать не хотим, особенно когда дело касается скриптов :)
Для такой задачи идеально подходит F#.
Во-первых, в F# вы (практически) никогда не словите NullReferenceException. Что бы вы не написали, если код компилируется - значит он будет исполнен так, как вы его написали, без всяких неявностей и потенциальных warning-ов. Добавим сверху ещё иммутабельность по-умолчанию и получим удобную и эффективную отладку.
Во-вторых, используя F#, вы получаете возможность использовать всю силу экосистемы dotnet. Нужно подключить в скрипт внешнюю .dll-библиотеку? Или вообще использовать внешний nuget-пакет? Легко, добавляем директиву
В-третьих, F# очень давно заточен быть в том числе скриптовым языком, что способствовало появлению масштабных инструментов, ориентированных на использование в контексте скриптов. Например, F# Make (FAKE), с помощью которого можно разбивать скрипт на шаги и контролировать пайплайн его исполнения более декларативно. По удобству - почти как docker compose, с сохранением гибкости языка.
Ну и в заключение, написание скриптов на F# - это просто хороший способ начать знакомство с языком, попутно притронувшись к функциональной парадигме программирования. А она дает не малые плюшки при кодировании в кровавом энтерпрайзе. Об этом как-нибудь отдельно поговорим :)
Активно пользуюсь F# скриптами в своей деятельности, и вам советую)
А начать свое погружение в удивительный мир функциональщины на F# рекомендую тут:
https://fsharpforfunandprofit.com/
👾 PICO
Наверняка всем знакома история с bash/poweshell-скриптами для деплоя приложения на окружение.
Приходишь в проект, а там ЭТО: сотни строк кода вперемешку с магическими константами, циклы и условные конструкции, которые несут для разработчика, читающего этот код, только одно - страдание.
Покажите мне хотя бы одного человека, которому нравится читать чужие скрипты командной оболочки.
Есть универсальное решение этой задачи - грамотно выстроенный CI, но иногда без скриптов обойтись действительно нельзя ввиду различных ограничений, или просто нужен быстрый fallback-вариант автоматизации.
C# обладает скриптовым диалектом, но жесткость синтаксических конструкций может приводить к появлению лишнего кода, а лишний код мы писать не хотим, особенно когда дело касается скриптов :)
Для такой задачи идеально подходит F#.
Во-первых, в F# вы (практически) никогда не словите NullReferenceException. Что бы вы не написали, если код компилируется - значит он будет исполнен так, как вы его написали, без всяких неявностей и потенциальных warning-ов. Добавим сверху ещё иммутабельность по-умолчанию и получим удобную и эффективную отладку.
Во-вторых, используя F#, вы получаете возможность использовать всю силу экосистемы dotnet. Нужно подключить в скрипт внешнюю .dll-библиотеку? Или вообще использовать внешний nuget-пакет? Легко, добавляем директиву
#r и используем внешний код из коробки. А подключить код из другого скрипта поможет директива #loadВ-третьих, F# очень давно заточен быть в том числе скриптовым языком, что способствовало появлению масштабных инструментов, ориентированных на использование в контексте скриптов. Например, F# Make (FAKE), с помощью которого можно разбивать скрипт на шаги и контролировать пайплайн его исполнения более декларативно. По удобству - почти как docker compose, с сохранением гибкости языка.
Ну и в заключение, написание скриптов на F# - это просто хороший способ начать знакомство с языком, попутно притронувшись к функциональной парадигме программирования. А она дает не малые плюшки при кодировании в кровавом энтерпрайзе. Об этом как-нибудь отдельно поговорим :)
Активно пользуюсь F# скриптами в своей деятельности, и вам советую)
А начать свое погружение в удивительный мир функциональщины на F# рекомендую тут:
https://fsharpforfunandprofit.com/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🤔5😁4
Социальный долг
На днях посчастливилось прочитать в книге Креативный программист (Ваутер Грунефелд) про один термин, который сильно привлек мое внимание - социальный долг.
Сначала, я интерпретировал его как долг перед обществом или коллективом, про личную ответственность в рамках какого-то сообщества. Но тезис про другое.
В среде программистов есть устоявшееся словосочетание - технический долг. Мы говорим про него как про что-то, что мешает долгосрочному развитию кодовой базы, достижению архитектурной гибкости, негативно влияет на Developer Experience или просто "плохо пахнет".
Автор предлагает взглянуть на социальные конструкты, в которых мы участвуем, через четкую, формализованную "призму", примерно так же, как если бы мы смотрели на код.
Для этого он приводит очень интересные примеры "маркеров" социального долга, которые могут присутствовать в любом сообществе, объединенном общей целью, ниже примеры некоторых из них:
Влияние социального долга трудно переоценить. Кажется, что он может сбавлять эффективность развития проекта или продукта намного сильнее, чем долг технический.
Обычно, когда дело касается межличностного общения, мне бывает трудно описать имеющиеся проблемы в четкие, формализованные тезисы. Отношения к таким проблемам как к "социальному долгу", выявление четких "маркеров" подобно тем, что встречаются в коде, помогло в выстраивании вектора развития взаимоотношений внутри команды.
И даже, немного, собственному самоопределению в коллективе.
Вывод из размышлений об этом очень прост. Общение - ключевой фактор уменьшения социального долга. Ретроспективы, дейлики, 1-1 - все эти инструменты по сути призваны решать эту задачу. Так что если подобные активности кажутся бесполезной тратой времени, возможно, это далеко не так, таким образом вычищается социальный долг из коллектива, что может способствовать кратному увеличению эффективности работы команды.
Можно, конечно, приклеить стикер на спину коллеги с подписью // Социальный долг, подобно тому, как мы оставляем тудушки в комментариях к техдолгу, но в таких важных вещах нужен более конструктивный подход :)
👾 PICO
На днях посчастливилось прочитать в книге Креативный программист (Ваутер Грунефелд) про один термин, который сильно привлек мое внимание - социальный долг.
Сначала, я интерпретировал его как долг перед обществом или коллективом, про личную ответственность в рамках какого-то сообщества. Но тезис про другое.
В среде программистов есть устоявшееся словосочетание - технический долг. Мы говорим про него как про что-то, что мешает долгосрочному развитию кодовой базы, достижению архитектурной гибкости, негативно влияет на Developer Experience или просто "плохо пахнет".
Автор предлагает взглянуть на социальные конструкты, в которых мы участвуем, через четкую, формализованную "призму", примерно так же, как если бы мы смотрели на код.
Для этого он приводит очень интересные примеры "маркеров" социального долга, которые могут присутствовать в любом сообществе, объединенном общей целью, ниже примеры некоторых из них:
- Заброшенность новичков. Ситуация, при которой процессы онбординга неэффективны или отсутствуют вовсе.
- Одинокие волки. Сотрудники, которые действуют не учитывая мнение других членов команды.
- Разработка по рецепту. Когда члены команды слишком консервативны к принятию новых идей, технологий или подходов.
Влияние социального долга трудно переоценить. Кажется, что он может сбавлять эффективность развития проекта или продукта намного сильнее, чем долг технический.
Обычно, когда дело касается межличностного общения, мне бывает трудно описать имеющиеся проблемы в четкие, формализованные тезисы. Отношения к таким проблемам как к "социальному долгу", выявление четких "маркеров" подобно тем, что встречаются в коде, помогло в выстраивании вектора развития взаимоотношений внутри команды.
И даже, немного, собственному самоопределению в коллективе.
Вывод из размышлений об этом очень прост. Общение - ключевой фактор уменьшения социального долга. Ретроспективы, дейлики, 1-1 - все эти инструменты по сути призваны решать эту задачу. Так что если подобные активности кажутся бесполезной тратой времени, возможно, это далеко не так, таким образом вычищается социальный долг из коллектива, что может способствовать кратному увеличению эффективности работы команды.
Можно, конечно, приклеить стикер на спину коллеги с подписью // Социальный долг, подобно тому, как мы оставляем тудушки в комментариях к техдолгу, но в таких важных вещах нужен более конструктивный подход :)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4👾3💩1
MECE - Mutually Exclusive and Collectively Exhaustive
В теории вероятностей существует понятие "полная группа событий", описывающее системы, в которых из множества возможных результатов в конечном итоге произойдет только одно. В качестве примера можно взять пресловутую монетку. В результате ее подбрасывания по итогу выпадет один из вариантов: орел, решка или ребро - полная группа событий.
Не знаю, вдохновлялись ли аналитики, придумавшие MECE, ВУЗовским тервером, но в 1960-х они как будто бы переизобрели полную группу событий, но для бизнеса, накинули ярлык "принципа" и достаточно замысловато назвали: Mutually Exclusive (взаимно исключающее) and Collectively Exhaustive (совместно исчерпывающее).
Начнем рассмотрение принципа с очевидного примера, так будет проще.
Задача
Мне нужно быть в офисе завтра в 10.00 утра
Очевидные решения
- Пойти в офис пешком
- Поехать на машине
- Поехать на метро
Теперь попробуем применить MECE к данной задаче.
Видно, что два последних варианта не являются взаимно исключающими, так как в них используется один и тот же способ движения - "поехать".
Развиваем мысль дальше. Под категорию транспорта подходят не только машина и метро, но и, например, такси, велосипед или самокат(пожалуйста, нет), что в очевидных решениях я не учел. Таким образом MECE помог найти новые варианты решения.
Теперь проверим, является ли пространство решений совместно исчерпывающим? Все ли решения мы рассмотрели? Как вариант, сегодня я мог бы остаться в офисе, чтобы завтра в 10.00 утра уже быть на месте(не является рекомендацией) .
Таким образом наше пространство решений из конкретных, но узких вариантов, превратилось в непересекающиеся, но исчерпывающие категории решений:
Задача
Мне нужно быть в офисе завтра к 10.00 утра
Решения по MECE
- Пойти в офис пешком
- Использовать транспорт
- Не покидать офис сегодня
Отталкиваясь от них, я могу спокойно прорабатывать детали конкретной реализации и учесть больше факторов, чем если бы рассматривал только очевидные решения, которые пришли мне в голову.
Хотя MECE и помогает в поиске решений, он также подвергается критике из-за жестких условий применения. Например, что если пересекающиеся решения будут более оптимальны к применению в рамках задачи? Или бывает так, что проблематика очень многогранна и не делится на взаимоисключающие блоки отдельных проблем, о которых можно думать подобным образом.
В любом случае, про принцип полезно знать. Это интересный способ применения строгих математических инструментов в повседневной реальности, да и просто хорошая методика, позволяющая систематизировать и структурировать пространство решений для различного рода задач.
👾 PICO
В теории вероятностей существует понятие "полная группа событий", описывающее системы, в которых из множества возможных результатов в конечном итоге произойдет только одно. В качестве примера можно взять пресловутую монетку. В результате ее подбрасывания по итогу выпадет один из вариантов: орел, решка или ребро - полная группа событий.
Не знаю, вдохновлялись ли аналитики, придумавшие MECE, ВУЗовским тервером, но в 1960-х они как будто бы переизобрели полную группу событий, но для бизнеса, накинули ярлык "принципа" и достаточно замысловато назвали: Mutually Exclusive (взаимно исключающее) and Collectively Exhaustive (совместно исчерпывающее).
Начнем рассмотрение принципа с очевидного примера, так будет проще.
Задача
Мне нужно быть в офисе завтра в 10.00 утра
Очевидные решения
- Пойти в офис пешком
- Поехать на машине
- Поехать на метро
Теперь попробуем применить MECE к данной задаче.
Видно, что два последних варианта не являются взаимно исключающими, так как в них используется один и тот же способ движения - "поехать".
Развиваем мысль дальше. Под категорию транспорта подходят не только машина и метро, но и, например, такси, велосипед или самокат
Теперь проверим, является ли пространство решений совместно исчерпывающим? Все ли решения мы рассмотрели? Как вариант, сегодня я мог бы остаться в офисе, чтобы завтра в 10.00 утра уже быть на месте
Таким образом наше пространство решений из конкретных, но узких вариантов, превратилось в непересекающиеся, но исчерпывающие категории решений:
Задача
Мне нужно быть в офисе завтра к 10.00 утра
Решения по MECE
- Пойти в офис пешком
- Использовать транспорт
- Не покидать офис сегодня
Отталкиваясь от них, я могу спокойно прорабатывать детали конкретной реализации и учесть больше факторов, чем если бы рассматривал только очевидные решения, которые пришли мне в голову.
Хотя MECE и помогает в поиске решений, он также подвергается критике из-за жестких условий применения. Например, что если пересекающиеся решения будут более оптимальны к применению в рамках задачи? Или бывает так, что проблематика очень многогранна и не делится на взаимоисключающие блоки отдельных проблем, о которых можно думать подобным образом.
В любом случае, про принцип полезно знать. Это интересный способ применения строгих математических инструментов в повседневной реальности, да и просто хорошая методика, позволяющая систематизировать и структурировать пространство решений для различного рода задач.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍4❤2🔥1🤔1💩1👾1
Упрощай
Последнее время мыслями витаю где-то между IT и психологией. Решил порассуждать про самый важный, на мой взгляд, термин, который объединяет эти две сферы - когнитивная сложность.
Часто можно услышать, что сложность кода (да и любого текста) можно измерить количеством появлений в голове фразы "what the f**k" за единицу времени при прочтении. По-моему это всё ещё лучший способ измерения когнитивной сложности, но есть и, безусловно, более формализованные инструменты.
Например, в IDE JetBrains можно установить специализированные плагины, позволяющие подсвечивать тяжёлые для восприятия участки кода по специальной методике. Но сейчас не о них, сфокусируемся на смыслах.
Сложность кода противопоставляется многим вещам.
Например, требованиям. Нам за простоту кода не платят, а платят за реализацию бизнес-фич, описанных в задачах на разработку. Требования продиктованы рынком. А рынку, в целом то, плевать на чистоту реализации.
Логично. Только почему-то менеджеры забывают, что рынку не плевать на конкуренцию, масштабирование и скорость роста. Они бросают все ресурсы на закрытие "срочного и важного", забывая о "важном, но не срочном". Как следствие, страдает именно код, а затем и разработчики, которым необходимо обеспечивать его поддержку. Эффективность реализации задач сокращается не на процентные пункты, а на порядки.
Все это выливается в неэффективность команд и текучку кадров. И это проблема менеджмента, как поставщика задач и ответственного за эффективность бизнеса.
Что может сделать разработчик в такой ситуации?
Для начала - осознать, что низкоквалифицированные менеджеры (которых большинство) не думают про упрощение. Поэтому брать в свои руки брозды правления над сложностью кода и резать ее под корень. Нам потом ещё его поддерживать.
А потом - кричать. Не от безысходности, а в сторону бизнеса о проблемах, которые есть в коде и о том, что грозит бизнесу, если эти проблемы не будут решены. Не перепишем этот участок кода? Через 3 месяца потеряем Серёгу, потому что он сгорит поддерживать этот кусок говна. Потеряем Серёгу - не сможем закрыть вот эту фичу, запланированную на Q3. Не закроем фичу - потеряем бабки. Потеряем бабки - и может быть все завтра вылетим на мороз.
Все упирается в "естественный" экономический отбор, и если айти-продукт стоит на песке в виде неподдерживаемого спагетти-кода - у всех большие проблемы.
Синхронизируемся с бизнесом, выруливаем, упрощаем и в конце концов выживаем, и обгоняем конкурентов, кто об этом не подумал. Зарабатываем больше, повышаем свою ценность, зарплату и репутацию. Вин-вин.
P.S. Спасибо коллегам за пикчу для поста
👾 PICO
Последнее время мыслями витаю где-то между IT и психологией. Решил порассуждать про самый важный, на мой взгляд, термин, который объединяет эти две сферы - когнитивная сложность.
Часто можно услышать, что сложность кода (да и любого текста) можно измерить количеством появлений в голове фразы "what the f**k" за единицу времени при прочтении. По-моему это всё ещё лучший способ измерения когнитивной сложности, но есть и, безусловно, более формализованные инструменты.
Например, в IDE JetBrains можно установить специализированные плагины, позволяющие подсвечивать тяжёлые для восприятия участки кода по специальной методике. Но сейчас не о них, сфокусируемся на смыслах.
Сложность кода противопоставляется многим вещам.
Например, требованиям. Нам за простоту кода не платят, а платят за реализацию бизнес-фич, описанных в задачах на разработку. Требования продиктованы рынком. А рынку, в целом то, плевать на чистоту реализации.
Логично. Только почему-то менеджеры забывают, что рынку не плевать на конкуренцию, масштабирование и скорость роста. Они бросают все ресурсы на закрытие "срочного и важного", забывая о "важном, но не срочном". Как следствие, страдает именно код, а затем и разработчики, которым необходимо обеспечивать его поддержку. Эффективность реализации задач сокращается не на процентные пункты, а на порядки.
Все это выливается в неэффективность команд и текучку кадров. И это проблема менеджмента, как поставщика задач и ответственного за эффективность бизнеса.
Что может сделать разработчик в такой ситуации?
Для начала - осознать, что низкоквалифицированные менеджеры (которых большинство) не думают про упрощение. Поэтому брать в свои руки брозды правления над сложностью кода и резать ее под корень. Нам потом ещё его поддерживать.
А потом - кричать. Не от безысходности, а в сторону бизнеса о проблемах, которые есть в коде и о том, что грозит бизнесу, если эти проблемы не будут решены. Не перепишем этот участок кода? Через 3 месяца потеряем Серёгу, потому что он сгорит поддерживать этот кусок говна. Потеряем Серёгу - не сможем закрыть вот эту фичу, запланированную на Q3. Не закроем фичу - потеряем бабки. Потеряем бабки - и может быть все завтра вылетим на мороз.
Все упирается в "естественный" экономический отбор, и если айти-продукт стоит на песке в виде неподдерживаемого спагетти-кода - у всех большие проблемы.
Синхронизируемся с бизнесом, выруливаем, упрощаем и в конце концов выживаем, и обгоняем конкурентов, кто об этом не подумал. Зарабатываем больше, повышаем свою ценность, зарплату и репутацию. Вин-вин.
P.S. Спасибо коллегам за пикчу для поста
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍11✍1💩1
Парадигма иммутабельности
Изменения - это гибко. Неважно о каких изменениях именно идёт речь. Меняем ли мы поле в строке базы данных, или свойство объекта в оперативной памяти - все эти процессы сопровождаются одним и тем же фактором: реакцией.
Реагирование на изменения формирует поведение программной системы, что в конечном итоге реализует требуемую бизнес-логику. Все логично, но есть одна проблема - все та же пресловутая сложность.
Чем больше изменений состояний объектов существует в программной системе, тем она тяжелее для восприятия и дальнейшей поддержки.
К сожалению, зависимость эта зачастую экспоненциальная. Одно изменение принять можно, два - приемлемо, три или более, особенно разнесенные по разным местам, уже являются признаком плохого кода.
Почему так происходит? Все упирается в ограничения контекста мозга программиста, который читает этот код.
Возьмём в качестве примера простейший ООП-шный код формирования коллекции, на основе предыдущей, допустим нам нужно возвращать все четные числа из исходных:
Теперь попробуем мысленно отмасштабировать правила, просто добавив требований к исходной задаче, ровно так же, как это может делать бизнес. Исходные числа нужно умножать на два, затем каждое делить на три и так далее.
Каждое новое требование расширяет контекст метода и добавляет вариативности объектам в коллекции. Чтобы добавлять новую логику, требуется поместить реализацию всех изменений в черепную коробку, начиная от инициализации коллекции заканчивая самой глубокой веткой в ветвлении, и только затем принять решение о том, куда же новый код вписать. А что если количество бизнес-правил приблизится к десяткам?
Мы занимаем больше оперативной памяти в мозге для анализа этого кода, у которой совершенно точно есть предел.
Мутабельность (изменяемость) - настоящее зло в легаси кодовых базах. Где, чтобы собрать воедино всю логику, требуется выписывать контекст на тетрадку или в excalidraw, потому что в человеческой оперативке места для анализа этой мешанины просто нет.
Как проблема решается? На помощь приходит функциональное программирование.
Зачем бороться с чем-то, если от этого в принципе можно отказаться? - подумали ФПшники и изобрели парадигму иммутабельности: неизменяемость объектов по-умолчанию.
Теперь изменения объектов невозможны. Единственное, что мы можем делать - это создавать новые объекты на основе существующих. Ветвистость кода уменьшается, а следом за ней и размер контекста, который нужно загружать в мозг для понимания правил бизнес-логики.
Взглянем на иммутабельный код:
Благодаря отсутствию изменяемой коллекции, мы сокращаем когнитивную сложность, то есть делаем код проще для чтения и восприятия, отлаживать код стало проще, а добавлять бизнес правила - легче.
К тому же, мы получаем бесплатный бонус в виде потокобезопасности. Изменение одного объекта двумя разными потоками в одно и то же время более невозможно, так как изменяемости нет :)
Такой подход, безусловно, несёт и определенные минусы. Например, в C# с иммутабельными коллекциями тяжело работать в асинхронных методах без дополнительных библиотек (таких как System.Linq.Async), иммутабельность может очень сильно расходовать оперативную память, а ограничения в изменениях иногда вынуждают добавлять новые промежуточные типы.
Тем не менее, на моей практике плюсы гораздо превышают минусы такого подхода. Сужение контекста восприятия - главный фактор, который несёт за собой парадигма иммутабельности, что ведёт к улучшению Developer Experience и, в конечном итоге, к счастливой жизни разработчика
👾 PICO
Изменения - это гибко. Неважно о каких изменениях именно идёт речь. Меняем ли мы поле в строке базы данных, или свойство объекта в оперативной памяти - все эти процессы сопровождаются одним и тем же фактором: реакцией.
Реагирование на изменения формирует поведение программной системы, что в конечном итоге реализует требуемую бизнес-логику. Все логично, но есть одна проблема - все та же пресловутая сложность.
Чем больше изменений состояний объектов существует в программной системе, тем она тяжелее для восприятия и дальнейшей поддержки.
К сожалению, зависимость эта зачастую экспоненциальная. Одно изменение принять можно, два - приемлемо, три или более, особенно разнесенные по разным местам, уже являются признаком плохого кода.
Почему так происходит? Все упирается в ограничения контекста мозга программиста, который читает этот код.
Возьмём в качестве примера простейший ООП-шный код формирования коллекции, на основе предыдущей, допустим нам нужно возвращать все четные числа из исходных:
int[] FilterEvenNumbers(int[] source)
{
var result = new List<int>();
foreach (var number in source)
{
if (number % 2 == 0)
{
// Прочие бизнес-правила
result.Add(number);
}
}
return result.ToArray();
}
Теперь попробуем мысленно отмасштабировать правила, просто добавив требований к исходной задаче, ровно так же, как это может делать бизнес. Исходные числа нужно умножать на два, затем каждое делить на три и так далее.
Каждое новое требование расширяет контекст метода и добавляет вариативности объектам в коллекции. Чтобы добавлять новую логику, требуется поместить реализацию всех изменений в черепную коробку, начиная от инициализации коллекции заканчивая самой глубокой веткой в ветвлении, и только затем принять решение о том, куда же новый код вписать. А что если количество бизнес-правил приблизится к десяткам?
Мы занимаем больше оперативной памяти в мозге для анализа этого кода, у которой совершенно точно есть предел.
Мутабельность (изменяемость) - настоящее зло в легаси кодовых базах. Где, чтобы собрать воедино всю логику, требуется выписывать контекст на тетрадку или в excalidraw, потому что в человеческой оперативке места для анализа этой мешанины просто нет.
Как проблема решается? На помощь приходит функциональное программирование.
Зачем бороться с чем-то, если от этого в принципе можно отказаться? - подумали ФПшники и изобрели парадигму иммутабельности: неизменяемость объектов по-умолчанию.
Теперь изменения объектов невозможны. Единственное, что мы можем делать - это создавать новые объекты на основе существующих. Ветвистость кода уменьшается, а следом за ней и размер контекста, который нужно загружать в мозг для понимания правил бизнес-логики.
Взглянем на иммутабельный код:
IEnumerable<int> FilterAndTransformNumbers(IEnumerable<int> source)
{
return source
.Where(number => number % 2 == 0)
// Прочие бизнес-правила
.Select(number => number * 2)
.Select(number => number / 3);
}
Благодаря отсутствию изменяемой коллекции, мы сокращаем когнитивную сложность, то есть делаем код проще для чтения и восприятия, отлаживать код стало проще, а добавлять бизнес правила - легче.
К тому же, мы получаем бесплатный бонус в виде потокобезопасности. Изменение одного объекта двумя разными потоками в одно и то же время более невозможно, так как изменяемости нет :)
Такой подход, безусловно, несёт и определенные минусы. Например, в C# с иммутабельными коллекциями тяжело работать в асинхронных методах без дополнительных библиотек (таких как System.Linq.Async), иммутабельность может очень сильно расходовать оперативную память, а ограничения в изменениях иногда вынуждают добавлять новые промежуточные типы.
Тем не менее, на моей практике плюсы гораздо превышают минусы такого подхода. Сужение контекста восприятия - главный фактор, который несёт за собой парадигма иммутабельности, что ведёт к улучшению Developer Experience и, в конечном итоге, к счастливой жизни разработчика
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4✍3👍3💩1