Мой поиск работы C# программистом в Нью-Йорке

:

imageЯ безработный! Теперь у меня будет время написать свою статью на Хабр! Эта мысль пришла ко мне значительно раньше страха перед предстоящими собеседованиями. Итак, мой контракт с инвестиционным банком в Нью-Йорке не был продлен, что явилось небольшой неожиданностью для меня. Мне предстояло съездить в давно запланированный отпуск и сразу по возвращению окунуться в процесс прохождения собеседований. После приятных мыслей о том, как много у меня теперь свободного времени на: домашний open source, Arduino и Хабр; стало приходить понимание, что прохождение собеседования — это отдельный навык, которого у меня нет. Я программист со стажем, работаю им со 2-ого курса, начинал с подработки на исследовательский институт, поработал 2 года в разработке игр, потом около 7 лет в компании, занимающейся аутсорсингом. Эта компания перевезла меня в Нью-Йорк и потом отпустила работать в тот самый банк. Последние серьезные собеседования я проходил 8 лет назад! Я постараюсь рассказать вам о том, каким я вижу процесс поиска работы С# WPF программиста в среде инвестиционных компаний Нью-Йорка. Здесь нет никакой морали — это просто моя история.

Звонок


Время подходит, уже без пяти минут. Музыка выключена, жена спряталась со своим ноутом в спальне, гарнитура подключена к сотовому телефону… Звонок: “Здравствуйте, я хотел бы задать вам пару вопросов по C#...”. “Что? Вот так вот просто, даже не представился? Он будет делать из меня гриль следующие полчаса, а я даже не узнаю как его зовут” — вот, что подумал я после такого начала телефонного интервью.

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

Незнакомец продолжает: “первый вопрос для разминки — чем отличается ref от out?”. А я не знаю. Я программирую на C# 8 лет, и это звучит как простой вопрос, но я действительно не знаю, отличаются ли они. Возможно, это из-за того, что я не пользовался ими. Ну ладно, я лукавлю — я пользовался методом Dictionary.TryGetValue, а там значение возвращается через out параметр. А ref я встречал используя COM из C#. Но мне всегда казалось, что обе эти вещи: возврат значений через параметры и COM — вещи неправильные, архитектурно плохо продуманные и нуждаются в безальтернативном обосновании при их использовании. Я не помню, что я ответил Незнакомцу, но все последующие собеседования я отвечал правильно.

Квадрипликация


imageПочти все вопросы, которые мне задали за пять собеседований, очень детально разобраны в книге Рихтера “CLR via C#”. С этой книгой только одна проблема — прочитав ее очень трудно отвечать на вопросы коротко, потому что вы знаете всё. Вопрос, находящийся на вершине моего хит-парада и очень качественно разобранный в этой книге: “чем отличаются события от делегатов?”. Популярность этого вопроса сильно повысило одно собеседование в офисе.

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

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

Многопоточность


Эта тема для вопросов — самая любимая. Отчасти потому, что вопросы по многопоточности — самые сложные. Вот набор вопросов, которые мне в той или иной форме задали почти на всех собеседованиях:
  • Что такое lock?
  • Как разрешать deadlock’и на C#?
  • Какие еще средства синхронизации вы знаете?

На самом деле у всех этих вопросов была одна цель — собеседующий хотел, чтобы я рассказал все, что знаю о многопоточности. На вопрос про lock надо сказать и про Monitor, а также из чего состоит структура, ассоциированная с синхронизированным объектом. А вот я не представлял, что делают методы Monitor.Wait и Monitor.Pulse до того, как начал готовиться к собеседованиям. Нужно было рассказать про средства синхронизации пользовательского уровня и уровня ядра, и про гибридные не забыть (Monitor, кстати, гибридное средство). А еще класс Mutex в C# — практически бесполезная вещь. Моя задача всегда была в том, чтобы времени было меньше, чем я могу сказать на тему многопоточности, в частности в C#.

В этой теме я всегда говорил, что едва ли в реальном проекте возникнет необходимость использовать эти средства синхронизации. Всегда, когда возможно, надо использовать высокоуровневую библиотеку Task Parallel Library. Я встретился с непониманием такого замечания на двух интервью. Выяснилось, что обе организации имеют свои собственные библиотеки для работы с многопоточностью. Обе организации не были в курсе, что Task Parallel Library доступна в .NET Framework 3.5. Эти интервью я не прошел, и это к лучшему.

Singleton


Да-да! Меня попросили написать singleton! Я был уверен, что это плохой вопрос для собеседования. Все знают на него ответ. Это просто трата времени.

