Senior. Туда и обратно: что я сначала не понимал в своей карьере, а потом как понял

в 6:17, , рубрики: data science, machine learning, python, джун, карьера, Карьера в IT-индустрии, карьера ИТ-специалиста, лаборатория касперского, развитие, развитие навыков, развитие программиста, сеньор, советы
За шесть лет в IT, и в команде Machine Learning Technologу Research «Лаборатории Касперского» в частности, я прошел путь от стажера до Data Science Team Lead. Шел честно :) И на каждой ступени проходил через разные нюансы, о которых и хочу рассказать в этой статье. Полагаю, мой опыт будет полезен как начинающим коллегам, чтобы увидеть для себя недостающие аспекты профессионального роста, так и более опытным специалистам, чтобы отрефлексировать свой опыт и задуматься о том, что помогло им в карьере. Кстати, было бы здорово послушать и о ваших аспектах роста в комментариях :)

Senior. Туда и обратно: что я сначала не понимал в своей карьере, а потом как понял - 1

Кто я и как буду рассказывать о пути

Начну с краткого рассказа о себе.

@dataclass
class Speaker:
    name: str = "Дмитрий Аникин"
    job_title: str = "Data Science Team Lead"
    employer: str = "Kaspersky"
    skill_years: int = 6
    tg_username: str = "uncle_dijkstra"
    email: str = "dmitry.anikin@kaspersky.com" 

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

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

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

Disclaimer: все изложенное ниже — мой личный опыт, и я не претендую на истину в последней инстанции. Также не забывайте, что я смотрю на все это через призму анализа данных, поскольку в команде Data Science есть свои нюансы и особенности. Ну а если вы не согласны, велкам в комментарии — буду только рад :)

Путь «Туда»

Шаг 1. Intern -> Junior. Трудолюбие и отвага.

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

Senior. Туда и обратно: что я сначала не понимал в своей карьере, а потом как понял - 2

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

Что есть в действительности:

  • Человек, который приходит на позицию стажера, имеет базовые навыки программирования, но не разработки, потому что в университете не учат разрабатывать. Там учат языку программирования — синтаксису, алгоритмам и так далее, но не учат, как писать код так, чтобы его можно было разделить с другими людьми и легко поддерживать. Поэтому, забегая вперед, хочу обратиться к нынешним сеньорам и тимлидам: если у вас есть такая возможность, подключайте своих интернов к код-ревью или ревью гипотез (если это анализ данных), чтобы они могли повышать свою «насмотренность».
  • После университета, как правило, у человека есть гигантская мотивация. У кого-то она сводится к зарабатыванию денег; в моем же случае это был интерес к изучению моделей машинного обучения в реальных задачах — так или иначе это сильно помогает. У героя есть огромное желание наблюдать за тем, как более опытные коллеги взаимодействуют между собой и принимают решения. И все это, опять же, повышает «насмотренность».
  • В университете дают знания, но не дают понимания, как их применить к бизнесу. Поэтому на начальных этапах у меня был целый список заметок о точках соприкосновения с бизнесом, который я постоянно пополнял. Мне всегда было интересно понять: если мы здесь не можем использовать какой-либо расчет метрик, а применяем некоторый хак — то почему и как мы натягиваем эту академическую сову на практический глобус.

А вот привычные ожидания с противоположной стороны:

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

На той самой культуре я еще остановлюсь подробнее в самом конце, ну а сейчас нам пора дальше.

Шаг 2. Junior -> Middle. Ответственность.

На шаге «джун — мидл» мне хочется подсветить девиз «ответственность».

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

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

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

И еще несколько моментов про ответственность:

  • Мидл — это самостоятельная боевая единица. Он может решать задачи целиком и самостоятельно инициировать процессы, которые требуются для решения: например, декомпозировать какие-либо этапы; взаимодействовать с коллегами из других команд, понимая, когда следует их привлекать, и так далее.
  • Помнить мелочи. Это очень классная джедайская техника, которая хорошо сказывается на репутации. Например, вы не забываете присылать минутки после встречи; проводите ревью тогда, когда попросили коллеги (потому что вы понимаете, что иначе застопорите их работу); вовремя готовите отчет… Все это сказывается не только на эффективности команды, но и на вашем реноме.
  • Чем больше грейд, тем выше ответственность. На какой позиции вы бы ни находились, однажды придет время донести до менеджера количество взятой вами на себя ответственности, чтобы это послужило триггером для дальнейшего карьерного роста. Как именно это сделать — вопрос индивидуальный, зависящий от компании и контекста; тут прямых рекомендаций давать не берусь. Скажу только, что в «Лаборатории Касперского» существует устоявшийся и прозрачный пайплайн повышения — промоушен-комитет. Если у вас в компании он тоже есть, то вы знаете, что делать; ну а если вдруг нет или вас в нем что-то не устраивает — добро пожаловать к нам :)

Шаг 3. Middle -> Senior. Предлагайте и доводите до конца.

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

Можно читать много статей о Data Science, рассматривать State-of-the-Art модели, но все это имеет нулевую ценность, если это никак не реализовано в продакшене и не приносит пользу бизнесу. Поэтому здесь важно брать ответственность за свои идеи и драйвить их — добиваясь этим результата, который приносит реальную пользу бизнесу.

