Повышение конверсии сайта и персонализация CRM коммуникаций с машинным обучением

От автора

Всем привет, я Павел. Из 15 лет отданных ИТ, на протяжении последних 6 лет я работаю в одном из старейших CRM агентств в СНГ на позиции системного архитектора и R&D. Каждый год через меня проходит множество интересных проектов. Некоторые из них добираются до стадии proof of concept, другие закрываются пилотами, третьи стали частью новых компонентов ИТ экосистем или CRM стратегий, идеи которым повезло меньше, остаются на бумаге. В эти непростые для отрасли времена, мне хочется поделиться опытом, рассказать о проектах и подходах, которые смогут вдохновить вас на реализацию новых продуктов и решений.


Введение

Каждый относительно успешный бизнес, связанный с продвижением продуктов или услуг, в определенный момент начинает испытывать неудовлетворенность от соотношения объема вложенных денежных средств к количеству привлеченных потребителей, а также потребность в оптимизации своих расходов, когда их объем становится значимым. Зачастую, поправки в эффективность использования бюджетов, даже при наличии качественной digital- или CRM стратегии, вносят множество незаметных с первого взгляда, но системных факторов, которые касаются организации процессов и распределения рисков. Описанный ниже кейс — яркий тому пример.

Какие проблемы скрывает рынок?

Современный рынок новых автомобилей, который мы наблюдали до 24 февраля 2022 года в России, сложный и каждый из его участников испытывает высокую конкуренцию. В борьбе за клиента импортеры тратят большие бюджеты на маркетинг продукции на уровне макрорегиона. Каждого такого рекламодателя окружает множество подрядчиков (агентств), а бюджеты между ними распределяются вместе с рисками. При этом разнообразие инструментов и технологий, которые применяют агентства так велико, что зачастую прямое взаимодействие между ними может быть затруднено техническими или организационными вопросами (например, агентства не заинтересованы в сотрудничестве будучи потенциальными конкурентами за бюджеты клиента).

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

Учитывая все эти факторы, собрать достаточно информации о потребительских интересах и опыте взаимодействия с брендом до покупки очень сложно. При том что цикл покупки автомобиля в upper-intermediate сегменте по СНГ, на момент проведения проекта, оценивался в 2-3 месяца.

Таким образом CRM агентство живет в условиях высокой неопределенности, в которой его эффективность и достижимость поставленных KPI часто зависит от решений, которые принимают другие компании, инструментов, которые управляются другими специалистами, и решений управленцев, преследующих личные интересы.

Однажды крупный автомобильный бренд поставил нам задачу найти способ повысить конверсию форм лидогенерации, размещенных на сайте, а также pop-up форм, за все это отвечало digital-агентство. Несмотря на большие инвестиции в рекламу и показательно высокий трафик на сайте, KPI по конверсиям в лиды не выполнялись.

Нашей команде предстояло найти проблемные места в пользовательском опыте, а мне разработать архитектуру решения и встроить его в ИТ ландшафт клиента.

Проблемы и гипотезы

Постараюсь тезисно привести факты и гипотезы, с которыми нам пришлось работать.

Вводные:

  • Дано кольцо сайтов не размещенных на единой платформе, но имеющих схожую, но не идентичную структуру. У сайтов разные владельцы: импортер, множество дилеров;

  • На сайтах размещены формы, которые имеют разную структуру, но схожие функции, например, заявка на тест-драйв, заявка на кредит;

  • Кросс-доменного отслеживания трафика и кампаний между сайтами нет;

  • На сайте импортера установлен pop-up сервис, который показывает попапы с html контентом, в некоторых случаях форму сбора персональных данных.

Гипотезы:

  • Настроив кросс-доменное отслеживание мы сможем понять как переливается трафик между сайтами и найти точки отказа.

  • Пользователи выполняют целевые действия в динамических формах, но не отправляют их — нужно собирать анонимные сведения о действиях с формой до сбора контакта.

Например, результатом работы формы калькулятора кредита является примерная ставка, а полезным действием формы для пользователя — форма сбора контакта для обратной связи. Очевидно, что пользователь не оставляет свой контакт.

  • Всплывающее сообщение можно персонализировать если узнать чего хочет клиент.

Например, независимо от действий пользователя на сайте на каждой странице клиенту показывается одно и тоже сообщение с красным кроссовером за 5М рублей, даже если он смотрел форму расчета trade-in на автомобиль за 1М, при этом pop-up форма настойчиво выскакивает на каждой странице через 10 сек после ее открытия.

  • Собирая и интерпретируя сведения о действия пользователей на сайтах мы сможем понять их интересы.

  • Использовать эти сведения можно для улучшения коммуникаций через персонализацию сообщений анонимных и авторизованных пользователей.

  • Профили авторизованных пользователей можно обогатить интересами и предпочтениями.

Концепция решения

В качестве решения мы решили использовать сведения о взаимодействии пользователей с сайтом и его элементами для определения интереса пользователя к той или иной модели автопроизводителя. Затем использовать эти данные для персонализации рекламы и коммуникаций чтобы повысить релевантность сообщения для потенциального покупателя.

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

Общий вид схемы процесса (с)
Общий вид схемы процесса (с)

Мы сформулировали следующие требования к набору данных который должны получить на выходе:

  • данные должны описывать интерес пользователя к нескольким моделям бренда,

  • данные должны содержать идентификаторы пользователей не нарушающие условия анонимности и действующее законодательство,

  • данные должны иметь TTL позволяющий сохранять релевантность полученных данных для бизнеса,

  • мы не должны упускать возможность использовать данные полученные с дилерский сайтов.

Также мы разработали функциональные требования, которым должно соответствовать разрабатываемое решение:

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

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

  • в архитектуре должны быть задействованы платформенные решения или решения с открытым исходным кодом,

  • результаты работы решения должны быть доступны через API для персонализации коммуникаций на сайте или использования третьими сервисами,

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

Работа с данными

Учитывая ежемесячную посещаемость сайта от 200 до 300 тыс. пользователей в мес., а также длительный цикл продаж, характерный для автомобильного рынка, мы рассчитывали собрать объем данных, который позволит нам разработать устойчивую модель, за 3-4 месяца. Сайты дилеров дали нам еще 40-50 тысяч уникальных пользователей и знания об их перемещениях между сайтами.

В основу дата-сета с которым предстояло работать должны были лечь сведения о взаимодействии пользователя с сайтом. В качестве источника данных мы рассматривали Google Analytics, но для этого нужно было решить несколько задач:

  • Настроить кросс-доменный счетчик Google Analytics,

  • Выделить нужные события на сайте импортера и дилеров, настроить теги GTM, а для отслеживания “сложных” событий написать отдельный код.

Переход на кросс-доменный счетчик с учетом аналитической работы может занять до 1,5-2 месяцев (с)
Переход на кросс-доменный счетчик с учетом аналитической работы может занять до 1,5-2 месяцев (с)

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

При решении вопроса стриминга данных были сформированы следующие требования:

  • сбор данных из уже настроенного источника,

  • простота реализации в стриминга данных,

  • низкая стоимость хранения данных.

Идеальным кандидатом, соответствующим этим критерием, стал BigQuery, а также очков в пользу сервиса от Google добавляло наличие инструмента OWOX BI, который позволял передавать события сгенерированные Google Analytics непосредственно в BigQuery. Не очень быстрое, но выгодное во всех смыслах решение для того чтобы накопить данные.

Концепт схемы сбора данных для исследования (с)
Концепт схемы сбора данных для исследования (с)

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

Разработка модели

Тип задачи, которую должен решать алгоритм, — это классификация пользователей на основе пространства признаков. Был использован класс алгоритмов, которые относятся к разделу «обучения с учителем», выборка была разделена на 3 выборки для обучения и оценки качества модели: обучающую, валидационную, тестовую.

Распределение дата-сета
Распределение дата-сета

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

