Публикации и ответы на комментарии в блогах JetBrains не выходят на русском языке с 2022 года.
Приносим извинения за неудобства.
Программировать во что бы то ни стало
Алина Комиссарова, координатор образовательных проектов JetBrains в Новосибирске, поговорила со своим коллегой, тоже сибиряком, Тагиром Валеевым, техлидом команды Java в проекте IntelliJ IDEA, о том, как живет и работает человек, у которого есть нескончаемый drive to develop, большое желание выступать и делиться своими знаниями, а еще изучать японский — тоже на пользу дела.
Тагир Валеев, техлид команды Java в проекте IntelliJ IDEA в JetBrains
Давай начнем с самого начала и даже чуть-чуть раньше. Расскажи, где ты работал до JetBrains, чем занимался, было ли это как-то связано с твоей кандидатской диссертацией?
Мой трудовой путь начался в 2004 году, когда я стал программировать за деньги, а не за идею. Я заканчивал магистратуру, учился на физфаке НГУ, на отделении физико-технической информатики. Предполагалось, что счастливые выпускники должны идти автоматизировать какие-нибудь коллайдеры, детекторы элементарных частиц. Это все действительно делают мои одногруппники, которые в ЦЕРНе работают. Но я шел на факультет все-таки за программированием, а не за физикой. Товарищ, с которым мы вместе играли в бридж, пригласил меня в компанию, в которой они занимались биоинформатикой. Им нужны были программисты, которые могли что-то на плюсах пилить, и я пошел к ним. Компания базировалась в Институте систем информатики. Я там же поступил в аспирантуру и стал заниматься проектом, основная задача которого — построение модели генной регуляции.
Расскажи, что это за задача?
Известно, что у человека порядка 20 тысяч генов. И они, во-первых, одинаковы в каждой клетке, а во-вторых, они одинаковы на протяжении всей жизни. Но понятно, что глаз отличается от печенки, больная клетка отличается от здоровой и т. д. Основная идея в том, что эти гены по-разному работают, то есть какие-то включаются, какие-то выключаются. Механизм включения-выключения — это генная регуляция, то есть у генов есть некоторые сигнатуры в промоторном регионе, такие сайты связывания. Можно считать, это как сигнатура файла. И если в данной клетке собирается определенный набор белков, они как бы мэтчатся, поставляют эту сигнатуру. И если сопоставление белка с сигнатурой проходит успешно, то соответственно ген включается и начинает работать. Это не дискретно, по типу «да и нет». Ген может плохо работать, то есть мало производить за единицу времени, или наоборот, с него может белок строгаться вообще с огромной скоростью. Из-за этого в разных клетках либо в разных жизненных ситуациях происходят разные вещи.
Сейчас этот процесс гораздо больше изучен, и уже появились первые экспериментальные платформы. Например, можно закинуть кусок ткани в специальный прибор и узнать, каких генов много в ней работает, а каких мало. Буквально незадолго до этого был опубликован полный геном человека. Можно было для каждого гена смотреть, что там у него в промоторе написано, и пытаться понять, как это вообще взаимосвязано с тем, что ген включился или выключился. На основании этого строили более высокоуровневые модели и пытались их оптимизировать.
Я использовал, как ни странно, генетический алгоритм для того, чтобы решить генетическую задачку, и была программка на плюсах, которая умела использовать экспериментальные данные, типа последовательности генов, наличия на промоторах каких-то определенных участков. Она пыталась предсказать, какая в этой клетке, например, генная ситуация, какие конкретно белки, транскрипционные факторы влияют на то, что там происходит. В том числе этому была посвящена моя кандидатская диссертация, которую я защитил в 2006.
Быстро! За два года, получается.
Да, я решил не тянуть с этим делом. Думаю, это зависело не только от меня, но и от института. Есть институты, где будь ты хоть трижды гений, десять лет не защитишься. А у нас многие за два-три года аспирантуры защищались.
Потом это дело вылилось в целую платформу, в которую можно было сразу загружать данные, фильтровать списки генов, сортировать их, разделять по группам. Туда же встроили анализ, который я защищал на диссертации, и еще кучу других алгоритмов. В принципе получилась прикольная система. Где-то в 2008-2009 годах у компании начались некоторые сложности, наступили кризисные времена. Но при Конструкторско-технологическом институте вычислительной техники была лаборатория биоинформатики. Там работали другие люди, но тоже мне знакомые — меня туда аккуратно передали. Они делали другую штуку — уже на Java. Так я познакомился с языком Java и стал активно программировать на нем с 2009 года.
А когда ты заинтересовался статическим анализом? Я так понимаю, у тебя еще до работы в JetBrains были свои проекты в этой области.
Это произошло тоже довольно случайно. Мне всегда было интересно рассматривать программу как предмет исследования, а не просто как инструмент, который выполнил операцию и ладно. В какой-то момент я стал заботиться о качестве нашего кода. Узнал, что есть статические анализаторы и, в частности, FindBugs для Java. Тогда он еще не совсем морально устарел. Плюс восьмая Java еще не вышла (это был 2013 год). Я его поставил, проанализировал наш проект, который уже был довольно крупный — 10 тысяч классов — и нашел много интересных вещей, что называется facepalm. Тогда мы писали в Eclipse, а в нем встроенный статический анализ был слабоват: помимо обязательных предупреждений компиляции не очень много чего сверху было. Поэтому я очень удивился, что можно вот так взять и найти в коде ошибки, и начал исправлять то, что FindBugs находил в нашем коде.
В какой-то момент в работе FindBugs начали обнаруживаться проблемы. Он чего-то не видел либо репортил то, что не надо. Я нашел, где на SourceForge тогда еще был проект. Стал предлагать: давайте вот это поправим, давайте то. Сперва я просто сообщал о багах, а потом патчи стал кидать. Но тот проект двигался в сторону своего заката, его создатель Билл Пью уже стал отходить от дел.
А я стал контрибьютить сперва по чуть-чуть, потом уже начал какие-то серьезные штуки делать. Например, сделал анализ целочисленных диапазонов. В FindBugs вообще такого не было. Он действительно находит интересные баги. Например, если ты проверишь икс больше нуля, а потом внутри этой ветки икс сравнишь с минус один, то он тебе скажет, что здесь этого не может быть, потому что мы уже знаем, что икс больше нуля. Это было уже солидное улучшение. Потом я стал понимать, что FindBugs — дорога в никуда. Дело даже не в том, что авторы теряют к нему интерес, а в том, что у него совершенно невменяемая архитектура с кучей глобальных переменных. Из-за этого его нормально не сделаешь многопоточным, например.
У тебя появился свой форк?
У меня даже не форк появился. Я просто в какой-то момент подумал, что мог бы написать свой статический анализатор. FindBugs анализирует байт-код, он не анализирует исходники. При этом FindBugs очень низкоуровневый, то есть он обычно работает с отдельными инструкциями байт-кода, и, если ты пытаешься сделать что-то нетривиальное, это адище. У тебя нет глобальной модели кода, а есть просто цепочка инструкций. Я сперва пытался сам сделать такую модель, но понял, что это задача не на пять минут и стал искать что-то готовое. Было два интересных движка: джетбрейновский Fernflower и Procyon.
Я выбрал Procyon. В основном потому, что JetBrains не сильно заботилась, чтобы Fernflower был как отдельный продукт. Не знаю, как сейчас, но тогда не было даже Maven-артефактов. Пришлось бы его еще собирать дополнительно.
А Procyon нормальный, его можно было использовать как библиотеку. Внутри он строил очень высокоуровневую модель кода по байт-коду, в которой уже можно было структуру видеть, вложенность циклов, условий и т. д. Еще он умел по возможности восстанавливать generic-типы по байт-коду после erasure, и у него очень неплохо это выходило. На этом уровне мне было вполне приятно писать статический анализатор. Я сделал свой, назвал его HuntBugs и какое-то время довольно активно его пилил. У меня было больше ста разных типов проверок. Я пытался повторить большую часть функциональности FindBugs и добавить что-то свое. В FindBugs на тот момент было около 400 инспекций (диагностик). Я, наверное, процентов 30 успел покрыть, пока у меня был запал.
А какова его судьба в итоге?
Он полностью заброшен, но сыграл важную роль в моем трудоустройстве в JetBrains. Я его как раз писал перед тем, как у JetBrains открылся офис в Новосибирске. Естественно, когда компания объявила, что собирается провести JetBrains Night и там будут собеседования, я решил, что это знак. Я смогу заниматься тем, что мне интересно, но при этом за деньги, а не за просто так.
Я сделал еще такой ход конем: взял IntelliJ IDEA Community, там самый большой JAR: в lib/idea.jar мегабайт 100, наверное, кода — и прогнал его через HuntBugs. Понятно, он много чего выдал, где-то был мусор, но были интересные штуки, корявый странный непонятный код. Я про это все написал статью на Хабре: вот, смотрите, у меня есть клевый анализатор HuntBugs, чтобы вы поняли, что это не поделка, а более-менее серьезная вещь. Я проверил IntelliJ IDEA Community Edition, у которой вообще-то свой довольно сильный статический анализ, то есть предполагалось, что ее авторы, наверное, следят за качеством кода. Но тем не менее мне что-то удалось найти.
То есть ты написал статью уже зная, что офис открывают?
По-моему, это было до моего собеседования. Но я уже на него записался. Это был сознательный ход, чтобы люди обо мне узнали со стороны.
У тебя на тот момент помимо своего статического анализатора был довольно большой рейтинг на Stack Overflow, статьи на Хабре, Twitter. Это тебе тоже как-то помогло при устройстве на работу, или все-таки та статья сыграла наибольшую роль?
Была параллельно еще история со стримами (Java Stream API), которые появились в Java 8. Что-то я на них запал. Сначала был энтузиазм в духе «ух-ты, как здорово и легко можно сделать сложные вещи», а потом я начал понимать, что на стримах каких-то вещей сделать нельзя. Я начал пилить свою библиотеку StreamEx, выложил ее на GitHub и написал на Хабре вводную статью, где показал, что там можно делать.
Но у Хабра довольно ограниченная аудитория и в первую очередь русскоязычная. Я стал думать, как еще можно пропиарить библиотеку, и мне пришел в голову Stack Overflow. Я стал смотреть, что вообще люди спрашивают про стримы. Во-первых, иногда из каких-то вопросов могла родиться новая фича StreamEx, во-вторых, я мог человеку ответить: «Стандартным Stream API этого сделать нельзя, либо будет очень некрасиво. Но если вы возьмете мою библиотеку, которая, кстати, бесплатная и опенсорсная, то вы очень красиво и легко решите свою задачу». По правилам Stack Overflow это разрешено.
Нехорошо, если человек прямо в вопросе пишет, мол, я не хочу использовать third-party solution, но если он так не пишет, то ему можно посоветовать. И в какой-то момент меня это затянуло. Это стало больше, чем просто поддержка StreamEx. У Stack Overflow очень хорошо построена геймификация: рейтинги, бейджи, графики. В итоге я примерно год отвечал довольно активно. В основном про стримы, но иногда и какие-то смежные темы затрагивал. Там же я увидел людей из Oracle: Брайан Гетц, Стюарт Маркс иногда отвечали. Я нашел какой-то баг прямо в стримах и зарепортил его в виде вопроса на Stack Overflow.
Они тебе ответили?
Да, Брайaн отреагировал. Они завели тикет в трекере OpenJDK и исправили в каком-то обновлении Java 8. Но я все же понял, что Stack Overflow не лучший способ для репорта багов: там далеко не всегда достучишься до людей. Лучше в мейлинг-листе общаться. Раньше я вообще не знал, как устроено развитие Java и что многие вещи происходят вполне открыто, в мейлинг-листах. Тогда я подписался и стал участвовать в обсуждениях, а потом потихонечку и контрибьютить. Я стал контрибьютором, потом автором и коммитером в OpenJDK.
Когда я устраивался в JetBrains, то указал, что у меня есть вот этот опенсорсный проект StreamEx, но в основном мы разговаривали про HuntBugs. Благодаря тому, что я указал эти два опенсорсных проекта, мне не стали давать тестовое задание. Люди, которые меня собеседовали, смотрели на мой код и спрашивали, почему я выбрал такое-то решение, почему сделал так, а не иначе. Действительно, можно понять, как человек программирует, глядя на его код.
Твой такой заметный след в интернете как-то продолжает влиять на твою жизнь? Тебе пишут, зовут в чем-нибудь участвовать или на работу, например?
Помимо этого я еще в конференциях участвую. Это способствует тому, что меня постоянно пытаются куда-то пригласить, чтобы я лекцию прочитал или доклад сделал. Я очень часто отказываюсь, потому что некогда и ресурсов мало. Я не люблю один и тот же доклад несколько раз читать, а готовить новый — большие затраты времени и энергии.
Ты говоришь, что отказываешься, но все равно много выступаешь, а еще преподаешь. Тебе нравится работать с аудиторией?
Мне интересно делиться знаниями. Мне кажется, что, когда я что-то такое прикольное знаю, очень здорово про это рассказать другим. Доклады и лекции отнимают кучу времени, потому что нужно все подготовить, отрепетировать. Иногда даже возникает мысль, а не бросить ли все это. Но когда доклад все-таки состоялся, становится просто приятно. Людям было интересно, они тебя слушали, задавали вопросы. Ты понимаешь, что принес пользу. Они что-то узнали и при этом не зевали. Мне кажется, у меня получается интересно рассказывать.
Я слушала твои лекции, мне было интересно. Написание статей преследует примерно ту же цель — поделиться знаниями. Но ты чаще выбираешь именно выступать. Почему?
Мне кажется, это немного другой формат. Мой первый доклад был на конференции Joker в 2015 году. Я тогда начал интересоваться, как Java что-то компилирует, и выяснил, что иногда происходят какие-то совершенно невероятные оптимизации. Сперва начал статью на Хабре писать про это дело, но получалось как-то серо и уныло. Там история такая немножко детективная: вот мы это делаем, но тут вот так получается и какая-то загадка необъяснимая, надо разбираться. И в какой-то момент просто пришло осознание, что если сделать доклад, должно получиться интереснее, чем сухой текст, потому что можно будет что-то обыграть, драматические паузы в нужные места вставить. Я так и сделал, и мне понравилось.
Ты работаешь в новосибирском офисе, хотя у нас в JetBrains есть программа релокации и ты мог бы переехать в другой город или страну. Почему ты остаешься здесь?
Я не вижу больших преимуществ в том, чтобы куда-то переезжать. Есть плюсы и минусы, и они друг друга уравновешивают, поэтому куда-то двигаться большого смысла нет. Например, климат. Тут бабушка надвое сказала, учитывая глобальное потепление. Может оказаться, что Новосибирск будет лучшим вариантом. Если переезжать в другую страну, то сразу языковой барьер, сложности с социальной адаптацией детей, отсутствие знакомых, друзей, которые есть здесь, родственников. В целом многие вещи придется делать с нуля. Я по натуре домосед. Бросать все и неизвестно куда перебираться мне не очень нравится.
Учитывая характер работы, нет большой разницы в том, откуда человек работает. Ты смотришь в тот же самый монитор. Неважно, где конкретно он расположен. По сравнению с Москвой или Питером в Новосибирске все дешевле. Здесь можно особо не считать деньги, потому что все что захочешь, в принципе можешь себе позволить. Особенно это касается сферы услуг. Устроить ребенка в частный садик, сходить к любому специалисту, например к врачу.
Может быть, тут еще есть момент патриотизма. Я всю жизнь прожил в Сибири, и почему бы не пытаться сделать Сибирь лучше. Например, проводить те же конференции, чтобы регион воспринимался как интересное место, где тоже хочется жить, а не уезжать туда, где и так много чего происходит. Все-таки земной шар большой, и зачем сосредотачиваться всем в одних и тех же местах, можно распределиться немножко.
Давай про удаленку поговорим, про работу, про команду. Команда у тебя распределенная, и в Новосибирске 4 часа разницы с Москвой и Питером, с Мюнхеном вообще 5-6 часов в зависимости от времени года. Сказался ли на вашей работе переход на удаленку?
Перед тем как мы ушли на самоизоляцию, в Новосибирске у нас было три человека из команды Java, которые сидели в одной комнате. Мы могли рабочие вопросы обсуждать вживую. Были задачи, которые мы вместе решали, то есть садились рядышком и было а-ля парное программирование. Сейчас этого нет, но так как все равно часть команды была в Питере, а часть в Мюнхене, в принципе не так страшно. Но скучаешь по тем временам, когда можно было человека о чем-то спросить через стол. Люди стали больше вариться в собственном соку и меньше знать, что происходит. Конечно, у нас есть еженедельные митинги в команде, созвоны one-to-one. Плюс я стараюсь появляться на виртуальных стендапах каждый день.
Еще есть новый формат виртуальной «чашки чая». Можно созвониться в определенное время всей командой и говорить не о работе. Иногда люди о жизни рассказывают, как дела, чем занимаются. Это даже больше сблизило нас с теми коллегами, которые не в Новосибирске.
В JetBrains есть такая штука как 20-процентный проект, во время которого можно заниматься чем-то, не связанным с основной работой. Ты используешь такую возможность?
В работе я довольно импульсивный человек. Когда мне приходит в голову идея сделать какую-то фичу, я все бросаю и начинаю ее пилить. Поэтому спланировать свой режим настолько, чтобы 20% времени каждую неделю специально заниматься чем-то другим, не мой вариант. Например, я никогда не участвовал в хакатонах: не чувствую, что это мой формат. Если у меня есть хорошая идея, я лучше буду над ней работать прямо сейчас. А если хорошей идеи нет, она не появится во время хакатона.
Тем не менее часть рабочего времени я действительно трачу на вещи, которые напрямую не связаны с моей работой. Иногда это деятельность, связанная с Java в целом. Мне очень нравится влиять на будущее языка. Я состою в экспертной группе проекта Amber, через который проходят все новые фичи языка Java, всякие records, pattern matching, switch expressions и т. д. Я довольно активно участвую в обсуждениях, вычитываю черновики спецификаций и иногда делаю патчи. Я не считаю, сколько времени на это трачу. Наверное, меньше 20%.
Когда ты только пришел, ты был старшим разработчиком и техническим руководителем стал уже вот в процессе. Как у тебя изменились задачи, нагрузка?
Меня стали чаще звать на разные митинги и на обязательный митинг для руководителей. Со мной стали в целом больше обсуждать межкомандные вопросы, плюс больше времени стало уходить на менторинг. Это все я считаю правильным, но я не хотел бы уходить совсем в менеджмент. Это не мое. Я считаю себя программистом и, конечно, стараюсь программировать во что бы то ни стало.
Как вы в команде обсуждаете какие-то вещи и принимаете решения? Расскажи об этом, есть ли у тебя свой подход?
Далеко не каждую вещь в принципе нужно обсуждать. Если перед человеком стоит задача, он сам поймет, как ее решать: у нас сотрудники все достаточно квалифицированы. Нет такого, что я как техлид должен сверху сказать, вот ты делай так, а не так. В любом случае у человека всегда есть право голоса, как конкретно ему что-то делать, и его голос часто оказывается решающим.
Иногда решения не просто связаны с кодом, а от них зависит user experience. Допустим, кто-то просит сделать новую инспекцию или новый warning. Во-первых, надо решить, в принципе будем мы это делать или нет. Потому что это может быть не очень важная штука, может быть, там будет очень много false positive срабатываний. Может быть, это связано с какой-то сторонней библиотекой, и мы вообще не хотим заниматься ее поддержкой. Такое решение мы стараемся обсудить, у нас есть даже документ, который мы год или полтора назад написали, о том, как такие запросы обрабатывать. Хотим мы делать новую инспекцию или нет? Лучше сделать совсем новую инспекцию или включить в существующую?
Если каждый раз делать новую инспекцию, их становится слишком много и люди начинают возмущаться, что все это в голове не уложить. С другой стороны, если новое предупреждение сделать частью существующей инспекции, его нельзя будет отключить отдельно от остальных, которые эта инспекция выдает. Такие решения мы принимаем коллегиально: все желающие высказывают свое мнение во внутреннем Slack-чате.
Бывает, мое мнение оказывается неправильным. В принципе считается, что лучше всего знает тот, кто уже с этим работал, не важно какая у этого человека роль в команде. Если ты более опытный, то чаще всего этот человек ты, потому что ты уже этот код ковырял. С другой стороны, если новичок взялся за какую-то подсистему и месяц в ней ковыряется, он автоматически становится главным экспертом в этой системе, несмотря на то, что в целом у него опыта меньше. Здесь мы прислушаемся к его мнению.
Как ты любишь проводить свободное время, чем увлекаешься? Я слышала, что у тебя была сертификация на предпоследнюю ступень владения японским.
В последнее время с увлечениями в обычном понимании становится все сложнее, все больше свободного времени уходит на семью. Но я считаю увлечениями какие-то околорабочие вещи, например участие в конференциях и в развитии Java.
Когда я готовлю доклад на выходных, дети спрашивают: «Папа, ты работаешь?». Я говорю: «Нет, я развлекаюсь». Потому что вроде бы нехорошо работать на выходных, когда и поразвлекаться можно. Раньше у меня были какие-то увлечения, более далекие от программирования: я действительно довольно долго изучал японский — лет шесть — и сдал экзамен «Нихонго Нореку Сикэн». По-английски он называется Japanese Language Proficiency Test, и это второй уровень. Максимальный был первый. Это было еще в 2006 году, очень давно.
Почему японский?
Я аниме смотрел. Это пошло с покемонов, потому что они мне очень понравились. Сперва в дубляже смотришь, потом в оригинале. Пытаешься понять, о чем вообще люди говорят. В принципе у меня есть интерес к языкам, и я считаю, у меня неплохо получается. Или память хорошая, или еще что-то. Вот и японский мне понравился. Он красиво устроен, у него интересная грамматика, при этом очень простая фонетика, такая приятная, нет вообще никаких проблем, как в английском — этого миллиона гласных, непонятно чем отличающихся друг от друга.
Но зато он сложный в плане написания, у них же там три азбуки, иероглифы…
Это как-то меня не сильно запарило. Ты визуально эти иероглифы запоминаешь. То, что сейчас люди пишут половину текста в эмодзи, это же все из Японии пошло, даже само слово «эмодзи» японское. Они действительно разговаривают картинками, у них головы что ли так устроены, и иероглифы — это по сути картинки. Ты просто запоминаешь их смысл. И даже если ты не знаешь слово из двух иероглифов, но один из них тебе знаком, можно догадаться, что это означает. Плюс их все-таки не запредельное количество.
Я выучил около 1000 иероглифов. Может 1100, плюс две азбуки, обе по 50 символов. 1100-1200 символов — это на самом деле реалистичный объем. Английский не сильно далеко ушел, потому что английские слова в некотором смысле тоже иероглифы. Когда видишь английское слово, если ты начинающий, ты часто не знаешь, как оно будет читаться. Тебе все равно нужно знать, как слово выглядит, как оно читается и что оно значит, это три разные штуки.
В японском в принципе то же самое, ты запоминаешь, как иероглиф выглядит, как читается и что значит. Со временем ты видишь закономерности и можешь даже незнакомый иероглиф прочитать — просто догадаться. В общем, мне нравится японский язык. Но, к сожалению, для меня он ушел на второй план. Хотя сейчас у нас большой проект по локализации IntelliJ IDEA, и я решил вернуться к былому и поставил себе локализованную версию, хотя это, конечно, несколько замедляет работу.
В смысле прямо в японской IntelliJ IDEA работаешь?
Да, она полностью локализована. Бывает, что я хочу что-то найти и не понимаю. Самое сложное — это, например, найти инспекцию, название которой я знаю по-английски. У меня есть список из 2000 инспекций и нужно догадаться, как они называются по-японски. А так в принципе работать вполне можно, я стал что-то вспоминать, и это такое приятное чувство ностальгии.
Это скорее тренировка, но если я замечаю, что что-то неправильно переведено, то сообщаю нашим переводчикам, они исправляют. Несколько десятков ошибок уже нашел, то есть это вполне приносит пользу компании.
Алина Комиссарова, координатор образовательных проектов JetBrains в Новосибирске