Senior. Туда и обратно: что я сначала не понимал в своей карьере, а потом как понял - 3

Вот что еще важно для сеньора:

  • Не делать лишнего. Умение сказать «нет» — это тонкое искусство. Да, заказчикам часто виднее, что именно им нужно, но и они иногда заблуждаются. В моей практике был такой кейс: коллегам казалось, что на ручное написание отчетов и заполнение карточек по инцидентам на хостах клиентов тратится слишком много времени, и они попросили прикрутить туда модель, которая будет сама собирать нужные данные и заполнять формы. Но оказалось, что, во-первых, времени на заполнение тратится не так уж и много, а во-вторых, пытаться сделать какую-то оптимизацию с помощью машинного обучения абсолютно нерационально, потому что боттлнек находится вовсе не на этапе заполнения карточки. Сэкономили месяцы потенциальной работы :)
  • Негативный результат — тоже результат, если он правильно отрефлексирован. Тут все очевидно: выводы и преобразование их в дальнейшее полезное value позволяют избежать аналогичных ошибок в будущем и даже открыть в себе дар «провидца» — сможете в схожих ситуациях уже на ранних стадиях замечать возможные проблемы, нюансы, риски и так далее.
  • Управление рисками. Риск-менеджмент можно применить практически к каждому проекту — придумать наиболее вероятные сценарии и описать способы реагирования на них. Например, если вы мониторите модель с помощью метрик, существует риск, что эти метрики выйдут за рамки. Если это произойдет ночью, кому девопсы должны об этом сообщить? Им от вас нужен скрипт, по которому действовать.
  • Чужие болевые точки — это точки вашего роста. Нужно обращать внимание на вещи, которые вызывают «боль» у заказчиков; возможно, даже в тех местах, где они сами не до конца понимают, что и почему «болит». Это можно заметить, например, благодаря регулярному общению с другими командами. Допустим, если вы каждый раз забираете у коллег данные по проекту с какой-то оформленной проблемой, возможно, у них что-то не то с конвейерами данных и системами их хранения. В идеале не просто заострить на этом их внимание — а сразу прийти с какими-то вариантами решения.
  • И еще немного про умение видеть боли и риски: важно доводить проблемы до руководства с опциями их решения. Например, если видим, что хранилище отвечает долго, можно прийти и просто пожаловаться, что данные грузятся долго. А можно сразу предложить вариант ходить за данными по ночам (и меньше нагружать сервис) или выделить подмножество кейсов, по которым стоит выгружать данные заранее. А еще есть вариант сделать реплику и поднять отдельное хранилище, чтобы ходить в него за данными. Способность предложить варианты «куда копать» выгодно выделяет будущего сеньора :)

Путь «Обратно».

А теперь вернемся с высоты сеньора к менее опытным позициям и поговорим о тех аспектах, которые я осознал далеко не сразу. А было бы классно, если бы кто-то подсветил их еще на пути «Туда»…

Шаг 1. Senior -> Middle. Решайте проблемы, а не задачи.

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

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

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

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

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

Словом, не забывайте, что есть задачи, а есть проблемы. Проблемы порождают задачи, но решаете-то вы все-таки проблемы…

Шаг 2. Middle -> Junior. Вопросы — это ответы.

На пути от джуна к мидлу мне было бы полезно знать, что вопросы — это на самом деле ответы. Да-да :)

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

Про вопросы нужно помнить некоторые моменты.

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

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

  • Вопросы надо задавать не только другим, но и себе. Прежде чем приступать к чему бы то ни было, можно спросить себя, а какие есть риски; почему мы используем именно это решение, а не какое-то другое; нужно ли делать именно эту задачу (или поискать что-то более фундаментальное). Так и развивается здоровое критическое мышление.
  • Умение задать правильный вопрос бывает очень кстати. Мне понравился пример с Data Fest. В одной из секций был вопрос: «Если бы к вам пришли и сказали, что нужны дашборды, что бы вы спросили?» Джун спросил бы, какие нужны дашборды и где мы будем их хостить. А вот сеньор спросил бы, кто будет на эти дашборды смотреть и как часто. Вот это вопрос в самый корень — возможно, кто-то пытается сделать эти дашборды, чтобы сместить работу на другую команду, которая ближе взаимодействует с данными (а той команде это не нужно, хе-хе :)).
  • Вопросами мы собираем информацию, а не подтверждаем свою правоту. Я и за собой раньше такое наблюдал: приходишь к коллегам и спрашиваешь не «Подскажите, как лучше забрать данные», а «Вот я забираю данные таким-то образом — это же правильно?» Последней формулировкой мы как бы пытаемся взять то, к чему уже предрасположены, и навязать это другому человеку. Но ответ на вопрос имеет большую ценность, когда мы получаем полный спектр вариантов, а не урезаем их.

В этом контексте хочу порекомендовать книжку «Спроси маму» — о том, как задавать вопросы в бизнесе. Книга учит нескольким полезным вещам:

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