Профиль пользователя состоит из примерно 140 переменных. Для разработки модели мы свели список переменных к тем, которые действительно играют роль в разделении пользователей на группы, то есть провести так называемый feature-selection.

Были проверены несколько алгоритмов – Наивный Байес, Метод опорных векторов, несколько реализаций деревьев решений, леса решений. Оценка алгоритмов проводилась по показателям полноты и точности, а также показателю AUC. В конце была проведена кросс-валидация —  данные перемешали, достали рандомные записи и посмотрел, как модель работает. Хотя можно было бы использовать и 2 выборки – что не является ошибкой. Наибольшую точность и полноту показали алгоритмы леса решений и дерево решений.

«Ну ещё бы» (с) Data Scientist из моей команды

Пример результата работы модели:

Диаграммы демонстрирующие результаты работы модели.
Диаграммы демонстрирующие результаты работы модели.

Техническое решение

К моменту завершения работ над моделью мы уже были на финишной прямой в вопросе завершения разработки инструментов для интеграции с внешними сервисами. Что у нас получилось в итоге?

Финальная архитектура решения к моменту его запуска (с)
Финальная архитектура решения к моменту его запуска (с)

Архитектура решения включает ряд компонентов, каждый из которых выполняет свою специализированную функцию:

  1. Счетчики сбора статистики на Web-сайте. В качестве источника этих данных использовался GTM, который отправлял детальные данные нашему Web-сервису и на машину в инфраструктуре Google для дальнейшего сохранения в MongoDB и BigQuery.

  2. Google AppEngine (Cron Jobs). Для сбора статистики в BigQuery необходим посредник, который бы аккумулировал поток событий. По мере накопления сохранял бы их в BigQuery.

  3. Google BigQuery. Система для проведения анализа и подготовки данных для расчета модели. В real-time взаимодействии никак не участвует.

  4. Google AppEngine (API). Это Web-приложение, с которым непосредственно общается сайт. Через него происходит разбор детальных данных статистики и сохранение их в MongoDB, запуск расчета и выбор профилей, применение модели к профилю.

  5. Google AppEngine (MongoDB). Для расчета профилей в real-time BigQuery не подходит в силу высокой задержки и дороговизны запусков (ориентирован на пакетную обработку).

  6. Google AppEngine (API ML). Развернутый интерфейс для доступа к модели через API.

Что получилось?

Сервис pop-up форм

Мы перевели сервис на собственный триггер для показа всплывающего сообщения. Получение профиля пользователя для показа оптимального изображения и CTA текста на всплывающей форме. В зависимости от содержания профиля — подбирается нужное сообщение. Если данных по пользователю нет или они устарели, очередной запрос приводит к расчету модели интересов пользователя и возврату нужных показателей.

Что поддаётся кастомизации во всплывающем сообщении: 1) текст и ссылки; 2) изображение; 3) страницы и момент показа.

Например:

#1 Пользователю присвоен признак интереса к автомобилю модели «А» красного цвета, интерес «кредит». Во всплывающем сообщении или в ретаргетинге для него будет демонстрироваться баннер про красный автомобиль с текстом про кредит до тех пор пока профиль интереса не изменится или не истечет срок актуальности профиля.

#2 Новый пользователь пришедший на сайт после определенного числа действий определен моделью с вероятностью N как пользователь заинтересованный в кроссовере. Во всплывающем сообщении вместо дефолтного изображения подставляется изображение кроссовера.

Обогащение данными CRM

Результаты расчета профилей и CRM данные получилось объединить для тех пользователей, которых мы знали или узнали в процессе взаимодействия. За счет обогащения данных стала возможна:

  • прогрессивная сегментация для персонализации контента и предложений в email коммуникациях,

  • выстроен процесс регулярной передачи сегментов медиа-партнёрам для повышения точности ретаргетинга и look-a-like.

Например:

Для пользователя, которому присвоен признак интереса к автомобилю модели «А» в письмах будут использоваться изображения модели «А».

Рост показателей конверсий

Несмотря на то, что статья про архитектуру и возможности решения — могу сказать что показатели конверсии пришли в норму для той части аудитории, которую охватывал эксперимент. Проводилось А/В тестирование с контрольной группой.

На этом всё. Надеюсь было интересно. Спасибо!

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Как вы думаете, сколько стоит реализация такого проекта?
25% Менее 0,5М 1
0% От 0,5М до 1М 0
50% От 1М до 2,5М 2
0% От 2,5М до 5М 0
25% Свыше 5М 1
Проголосовали 4 пользователя. Воздержались 3 пользователя.

ссылка на оригинал статьи https://habr.com/ru/post/666744/

Это спираль, Солнышко

Ой, ну надо же! Кто это мне там пишет? Неужели Валя? Какая же она молодец – помнит. Точнее, вспоминает. Когда припрёт.

Благо пишет, а не звонит. Можно лёгким движением пальца добраться до цифры, которую назвал в прошлый раз. Валя ведь уже прекрасно поняла, как работает карусель. Она и спрашивает-то ровно для того, чтобы убедиться: да, мы были дураками. И ничего не изменилось. И так будет всегда.

Стандартные вопросы – как дела, где работаешь, «а вот помнишь этого». Ну давай уже, Валюша, переходи к главному.

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

Знакомьтесь, друзья. Этот Стас, и ему очень весело. Он движется по спирали вокруг жадины. Но это не его выбор.

АйТи

Словом «АйТи» я условно назвал компанию, в которой Стас начал свою трудовую деятельность. Это была IT-компания, где работают, в основном, программисты. Да, 1С. Раньше у меня язык не поворачивался называть их IT-компаниями, но они так упорно настаивают на своей принадлежности к Большому и Великому, что я плюнул.

Итак, Стас пришёл после института, сел, засучил рукава и погрузился в мир программирования на русском языке. Было страшно интересно, хотя местами сложно – программирование 1С требует кучи навыков, кроме, собственно, разработки.

Зарплата на входе была очень небольшая, что нормально. Это ведь даже не зарплата, а стипендия. Тыщ 20-30, пожалуй. Стаса это не смущало – было понимание, как увеличивать свой доход. Ещё на собеседовании этот вопрос детально прояснил.

Ну и попёр по обозначенной линейке роста, как бульдозер. Для повышения дохода надо было давить на два рычага – формальный и неформальный. Формальный – это сдавать экзамены в 1С на знания и умения. То в программировании, то в знании предметной области. Чётко, понятно. Эту часть Стас прошёл очень быстро, чем весьма удивил руководство (почему-то остальные программисты сдавали экзамены неохотно).

Всё сдал и обнаружил, что линейка роста дохода… Закончилась! Как тот бычок, у которого доска кончается. Пошёл к руководству. Узнал про неформальную линейку.

Тут всё оказалось сложно и мутно. Если очень примерно, то надо «быть молодцом». Что это значит – доподлинно не известно никому. Например, один парень «был молодцом» в том, что умел успешно завершать погибающие проекты. У другого получалось создавать и поддерживать хорошую атмосферу в углу офиса. Третий понимал бизнес-задачи настолько хорошо, что выдавал решение, не дослушав вопрос клиента. Ну вы поняли.

Стас слушал-слушал, думал-думал, но так и не понял, что от него требуется. И пришёл к начальству во второй раз с простым вопросом: как мне увеличивать свой доход? Это не было ни требование, ни претензия. Стас уже доказал, что готов пахать, как лошадь, изучать новое, терпеть стресс, недосыпать. Но нужна цель, а не «будь молодцом».

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

Так Стас двинулся по спирали.

Завод

Стас уволился из АйТи и пошёл на Завод – тоже условное название. Производственное предприятие, где есть какая-то корпоративная информационная система (читай «одинэска»), её надо поддерживать и, если получится, развивать.

