Это конспект интервью с Иваном Дёмшиным, Head of Engineering в Miro, про структуру продуктовой разработки, смену технологий на фронте и бэке, эволюцию тестирования, процесс найма и развития инженеров.



Полную двухчасовую версию можно посмотреть на Ютуб-канале Хекслет.

Оглавление:

История продукта и компании


Как устроена продуктовая разработка


Выбор технологий и их эволюция



Процессы в разработке


История продукта и компании


Miro — платформа для визуальной коллаборации в виде бесконечной онлайн-доски (online collaborative whiteboard platform). Ключевое слово — коллаборация, совместная работа, соответственно, ключевые метрики, по которым мы меряем свою эффективность, — количество коллаборативных досок и коллаборативных сессий, которые случаются в продукте.

Мы называем себя платформой, потому что уже вышли за рамки просто продукта: у нас есть открытый API, marketplace, кабинет разработчика, поэтому любая компания может расширять продукт под себя.

Наша целевая аудитория — продуктовые команды, которые работают из одного или разных офисов. Чаще всего Miro используют для проведение воркшопов, стратегических сессий, мозговых штурмов, agile-практик (планинги, ретроспективы).



Я руковожу разработкой в Miro. Я вырос в Перми и продолжаю здесь жить. Компания исторически появилась в Перми, отсюда родом наши основатели. Большая часть нашего отдела разработки находится сейчас здесь, а в 2019 году мы запустили и активно развиваем второй инженерный офис — в Амстердаме.

Раньше я работал в заказной разработке: начинал с построения аналитических хранилищ данных в качестве разработчика, потом проектировал их, а затем руководил большими проектами. В 2016 году присоединился к Miro, когда в компании работало 30 человек. С тех пор мы сильно выросли: сейчас у нас пять офисов, 400 человек, из них 140 инженеров.

image

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

Смена названия


О ребрендинге мы задумывались ещё в 2015 году, но сделали его в итоге в 2018. Наше прежнее название RealtimeBoard длинное и сложное. В нём часто допускали ошибки, сокращали до RTB или, что самое плохое, вообще его забывали. Кроме того, оно неэмоциональное, за ним нет истории. Мы хотели сделать новое название коротким, ёмким, говорящим, запоминающимся.

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


К новому названию быстро привыкли и мы, и пользователи. Мы быстро растём, поэтому несколько миллионов новых пользователей даже не знают о том, что мы назывались иначе. Приятным бонусом ребрендинга стали награды от European Design Awards за айдентику, которую мы разработали в рамках ребрендинга совместно с европейским агентством Vruchtvlees.

Как устроена продуктовая разработка в Miro


Вся команда продуктовой разработки из 170 человек находится в Перми и Амстердаме: инженеры, продакты, продуктовые дизайнеры, скрам-мастера.

Мне раньше было сложно представить, что так много человек может работать над одним продуктом. Но сегодня я знаю, что в Uber, Slack и Atlassian над одним продуктом работают тысячи инженеров. Мы продолжаем расти и понимаем, что нас сейчас явно недостаточно, и следующая целевая точка в моей голове — 300 человек в разработке, а потом мы продолжим расти дальше. Это не просто число из головы. У нас есть стратегическое планирование, мы понимаем, где мы хотим быть через два года, через пять лет и что нам для этого нужно сделать.

С точки зрения оргструктуры есть гильдии: фронтенд, бэкенд, QA и так далее. Для работы над проектами они объединяются в кросс-функциональные команды.