Шаг 3. Junior -> Intern. Скепсис.

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

Senior. Туда и обратно: что я сначала не понимал в своей карьере, а потом как понял - 4

  • Не бойтесь предлагать свои идеи и мнения — вы такой же участник команды, как и все остальные. Часто более молодые ребята лучше шарят в современных фреймворках. Например, в сегменте машинного обучения с помощью новых коллег вещи, которые раньше надо было писать несколькими строчками кода, получилось сделать эффективнее. Еще раз: не бойтесь показаться глупым :)
  • Не сотворите себе кумиров :) Взятое на веру мнение старшего коллеги может лишить вас части информации и возможностей, обрубить пути решения. Например, в Data Science часто можно встретить вопрос, устойчив ли ROC AUC (это такая метрика) к дисбалансу класса. Если начать копать, выяснится, что мнения разнятся. Кто-то говорит, что устойчив, а кто-то — что нет. При этом противоположные мнения могут исходить от довольно известных в отрасли ребят. Остается вопрос — кому верить?

    Так вот, хорошо иметь людей, на которых хочется равняться. Но в то же время надо задавать вопросы, быть критичным и понимать, что есть нюансы, в которых они также могут заблуждаться. И да, ROC AUC не чувствителен к дисбалансу, верите? :)

  • Используйте инструменты осмысленно. Best Practice, State-of-the-Art модели и тому подобные не всегда уместны. Они на слуху, особенно в LLM: Telegram-каналы кишат сообщениями о новых подходах. Но не нужно сразу пытаться их применять: есть ограничения по ресурсам, срокам и стеку, который используют смежные команды. Новые инструменты — это классно, но стоит использовать их осмысленно.

Культура в команде

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

Чтобы все это работало, команда должна одинаково смотреть на многие вопросы, в частности на используемые фреймворки и алгоритмы. А следовательно, надо формировать определенную культуру в команде. Но это не всегда легко; иногда придется преодолеть некоторые слои сопротивления. Как правило, мы все тугие на перемены, поэтому важно объяснить, в чем ценность предлагаемых процессов.

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

Допустим, есть джун, который пишет код, понятный ему самому. Он в принципе даже использует правильный нейминг, но делает функции по 50 строк кода. Другим в таких функциях разобраться сложно. Можно объяснить на словах, что функции надо дробить на части (написать ему об этом в код-ревью). Он это прочитает и, возможно, даже исправит, подумав про себя, что это просто «дед ворчит»; ему-то код понятен! Но вряд ли это закрепится в виде практики и войдет в культуру команды. Другой подход — предложить ему сниппет нарочито плохо написанного кода и попросить рассказать, что в нем происходит. Когда он будет долго читать код и в итоге не въедет, что там происходит, он прочувствует всю эту проблему, что называется, на своей шкуре. И тогда-то станет понятно, что «ворчащий дед» имел в виду на код-ревью…

Или, напротив, можно «замедлить» внедрение каких-то новых практик, чтобы они прижились в команде. Например, вы хотите проводить ревью гипотез, а писать многоступенчатые отчеты сложно и долго. Начните с простого, с baby step: просто созванивайтесь с коллегой, когда заводите задачу, и обсуждайте словами, что хотите сделать. Возможно, вам идея кажется настолько крутой, что вы не замечаете моментов, которые ограничивают ее применение…

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

Например, мы с командой сейчас читаем Fluent Python. Делаем это очень лениво — по одной главе за две недели, так что, по моим расчетам, мы должны закончить книгу где-то за девять месяцев. Да, мы потратим на это много времени, но зато в код-ревью можно все чаще видеть моменты, которые мы подсветили именно в ходе дискуссий в книжном клубе. Так что здесь тоже работают терпение и baby steps.

Вместо заключения

  • Цели есть цели, а путь есть путь. И если первые у разных людей с высокой долей вероятности могут совпадать, то путь у каждого почти наверняка свой. Я подсветил свой личный опыт, который отрефлексировал и посчитал полезным. Я не рассчитываю, что найдутся люди, которые подпишутся от и до под этой статьей. Но будет здорово, если вы найдете для себя что-то полезное, выделите свои собственные аспекты. И принесете их в комментарии.
  • Услышать не равно понять. Все приходит со временем и опытом. У вас всегда будет возможность вернуться к этой статье по мере накопления опыта. В какой-то момент у вас может срезонировать то, что не срезонировало ранее — и вы вспомните мои рассуждения. И я буду рад, если мои мысли помогут вам быстрее отрефлексировать опыт.
  • Более опытным ребятам следует создавать культуру, которую они ожидают от менее опытных. Культура в команде — классная вещь, которую нужно внедрять и поддерживать. Но если тот самый опытный — это вы, то вам и придется брать ответственность и двигать эту самую культуру «в массы».

И финальное. Если вам все это откликнулось, приходите к нам в «Лабораторию Касперского». От себя, как питониста, подсвечу вакансии, связанные с Python в продуктах, с которыми мы в основном работаем, и, конечно, вакансии в нашем департаменте Data Science & Big Data — будем расти вместе :)

Автор: uncle_dijkstra

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js