Стас ушёл на оклад 60 т.р. – примерно до этой цифры он поднялся в АйТи по стандартной шкале роста дохода. Пришёл, сел, засучил рукава. В первые пару месяцев наладил поддержку и сопровождение. В смысле избавился от необходимости в них, вылечив все детские болезни системы.

Ну и пошёл, по традиции, к начальству. Про зарплату пока не спросил – мало времени прошло. Лишь о Больших Проблемах, в которых может помочь автоматизация. Ему с радостью вывалили целый список, рассказали грустные истории («уже 10 лет мучаемся, всю эксельку до дыр протёрли»), назвали ключевых людей, с кем поговорить и т.д.

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

Сделал, действительно, блестяще. Понравилось всем. Обзавёлся массой знакомых, друзей, почитателей и даже обожателей. Изучил – причём, очень глубоко – несколько предметных областей, на уровне крепкого специалиста с профильным образованием. Торжественно разрезал ленточку выполненных проектов и пошёл говорить про зарплату.

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

Сошлись на том, что сейчас поднимают до 80, а если (когда) сделает ещё пару проектов, то будет 100. Стас поскрипел, но согласился. Всё-таки, условия довольно прозрачные. Опять засучил рукава и в бой.

Примерно на середине пути от 80 до 100 Стасу позвонили. Из АйТи. Оказывается, они пересеклись с начальством Завода на какой-то конференции, потрындели, наслушались об успехах проектов автоматизации, и тоже захотели. Точнее, сопоставили деяния Стаса с запросами от своих клиентов и возможностями собственных программистов. Ну и решили позвать Стаса обратно.

Как и положено жадинам, денег больше не предложили, просто позвали. Стас сказал, что обсудить можно, но только за 100. Жадины сказали, что дорого, и ушли.

Тем временем, Стас закончил пару проектов «за 100» и получил то, о чём договаривались. Пару месяцев тупо поработал и снова пришёл. Чем могу быть полезен, куда двинемся в развитии, какие технологии, проекты, цели и т.д. Хочу делать больше и, соответственно, больше получать. 150, например.

Начальство сказало, что ничего в голову не приходит. Стас сказал, что так не интересно, и ему придётся уйти. Начальство пожало плечами.

Стас двинулся дальше по спирали. В её центре уже находились две жадины.

Холдинг

Дальше был производственно-торговый холдинг, состоящий из нескольких предприятий с разрозненной ИТ-инфраструктурой. Стаса взяли программистом на 100. Он сел, засучил рукава… Нет, на этот раз не сел – приходилось много бегать и ездить, т.к. предприятия находились в разных городах.

Что интересно – взяли Стаса именно за то, чем он занимался на Заводе. За умение выстроить систему, почти не требующую сопровождения и самостоятельное выполнение серьёзных проектов. Собственно, этим Стас и занялся.

Привёл в порядок инфраструктуру – сначала в том виде, как была, со всеми её лоскутками. Потом пошёл и предложил проект по переводу на одну систему. Оказалось, это – голубая мечта руководства.  Просто делать было некому, а подрядчики сильно заламывали суммы.

Стаса трудности не пугали, поэтому он рьяно взялся за дело. На проект ушёл где-то год. После успешного выполнения Стас пришёл за новыми целями и, конечно, доходом. Хотел подняться на уровень 150.

Начальство согласилось, составили перечень проблем и проектов, получилось полтора десятка. Выбрали три, Стас поскакал разбираться и делать. Проекты были сложные, организационно-технические – и программировать, и процессы выстраивать, и интриги плести, и людей подсиживать, иначе саботаж съедал все результаты поступательного движения.

Где-то на середине пути от 100 до 150 Стасу написала (появились смартфоны и мессенджеры) первая жадина – АйТи. Угадайте, что сказали? Согласны платить 100! Стас впервые за долгое время улыбнулся и начал примерно понимать, что вообще происходит.

Сказал, что уже стоит 150. Объяснил почему – рассказал про Холдинг, решённые и решаемые задачи автоматизации. АйТи сказали, что дорого и ушли.

На выполнение трёх проектов у Стаса ушло полгода. Начальство честно подняло доход до 150. Стас был жутко доволен, хотел пару месяцев «отдохнуть», но не дали.

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

Стас был счастлив – новая цель, да ещё какая амбициозная! Не потому, что делать много, а потому, что делать новое, учиться и развиваться. Руководить людьми Стасу ещё не приходилось.

Естественно, спросил про доход. Сошлись на 200 – когда Стас наймёт трёх программистов, двух сисадминов и выполнит оставшиеся проекты списка. Йехххху! На этот раз Стас засучил не только рукава.

И тут, как вы думаете, что произошло? Написали с завода, ага. Типа мы думали-думали, решали-решали, долго согласовывали с Руководством, и приняли твои условия. Будем тебе платить 150. Стас аж поперхнулся и закашлял. Вежливо написал, что теперь надо уже 200. Жадины долго ныли, что ради Стаса прошли длинный и трудный путь согласований, чуть ли не «мировоззрение руководства пошатнули», а он такой засранец неблагодарный. Теперь была очередь Стаса пожимать плечами.

Год Стаса дома почти не видели. Он, правда, молодец – всё объяснил, зачем такие трудности и что будет после. Поняли, приняли. По утрам его ждал горячий завтрак и поглаженная футболка, а вечером – ужин из трёх блюд.

Основные трудности были с управлением людьми, ибо опыта не было. Но Стас справился. Даже умудрился выработать две модели менеджмента – для программистов и админов. Первым нужно «интересно и перспективно», вторым – «тихо и спокойно». Пару раз, конечно, Стас ошибался, перегибал палку, люди бежали увольняться, но в итоге удалось разрулить.

По окончании года ИТ-отдел было не узнать. Обслуживание инфраструктуры работало, как часы. Все люди знали, куда и зачем обращаться, когда будет решение. Программисты к концу года уже немножко сами вели проекты, а не только исполняли их. Но Стас не звездился и продолжал много работать руками.

Где-то в этот момент на горизонте опять возникли АйТи. Сказали, что нашли решение, как платить Стасу 150 – сделают его руководителем отдела программистов. Правда, не уверены были, что Стас справится. Пользуясь случаем, наш герой рассказал о своих успехах на стезе менеджмента. Заодно упомянул, что теперь ценник 250 – не уходить же на 200, которые у него почти в кармане. Опять послушал про наглость, пожал плечами и пошёл к начальству.

Начальство строго поспрашивало о результатах (хотя прекрасно о них знало). Что-то поныло насчёт трудностей с деньгами – решили строить новый завод, раз всё так хорошо. Стас вскользь упомянул, что «всё так хорошо», в т.ч., благодаря его работе. Ещё немного поскрипев, согласились и дали обещанные 200.

Немного покайфовав, Стас опять пришёл за целями, уровнями и повышением дохода. Как всегда, сказал, что готов пахать, учиться, развиваться. Но хочет точно знать, зачем. Например, хорошая цифра 250.

Начальство сказало, что не знает, что предложить. Всё вроде хорошо, всё работает, ничего особо улучшать не надо. И вообще – ты ж набрал команду, ребята отличные, и вообще ИТ-отдел уже стал достаточно дорогим удовольствием. Предложили пока просто работать и ждать.

Стас сказал, что ждать – себе дороже. Начальство пожало плечами.

Так в центре спирали появилась ещё одна жадина. Теперь они втроём могли наблюдать, как Стас удаляется от них на новые, неизведанные орбиты.

Разработка

Стас решил сменить сферу деятельности и пошёл в разработку. Контора создавала, поддерживала и развивала облачные B2B сервисы. Было несколько команд, у каждой по 1-3 проекта. Стасу, конечно, дали самое лежачее – и команду, и сервис. Правда, дали и 250.

Ну, что делал Стас, вы догадываетесь. Засучил рукава и побежал осваивать область, лежащую чуть в стороне от его опыта – разработку. Все слова, технологии и ЯП были знакомые, а подходы, цели, стратегии – нет.