Это было интервью на позицию в довольно интересную команду. Команда новая, в канадском инвестиционном банке, который планирует расширить свой бизнес в США. У них есть небольшая часть кода на С++ на серверной стороне (вычислительные библиотеки и кое-какая оптимизированная логика вокруг них). Мне нравятся такие проекты, я люблю разные платформы и языки и чувствовал, что уже засиделся на C#. Все шло гладко до этого вопроса про singleton: я уже поговорил с менеджером и казалось произвел приятное впечатление. Кроме того, оба: и менеджер, и собеседующий программист — русские. Я не националист и не испытываю положительных иллюзий относительно своей национальности, просто работать с русскими мне ментально проще. Я их понимаю, даже если не поддерживаю. И тут на тебе — они всерьез считают, что у меня могут быть проблемы с singleton’ами.

Я написал singleton, и после этого мне показали, как увлекательны бывают эти singleton’ы. Меня спросили является ли мой singleton потокобезопасным и попросили сделать его таковым. Тут мне пришлось вспомнить про блокировку с двойной проверкой (double-checked locking). Мы даже обсудили популярность этого подхода в связи с его интересными приключениями в языке Java. Java еще появится в этой истории.

Это нам не задавали


C# 4.0 — нет, не слышали. Так и не были заданы интересные вопросы по последним нововведениям в языке C#. Я очень ждал вопросов про то, что такое ковариация и контрвариация или dynamic и зачем они нужны. Я не должен был этому удивляться — я и сам на работе не использовал С# выше 3.0 и .NET выше 3.5. Просто еще очень мало из инвестиционных организаций перешло на C# 4.0, а многие все еще на C# 2.0.

Мне почти не задавали вопросов по WPF. Был один и довольно серьезный. Как показать таблицу со столбцами, количество которых определяется в ходе работы программы? Есть много способов сделать это, но основная сложность в том, чтобы сделать это не смешивая view и model и без code behind. Я как-то делал это с помощью ITypedList.

“Это не собеседование”


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

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

Позиция, на которую меня приглашали не WPF и даже не C# — это Java позиция. У меня практически не было интервью. Был разговор о жизни с начальником моего знакомого, Робертом. Роб, увидев мое напряжение в середина разговора, сказал: “Расслабься, это не собеседование — мы просто говорим о жизни. Я полностью доверяю Майклу — если он говорит, что ты хорош, то это не ставится под сомнение, тем более твое резюме говорит за тебя. Так когда ты хотел бы начать работу?”. Это было мое первое успешное интервью.

Гонка


К концу первой недели банк из раздела Singleton тоже выявил желание нанять меня. Они позвонили агенту сразу после офисного интервью, в тот же день. Это мне понравилось — такая прыть редкость, тем более в среде инвестиционных компаний.

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

Я стал ждать официальных бумаг от моих знакомых с Java позицией и от любителей singleton’ов на позицию C# WPF. Я называю это гонкой предложений. Агентская контора (они отправляли меня на позицию C#) звонила мне каждое утро, нередко поднимая меня с кровати, с заверениями, что все идет хорошо, и что вот-вот я получу контракт. Я упомянул им, что у меня наклёвывается другое предложение и поднял немного заработную плату, они обо всем договорились с будущим работодателем. Их рвение дошло даже до того, что в одно утро агент взял с меня обещание, что, если я получу контракт в течение 24 часов, то я подпишу его и не продолжу торговаться с другим потенциальным работодателем. Прошло 24 часа — контракта не было, наступила пятница.

Велосипед


imageВ конце недели в пятницу около 4 часов вечера мне позвонил мой знакомый и сказал, что все бумаги готовы и что я получу их в течение вечера. Все так и случилось. В течение выходных я заполнил все бумаги, а в понедельник утром уже сдавал отпечатки пальцев. И вот теперь я — программист на Java! На мой выбор повлияли две вещи: во-первых, мне дали возможность поменять язык программирования, без каких-либо жертв с моей стороны, это чего-то стоит и это аванс мне; во-вторых, этот работодатель ближе к моему дому. До него на велосипеде добираться быстрее, чем на метро — всего 30 минут. Когда я сказал об этой причине агентам, они смеялись, и ответили, что я веселый шутник. Кстати, они были готовы прислать контракт на C# позицию в понедельник утром.

В понедельник я выхожу на работу. Домашний open source продвигается очень медленно, Arduino и паяльник я даже в руки не брал, но зато первую статью на Хабр я написал!

Раскроем имена


Мало ли кому интересно:
Геймдев — я работал в creat studios 1 год и еще 1 год до этого работал в фирме, которую creat поглотил.
Компания, занимающаяся аутсорсингом — это DataArt.
Банк, в котором мне не продлили контракт — Credit Suisse.
Банк, страдающий квадрипликацией — Royal Bank of Canada.
Банк, предложивший C# позицию — TD Securities.
С понедельника я — программист на Java в Bank of America / Merrill Lynch.