Команды распределяются по ключевым направлениям:

  • Горизонтальный продукт — основная функциональность продукта, которую видят все пользователи: стикеры, текст, шейпы, фреймы и т.д.
  • Системное направление — отвечает за core-платформу и инфраструктуру.
  • Growth — всё про рост числа пользователей: активация, вовлечение, возврат, монетизация.
  • Enterprise — доработка продукта для крупных компаний, у которых много специфических требований. Во-первых, тысячи и десятки тысяч их сотрудников пользуются Miro, а это значит что для их аккаунтов нужны разные права доступа и удобные инструменты управления ими. Во-вторых, есть международные стандарты качества и безопасности для SaaS-продуктов, которым мы должны соответствовать. Мы не делаем кастомизацию под конкретного пользователя, а выбираем, что необходимо сделать в соответствии со стандартами и требованиями большинства крупных пользователей.
  • Платформа — мы запустили открытую бету в 2019 году. Уже есть открытый API, кабинет разработчика, marketplace, — всё это нужно поддерживать и развивать, давать больше возможностей внешним разработчикам, которые хотят создавать для себя и других дополнительную ценность на базе нашего продукта.
  • Основные юзкейсы продукта — новое направление, которое мы активно масштабируем. Пользователи приходят в продукт, чтобы решить конкретную задачу, но большинство способов, с помощью которых они её решают в Miro, можно объединить в несколько групп: Meetings & Workshops, Ideation & Brainstorming, Research & Design, Agile Workflows, Strategy & Planning, Mapping & Diagramming.

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

Рабочее окружение


Основной софт инженеров: IntelliJ Idea, Jira, Slack, Zoom, Miro, Confluence. Большинство сотрудников работают на MacBook, большинство инженеров — на MacBook Pro, некоторым покупаем более мощные машины при необходимости.

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

Стек, монолит


Фронт у нас на Typescript, React и AngularJS. Бэкенд — Java. Базы данных — Redis, Postgres, для кластерного взаимодействия — Hazelcast и ActiveMQ. Хостимся в Amazon, в одном дата-центре. В продакшене порядка 400 серверов. Application servers, которые обрабатывают доски пользователей, бывает до 100, всё автоматически оркестрируется.

Используем стек от Atlassian: Jira, Bitbucket, Bamboo и собственные скрипты, которые прикручены к Bamboo и позволяют всё раскатывать на сервера. Пока все релизы — один большой релиз на фронт и один большой на бэк. Сейчас думаем, как сделать, чтобы этих релизов было больше.

Наше основное приложение – модульный монолит: есть модуль, который отвечает за API, за доску, за сервисную функцию. Деплоится монолит модулями на нужные сервера, а не одним большим куском на все сервера подряд, то есть сервера у нас тоже с разными ролями.

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

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

Релизы


Сама сборка занимает 15-20 минут, включая выполнение юнит-тестов. End-to-end тесты могут выполняться до 40 минут. Весь процесс занимает полтора-два часа, чтобы довести мастер до релиза. Это долго, нам ещё есть над чем здесь поработать.

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

Выбор технологий и их эволюция


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

Маленькие компании, которые только начинают и ищут product market fit, бегут быстро, быстро собирают MVP и быстро их выбрасывают. Для них важнее найти рынок, а не создать сложные технические решения. Но когда рынок найден — технические решения выходят на первый план, потому что позволяют создать запас прочности для роста и безопасности.

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

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

Больших смен технологий у нас было несколько, на фронте и на бэкенде. Приведу несколько примеров.

Flash > Canvas


До 2015 года весь фронт был на Flash, потом Flash начал умирать и мы перешли на HTML и Canvas. Смена стека хорошо сказалась на производительности и удобстве продукта, привела к заметному росту аудитории. Переход занял примерно год, это был большой и сложный проект. Статья про детали этого проекта.

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

Angular > React


Последние пару лет мы постепенно переходим с Angular JS на React. Основные причины:

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

Сервера и базы данных


В 2015 году мы перехали с арендуемых серверов Hetzner на хостинг в Amazon. Больше года идёт проект по переносу основной базы данных с Redis на PostgreSQL. У нас есть статьи об этом: проектное управление миграцией данных, создание отказоустойчивого кластера.

image

Наш кейс осложняется тем, что с Key Value хранилища мы переезжаем на SQL базу. Рефакторинга много. Важно делать всё так, чтобы приложение не останавливалось. Это как поменять колесо у едущей машины, потому что база данных – фундамент, на котором стоит приложение. Непосредственно для контента досок мы реально делали всё без maintenance. Да, процесс перехода затянулся по времени, зато пользователи ничего не заметили, продукт работал.