Начал, по уже укоренившейся традиции, со стабилизации. Взялся за два вектора – скрепить команду и вылечить продукт. Пригодился опыт Завода и Холдинга. Команде обещал, что она станет лучшей в компании. Посмотрев, как Стас работает, команда поверила.

Через месяц продукт ушёл из чёрного списка вечных проблем. Список известных ошибок сократился почти до нуля, зато выросли два перечня – планируемых и выполненных доработок. На Стаса и его команду обратили внимание. Дали ещё один сервис на поддержку и развитие – забрали у другой, перегруженной команды.

Ещё через 1-2 месяца Стас и его команда были в лидерах по поддержке и развитию сервисов. Стас вызвали и предложили заняться ещё и разработкой сервиса. Разумеется, за такое платят больше – сами назвали цифру 300.

Всё это время Стасу продолжали звонить и писать жадины. Их стало сильно больше, потому что люди (эйчары, директора и проч.) уходили из АйТи, Завода, Холдинга, куда-то там приходили, видели IT-дичь и вспоминали про Стаса. Цокали языками, ныли, просили «ну давай пока 150, потом договоримся» и т.д.

Да, Стас называл цифру 350. Даже думал её в статус мессенджера написать, или на фотографию. Был бы как изотоп: Стас-350.

А разработка шла своим чередом. Стас через боль познавал разработку и эджайл. Унывать к тому времени он уже разучился, а боль считал непременным спутником развития. Команда тоже терпела, т.к. вслед за внутренним рейтингом и уважением выросли их зарплаты.

Через полгода полгода выкатили бету, ещё через три месяца сервис начал приносить деньги. К концу года вопросов о будущем сервиса не осталось. По совокупности всех факторов команда Стаса поднялась на первое место в рейтинге.

Да, разумеется, Стасу дали 300. Он, не откладывая, спросил про 350. Сказали подумают. Стас ждать не хотел, и предложил сам – может поднять качество и настроение других команд. Может быть командиром командиров. Правда, это стоит уже 400.

Начальство всё-таки ушло думать, пришло с предложением золотой середины – 350, и не все команды, а 2-3. И только те, которые сами захотят.

Захотели не все, но больше, чем 2-3. Стас понимал, что много брать нельзя – риск сильно высокий. Взял 4 команды, в довесок к своей.

Правда, поступил несколько непредсказуемо. Все ждали больших речей, совещаний, процессов, порядков и прочих атрибутов бюрократического масштабирования best practices. А Стас решил, что лучше подойдут «комиссары в пыльных шлемах» — выдернул из своей команды 4 самых толковых, идеологически подкованных и верных лично ему программиста, и отправил в 4 новые команды, вроде как политруками.

Сам продолжал руководить и своей командой, и всем процессом «трансформации». Даже программировать успевал. Чтобы не потерять навык, продолжать развиваться и случайно не стать «Большим Начальником».

Где-то в процессе обратился АйТи. Сказали, что тоже хотят идти в ногу со временем, и открывают отдел разработки. Цифра 400 напугала.

Завод тоже периодически позванивал. Начитались про «цифровую трансформацию». Конечно, даже не думали, что придётся отвалить 400.

Холдинг звонил чаще всех – Стас находился всего в паре витков спирали от них. Сказали, что случайно всё порушили. Сначала команду – поставили над ними эффективного менеджера без IT-образования. Следом упало набок развитие. Дальше, по эффекту домино, сломалась поддержка. Короче, опять от печки начинать. Стас изменил себе и назвал цифру 500. Спираль продолжала раскручиваться.

На «трансформацию» 4 команд ушло полгода. Всё получилось, Стас получил свои 350. Напомнил про остальные команды и 400. Сказали, подумают.

Не подумали, а собрали руководителей команд и задали им вопрос – хотят ли. Думали, будет консенсус и троекратное «Ура!». Увы, нашлось достаточно тимлидов, живущих по принципу «давно тут сидим». Оказывается, Стас успел нажить себе врагов. Правда, он ничего об этом не знал.

Начальство думало-думало, и придумало: пусть всё остаётся, как было. Стас пусть руководит теми командами, которые сами того хотят. Соответственно, те же 350. Или иди, убеждай, продавай.

Стас сначала расстроился, потом обрадовался, и ушёл. Начальство пожало плечами.

Сам

Теперь Стас сам. Тут рассказывать особо нечего, т.к. история продолжается прямо сейчас. Собрал ребят, которые после него ушли из АйТи, Холдинга и Разработки. Занялся тем, что умеет – разработкой сервисов и сложной автоматизацией (когда не просто «продать и установить»).

Ему продолжают звонить и писать жадины из спирали. Теперь уже, правда, по другому поводу.

АйТи сначала предлагали купить бизнес Стаса. Потом – объединиться. Сейчас уже вскользь звучит «купи нас».

Завод и Холдинг просят заниматься их обслуживанием и развитием. Но непременно «только чтобы сам Стас участвовал». Слыша цену за личное участие Стаса, уходят ждать следующего витка спирали.

Разработка зовёт руководить-таки всеми командами, потому что с уходом Стаса те, кто «давно тут сидим», совсем обнаглели и их разогнали. Предлагают 400. Стас улыбается и уже не называет никакой суммы.

Спираль

Про спираль вы поняли, но я, на всякий случай, изложу мнение Стаса, это ж его история.

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

Собственно, это нормально – не знать. Но когда не знаешь, надо изучать и думать. IT развивается так стремительно, что любой бизнес будет вечно в позиции догоняющего солнце, работая от «проблемы» или «реальной потребности». Это ни хорошо, ни плохо, это – выбор, который делает бизнес.

Но у этого выбора есть последствия – возрастающая стоимость. Один и тот же неугомонный специалист, или одна и та же приличная IT-компания, очень быстро дорожают (не важно, как именно выражена стоимость – в виде оклада, бюджета проекта, цены часа и т.д.). Пока бизнес думает, а точнее – ждёт возникновения реальной проблемы, IT подорожает.

Бизнес, по словам Стаса, этого не понимает, т.к. живёт по гелиоцентрической модели. Себя считает Солнцем, а всех остальных – планетами и астероидами, вращающимися по круглой, от силы – эллиптической орбите. Они, эти IT, инженеры и прочая нечисть, всегда рядом, под рукой, на одном и том же расстоянии от Бизнеса-Солнца. И есть миллионы лет на раздумья.

В модели Стаса орбита IT-спецов – спиралевидная. Да, движется почти по кругу, поэтому у бизнеса есть ощущение, что программист (вроде Стаса) всегда рядом, где-то тут, ему можно позвонить, «простить и позвать». И только в этот момент понять, что программист ушёл на другую, недоступную орбиту.

А однажды – выйдет за пределы Солнечной Системы Бизнеса. И, наверное, сам станет Солнцем.

P.S.

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

Да, разумеется, есть спецы, которые летают по идеально круглой траектории. Они и правда всегда под рукой. Но когда нужно сделать что-то Большое и Страшное, звонят не им.


ссылка на оригинал статьи https://habr.com/ru/post/667896/

Зачем нужен протокол языкового сервера (LSP)?

LSP (протокол языкового сервера) сегодня весьма популярен. Есть стандартное объяснение этого феномена. Возможно, ранее вам уже попадалась эта картинка, у нас также являющаяся заглавной.

Считаю, что такое стандартное объяснение популярности LSP – неверное. Ниже предложу вам альтернативную трактовку.

Стандартное объяснение

Стандартное объяснение строится так:

Существует M редакторов и N языков. Если вы хотите поддерживать конкретный язык в интересующем вас редакторе, то для этого вам понадобится выделенный плагин. То есть, M * N будет работать, что наглядно показано на картинке выше. В данном случае LSP сужает эту картинку, приводя к тонкому общему знаменателю M + N – как показано на картинке ниже.

