Довелось мне тут пройти серию собеседований в Тинькофф и добраться до стадии обсуждения проекта, в котором я мог бы поучаствовать. Мог бы, но не захотел. Если кому-то интересны подробности, то милости прошу под кат.
Преамбула
С прошлого года у нас есть заказчик из Западной Европы. "У нас" -- это у крошечной компании "СтифСтрим", в которой я соучредитель. После февраля 2022-го и начала санкций против РБ/РФ у нас начались приключения.
Первый звоночек прозвучал уже в марте. Белорусский Сбербанк закрыл свой долларовый корреспондентский счет в CityBank и нам пришлось перезаключать контракт с клиентом для того, чтобы деньги приходили в другой банк и в другой валюте.
А спустя еще пару месяцев прозвучал набат: не смотря на то, что клиент нам деньги перечислил, дойти к нам они никак не могли.
Получается, что клиент с заказом есть, а вот денег от него нет. И, даже если очередной платеж в конце-концов дойдет, то нет гарантий, что не введут еще более жесткие санкции из-за которых сотрудничество станет невозможным.
Собственно, такое развитие событий просматривалось, поэтому я стал осторожно закидывать в блоге удочки с целью найти заказчиков из РФ или РБ. Сперва завуалировано, потом совсем уже прямым текстом, продублировав ссылку в Twitter.
Один добрый человек поделился этим твитом и тут-то все и завертелось.
Амбула
Твит попался на глаза менеджеру Тинькофф (первому из). Он спросил не желаю ли я пообщаться. Я пожелал и меня свели со вторым менеджером, после чего состоялось Zoom-встреча со вторым менеджером и руководителем одного из направлений разработки.
Рассказал о себе, о своем опыте, о ситуации в которой оказался и о том, почему нахожусь в поиске.
Полагаю, что произвел нормальное впечатление и мне предложили пройти по их стандартному пути найма: общение с HR, затем несколько собеседований, затем еще одна беседа о том, куда меня можно будет пристроить в случае успешного прохождения всех стадий отбора.
В общем, процесс пошел.
Пообщался с HR. После чего мне назначили первое собеседование, на котором оценивалось знание языка C++.
После первого собеседования состоялось второе, на котором уже оценивалось мое умение программировать и способность решать задачи.
Затем было еще и третье собеседование, посвященное т.н. system design.
Видимо, все собеседования я прошел нормально, т.к. затем состоялся разговор о том, какой именно проект мне хотят предложить.
Это должна была стать работа над OpenSource версией СУБД greenplum.
Поскольку про greenplum я услышал впервые, то взял некоторое время, чтобы познакомиться с этой разработкой. Изначально я рассчитывал уложиться в два-три дня, но сильно недооценил глубину кроличьей норы. Поэтому попросил еще несколько дней чтобы лучше разобраться в теме и решить для себя хочу ли я в этом участвовать.
В итоге понял, что не хочу.
Другого проекта для меня не нашлось, так что в Тинькофф я не попал.
Ниже немного впечатлений о процессе прохождения собеседований, о проекте greenplum, и о том, почему же мне не захотелось в эту тему вписываться.
Немного о самих собеседованиях и моем отношении к происходившему на собеседованиях
Некоторой пикантности ситуации могло бы придать то, что сам я более чем скептически отношусь к такому методу отсева соискателей. Кроме того, мой код спокойно лежит в OpenSource, его можно посмотреть и сделать выводы о моем уровне. Если этого недостаточно, то можно было бы пообщаться по поводу какой-то из открытых разработок. ИМХО, разговор бы получился предметнее.
Но я сам был менеджером, поэтому понимаю что значит процесс, зачем он нужен и почему крупные компании завязаны на процессы. Поэтому желания что-то из себя воображать не было: раз надо, значит надо. Плюс к тому был еще один фактор, о котором я упомяну ниже, и этот фактор делал происходящее очень интересным для меня, так что к перспективе пройти серию собеседований отнесся как к шансу поучаствовать в уникальном для меня эксперименте.
Большой проблемой представлялось то, что основной принцип онлайн-собеседований, а именно решение задачек здесь и сейчас, не отходя от кассы, -- это ну прям полная противоположность тому, как я привык работать.
Много лет я вообще программировал сперва на бумаге, а потом уже набирал код на компьютере. В последние годы так уже редко делаю, но все равно мне нужно сперва хорошенько подумать, порисовать каракули в тетрадке, набросать черновые кусочки будущего решения. Только после этого из каши в голове начинает выкристализовываться то, что должно быть воплощено в коде. Да и то, в процессе кодирования многое может кардинально поменяться.
В общем, были у меня серьезные опасения на счет того, что в процессе собеседований буду тупить и выглядеть тормознутым идиотом. Вроде бы оправдавшиеся :(
Первое собеседование на знание языка включало в себя, если мне не изменяет склероз, три задачки. Первые две по типу понять, что должно получиться в результате запуска программы и объяснить почему. Попутно разбирая отдельные фрагменты, предлагая улучшения, реагируя на новые вводные от интервьюера. Третья задача была из категории сделать набросок кода решающий некую проблему (кстати говоря, именно по следам спокойного обдумывания наброска к этой задаче появилась заметка в блоге про запуск/останов фоновой рабочей нити).
Вроде как особых затруднений ничего не вызвало, но зато в очередной раз понял, что внимательность не сильная моя сторона. Ряд моментов должен был бы прямо броситься в глаза, но я почему-то их не заметил. Ну и да, здесь как раз нашлось место обсуждению виртуального деструктора* ;)
На первое собеседование отводилось 1.5 часа, мы чуть вышли за эти рамки, но это больше за счет разговоров о вопросах на собеседованиях по C++ и о сложности C++ вообще.
Второго собеседования, на знание алгоритмов и структур данных, я опасался больше всего. Т.к. и программировать около олимпиадные задачки на время не приходилось уже не один десяток лет, и описания структур данных привык искать в Интернетах (а это вообще редко происходит, поскольку крайне редко нужно что-то специфическое), и про O-большое помню только то, что когда-то давным-давно, лет тридцать назад, нам об этом кратко рассказывали в рамках какого-то спецкурса в универе.
По мере сил постарался подготовиться: порешал что-то по вечерам (списки поразворачивал, ну и строку развернул заодно**). Даже на leetcode зарегистрировался и сделал там пару простеньких упражнений, чтобы почувствовать каково оно, писать код с места в карьер и сразу в Web-IDE.
На самом собеседовании было две задачки, решение которых я запрограммировал. Тупил правда с поиском того решения, которое было бы оптимальным, а не самым очевидным. Но тут уж ничего не поделать, сказывается и возраст, и привычка думать не торопясь, рисуя каракули в тетрадке.
В конце пообсуждали третью задачку. Запрограммировать решение времени не было, но там основной фокус был в том, чтобы придумать именно что алгоритм решения. Естественно, не придумал, но вроде бы на наводящие вопросы интервьюера отвечал :)
На второе собеседование отводился один час и мы за пределы этого лимита, если не ошибаюсь, не вышли.
Видимо, два этих собеседования я прошел нормально, поэтому меня допустили к интервью на тему проектирования систем, которое должны проходить претенденты на senior-скую должность.
К этому собеседованию я относился гораздо проще, чем двум предыдущим, ибо облажаться по первым двум не хотелось, как-никак больше тридцати лет в программизме и около 30 лет в обнимку с C++. А вот "проектированием систем", да еще и относящихся к Web-у, не приходилось заниматься уже лет 8 как. Так что нарастить здесь опыт за несколько дней было нереально. Поэтому, если к двум первым я еще пытался хоть как-то подготовиться, то перед третьим разве что прочитал несколько, как оказалось, бесполезных статеек в Интернете на тему "system design interview".
На собеседовании же я честно пытался разыскивать последние крупицы в скудных запасах общей эрудиции чтобы предложить хоть что-то отдаленно напоминающее рабочую схему. Плюс даже умудрился набросать схемки трех простеньких табличек в БД, хотя с РСУБД дел не имел уже лет 10, если не больше. Ну и на вбрасывания и замечания со стороны интервьюера, вроде бы, реагировал адекватно, хотя и тупил изрядно.
Третье собеседование также ограничивалось одним часом и мы в это время уложились.
По итогу от собеседований остались самые теплые и приятные впечатления, которые можно суммировать как-то так:
- ожидал, что будет хардкорнее. Сильно хардкорнее. Скажем так, сам себя бы по C++ я бы срезал, даже не углубляясь совсем уж в тонкости языка ;) Ну и если бы пришлось инвертировать бинарное дерево, то мог бы выйти конфуз, т.к. я даже и не знаю, что это за операция такая, не дошел в самоподготовке до этой животрепещущей темы*** :)))
- отличные впечатления произвели все трое интервьюеров. Приятно было общаться, чуствовалось, что ребята и грамотные, и понимающие, и внимательные. Никаких попыток самоутвердиться, ничего и близко похожего на желание как-то принизить соискателя или "докопаться до столба". Так что собеседования, для меня лично, напоминало спокойное и конструктивное общение коллег, работающих над общей проблемой, а не выяснение того, кто и чего стоит.
Немного о впечатлениях от greenplum
Для тех, кто, как и я, про greenplum раньше ничего не слышал, попробую резюмировать в двух словах: это сильно доработанный напильником форк PostgreSQL, который за счет архитектуры MPP (massively parallel processing) позволяет эффективно выполнять задачи OLAP (online analytical processing) на больших объемах данных.
Как я понял, доработан PostgreSQL в greenplum очень значительно. Что-то написано на C++ (вроде оптимизатора запросов), что-то на чистом Си (вроде собственного протокола общения между нодами).
Сам по себе greenplum существует в двух версиях: платной, с некоторыми дополнительными возможностями + поддержка от вендора, и бесплатной OpenSource-ной, доступной на GitHub-е. В связи с известными событиями вендор свою поддержку для российских компаний прикрыл, из-за чего и возникла потребность в доработках открытой версии greenplum своими силами.
Время, которое я взял на знакомство с greenplum, ушло на то, чтобы найти и прослушать несколько докладов о greenplum на YouTube, а также на то, чтобы попытаться посмотреть на код greenplum.
И чем больше я знакомился с greenplum, тем меньше мне нравилась идея вписаться в этот проект.
Во-первых, сама по себе тема СУБД для больших объемов данных и OLAP меня ну вот вообще никак не зацепила. Казалось бы десятки петабайт информации, кластера, нагрузка, все дела... А не торкает и все.
Ну вот бывает так, что предлагают какую-нибудь совсем дурацкую тему, вроде "А давайте забежим босиком на Эверест"****, и ты такой: "А давайте! Когда стартуем?" и с нетерпением ждешь отмашки.
А тут отличная жизненная и востребованная тема... И ноль эмоций.
Ну да, десятки петабайт информации. Ну да, кластера. Ну да, нагрузка. Но не торкает. Вообще.
Особенно грустно это было осознавать слушая очередной доклад по greenplum-у: у докладчика глаза горят, он полон энтузиазма и видно какой кайф он от своей работы получает. А вот тебя не торкает.
Во-вторых, я все-таки C++ разработчик. От использования чистого Си отказался давным давно, еще будучи студентом, о чем ни разу с тех пор не пожалел. Время от времени с чистым Си мне дело иметь приходиться, но в восторг это не приводит. Более того, я постоянно ловлю себя на том, что не понимаю, как нормально программировать на Си: вещи, которые на C++ очевидны и делаются с полтычка, на чистом Си превращаются в написание простыней кода, где за каждой строчкой приходится следить гораздо тщательней.
И вот мне предстоит вписаться в проект, значительная часть которого написана на Си.
Да и та часть, которая на C++, там весьма специфическая.
Сперва я нашел тот самый реализованный на C++ оптимизатор для greenplum пятой версии. Написан он на С++98. По следам первых впечатлений от кода оптимизатора на C++98 я даже маленькую заметку в блог закинул.
Правда, затем "Зоркий Глаз" заметил, что в шестой версии greenplum оптимизатор лежит уже прямо внутри исходников greenplum. И там уже C++14. Но, как я и предполагал, заметного эффекта переход на более свежий стандарт не дал.
Суть в том, что в этом куске greenplum-а чуть ли не своя маленькая C++ экосистема создана -- там очень много своего: свои контейнеры, свой менеджер памяти (по типу арены), своя система тасков и т.д.
Т.е., грубо говоря, там используется подмножество C++ со своей базовой библиотекой. Такой замкнутый сам на себя мирок, максимально заточенный под одну конкретную задачу.
Причем сам по себе C++ный код производит двоякое впечатление. С одной стороны, он нормально написан. Все читается, не встречается каких-то явных косяков, глядя на которые тебя передергивает. Достаточное количество комментариев, чтобы разобраться в коде. В общем, вполне себе хорошая кодовая база, ее авторам совершенно нечего стыдиться, скорее наоборот.
Сильно смущали в коде всего две вещи (прошу здесь сделать скидку на то, что я в код лишь заглянул, если бы я целенаправленно погружался в него на протяжении нескольких недель, то мог бы к этим вещам привыкнуть):
- венгерская нотация. Да-да, она самая. Префиксы у имен типов и переменных. Если кто-то заглядывал в исходники MFC, то поймет о чем я. И если к именам классов/структур привыкнуть несложно, то вот способы именования методов и элементов перечислений (enum-ов) вымораживали меня гораздо больше;
- странное проектное решение, при котором вроде как для контроля времени жизни объектов использовался счетчик ссылок (там даже базовый класс есть, от которого для этих целей нужно наследоваться), но при этом увеличивать/уменьшать количество ссылок в коде приходиться вручную (вот случайный пример метода, в котором AddRef и Release вызываются вручную). Что, как мне показалось, делает код менее C++ным, чем хотелось бы.
Поэтому чем больше я знакомился с исходным кодом greenplub, тем больше задавался вопросом о том, а хочу ли я на ближайшие несколько лет (а может и больше) застрять в этом маленьком завязанном самом на себя мирке потрохов PostgreSQL+greenplum? Да еще и заниматься поддержкой не только C++ного, но и чисто Си-шного кода...
И чем больше я об этом думал, тем меньше мне этого хотелось.
Тут ведь и еще один фактор сказывался: в последнее время у меня есть ощущение, что подзастрял в C++14 и C++17, что надо бы как-то заставить себя двигаться в сторону C++20. Если уж я не решаюсь уйти из C++ в какую-то более современную экосистему (вроде Rust-а или Go), то хотя бы в C++ нужно пытаться сильно не отстать. Ибо есть у меня ощущение, что C++20 разделит мир C++ на "до" и "после" не хуже, чем это сделал C++11. И лучше бы оказаться на той стороне, которая "после".
Плюс к тому у меня есть некоторый опыт в многопоточном программировании. Кроме того, хоть я и не спец по шаблонной магии, но все-таки в пределах своих возможностей пытаюсь ее использовать (примерами могут служить easy_parser из RESTinio, json-dto или timertt). В общем, какой-никакой уровень есть и этому уровню хотелось бы найти применение.
А вот глядя на C++ из greenplum и у меня было подозрение, что здесь многопоточность не нужна от слова совсем (я так понял, что код там принципиально однопоточный). Да и для самой простенькой шаблонной магии здесь вряд ли найдется место.
Короче говоря, мне показалось, что если уж оставаться в мире C++, то хотя бы в проектах, где нужно использовать современный C++ и где мой прошлый опыт в той же многопоточности окажется востребованным.
А greenplum не был похож на такой проект :(
На мой взгляд, конечно же. Вполне возможно, что я сильно ошибся.
Так почему же я все-таки отказался?
Основной причиной было опасение оказаться в "золотой клетке". Это когда тебе не нравится то, что ты делаешь, но ты вынужден это делать изо дня в день. А платят тебе при этом так, что ты не можешь решиться уйти.
В прошлом я пару раз оказывался в ситуации "золотой клетки", каждый раз это было неприятно, местами тяжко, и пагубно сказывалось на здоровье. Выходить из этого было непросто и требовало времени на восстановление.
С учетом того, что моложе я не становлюсь, отпущенного мне срока остается все меньше и меньше, посему тратить его на то, чтобы работать нелюбимую работу пусть даже и за хорошую зарплату, не хочется от слова совсем.
Что касается самой задачи по развитию greenplum-а, то как мне кажется, она на ура зайдет следующим категориям разработчиков:
- молодые специалисты, возможно вчерашние или даже действующие аспиранты, у которых реляционные СУБД являются предметом их научного интереса. Если тема РСУБД интересна, особенно специфика БД для OLAP, то это шикарный шанс поучаствовать в разработке одного из флагманских продуктов в данной нише;
- разработчики, которые уже принимали участие в работах над СУБД (особенно если это что-то вроде PostgreSQL или MariaDB). Для них это будет привычный мир и привычные задачи;
- разработчики солидного возраста, которые хотели бы спокойно доработать оставшиеся 3-5 лет до пенсии на хорошем проекте, с нормальным уровнем качества кода, с большим наследием, с отсутствием погони за модными и молодежными стандартами. Как по мне, так это именно такой проект: для спокойного и вдумчивого разбирательства, для тщательно продуманных изменений и дополнений, без необходимости насыщать код фишками из последних стандартов.
Вот только сам я ни в одну из этих категорий не попадаю.
Вместо заключения
Не смотря на то, что с трудоустройством в Тинькофф не вышло, впечатления остались самые положительные.
Во-первых, я впервые в жизни прошел через подобные собеседования.
Вот реально, никогда такого не было.
На все свои предыдущие места работы я устраивался либо потому, что меня знали и предлагали работу именно мне, либо потому, что меня рекомендовали. В двух случаях были встречи с будущим руководством, но это никак не было собеседованием в традиционном смысле, скорее просто знакомство и, в одном из случаев, предварительное согласование некоторых аспектов будущей совместной работы.
А тут тебе и собеседование на знание языка, и программирование в on-line. Хоть на себе прочувствовал что это такое.
Во-вторых, мне понравилось то, как в Тинькофф это устроено. Все четко, все по делу. Молодцы, решпект и уважуха.
PS. Забавный факт. Весной 2021-го года у нас была перспектива заказа на доработки MariaDB. Я тогда краем глаза заглянул в исходники этой самой MariaDB и чуть ли не сходу нашел мелкий баг. Зарепортил и его через какое-то время пофиксили. Сейчас краем глаза заглянул в greenplum и нашел мелкий баг :) Зарепортил (цынк), наверное пофиксят со временем.
* Это мем про уровень знания C++. Активно эксплуатировался в Рунете, в частности на RSDN.
** Еще один мем. Некоторые ыксперды в Интернетах утверждают, что большинство соискателей, претендующих на сеньорские позиции, не способны написать разворот списка или разворот строки.
*** Это о том, как автора homebrew не взяли в Google.
**** Отсылка к "Смертельный марш" Нортона.