Стабильность продукта — ключевой фокус. Пользователи хранят много контента в Miro. Соответственно, если пользователь запланировал сессию или встречу, подготовил для неё доску с контентом, а продукт в этот момент недоступен — это провал, контент использовать невозможно. Если условный Zoom можно быстро заменить на Hangouts, то контент быстро заменить нельзя. Поэтому одна из наших ключевых задач — чтобы контент для пользователей был всегда доступен.

Java


Java очень сильно помогает нам в плане производительности и ресурсов разработчиков, которые мы можем найти. Знаю, что Booking переходит с Pearl на Java, потому что они устали переучивать своих инженеров.

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

Эволюция тестирования


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

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

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

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

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

image

Подробное описание всех этапов нашего QA-процесса.

Рост нагрузки и рефакторинг


В связи с массовым переходом на удалённую работу в 2020 году у нас резко выросло количество пользователей и наш годовой запас прочности инфраструктуры и приложения закончился за несколько недель. В первую же неделю резкого роста нагрузки мы остановили всю продуктовую разработку и переориентировали команды на работу над отказоустойчивостью и производительностью.

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

Мы много рефакторим, чтобы пользователь быстрее получал отклик и контент с доски, а потом уже весь основной функционал – скрипты, интерфейс – потихонечку подъезжает. Для этого перешли на деление кода, на “ленивые” модули. Благодаря этому ускорились примерно на треть, а в ближайший месяц планируем ещё в два раза ускориться с точки зрения загрузки.

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

Процессы в разработке


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


Любая задача начинается с подготовки продуктового решения. Продуктовое решение — это ответ на вопрос “Что мы будем делать?”. Продакт-менеджер на основе продуктовой стратегии и OKRs проводит большое исследование, чтобы выяснить, чего сейчас не хватает пользователям в нашем продукте. На основе исследования продакт описывает решение. Продуктовая гильдия обсуждает решение, дорабатывает при необходимости.

На базе продуктового решения формируется техническое решение, которое отвечает на вопрос “Как мы будем это делать?”. Его разрабатывают инженеры команды, которая будет реализовывать функционал. Техническое решение проходит несколько процессов review:

  • с командами, с которыми есть пересечения в функциональности;
  • security review по компонентам, которые мы будем затрагивать в архитектуре;
  • как мы будем деплоить результат.

После начинается непосредственно разработка. Важно, чтобы code review не тормозил разработку, поэтому недавно вместо обязательного получения двух code review мы внедрили персональную ответственность на уровне компонентов. Теперь на уровне кода мы всегда знаем, кто отвечает за этот кусок, что сильно облегчает коммуникацию при разработке. Соответственно, как только ты внёс изменения в код, автоматически назначается reviewer, владелец этого кода. Если код твой, то review делает участник твоей команды.

Зачем мы ввели персональную ответственность? Раньше было несколько человек, “старичков”, которые знали, как работает весь продукт и могли проверить любой кусок кода. Но по мере роста продукта возможностей этих людей стало не хватать, они уже не могли знать про всё, что происходит в разработке. Процесс code review начал тормозить остальные процесса, было непонятно, к кому идти на code review. Тогда мы начали нести всю необходимую компетенцию по конкретным блокам продукта в команду, которая работает над ними. Так команды смогли проводить code review самостоятельно. В своё время это помогло нам сильно ускориться.

Performance Review


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

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

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



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

К сожалению, люди часто не успевают расти так же быстро, как компания — это нормально. Мы готовы много инвестировать в обучение, потому что рост компании напрямую зависит от роста сотрудников. У нас есть компенсация внешних курсов, есть рекомендуемые курсы и менторы. Обязательное обучение компенсируем на 100% (например, английский язык), остальное стараемся компенсировать 50 на 50, чтобы была взаимная ответственность за результаты.

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

Как устроен найм инженеров


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

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

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

После скрининга — тестовое задание, затем техническое интервью, которое включает в себя в том числе обсуждение тестового задания. Затем — встреча с командой, в которой будет работать кандидат. Для нас это обязательный этап, потому что он помогает в первую очередь понять culture fit кандидата, а не его технические навыки.

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

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

Джуниор-позиции


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

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

Высокие требования при найме


Ходит легенда, что к нам очень сложно устроиться на работу из-за очень высоких требований. Это не совсем так.

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

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

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