Почему это объяснение ошибочное?

Проблему, возникающую с этим объяснением, также удобнее всего проиллюстрировать. Если коротко, на картинках выше не соблюден масштаб. На следующей картинке точнее показано, как, например, взаимодействует комбинация rust-analyzer + VS Code:

(Большой) круг слева – это  rust-analyzer (языковой сервер). Расположенный справа круг примерно такого же размера — это VS Code (редактор). Маленький кружок в центре – это склеивающий их код, включающий, в том числе, реализации  LSP.

Этот код крошечный, как в абсолютном, так и в относительном выражении. Базы кода как за языковым сервером, так и за редактором – гигантские.

Если бы стандартная теория была верна, это бы означало, что до LSP мы жили в мире, где некоторые языки имели бы превосходную поддержку на уровне IDE в некоторых редакторах. Например, IntelliJ отлично показывала бы себя в Java, Emacs в C++, Vim в C#, т.д. Я помню, что в те времена было несколько иначе. Чтобы получить достойную поддержку IDE, требовалось либо пользоваться языком, поддерживаемым JetBrains (IntelliJ или ReSharper), либо…

Был всего один редактор, дававший осмысленную семантическую поддержку IDE.

Альтернативная теория

Я бы сказал, что истинная причина такой плохой поддержки IDE в те древние времена иная. Дело в том, что уровень M * N был не слишком большим, а слишком маленьким, так как N равнялось нулю, а M было всего лишь немного выше нуля.

Начну с N — количества языковых серверов, так как на этой стороне я относительно хорошо ориентируюсь. До LSP было просто не так много рабочих решений, работавших по принципу языкового сервера. В основном потому, что написать языковой сервер сложно. Сервер по сути своей слишком сложен, это так. Известно, как сложны компиляторы, а языковой сервер – это компилятор  и маленькая тележка.

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

Во-вторых, тогда как пакетный компилятор является чистой функцией, преобразующей исходный код в машинный, языковому серверу приходится работать с базой кода, в которую пользователь постоянно вносит изменения. Это компилятор с еще одним измерением – временным, а эволюция состояния с течением времени является одной из сложнейших проблем в программировании.

В-третьих, пакетный компилятор оптимизирован под максимальную производительность, тогда как языковой сервер стремится минимизировать задержки (но и аспект производительности при этом не забрасывается). Добавление требования «уменьшить задержку» не означает, что нужно оптимизировать еще сильнее. Напротив, это означает, что нужно перевернуть всю архитектуру с ног на голову, только чтобы привести задержку к приемлемому значению.

И все это приводит нас к плотному клубку взаимосвязанных проблем, касающихся побочной (ненужной) сложности, характерной для языковых серверов. Вполне понятно, как написать пакетный компилятор. Это общеизвестно. Притом, что не каждый читал книгу с драконом (я совершенно не смог разобраться в главах о синтаксическом разборе), каждому известно, что все ответы – в этой книге. Поэтому большинство существующих компиляторов выглядят как типичный компилятор. А когда авторы компиляторов начинают задумываться о поддержке на уровне IDE, первая их мысль: «ну, IDE это в своем роде компилятор, а компилятор у нас есть, значит, задача решена – разве не так»? Это очень не так, поскольку по внутренней организации IDE очень отличается от компилятора, но до недавнего времени этот факт не был общеизвестен.

Языковые серверы – контрпример к правилу «никогда не переписывай». Большинство респектабельных языковых серверов переписаны с пакетных компиляторов или являются их альтернативными реализациями.

Как IntelliJ, так и Eclipse написали собственные компиляторы, а не стали переиспользовать javac внутри IDE. Чтобы предоставить адекватную поддержку на уровне IDE для C#, Microsoft переписала свой пакетный компилятор, сделанный на C++, и превратила его в интерактивный самоподдерживающийся аналог (проект Roslyn). Dart, хотя и сделан с нуля, и является относительно современным языком, получил три реализации (хост-компилятор с опережающим (AOT) подходом, хост-компилятор для IDE (dart-analyzer), а также динамический (JIT) компилятор, работающий на устройстве). В Rust опробовали оба варианта — поступательную эволюцию в случае с rustc (RLS) и реализацию с нуля (rust-analyzer), причем, rust-analyzer решительно победил.

Мне известны два исключения из этой картины: C++ и OCaml. Любопытно, что в обоих требуются как предварительные объявления (forward declarations), так и заголовочные файлы. Совпадение? Не думаю. Подробнее об этом см. в посте Three Architectures for a Responsive IDE.

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

Я не так уверен, что же происходит на стороне редактора. Поэтому не хочу утверждать, что не бывает редакторов, которые могли бы выступать в качестве полноценной IDE.

IDE воспринимается как куча семантических фич. Самая замечательная из них – это, конечно же, автозавершение. Если вы хотите написать собственный вариант автозавершения для VS Code, то ваш код должен реализовывать интерфейс CompletionItemProvider:

interface CompletionItemProvider {     provideCompletionItems(         document: TextDocument,         position: Position,     ): CompletionItem[] }

Таким образом, в VS Code автозавершение кода (как и десятки других фич, касающихся работы с IDE) на уровне редактора являются сущностями первого класса, у них единообразный пользовательский UI и API разработчика.

Сравните с Emacs и Vim. У них просто нет нормального завершения, которое могло бы послужить исходной фичей для расширения редактора. Они просто предоставляют низкоуровневый курсор и API для манипуляции с экраном, а потом людям приходится поверх всего этого реализовывать фреймворки автозавершения, конкурирующие между собой!

А это только завершение кода. Что насчет информации о параметрах, вложенных подсказок, навигации по хлебным крошкам, расширенного поиска, помощи, символьного поиска, функции «найти» (достаточно?) J  ?

Кратко резюмируя вышесказанное – проблема с годной поддержкой IDE лежит не в плоскости N * M, а связана с неверно откалиброванным равновесием этого двустороннего рынка.

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

Со стороны редактора не было особого стимула добавлять высокоуровневые API, нужные для IDE, поскольку не было потенциальных провайдеров таких API.

Почему LSP – отличная штука

Вот почему, на мой взгляд, LSP так хорош!

Не думаю, что это серьезная техническая инновация (очевидно, что нам хочется иметь отдельный редактор, не связанный с языком и языково-специфичный сервер). Полагаю, это весьма плохая (т.н., «довольно хорошая») техническая реализация (вы уже настроились почитать пост «Почему LSP отстой?»). Но эта штука позволила нам покинуть мир, где было нормально не иметь языковой IDE, и никто даже не думал о языковых серверах – в мир, где язык без действенного автозавершения и определения goto выглядит непрофессионально.

Примечательно, что проблема уравновешивания рынка была решена Microsoft, являющейся вендором как языков (C# и TypeScript), так и редакторов (VS Code и Visual Studio), которая, кстати, проиграла нишу IDE конкуренту (JetBrains). Притом, что я могу поругаться на конкретные технические детали LSP, я абсолютно восхищаюсь их стратегической прозорливостью в данной конкретной области. Они:

  • Построили редактор на основе веб-технологий.

  • Разглядели в вебдеве большую нишу, в которой JetBrains буксует (поддерживать JS в IDE почти невозможно).

  • Написали язык (!!!!), на котором стало возможно предоставить поддержку IDE для вебдева.

  • Построили платформу IDE с очень дальновидной архитектурой.

  • Запустили LSP, чтобы даром повысить ценность своей платформы в других предметных областях  (переведя весь мир в значительно более уравновешенную ситуацию с IDE – что всем пошло на пользу).

  • А теперь, имея Code Spaces, превращаются в ведущего игрока на поле «исходно удаленная разработка», а вдруг мы действительно прекратим редактировать, собирать, и выполнять наш код на локальных машинах.

Но, если честно, до сих пор надеюсь, что победа останется за JetBrains, ведь их Kotlin задуман как универсальный язык для любых платформ :-). Притом, что Microsoft выжимает максимум из доминирующих сегодня технологий «чем хуже, тем лучше» (TypeScript и Electron), JetBrains пытаются исправлять ситуацию, двигаясь снизу вверх (Kotlin и Compose).

