Примечание: пост был доработан после публикации для большей ясности, с учётом отзывов читателей.

«Как ты находишь проблемы, которые стоит решать?» — спросил недавно старший инженер, которому автор помогает как ментор. Тот пытается перейти на позицию staff engineer и осознал, что эта роль подразумевает не только выполнение поставленных задач, но и участие в определении того, что вообще должны делать команда и организация.

Кто-то посоветовал ему выделять время в календаре, чтобы думать о «большой картине». Он попробовал, но не нашёл это продуктивным, и спросил, есть ли альтернативы.

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

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

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

Впитывать проблемы, а не запросы

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

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

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

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

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

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

Дать проблемам накопиться

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

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

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

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

Найти общую форму

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

Хороший пример — Perfetto, инструмент для отладки производительности, над которым работает автор. Он отображает записи системной активности на временной шкале, состоящей из строк — «треков». В течение пары лет команды раз за разом просили небольшие, точечные доработки интерфейса. Одна команда хотела команду для закрепления избранных треков вверху экрана; следующая просила то же самое, но для совершенно другого набора треков. Кто-то хотел, чтобы Perfetto открывался сразу с приближением на нужный участок записи, или показывал кастомную агрегацию под их конкретные нужды. Некоторые команды перестали ждать и сами построили сложные обходные решения на букмарклетах.1

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

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

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

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

Проверять идею на прочность до того, как строить

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

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

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

Когда идея выдерживает проверку, необязательно самому её реализовывать. Это может сделать сам автор, кто-то другой из команды, либо это может изменить фокус всей организации. Найти и правильно сформулировать проблему — уже само по себе может иметь эффект, даже если реализация остаётся за кем-то другим.

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

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

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

Решение полезных проблем помогает найти следующую

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

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

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

Это отличается от представления, что стать staff engineer — значит заменить техническую работу встречами и координацией. Разговоры здесь — не конечный результат, а входные данные для того, что в итоге создаётся.

Заключение

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