Срочные задачи — бич современного IT или как сделать так, чтобы сотрудник не спрашивал:
Если вам не приходится решать срочные задачи на постоянной основе — вам повезло. Их появление может быть продиктовано как реальной необходимостью, так и следствием плохого планирования и даже манипуляций. Важно понимать причины и принимать работающие меры для борьбы с этим коварным противником.
А в чем проблема проблема?
☝️Команда/сотрудник работает в состоянии хронического стресса, бесконечного аврала, постепенно выгорая,
и/или
☝️спринт команды продолжает наполняться задачами после этапа планирования, что приводит к невыполнению плана,
и/или
☝️сдвигаются сроки поставки запланированных фич.
Исходя из моего опыта, самое главное — понять, с чем мы столкнулись: искусственно созданная срочность или реально срочная задача?
Враг 1. Рили срочная задача
Бывают такие продукты и компании, которые не могут развиваться тихо, мирно, планомерно. Если ваши команда/компания/продукт должны давать молниеносные ответы на вызовы судьбы (адаптация к всплескам активности пользователей; стабилизация сервиса в ходе DDOS-атак; реализация фичи, как компенсирующая реакция на действия конкурентов и т.п.), то от срочных задач никуда не деться. Это вполне нормально, если вы заранее понимали, на что подписывались. Надеюсь, от вас этого не скрывали😑
В качестве срочных задач также могут выступать прилетевшие баги/уязвимости с прода.
Решение:
1) Срочные задачи стали нормой уже после вашего прихода в команду (время идет — все меняется), или вы не поняли об этом на этапе собеседований (по своей вине или вине работодателя)? Это уже не так важно. Если вам не подходит такой темп работы, то лучше уволиться и не мучить себя.
2) Если увольнение — не ваш вариант, то стоит подстелить себе соломку, чтобы комфортно работать в долгосрочной перспективе. Каким образом? Если срочные неотложные задачи появляются часто, то в зависимости от используемой методологии команда при планировании должна систематически закладывать на них 10/20/...% спринта (scrum) либо сдвигать сроки по разрабатываемым фичам (kanban).
Враг 2. Искусственносрочная задача
Коллега создает ощущение срочности там, где её нет, чтобы заставить команду:
1) либо работать в ускоренном режиме
2) либо отвлечься от взятых в спринт задач
Искусственная срочность может создаваться неосознанно или быть следствием преднамеренных манипуляций.
Решение:
1) вместе с заказчиком нужно понять, является ли прилетевшая задача, действительно, срочной. Как это сделать? Оценить профит/последствия, если мы ее сделаем/не сделаем. Может она подождет до следующего планирования?
2) не все заказчики готовы к открытому диалогу, поэтому пункт 1 не всегда сработает в моменте. В этом случае рекомендую на дистанции собрать статистику таких задач и их последствий для планов/сроков. Ее можно будет обсудить на ретро команды с заказчиком. Обычно собранная и хорошо представленная фактура действует очень отрезвляюще.
А эта задача просто срочная или срочная-срочная?
Если вам не приходится решать срочные задачи на постоянной основе — вам повезло. Их появление может быть продиктовано как реальной необходимостью, так и следствием плохого планирования и даже манипуляций. Важно понимать причины и принимать работающие меры для борьбы с этим коварным противником.
А в чем проблема проблема?
☝️Команда/сотрудник работает в состоянии хронического стресса, бесконечного аврала, постепенно выгорая,
и/или
☝️спринт команды продолжает наполняться задачами после этапа планирования, что приводит к невыполнению плана,
и/или
☝️сдвигаются сроки поставки запланированных фич.
Исходя из моего опыта, самое главное — понять, с чем мы столкнулись: искусственно созданная срочность или реально срочная задача?
Враг 1. Рили срочная задача
Бывают такие продукты и компании, которые не могут развиваться тихо, мирно, планомерно. Если ваши команда/компания/продукт должны давать молниеносные ответы на вызовы судьбы (адаптация к всплескам активности пользователей; стабилизация сервиса в ходе DDOS-атак; реализация фичи, как компенсирующая реакция на действия конкурентов и т.п.), то от срочных задач никуда не деться. Это вполне нормально, если вы заранее понимали, на что подписывались. Надеюсь, от вас этого не скрывали
В качестве срочных задач также могут выступать прилетевшие баги/уязвимости с прода.
Решение:
1) Срочные задачи стали нормой уже после вашего прихода в команду (время идет — все меняется), или вы не поняли об этом на этапе собеседований (по своей вине или вине работодателя)? Это уже не так важно. Если вам не подходит такой темп работы, то лучше уволиться и не мучить себя.
2) Если увольнение — не ваш вариант, то стоит подстелить себе соломку, чтобы комфортно работать в долгосрочной перспективе. Каким образом? Если срочные неотложные задачи появляются часто, то в зависимости от используемой методологии команда при планировании должна систематически закладывать на них 10/20/...% спринта (scrum) либо сдвигать сроки по разрабатываемым фичам (kanban).
Враг 2. Искусственносрочная задача
Коллега создает ощущение срочности там, где её нет, чтобы заставить команду:
1) либо работать в ускоренном режиме
2) либо отвлечься от взятых в спринт задач
Искусственная срочность может создаваться неосознанно или быть следствием преднамеренных манипуляций.
Решение:
1) вместе с заказчиком нужно понять, является ли прилетевшая задача, действительно, срочной. Как это сделать? Оценить профит/последствия, если мы ее сделаем/не сделаем. Может она подождет до следующего планирования?
2) не все заказчики готовы к открытому диалогу, поэтому пункт 1 не всегда сработает в моменте. В этом случае рекомендую на дистанции собрать статистику таких задач и их последствий для планов/сроков. Ее можно будет обсудить на ретро команды с заказчиком. Обычно собранная и хорошо представленная фактура действует очень отрезвляюще.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔1
Ты сталкиваешься со срочными задачами?
Anonymous Poll
36%
да и умею с ними справляться
14%
да, но не умею с ними справляться
50%
На что ты обращаешь внимание при выборе технического решения / технологии? Я в первую очередь руководствуюсь этими критериями:
👉 должна решаться поставленная задача
👉 простота (освоения, реализации, поддержки)
👉 гибкость (в том числе кастомизируемость, расширяемость)
👉 стандартизация (на уровне команды / компании / индустрии)
Разберём на примере выбора хранилища в существующем проекте под новую задачу.
1️⃣ Должна решаться поставленная задача
Если задача не решается, то мы такое решение / технологию в расчёт не берём. Сильно? Я тоже так думаю, однако на практике могут возникнуть сложности.
Что нам поможет очертить круг подходящих решений?
* качественно собранные требования, в том числе на перспективу (must have)
* собственный опыт, опыт коллег из команды/компании или за их пределами, в том числе доклады с конференций и статьи
* изучить документацию и книги
* початгэпэтышить или подипсикать (даст дополнительную пищу для размышления)
* платная поддержка (идеально, но дорого и не всегда есть)
2️⃣ Простота
Из нескольких рабочих альтернатив я выбираю то, что будет максимально простым.
Готовы ли мы принять новую зависимость в проект, тем самым значительно усложнив систему? Что компенсирует негативные факторы, которые окажутся на второй чаше весов:
* усложняется найм и онбординг новых, а также требуется адаптация "старых" сотрудников (разработка/DevOps/SRE)
* требуется поддерживать в актуальном состоянии скрипты раскатки с версиями раскатываемой инфраструктуры, документацию, базу знаний, мониторинги
* усложняется обновление самих сервисов в связи с подключением новых библиотек/стартеров (привет, Spring Hell🖕 )
* больше потенциальных уязвимостей и багов в системе
* в связи с перечисленным могут страдать бизнес-метрики
3️⃣ Стандартизация
Из нескольких равнозначных альтернатив я выберу то, которое чаще используется в команде / компании / индустрии. Честно говоря, не хочется обслуживать зоопарк решений, тратя на это драгоценное время команды. Технологии должны служить нам, а не мы им.
В данном случае простое и стандартное решение довольно сильно пересекаются. Чаще всего сложное решение делают стандартом за неимением простых альтернатив или сложности миграции на них.
А когда новые технологии пробовать? Стандарты могут и должны пересматриваться, если это оправдано. Мы сами недавно с Prometheus на Вику мигрировали, с Mesos на k8s, с Hazelcast на Redis.
4️⃣ Гибкость
Зная текущую задачу и перспективы развития продукта, я буду выбирать наиболее гибкое решение, которое позволит мне адаптироваться к новым вызовам без пересмотра архитектуры / логики и т.п. Это так же может быть полезно, если бизнес не до конца определился или вообще не знает, чего хочет.
PostgreSQL и Redis, например, за счет расширений и внутренней архитектуры могут хорошо справляться не только со своими "прямыми обязанностями".
P.S. последние 4 года эта логика меня не ни разу подводила, движемся дальше🏃♀️
👉 должна решаться поставленная задача
👉 простота (освоения, реализации, поддержки)
👉 гибкость (в том числе кастомизируемость, расширяемость)
👉 стандартизация (на уровне команды / компании / индустрии)
Разберём на примере выбора хранилища в существующем проекте под новую задачу.
1️⃣ Должна решаться поставленная задача
Если задача не решается, то мы такое решение / технологию в расчёт не берём. Сильно? Я тоже так думаю, однако на практике могут возникнуть сложности.
- Как будем работать с денормализованными данными? Возьмём наш PostgreSQL или поднимем MongoDB? Документы будут большие, в TOAST придется залезть.
- Напрашивается MongoDB. А какие нагрузки предполагаются и какой объем данных будем хранить?
- Бизнес пока не понимает.
- Нам же транзакции не нужны будут? Может Redis возьмём?
- Нужно познакомиться c его API.
Что нам поможет очертить круг подходящих решений?
* качественно собранные требования, в том числе на перспективу (must have)
* собственный опыт, опыт коллег из команды/компании или за их пределами, в том числе доклады с конференций и статьи
* изучить документацию и книги
* початгэпэтышить или подипсикать (даст дополнительную пищу для размышления)
* платная поддержка (идеально, но дорого и не всегда есть)
2️⃣ Простота
Из нескольких рабочих альтернатив я выбираю то, что будет максимально простым.
- Изучил документацию. Redis не подойдёт, слишком бедный API. Еще бизнес с фактурой по нагрузке вернулся: клиенты — юридические лица, объем хранения данных и RPS'ы скромные будут. Самое время разобраться с MongoDB на такой простой задаче!
- Но у наших разработчиков и SRE нет компетенции в MongoDB. PostgreSQL с такой задачей легко справится.
- Научатся! Еще одна технология будет в нашем арсенале.
Готовы ли мы принять новую зависимость в проект, тем самым значительно усложнив систему? Что компенсирует негативные факторы, которые окажутся на второй чаше весов:
* усложняется найм и онбординг новых, а также требуется адаптация "старых" сотрудников (разработка/DevOps/SRE)
* требуется поддерживать в актуальном состоянии скрипты раскатки с версиями раскатываемой инфраструктуры, документацию, базу знаний, мониторинги
* усложняется обновление самих сервисов в связи с подключением новых библиотек/стартеров (привет, Spring Hell
* больше потенциальных уязвимостей и багов в системе
* в связи с перечисленным могут страдать бизнес-метрики
3️⃣ Стандартизация
Из нескольких равнозначных альтернатив я выберу то, которое чаще используется в команде / компании / индустрии. Честно говоря, не хочется обслуживать зоопарк решений, тратя на это драгоценное время команды. Технологии должны служить нам, а не мы им.
- Ради одной задачи разбираться с новой базой? Не перебор?
- Архитектор передал, что MongoDB одобрили для занесения в стек компании. В ближайшее время планируется значительный рост числа задач, где MongoDB будет необходима.
В данном случае простое и стандартное решение довольно сильно пересекаются. Чаще всего сложное решение делают стандартом за неимением простых альтернатив или сложности миграции на них.
А когда новые технологии пробовать? Стандарты могут и должны пересматриваться, если это оправдано. Мы сами недавно с Prometheus на Вику мигрировали, с Mesos на k8s, с Hazelcast на Redis.
4️⃣ Гибкость
Зная текущую задачу и перспективы развития продукта, я буду выбирать наиболее гибкое решение, которое позволит мне адаптироваться к новым вызовам без пересмотра архитектуры / логики и т.п. Это так же может быть полезно, если бизнес не до конца определился или вообще не знает, чего хочет.
- А как мы события будем получать? Через Kafka?
- Тот же PostgreSQL можно использовать для простой очереди, судя по аналитике нам должно этого хватить.
PostgreSQL и Redis, например, за счет расширений и внутренней архитектуры могут хорошо справляться не только со своими "прямыми обязанностями".
P.S. последние 4 года эта логика меня не ни разу подводила, движемся дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
«Моей матерью был компьютер»
Сходил на выставку о том, как как искусственный интеллект меняет окружающий нас мир. Галерея Цифергауз, что в Новой Голландии, в Питере, как всегда радует качественным контентом. Для меня она стала своего рода продолжением выставки-размышления «Конструктор EGO», проходившей летом прошлого года в не менее прогрессивном Третьем месте. Она, однако, была направлена уже на изучение мира внутреннего. Горячо рекомендую посещать эти места-жемчужины🥰
---
А что по новостям искусственного интеллекта так сказать с полей?
У нас в компании продолжают активно внедрять AI в двух направлениях:
1️⃣ для ревью PR (пока результаты удручающие)
2️⃣ для упрощения кодирования
По второму пункту, как и у всех, есть успехи. Развернули DeepSeek во внутреннем контуре и прикрутили его в IDE-плагин Continue, которому можно скармливать открытый проект для наполнения контекста. Плюсы решения в целом понятны: данные не утекают наружу + проводим донастройку под свои задачи.
От моего друга-синьора-дата-инженера знаю, что в Ozon тоже подняли свою локальную инсталляцию. Тем не менее там еще остаются команды, которые пишут код по-старинке, используя белковые мозги. Мой друг до пятницы был в их числе. Поздравил его с тем, что он теперь тоже на "игле" и сможет по скорости работы конкурировать с вчерашними джунами. Мой друг-go-разработчик изСберКлауда пока сопротивляется, удивляясь производительности своего коллеги. Друга пока не увольняют, потому что есть еще один менее продуктивный, чем он сам, разработчик. Шутка (?). Так что ИИ пока погромистов не заменил.
---
В YT как на дрожжах появляются видео про low‑code / no-code платформу n8n.io. Если кто еще не в курсе, то с ее помощью вы можете строить пайплайны из классических (tg, Slack, Google и т.д.) и "умных" (ChatGPT, YandexGPT, или, например, OpenRouter, если хочется бесплатно) API для автоматизации разного рода сценариев, используя визуальный интерфейс. Если не готовы платить денежку за сервис, то можно развернуть его как как self-hosted на своем VPS. На зарубежных фриланс-площадках тысячи предложений по автоматизации с помощью n8n.io, make.com. Наши умельцы на фрилансе уже готовы поднять n8n за вас за скромную сумму. Думаю, что часть исполнителей уже написала свой Ansible-плейбук, другая — использует elest.io, а третья — делает все ручками. Сам сценарий тоже разработают, но значительно дороже: тут уже "наукоемкость" какая-то появляется.
Малый, как в целом и средний и крупный, бизнес теперь может буквально за копейки получить то, на что раньше не хватило бы никаких средств. Общаюсь по этому поводу с владельцем массажной студии, куда наведываюсь еженедельно. Так вот для него идея автоматизации интересна, но начинать погружаться в эту пучину нет ни сил, ни времени. Но это я ему ценность идеи пока плохо продал. В этом контексте с удовольствием посмотрел, как дядечка настраивал чат-бот для своего сайта с пассивными балансирами для аккумуляторов 😐 . Не знаю, какой у него бэкграунд в IT, но сделал он все четко!
---
ИИ продолжает активно проникать в задачи обывателя в том числе на уровне решения комплексных задач. Я уже не говорю о генерации картинок, видео, текстов, музыки. Тем не менее, это не помешало мне вчера отправить письмо через Почту России, написав от руки в двух экземплярах опись вложения. Вот уж кто точно не торопится за этими вашими трендами. А у тебя получается оседлать эту ИИ-волну?
Сходил на выставку о том, как как искусственный интеллект меняет окружающий нас мир. Галерея Цифергауз, что в Новой Голландии, в Питере, как всегда радует качественным контентом. Для меня она стала своего рода продолжением выставки-размышления «Конструктор EGO», проходившей летом прошлого года в не менее прогрессивном Третьем месте. Она, однако, была направлена уже на изучение мира внутреннего. Горячо рекомендую посещать эти места-жемчужины
---
А что по новостям искусственного интеллекта так сказать с полей?
У нас в компании продолжают активно внедрять AI в двух направлениях:
1️⃣ для ревью PR (пока результаты удручающие)
2️⃣ для упрощения кодирования
По второму пункту, как и у всех, есть успехи. Развернули DeepSeek во внутреннем контуре и прикрутили его в IDE-плагин Continue, которому можно скармливать открытый проект для наполнения контекста. Плюсы решения в целом понятны: данные не утекают наружу + проводим донастройку под свои задачи.
От моего друга-синьора-дата-инженера знаю, что в Ozon тоже подняли свою локальную инсталляцию. Тем не менее там еще остаются команды, которые пишут код по-старинке, используя белковые мозги. Мой друг до пятницы был в их числе. Поздравил его с тем, что он теперь тоже на "игле" и сможет по скорости работы конкурировать с вчерашними джунами. Мой друг-go-разработчик из
ИИ научился кодить.
Ожидание: вайбкодинг👦
Реальность: бизнес дает в 10 раз больше задач🤣
---
В YT как на дрожжах появляются видео про low‑code / no-code платформу n8n.io. Если кто еще не в курсе, то с ее помощью вы можете строить пайплайны из классических (tg, Slack, Google и т.д.) и "умных" (ChatGPT, YandexGPT, или, например, OpenRouter, если хочется бесплатно) API для автоматизации разного рода сценариев, используя визуальный интерфейс. Если не готовы платить денежку за сервис, то можно развернуть его как как self-hosted на своем VPS. На зарубежных фриланс-площадках тысячи предложений по автоматизации с помощью n8n.io, make.com. Наши умельцы на фрилансе уже готовы поднять n8n за вас за скромную сумму. Думаю, что часть исполнителей уже написала свой Ansible-плейбук, другая — использует elest.io, а третья — делает все ручками. Сам сценарий тоже разработают, но значительно дороже: тут уже "наукоемкость" какая-то появляется.
Малый
---
ИИ продолжает активно проникать в задачи обывателя в том числе на уровне решения комплексных задач. Я уже не говорю о генерации картинок, видео, текстов, музыки. Тем не менее, это не помешало мне вчера отправить письмо через Почту России, написав от руки в двух экземплярах опись вложения. Вот уж кто точно не торопится за этими вашими трендами. А у тебя получается оседлать эту ИИ-волну?
Please open Telegram to view this post
VIEW IN TELEGRAM
👌5👍2
С последнего моего прогноза прошло уже 4 месяца! Пора снова заглянуть в будущее.
У меня есть 5 примеров из ближнего круга, когда тестировщики переходили в разработчики. Этот сценарий, чтобы войти в айти, а затем и в разработку (с часто бОльшими зарплатами) давно на слуху. Почему он до сих пор актуален? Да простят меня тестировщики, но на начальных позициях требования к ним меньше, особенно к специалистам по ручному тестированию.
Удивительно, но примеров, когда системный аналитик переходил в разработчики, у меня нет. Читал про такие кейсы в этих ваших интернетах, и то пару раз.А сейчас их станет ещё меньше — ниже объясню, почему.
Почему меня это удивляет? Разве набор компетенций системного аналитика гораздо не ближе к разработчику?
* сбор и описание функциональных, нефункциональных, пользовательских и бизнес-требований
* постановка задач
* проектирование БД
* написание SQL-запросов
* проектирование интеграций и API (JSON, SOAP, RPC, очереди, шины, GraphQL, WebSocket, Webhook и другие)
* проектирование архитектуры (System Design)
Давай проанализируем этот список. Чего в нем не хватает? Навыка написания кода⌨️ ! Какой вывод напрашивается? Системный аналитик с помощью ИИ вполне может заменить команду разработки.
Нужно просто поменять вектор приложения усилий: аналитик будет наполнять контекст и ставить задачи не кожаным мешкам, а ИИ. Больше не придется быть прокси между бизнесом и инженерами. А как мы знаем, любые вынужденные коммуникации внутри и между командами значительно бьют по производительности труда. Бизнес будет счастлив!
Первой целью вижу проекты, которые сосредоточены на перекладывании JSON'а. Это тот случай, когда сложность прикладного кода приложения невысока, но документация проекта может быть значительной. В этой схеме бизнес платит не за сложность технических решений, а за высокую когнитивную нагрузку на членов команды, а ИИ с рядом наполненных контекстов с этим прекрасно справится. Кажется, что в России финтех может стать первой такой экспериментальной площадкой.
Что думаешь? Объявляем бойкот системным аналитикам😡 ?
У меня есть 5 примеров из ближнего круга, когда тестировщики переходили в разработчики. Этот сценарий, чтобы войти в айти, а затем и в разработку (с часто бОльшими зарплатами) давно на слуху. Почему он до сих пор актуален? Да простят меня тестировщики, но на начальных позициях требования к ним меньше, особенно к специалистам по ручному тестированию.
Удивительно, но примеров, когда системный аналитик переходил в разработчики, у меня нет. Читал про такие кейсы в этих ваших интернетах, и то пару раз.
Почему меня это удивляет? Разве набор компетенций системного аналитика гораздо не ближе к разработчику?
* сбор и описание функциональных, нефункциональных, пользовательских и бизнес-требований
* постановка задач
* проектирование БД
* написание SQL-запросов
* проектирование интеграций и API (JSON, SOAP, RPC, очереди, шины, GraphQL, WebSocket, Webhook и другие)
* проектирование архитектуры (System Design)
Давай проанализируем этот список. Чего в нем не хватает? Навыка написания кода
Нужно просто поменять вектор приложения усилий: аналитик будет наполнять контекст и ставить задачи не кожаным мешкам, а ИИ. Больше не придется быть прокси между бизнесом и инженерами. А как мы знаем, любые вынужденные коммуникации внутри и между командами значительно бьют по производительности труда. Бизнес будет счастлив!
Первой целью вижу проекты, которые сосредоточены на перекладывании JSON'а. Это тот случай, когда сложность прикладного кода приложения невысока, но документация проекта может быть значительной. В этой схеме бизнес платит не за сложность технических решений, а за высокую когнитивную нагрузку на членов команды, а ИИ с рядом наполненных контекстов с этим прекрасно справится. Кажется, что в России финтех может стать первой такой экспериментальной площадкой.
Что думаешь? Объявляем бойкот системным аналитикам
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6👍1
На прошлой неделе чинил логирование в реактивном приложении. Это был Spring Cloud Gateway на WebFlux, который достался нам по наследству от другой команды. Наконец дошли руки до этой задачи.
Меня, однако, зацепил другой момент. Нужно было залогировать ошибку, когда из реактивного контекста и ThreadLocal все было заботливо удалено:
В😐 .
Чем не угодили❌ , которые в некоторых ситуациях предполагались для
Нет, спасибо, эта история не для гейтвея.
Почувствуйте всю мою боль, пришлось писать полотно:
Дайте работягам one liner для HashMap по аналогии с
Утерев слёзы, я собрал все(потокобезопасные не рассматривал) one liner'ы ванильной Java для хэш-таблиц в сводную таблицу, где расписал свойства иммутабельности, возможность хранить nullable key и value, ограничения на число элементов, ловушки реализации и реализацию под капотом. Каждый из вариантов бережно приправлен тестами. Красота 🐸 🐸 🐸
Меня, однако, зацепил другой момент. Нужно было залогировать ошибку, когда из реактивного контекста и ThreadLocal все было заботливо удалено:
log.atError()
.addMarker(Markers.appendEntries(entries))
.setCause(e)
.log("Error occurred in MDCFilter");
В
Map<?, ?> entries передаем пары ключ-значение, которыми хотим обогатить запись в логе. В моем случае это trace_id и user_id. Конечно, хочется написать one liner для инициализации entries. Только сделать это на ванильной Java не получится: нет подходящего решения Чем не угодили
Map.of(...) и Map.ofEntries(...)? Они не принимают null-value user_id. Может тогда возьмём HashMap c Double Brace Initialization?new HashMap<>() {{
put(TRACE_ID, traceId);
put(USER_ID, userId);
}};Нет, спасибо, эта история не для гейтвея.
Почувствуйте всю мою боль, пришлось писать полотно:
Map<String, String> entries = new HashMap<>();
entries.put(TRACE_ID, traceId);
entries.put(USER_ID, userId);
Дайте работягам one liner для HashMap по аналогии с
Map.of(...) или Map.ofEntries(...)!Утерев слёзы, я собрал все
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💯2❤1🔥1
А что собственно с логированием? В прошлый раз обещал рассказать подробнее. Это будет очередное подтверждение, зачем нужно знать многопоточку. Тем сложнее, что она здесь используется не в чистом виде, а в составе библиотек.
В очередной раз, бороздя просторы кибаны, я наткнулся на несоответствие идентификатора пользователя и содержимого в логируемых сообщениях. Пришлось приступить к исследованию кодовой базы сервиса. Я, честно, сначала грешил на нашу библиотеку логирования, однако дело было вобычном советском ... неаккуратной работе с MDC (Mapped Diagnostic Context) в нашей реализации интерфейса
🤪
Если бы нам было достаточно локальной видимости ключа в рамках одного оператора, то мы могли бы:
* явно удалять ключ с помощью
* использовать
* использовать
При использовании цепочек операторов мы не можем работать с
Это позволяет сделать библиотеку осведомлённой о состоянии злополучного
Углубиться в детали можно в цикле из трех статей.
А что в Kotlin? Все несколько проще, хотя при работе с корутинами и suspend-функциями мы так же не можем напрямую использовать
Такие дела😎
В очередной раз, бороздя просторы кибаны, я наткнулся на несоответствие идентификатора пользователя и содержимого в логируемых сообщениях. Пришлось приступить к исследованию кодовой базы сервиса. Я, честно, сначала грешил на нашу библиотеку логирования, однако дело было в
org.springframework.cloud.gateway.filter.GlobalFilter:@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
...
MDC.put(USER_ID, userId);
...
}
org.slf4j.MDC используется для правки значений в MDC. Делается это с помощью вызова MDC.put(), который устанавливает пару ключ-значение. Под капотом MDC работает с экземпляром ch.qos.logback.classic.util.LogbackMDCAdapter. LogbackMDCAdapter в свою очередь работает на ThreadLocal-переменных.
ThreadLocal привязан к конкретному потоку, а не к запросу пользователя. Если вы установили значение в MDC (ThreadLocal) в операторе реактивной цепочки, то следующий оператор, может не увидеть его, так как вполне возможно будет выполнен на другом потоке. Наша задача — подружить библиотеку, которая понятия не имеет о том, что работает в реактивном приложении с этим самым реактивным приложением Если бы нам было достаточно локальной видимости ключа в рамках одного оператора, то мы могли бы:
* явно удалять ключ с помощью
MDC.remove() в блоке finally * использовать
MDC.putCloseable() в блоке try-with-resources* использовать
MDC.getCopyOfContextMap и MDC.setContextMap для захвата и дальнейшего восстановления состояния MDCВажно понимать, что метод MDC.putCloseable() не восстанавливает предыдущее значение, которое было перезаписано под уже существующим ключом!
При использовании цепочек операторов мы не можем работать с
org.slf4j.MDC напрямую. Вместо этого, начиная с Spring Framework 6.0 /Spring Boot 3.0 / reactor-core 3.5.0, у нас появилась возможность использовать связку io.micrometer:context-propagation и reactor.core.publisher.Hooks. Вызов Hooks.enableAutomaticContextPropagation() позволяет библиотеке встроиться в механизм Project Reactor. После этого мы можем взаимодействовать с io.micrometer.context.ContextRegistry через метод registerThreadLocalAccessor:public static void registerMdcKey(String mdcKey) {
Supplier<String> getKey = () -> MDC.get(mdcKey);
Consumer<String> putKey = value -> MDC.put(mdcKey, value);
Runnable removeKey = () -> MDC.remove(mdcKey);
ContextRegistry.getInstance()
.registerThreadLocalAccessor(mdcKey,
getKey,
putKey,
removeKey);
}Это позволяет сделать библиотеку осведомлённой о состоянии злополучного
ThreadLocal. После этого мы можем использовать contextWrite на Flux/Mono, чтобы установить "метаданные", которые мы хотим передавать по цепочке:chain.filter(exchange)
.contextWrite(ctx -> ctx.putNonNull(USER_ID, userId))
Углубиться в детали можно в цикле из трех статей.
А что в Kotlin? Все несколько проще, хотя при работе с корутинами и suspend-функциями мы так же не можем напрямую использовать
org.slf4j.MDC: корутина может "уйти" на другой поток. Нужно прокинуть свой kotlinx.coroutines.slf4j.MDCContext в контекст корутины:withContext(MDCContext(...) + ..., block)
MDCContext имплементирует kotlinx.coroutines.ThreadContextElement (который в свою очередь имплементирует CoroutineContext.Element) и автоматически обновляет MDC при каждом переключении потока. Такие дела
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤🔥1🔥1
Часть 1. Есть ли настоящее и будущее у микробенчмаркинга?
С коллегами все чаще начали задаваться вопросом: "Не стоит ли поэкспериментировать с нагруженными core-сервисами?"
Что подразумевается под экспериментами?
1) остаться в лоне jvm, но сменить фреймворк с Java/Kotlin + SpringBoot + Webflux
2) переписать сервис на другой язык
Первое, что приходит в голову и в то же время наименее болезненно — отказаться от Webflux в пользу VirtualThreads, но 25-ый LTS-релиз еще не завезли. Почему его надо ждать — писал ранее.
На слепое переписывание сервисов под разные связки язык-фреймворк, понятное дело, времени нет, поэтому нужно проводить ресерч для определения наиболее перспективных кандидатов.
Может быть кто-то сделал эту работу за нас? Коллеги, опять же, поделились такой ссылочкой — sharkbench.dev.
Что понравилось? Достаточно богатый список языков и фреймворков. Можно посмотреть тестируемый код, который, на удивление, прикладывают не всегда. Для этого нажимайте на...сам не сразу додумался, пока в исходный код страницы не залез 🤣 .
Всего видим два набора тестов: с IO-bound (раздел Web frameworks) и CPU-bound (раздел Computation) нагрузкой. Если CPU нагружается алгоритмом вычисления приближения числа π, уже ставший стандартом де-факто, то с IO-bound нагрузкой нужно разобраться. Тестируется достаточно простой сценарий: происходит случайное обращение к двум параметризированным GET-ручкам, которые проксируют json'ы из локально выставленного источника, что и создает IO-нагрузку. К результатам такого тестирования, однако, надо подходить критически, так как профиль нагрузки вряд ли можно назвать prod like. Вместо реальной эффективности языка-фреймворка мы видим, как хорошо решается узкая задача.
Особенно хорошо в тестах это демонстрирует JDK Semeru от IBM, чей сборщик мусора по умолчанию как раз заточен на работу с большим числом короткоживущих объектов. Может быть, конечно, это и была идея автора.
Подведем итоги. Для первого знакомства ресурс подойдёт вполне неплохо, но пока хочется изучить альтернативы для принятия взвешенного решения. Как минимум ещё один такой есть на примете, ждите в следующих сериях.
P.S. Пока изучал, что за зверь такой IBM Semeru, наткнулся на сайт с хорошим верхнеуровневым сравнением JDK от разных вендоров jdkcomparison.com, рекомендую. И еще один whichjdk.com.
С коллегами все чаще начали задаваться вопросом: "Не стоит ли поэкспериментировать с нагруженными core-сервисами?"
Что подразумевается под экспериментами?
1) остаться в лоне jvm, но сменить фреймворк с Java/Kotlin + SpringBoot + Webflux
2) переписать сервис на другой язык
Первое, что приходит в голову и в то же время наименее болезненно — отказаться от Webflux в пользу VirtualThreads, но 25-ый LTS-релиз еще не завезли. Почему его надо ждать — писал ранее.
На слепое переписывание сервисов под разные связки язык-фреймворк, понятное дело, времени нет, поэтому нужно проводить ресерч для определения наиболее перспективных кандидатов.
Может быть кто-то сделал эту работу за нас? Коллеги, опять же, поделились такой ссылочкой — sharkbench.dev.
Что понравилось? Достаточно богатый список языков и фреймворков. Можно посмотреть тестируемый код, который, на удивление, прикладывают не всегда. Для этого нажимайте на
<> в первой колонке Всего видим два набора тестов: с IO-bound (раздел Web frameworks) и CPU-bound (раздел Computation) нагрузкой. Если CPU нагружается алгоритмом вычисления приближения числа π, уже ставший стандартом де-факто, то с IO-bound нагрузкой нужно разобраться. Тестируется достаточно простой сценарий: происходит случайное обращение к двум параметризированным GET-ручкам, которые проксируют json'ы из локально выставленного источника, что и создает IO-нагрузку. К результатам такого тестирования, однако, надо подходить критически, так как профиль нагрузки вряд ли можно назвать prod like. Вместо реальной эффективности языка-фреймворка мы видим, как хорошо решается узкая задача.
Особенно хорошо в тестах это демонстрирует JDK Semeru от IBM, чей сборщик мусора по умолчанию как раз заточен на работу с большим числом короткоживущих объектов. Может быть, конечно, это и была идея автора.
Подведем итоги. Для первого знакомства ресурс подойдёт вполне неплохо, но пока хочется изучить альтернативы для принятия взвешенного решения. Как минимум ещё один такой есть на примете, ждите в следующих сериях.
P.S. Пока изучал, что за зверь такой IBM Semeru, наткнулся на сайт с хорошим верхнеуровневым сравнением JDK от разных вендоров jdkcomparison.com, рекомендую. И еще один whichjdk.com.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤1
Часть 2. Есть ли настоящее и будущее у микробенчмаркинга?
Продолжаем исследование, первая часть здесь.
Пробежавшись по Интернетам я понял, что примеров таких проектов, которые ведут систематические наблюдения за языками/фреймворками, не так уж и много. Предлагаю посмотреть, что удалось найти:
programming-language-benchmarks.vercel.app → тестируются базовые алгоритмы, написанные на разных языках (без фреймворков), представлено несколько связок алгоритм + рантайм / компилятор для каждого языка, удобный интерфейс для проведения сравнительного анализа языков, можно посмотреть исходный код (как впрочем и на всех остальных ресурсах)
benchmarksgame-team.pages.debian.net → аналогичен предыдущему, но с менее дружелюбным интерфейсом. Из интересного: судя по дискуссии, там когда-то был Kotlin, но выпилили за отсутствием интереса☔️
web-frameworks-benchmark.netlify.app → расширенный вариант (по количеству исследуемых связок) рассматриваемого ранее sharkbench.dev. Также тестируются довольно простые сценарии на железе уровня домашнего ПК.
techempower.com/benchmarks → самый фундаментальный труд из представленных: много, нет, МНОГО связок-язык фреймворк, которые почти ежегодно тестируются на prod-like железе в 7 различных сценариях (JSON Serialization, Single Database Query, Multiple Database Queries, Fortunes, Database Updates, Plaintext, Caching). Подробнее в их wiki.
Первые два кандидата хороши, но ответа на вопрос «какую взять связку для нового микросервиса» они не дадут. Тем не менее, если интересует изолированная производительность рантайма — эти ресурсы можно добавить в закладки.
Перейдем сразу к четвертому кандидату и работе, проделанной TechEmpower. Титанический труд, моё почтение! Получился фундаментальный обзор существующих решений. Я точно на час-другой залип, разбираясь кто такой Вован и что мне делать с офисным этажом🤣 . Если рассматривать решения на Java / Kotlin / Go / Scala / Rust, то в каждой из категорий чаще побеждают связки на Rust или Java. Уфф, не придется Go учить пока! Как и в прошлый раз в категории Java в топах видим Quarkus и Vert.x. Прощай Spring? Rust судя по этим тестам можно считать абсолютным лидером среди вообще всех языков. Вот и определились потенциальные кандидаты для гейтвея 👦 ?
Добавлю ложку дегтя, чтобы жизнь медом не казалась. Для честного сравнения абсолютно необходим вдумчивый разбор каждой реализации — насколько корректно реализована микрологика и используются библиотеки, что кэшируется, не было ли решение намеренно затюненоили наоборот под конкретный бенчмарк. Чего пока не хватает и, наверное, чего никогда не будет в такого рода бенчмарках, так это навороченных боевых сценариев, которые можно найти в кровавом enterprise, а именно:
* приближенности тестируемого кода по сложности к уровню микросервиса, а не просто "выжать максимум из худенькой ручки"
* сериализации / десериализации сложных структур
* интеграции с брокерами сообщений (хотя взаимодействие с реальными СУБД есть)
Много хочу? Определенно👍 . Удивительно, что нет или я не нашел? ресурса, где бы упор шел на тестирование прицельно JVM-приложений, обмазанных логикой и интеграциями. Кажется, что написав сервис один раз, его будет не так сложно портировать под другие фреймворки. Может нам было бы достаточно поменять библиотеку сериализации / работы с MongoDB / Kafka? Хотя, конечно, с точки зрения долгосрочной поддержи это будет достаточно затратное мероприятие. Да и насколько такому тестированию можно будет верить? Подняли мы тут на днях немажорные версии библиотек на гейтвее и нагрузочное тестирование показало рост CPU в районе 10% 🤣 В итоге никогда точно не скажешь, как фреймворк поведёт себя на реальных задачах, а не в изолированном микробенчмарке. Идем проводить эксперименты на стенде нагрузочного тестирования? 💯%
Если знаешь другие ресурсы, где проводят такие сравнения — пишите мне в личку @senior_junior_dev, буду рад дополнить подборку.
Продолжаем исследование, первая часть здесь.
Пробежавшись по Интернетам я понял, что примеров таких проектов, которые ведут систематические наблюдения за языками/фреймворками, не так уж и много. Предлагаю посмотреть, что удалось найти:
programming-language-benchmarks.vercel.app → тестируются базовые алгоритмы, написанные на разных языках (без фреймворков), представлено несколько связок алгоритм + рантайм / компилятор для каждого языка, удобный интерфейс для проведения сравнительного анализа языков, можно посмотреть исходный код (как впрочем и на всех остальных ресурсах)
benchmarksgame-team.pages.debian.net → аналогичен предыдущему, но с менее дружелюбным интерфейсом. Из интересного: судя по дискуссии, там когда-то был Kotlin, но выпилили за отсутствием интереса
web-frameworks-benchmark.netlify.app → расширенный вариант (по количеству исследуемых связок) рассматриваемого ранее sharkbench.dev. Также тестируются довольно простые сценарии на железе уровня домашнего ПК.
techempower.com/benchmarks → самый фундаментальный труд из представленных: много, нет, МНОГО связок-язык фреймворк, которые почти ежегодно тестируются на prod-like железе в 7 различных сценариях (JSON Serialization, Single Database Query, Multiple Database Queries, Fortunes, Database Updates, Plaintext, Caching). Подробнее в их wiki.
Первые два кандидата хороши, но ответа на вопрос «какую взять связку для нового микросервиса» они не дадут. Тем не менее, если интересует изолированная производительность рантайма — эти ресурсы можно добавить в закладки.
Перейдем сразу к четвертому кандидату и работе, проделанной TechEmpower. Титанический труд, моё почтение! Получился фундаментальный обзор существующих решений. Я точно на час-другой залип, разбираясь кто такой Вован и что мне делать с офисным этажом
Добавлю ложку дегтя, чтобы жизнь медом не казалась. Для честного сравнения абсолютно необходим вдумчивый разбор каждой реализации — насколько корректно реализована микрологика и используются библиотеки, что кэшируется, не было ли решение намеренно затюнено
* приближенности тестируемого кода по сложности к уровню микросервиса, а не просто "выжать максимум из худенькой ручки"
* сериализации / десериализации сложных структур
* интеграции с брокерами сообщений (хотя взаимодействие с реальными СУБД есть)
Много хочу? Определенно
Если знаешь другие ресурсы, где проводят такие сравнения — пишите мне в личку @senior_junior_dev, буду рад дополнить подборку.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1❤1
This media is not supported in your browser
VIEW IN TELEGRAM
После того, как мой прошлый помидорный таймер приказал долго жить после трех дней работы, потребовав 11$, я понял, что не хочу больше это терпеть ☝ . Я хочу гибкости, настраиваемой статистики и полного контроля над происходящим. Пришлось повайбкодить, чтобы у тебя тоже был такой инструмент. Итак...
Открой для себя Pomodoro Supreme — сверхнадёжный отказоустойчивый таймер фокусировки моей собственной разработки.
🚀 Особенности, которые вдохновляют
🌐 Всегда с тобой — в любой точке планеты
Работает в облаке, синхронизируется автоматически: начни сессию в Москве, продолжи во Владивостоке. Всё, что тебе нужно — Google-аккаунти доступ в сеть Интернет.
🛡 Абсолютная отказоустойчивость
Google-инфраструктура обеспечивает надежность уровня 99.999%. Даже апокалипсису придётся подождать до конца твоей фокус-сессии.
🧩 Гибкость без ограничений
Поддержка любых активностей, настройка длительности, расширяемость через Google Apps Script — хочешь Telegram-бота, Slack-оповещения или аналитику? Легко!Ты всё это сможешь добавить сам!
📦 Полная автономность
Не требует хостинга, развертывания или оплаты серверов. Все данные хранятся в Google Таблице — просто, прозрачно, под твоим контролем.
💡 Для кого это?
Для всех, кому важно работать в ритме и тех, кто хочет по окончании очередной сессии слышать этот эпический звук.
Никаких установок. Никаких банковских карт. Только ты, твоя цель и максимальная концентрация.
Готов начать? Просто открой Google Таблицу. Скачай код тут😵💫 Перейди в интерфейс Apps Script, скопируй код в соответствующие файлы и нажми "Начать развертывание" ⌨️
Открой для себя Pomodoro Supreme — сверхнадёжный отказоустойчивый таймер фокусировки моей собственной разработки.
🚀 Особенности, которые вдохновляют
🌐 Всегда с тобой — в любой точке планеты
Работает в облаке, синхронизируется автоматически: начни сессию в Москве, продолжи во Владивостоке. Всё, что тебе нужно — Google-аккаунт
🛡 Абсолютная отказоустойчивость
Google-инфраструктура обеспечивает надежность уровня 99.999%. Даже апокалипсису придётся подождать до конца твоей фокус-сессии.
🧩 Гибкость без ограничений
Поддержка любых активностей, настройка длительности, расширяемость через Google Apps Script — хочешь Telegram-бота, Slack-оповещения или аналитику? Легко!
📦 Полная автономность
Не требует хостинга, развертывания или оплаты серверов. Все данные хранятся в Google Таблице — просто, прозрачно, под твоим контролем.
💡 Для кого это?
Для всех, кому важно работать в ритме
Никаких установок. Никаких банковских карт. Только ты, твоя цель и максимальная концентрация.
Готов начать? Просто открой Google Таблицу. Скачай код тут
Please open Telegram to view this post
VIEW IN TELEGRAM
😁3🔥2🫡2🎉1
Везде говорят, что найм умер, а мы активно набираем джавистов. Посмотрел вакансии Сбера, их сейчас тоже много. Наблюдаю, что банки активно развивают небанковские продукты, постепенно захватывая новые рынки. Это всё еще раз подтверждает, что банкиры всегда зарабатывают, даже в кризис. Сразу всплывают в голове мемы про доступное жилье доступную ипотеку 😃 . Яндекс тоже не отстает.
Активный найм — много собеседований. Чтобы не нарваться на кандидата, который проходит паровозик (несколько кандидатов идут на одну и ту же вакансию, собирая базу вопросов) или пользуется базой слитых вопросов, выработал для себя ультимативную тактику. Каждый раз задаю на 80% новый набор вопросов, благо ChatGPT не страдает от недостатка фантазии. Конечно, такой подход требует как бОльшую подготовку перед самим собеседованием, так и сильную теоретико-практическую базу. Все это в наличии😎
Для того, чтобы отсеять накрутчиков опыта, выполняем ревью кода и решаем небольшие практические задачки на знание языка. Условие одной из них: нужно написать неблокирующий потокобезопасный стек, не используя коллекций из библиотеки j.u.c. Попробуй свои силы. Вот решение:
На medium есть целая статья, которая предлагает более элегантное решение с хвостовой рекурсией на Kotlin.
Раньше давал алгоритмическую задачу, от которой впоследствии отказался. За отведенные 15 минут нужно было нарисовать лестницу заданной высоты N вида:
Казалось бы, отступил нужное число пробелов и вывел
Сейчас есть множество других методов, чтобы обмануть интервьюера:
* AI-инструменты, которые позволяют отвечать на вопросы в режиме реального времени, но невидимые при демонстрации экрана. Можно приспособить под это отдельный монитор или мобильное устройство/планшет в идеале с AI-коррекцией направления взгляда
* синхронизация речи и движений губ у AI-клона в реальном времени
* парное прохождение собеседований, когда ответы диктуются более подготовленным напарником, или вообще прохождение собеседования другим человеком
В целом не имеет значения, удалось ли обмануть кандидату интервьюера, если в дальнейшем на испытательном сроке он справляется с поставленными задачами. Хуже, когда команда в течение трех месяцев не получает ожидаемой отдачи от новичка, а тянет ношу и за себя и за того парня. Жаль, что испытательный срок перестал быть лишь формальностью.
Активный найм — много собеседований. Чтобы не нарваться на кандидата, который проходит паровозик (несколько кандидатов идут на одну и ту же вакансию, собирая базу вопросов) или пользуется базой слитых вопросов, выработал для себя ультимативную тактику. Каждый раз задаю на 80% новый набор вопросов, благо ChatGPT не страдает от недостатка фантазии. Конечно, такой подход требует как бОльшую подготовку перед самим собеседованием, так и сильную теоретико-практическую базу. Все это в наличии
Для того, чтобы отсеять накрутчиков опыта, выполняем ревью кода и решаем небольшие практические задачки на знание языка. Условие одной из них: нужно написать неблокирующий потокобезопасный стек, не используя коллекций из библиотеки j.u.c. Попробуй свои силы. Вот решение:
public class LockFreeStack<T> {
// по классике хранит непосредственно значение и ссылку на следующую Node
private static class Node<T> { ...
private final java.util.concurrent.atomic.AtomicReference<Node<T>> head = new AtomicReference<>();
public void push(T element) {
Node<T> newNode;
Node<T> currentHead;
do {
currentHead = head.get();
newNode = new Node<>(element, currentHead);
} while (!head.compareAndSet(currentHead, newNode));
}
public T pop() {
Node<T> currentHead;
Node<T> nextNode;
do {
currentHead = head.get();
if (currentHead == null) {
return null;
}
nextNode = currentHead.next;
} while (!head.compareAndSet(currentHead, nextNode));
return currentHead.value;
}
}
На medium есть целая статья, которая предлагает более элегантное решение с хвостовой рекурсией на Kotlin.
Раньше давал алгоритмическую задачу, от которой впоследствии отказался. За отведенные 15 минут нужно было нарисовать лестницу заданной высоты N вида:
|¯
|¯
|¯
Казалось бы, отступил нужное число пробелов и вывел
|¯, но справился за все время с этим единственный синьор. Не знаю почему, но это был реальный гроб.Сейчас есть множество других методов, чтобы обмануть интервьюера:
* AI-инструменты, которые позволяют отвечать на вопросы в режиме реального времени, но невидимые при демонстрации экрана. Можно приспособить под это отдельный монитор или мобильное устройство/планшет в идеале с AI-коррекцией направления взгляда
* синхронизация речи и движений губ у AI-клона в реальном времени
* парное прохождение собеседований, когда ответы диктуются более подготовленным напарником, или вообще прохождение собеседования другим человеком
В целом не имеет значения, удалось ли обмануть кандидату интервьюера, если в дальнейшем на испытательном сроке он справляется с поставленными задачами. Хуже, когда команда в течение трех месяцев не получает ожидаемой отдачи от новичка, а тянет ношу и за себя и за того парня. Жаль, что испытательный срок перестал быть лишь формальностью.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6⚡2👍1