Подробнее о M * N

Теперь я просто подытожу, что все дело, в сущности, не в M * N 🙂

Во-первых, тезис M * N игнорирует тот факт, что это чрезвычайно параллельная задача. Проектировщикам языка не требуется писать плагины для всех редакторов, равно как не требуется добавлять в редакторах специальную поддержку для всех языков. Нет, язык должен реализовывать сервер, который общается по некоторому протоколу, редактор должен реализовывать API, работающие независимо от языка и обеспечивающие автозавершение. В таком случае, если и язык, и редактор не слишком экзотические, то человек, заинтересованный как в первом, так и во втором, просто напишет немного склеивающего кода в качестве связки между ними! Плагин от rust-analyzer для VS Code состоит из 3.2k строк кода, плагин neovim из 2.3k строк и плагин Emacs из 1.2k строк. Все три разработаны независимо, разными людьми. В этом и заключается магия децентрализованной опенсорсной разработки в наивысшем выражении! Если бы плагины поддерживали специализированный протокол, а не LSP (при условии, что внутри редактора поддерживается высокоуровневый API для IDE), то, полагаю, на все это потребовалось бы добавить, может, еще 2k строк кода, что нормально для бюджета хобби-проекта, выполняемого в свободное время.

Во-вторых, для оптимизации вида M * N следовало бы ожидать, чтобы реализация протокола генерировалась из какой-нибудь машинно-читаемой реализации. Но до самого последнего релиза источником истины для спецификации LSP служил неофициальный документ, оформленный в виде разметки. На каждом языке и клиенте изобретается собственный способ извлекать из него протокол, многие (в том числе, rust-analyzer) предполагали просто синхронизировать изменения вручную, с серьезным объемом дублирования.

В-третьих, если M * N является проблемой, то ожидаемо, чтобы на каждый редактор существовало всего по одной реализации LSP. В реальности же существуют две конкурирующие реализации для Emacs (lsp-mode и eglot) и, поверьте, я не прикалываюсь, на момент написания этой статьи, в мануале по rust-analyzer содержится инструкция по интеграции 6 (шестью) различными LSP-клиентами для  vim. В тон первому пункту, все это опенсорс! Общий объем работы практически не имеет значения, а что в данном случае действительно важно – это суммарная работа по координации, которую нужно проделать, чтобы добиться результата.

В-четвертых, Microsoft сама не пытается извлекать выгоду из M + N. Нет никакой универсальной реализации LSP в VS Code. Напротив, для каждого языка требуется выделенный плагин с физически независимыми реализациями LSP.

Что делать

Всем

Пожалуйста, требуйте более качественной поддержки IDE! Думаю, сегодня мы уже переступили порог, после которого наступила всеобщая доступность базовой поддержки IDE, но с ее помощью почти ничего не сделать кроме элементарных вещей. В идеальном мире должна была бы существовать возможность проверить все мельчайшие семантические детали о выражении, на которое наведен курсор, при помощи все того же простого API, при помощи которого сегодня любой желающий может проверить содержимое буфера в редакторе.

Авторам текстовых редакторов

Уделяйте внимание архитектуре VS Code. Притом, что степень удобства работы с electron вызывает вопросы, в их внутренней архитектуре заложено много мудрости. Ориентировать API редакторов нужно вокруг высокоуровневых возможностей, не зависящих от конкретного представления. Базовая функциональность IDE должна расцениваться как точка расширения первого класса, не следует делать так, чтобы автору каждого плагина приходилось ее переизобретать. В частности, добавление assist/code action/ в качестве возможности первого класса на уровне UX – уже норма. Это первая по важности инновация в области пользовательского опыта, применяемая в IDE, и на настоящий момент она уже довольно старая. Просто нелепо, что она еще не стала стандартным интерфейсом, обязательным во всех редакторах.

Но не делайте LSP как таковой сущностью первого класса. Как ни удивительно на первый взгляд, VS Code ничего не знает о LSP. Она просто предоставляет набор точек расширения, нисколько не заботясь о том, как они реализуются. Тогда реализация LSP – это просто библиотека, используемая плагинами, специфичными для конкретных языков. Например, расширения под Rust и C++ для VS Code не разделяют во время выполнения одну и ту же реализацию LSP, в памяти одновременно хранится два разных экземпляра библиотеки LSP!

Кроме того, попытайтесь обуздать силу опенсорса. Не требуйте централизации всех реализаций LSP! Дайте возможность разным группам независимо разработать для вашего редактора превосходную поддержку Go и отличную поддержку Rust. Одна из возможных моделей представлена в VS Code, там есть маркетплейс и распределенные независимые плагины. Но, вероятно, должна быть возможность организовать всю работу в рамках единого разделяемого репозитория/дерева исходников, поскольку за каждый из языков может отвечать своя независимая команда поддержки.

Авторам языковых серверов

Вы славно работаете! Качество поддержки IDE стремительно улучшается для всех языков, хотя, у меня такое ощущение, что мы только в начале долгого пути. В частности, нужно не забывать о том, что LSP – это один из интерфейсов для семантической информации о языке, но не единственный такой интерфейс. В наличии может появиться что-нибудь получше. Поэтому попробуйте воспринимать LSP как формат сериализации, а не внутреннюю модель данных. Также пытайтесь больше писать о том, как реализовывать языковые серверы – на мой взгляд, в доступе по-прежнему не хватает информации на эту тему.

Вот и все!


ссылка на оригинал статьи https://habr.com/ru/company/piter/blog/667882/

Земля и Луна с борта Кассини

История одного расследования

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

Недостающее звено это — пустота между процессом получения данных и их публикацией.

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

Перейдем к теме

Очевидно, к годовщине события в Фейсбуке появилась фотография, сделанная одной из камер межпланетной станции Кассини: Вид Земли и Луны из окрестностей Сатурна. На снимке только лучистая “звёздочка” Земли, и средней яркости точка Луны. И еще блик — результат переотражения в линзах — от Земли, предположительно (но это не точно).

И конечно же, незамедлительно последовал вопрос:

«Почему не видно звёзд?»

Вопрос не новый. Его уже задавали в тысяче споров о том “Летали американцы на Луну или нет?”. Но в “Лунной теме” все понятно — яркость лунного ландшафта такова, какова яркость раскаленного летнего асфальта, слепящего глаза в солнечный день. Какие уж тут звезды, если выдержка при съемке 1/1000 секунды — звездам нужно в 1000 раз больше — как минимум.

Но в дальнем-то космосе, когда на снимке есть далекие Земля и Луна — сами как звезды, почему звёзд опять не видно?

Попытаемся в этом разобраться

Систему “Земля-Луна” и Сатурн в среднем разделяет расстояние около 10 астрономических единиц или полутора миллиардов километров. Насколько яркими являются Земля и Луна с такого расстояния?

Можно приблизительно прикинуть, что Земля Подобна Венере — альбедо (отражающая способность) нашей планеты более чем в полтора раза слабее венерианской. Правда, Земля чуть крупнее Венеры. Поэтому оценка “полтора раза” по альбедо будет в самый раз. Венера с расстояния в 1 астрономическую единицу видна как светило -4,5 звездной величины. Земля была бы видна с такого расстояния в полтора раза слабее — на половину звездной величины — то есть, минус четвертой звездной величины был бы блеск Земли в тех условиях, в которых мы наблюдаем Венеру — то есть, с расстояния в 1 астрономическую единицу.

Перенесемся на Сатурн. Расстояние увеличилось в 10 раз. Значит яркость Земли уменьшится в 10 в квадрате — в сто раз.

Из курса астрономии (надеюсь на эту тему написать отдельную статью) разница по яркости в 100 раз — это ровно 5 звездных величин. Нужно добавить еще одну, потому что Земля отстоит от Солнца в полтора раза дальше Венеры, что при возведении в квадрат дает более двух раз, и обеспечивает разницу блеска в 1 звездную величину.

Стало быть Земля с орбиты Сатурна будет на шесть с половиной звездных величин слабее, чем Венера в небе Земли.

По этой весьма приблизительной оценке, яркость Земли на снимке станции Кассини — это вторая звездная величина.

Луна — по альбедо она в три с половиной раза тусклее Земли, а еще Луна по диаметру в три с половиной раза меньше (а соотношение диаметров нужно возвести в квадрат, потому что нам критична видимая площадь объекта). Итого, соотношение яркостей Земли и Луны будет три с половиной в кубе, что есть около 40 раз, или 4-х звездных величин.

Предполагаемая звездная величина Луны, при наблюдении её из окрестностей Сатурна будет всего 6m — на пределе видимости глазом.

Значит, если бы поблизости луча зрения в сторону Земли и Луны располагались какие-то звезды, доступные глазу по своей яркости, они на снимке обязаны были получиться.

Но были ли в этом районе неба столь яркие звезды?

У нас есть способ проверить это.

Программа Stellarium

Это виртуальный планетарий в вашем компьютере или смартфоне, который показывает вид звездного неба на заданную дату и момент времени для некоторого конкретного пункта на земном шаре. Но Stellarium может показать вид звездного неба — с планетами и малыми телами Солнечной системы — для виртуального наблюдателя, находящегося на поверхности того или иного небесного тела. Мы можем перенестись на один из спутников Сатурна, и посмотреть в сторону Земли глазами Кассини.

Спутник Сатурна Мимас — еще одна «Звёзда Смерти»

Какой спутник Сатурна выбрать?

Предлагаю Тефию — эдакое подобие “Звезды смерти” из Звёздных войн — обладательницу самого большого ударного кратера в Солнечной системе. Для этого всего лишь надо выбрать название спутника в выпадающем списке небесных тел, до которых в программе Stellarium предусмотрены прямые и регулярные рейсы. мы можем выбрать даже точку посадки — например дно того самого огромного кратера с названием “Одиссей”.

А еще нам необходимо перенестись в дату, когда был сделан обсуждаемый фотоснимок — 19 июля 2013 года.

Перелет в пространстве и времени совершается практически мгновенно. Нашему взору предстает завораживающая картина:

Мы смотри на Сатурн с неосвещенного Солнцем тыла. Помимо известных нам звезд и созвездий в небе блестят некоторое количество непривычных для землянина светил — это свита спутников “Властелина времени”, коим считался Кронос у древних греков, знакомого нам своим римским именем — Сатурн. Но не только спутники Сатурна украшают небо окраин Солнечной системы. Вокруг далекого Солнца можно отыскать несколько планет. Где-то среди них таится Земля с Луной. Сразу и не угадаешь, где здесь Земля.

К счастью, в Stellarium небесные объекты подписаны. Я намеренно отключил подсказки, чтобы проникнуться непривычным видом сатурнианских небес. Но если включить маркеры обратно, все станет понятно:

Земля оказалась совсем рядом с Солнцем. И это не удивительно, ведь орбита Земли находится глубоко внутри орбиты Сатурна. И для наблюдателя этих холодных и далеких краев Земля не удаляется от Солнца далее, чем на 7 градусов. Это очень мало. Неуловимый Меркурий с Земли трудно наблюдать именно из-за близости к Солнцу, а ведь он в максимальных элонгациях уходит от Солнца на 27 градусов. И все равно его мало кто видел. Это я к тому, что сфотографировать Землю из окрестностей Сатурна очень непросто из-за видимой близости к Солнцу.

В этот день — 19 июля 2013 года — элонгация Земли как раз была максимальной. Нам повезло. И вероятнее всего это время для съемки было выбрано не случайно.

Ну, а где же Луна?

Для этого нам нужно существенно увеличить масштаб — применить буквально телескопическое увеличение.

В процессе увеличения масштаба, многочисленные звезды будут появляться на экране и разбегаться к его краям, но Луна окажется видимой отдельно от Земли лишь тогда, когда самые слабые звезды, которые показывает Stellarium, исчезнут из нашего поля зрения.

Это не значит, что звезд в этом направлении во Вселенной не существует. Просто, они настолько слабые, что даже Stellarium о них ничего не знает.

Впрочем, если обратно уменьшить масштаб и найти ближайшую на небе к Земле и Луне слабую звезду, можно навести о ней справку — она будет слабее 10-й звездной величины. Но даже она осталась бы за пределами поля зрения камеры межпланетной станции Кассини.

Из Сатурнианских далей Земля и Луна практически сливаются. Расстояние между ними в этот день составляло лишь 24 угловые секунды — это в полтора раза меньше, чем между компонентами двойной звезды Альбирео. Когда фотографируют Альбирео, чаще всего тоже получается кадр, на котором только два компонента системы, и — всё — других звезд почти не видно.

Мы можем увеличить масштаб еще больше, и посмотреть Землю и Луну более детально. Это познавательно.

Кстати, Stellarium с легкостью вычисляет блеск того и другого светила. По его данным блеск Земли составляет 2,85m, а блеск Луны 7,16m. В предлагаемых мною быстрых и грубых оценках мы ошиблись в среднем на 1 звездную величину. И как можно понять, средние по яркости звезды камера станции Кассини берет уверенно, просто их в поле зрения поперечником в несколько угловых минут (Stellarium-у спасибо — он и это подсказывает) просто не оказалось. Но какие-то звезды там, конечно есть, которые просто камерам недоступны… или…

А что, если мы их поищем?

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

И что-то, напоминающее звезды, на картинке вылезло. Хотя, нет никакой гарантии, что это именно звезды — отождествить с реальными светилами мы их не можем — Stellarium тут не помощник. Быть может это просто артефакты сжатия, ведь снимок скачан из соцсети, и там он был пережат многократно и безжалостно.

Но я не поленился поискать нечто альтернативное. Ведь не только в фейсбуке этот снимок существует. И я нашел аналогичный имидж на сайте Phys.org — в публикации описывающей, именно обсуждаемую тему. И там качество картинки лучшее. И на ней — вот, сюрприз! — присутствуют звезды.

Какие здесь есть замечания?

Снимки имеют разную ориентацию. быть может это лишь центральные фрагменты некоторого большого и непригодного к публикации исходника, по разному вырезанные для тех или иных статей и отчетов. А может быть это снимки сделанные в разное время и из разных положений космической станции с разной ориентацией поля. Потому что я попытался сопоставить подозрительные звездные объекты на обоих снимках, и они по большей части не совпали, И было бы странно, если бы Кассини делал лишь по одному кадру каждой выбранной для него цели. Так не бывает. А может быть на имидже из Фейсбука действительно нет никаких звезд — только шумы и артефакты сжатия. Но, как минимум мы убедились в том, что это вполне правдоподобная ситуация — попадание в кадр с Землей и луной какой-то более или менее яркой звезды — скорее большое везение, нежели обязательное дело.


ссылка на оригинал статьи https://habr.com/ru/post/667902/

Где именно лежит граница между зарплатными грейдами: как это устроено у нас

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

В итоге мы сделали опросник из 14 пунктов, по которому за несколько минут можно оценить себя. То же самое делает про вас тимлид, и если оценки совпадают, то всё отлично, есть грейд и зарплата в нём (у нас по три уровня внутри каждого грейда, например, джун-джун, опытный джун и джун 80-го уровня). Если оценки не совпадают — начинается процесс переговоров с приведением примеров для синхронизации по части оценки и ожиданий, чтобы потом на следующей итерации они всё-таки совпали.

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

Почему мы не грейдируем только по хардам

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

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

Из опроса удалось получить большой список факторов, которые влияют на уровень именно с точки зрения разработчиков.

Основное, в чём сходились почти все опрошенные, — это то, что мы позже назвали «самоходность», то есть умение решить задачу самостоятельно. Или, если точнее, целиком и полностью реализовать задачу с достаточным качеством в разумные сроки и при этом понимать, что в задаче важно бизнесу и почему, на какие метрики будут смотреть продакты и какие технические метрики важно собирать. Второй наиболее часто упоминаемый фактор — это «технический кругозор», под которым мы понимаем владение текущим техническим стеком. Мы решили, что без двух этих качеств разработчик в принципе не может быть синьором. А позднее к ним добавились ещё «понимание бизнес-проблемы» и «умение действовать в условиях неопределённости».

Что убрали из оценки

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

Как это ни странно, ушла из списка коммуникация с коллегами и заказчиком. Да, коммуникация с коллегами очень важна, но мы не можем на её основании определить грейд. Плюс у нас есть достаточно общие вопросы, которые косвенно включают в себя это проявление. Важно помнить, что грейд — это про уровень решения задач, про результативность. Если синьор токсичный, то это не значит, что он не может классно решить задачу. Это значит, что, возможно, мы просто не будем готовы с ним работать, но это не повод снижать грейд.

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

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

Давайте их и разберём.

Опросник

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

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

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

Как и в следующих пунктах, тут нет какой-то объективной оценки вроде подсчёта частоты задаваемых вопросов, вполне хватает субъективной самооценки тимлида, и она по тестам оказывается довольно точна.

Это второй определяющий критерий для синьора в наших условиях. Если нет умения решать задачу в ситуации неопределённости, то перед нами — исполнитель, работающий преимущественно по ТЗ. А синьор — это тот, кто может выяснить и решить, как надо делать. Кто-то может справедливо отметить, что это может делать PM, но не стоит забывать, что критерии отличаются от компании к компании исходя из внутренней культуры.

Простую типовую задачу «под ключ» может решить и джуниор, а вот в случае, когда бизнес приходит и говорит «хотим сделать, чтобы вот так», часто надо придумать решение, которое не только «сделает вот так», но и выбрать архитектуру, понять, кого это может задеть внутри компании и на что ещё может повлиять, договориться с инфраструктурой, смежными командами и так далее, а потом уже сказать, какие есть варианты и чем они отличаются. Это похоже на аналитику задачи, но включает в себя умение искать оптимальное решение в локальной ситуации.

Ещё один пример неопределённости — это когда нужно что-то поправить, а никто не знает, где вообще эти правки вносить.

Понимание проблемы — это ответ на вопрос, зачем, собственно, решается эта задача. Разница принципиальна: если просто реализовывать ТЗ, то может быть выбрана не та архитектура. Или вообще может выясниться, что задачу в таком виде решать не надо, потому что есть другой путь. И опытный специалист должен его показать.

Конечно, бывают разные проектные менеджеры. Для некоторых важно, чтобы то, что они сказали, было сделано именно так, как они хотят. Но мы считаем, что такое слепое следование ТЗ обычно говорит о недостаточном понимании бизнес-задачи и имеет больше негативных последствий. Очень часто нужно делать не прямо по хотелкам, а чуть больше, чуть иначе и вообще обсуждать эти решения и их последствия. Но аргументированно.

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

Зачастую лучше чего-то не делать, чем реализовывать сомнительное решение либо делать по-другому.

Стратегическое мышление — это черта сильного специалиста с богатым кругозором и насмотренностью. Синьор будет проектировать решение, которое закрывает среднесрочные и долгосрочные цели бизнеса без дополнительных крупных затрат. Конечно, не всегда так получается, но пытаться важно. Хорошо, если специалист об этом думает и регулярно проявляет эту черту.

Очень часто бывает, что приходит бизнес, говорит: «А покрасьте вот эту кнопку в красный». Джун возьмёт и покрасит через костыль. Мидл сделает отдельный класс красных кнопок и позволит ставить их там, где надо бизнесу. Синьор спросит, как часто нужно красить кнопки, зачем, какие ещё есть цвета, и, возможно, даст возможность бизнесу самому выбирать цвет кнопки без того, чтобы ходить в разработку.

Межкомандная работа — это наша специфика и временами боль, поэтому этот критерий попал в опросник. У нас много команд и много пересекающегося функционала. Охотно верю, что в других компаниях не так, но мы ждём от своих синьоров умения организовывать работу над межкомандными задачами. Чтобы они брали ответственность на себя, собирали тех, кто нужен для решения, раскручивали цепочку, как решать, и решали, а не просто оставляли задачу болтаться, «потому что непонятно, кто у них там должен».

То есть по факту у нас нельзя стать синьором, не имея хоть одной задачи, решённой на стыке команд.

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

Это, пожалуй, самая субъективная оценка нашего опросника, потому что измеряется исключительно по ощущениям руководителя. Здесь мы оцениваем, насколько эффективно сотрудник выполняет задачи, с учётом скорости, количества решённых задач и качества их исполнения. Понятно, что в идеале надо сводить метрики по всей компании и сравнивать всех со всеми.

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

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

Этот пункт — про внимательность и ответственность за состояние задачи на момент её передачи в тестирование. Если разработчик считает, что его задача — «код писать, а не тестить» и передаёт её QA без проверки, то увеличивается нагрузка на тестировщика, а жизненный цикл задачи растягивается, так как она возвращается на доработку.

Пока для простоты оценки выбрали метрику «кол-во возвратов задачи после тестирования», но, как уже подсвечивали коллеги из некоторых команд, такая метрика не всегда объективна. Например, у QA могут быть проблемы с инфраструктурой, а не кодом. Поэтому как альтернатива метрике — это дойти до QA и узнать, насколько качественно сделаны задачи, передаваемые в тестирование.

На старте нового проекта или реализации большой задачи опытный разработчик закладывает архитектуру, которая долгое время позволяет гибко реагировать на запросы бизнеса. Этот критерий дополняет «стратегическое мышление», но там больше про потребности бизнеса и риски, а тут — про реализацию.

Тут, думаю, всё понятно.

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

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

Code Review — устоявшаяся практика в разработке, поэтому она тоже попала в оценку.

Знание стека — это суммарная оценка хардов по каждой части используемого стека, она проводится отдельно и просто заносится в опросник как один из пунктов. Важно, что нельзя стать синьором, не обладая глубоким пониманием технологий и умением применять их на практике.

Недостатки

Первая особенность в том, что у начинающего тимлида в команде по итогам оценки может оказаться больше синьоров, чем у опытного, поскольку его будет легче убедить в наличии отсутствующего навыка из-за субъективности оценки. В таких случаях рекомендуется проводить опросник в формате 270 градусов (самооценка, оценка руководителя, оценка коллеги или той роли, которая может оценить).

Вторая особенность — не все навыки объективно могут проявиться в конкретной команде. Например, у нас достаточно команд, которые работают полностью автономно без взаимодействия с кем-то ещё, и там нельзя показать ту же компетенцию межкомандного взаимодействия. Мы предполагаем, что разработчик, который поймёт, что хочет расти дальше, сможет при необходимости перейти в команду, где такая практика есть, просто чтобы получить нужный опыт. Либо сможет затащить какие-то проекты на уровне юнита или компании, находясь в своей команде.

Третья особенность — сами критерии достаточно субъективны: сразу стало заметно, что пункты начинают трактоваться по-разному. Сейчас выравниваем эту трактовку через добавление примеров.

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

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

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

Вот здесь за пять минут можно пройти опросник и оценить, какой грейд был бы у вас в Skyeng.


ссылка на оригинал статьи https://habr.com/ru/company/skyeng/blog/667740/