Привет!
Сейчас никого не удивляет, что в IT компаниях для студентов организуются стажировки. При этом сами работодатели преследуют разные цели: выбрать среди студентов лучших для дальнейшей работы, познакомить новичков со своим рабочим процессом или даже просто удовлетворить потребность университета в том, чтобы пристроить к себе на лето студентов. У нас в прошлые годы специальных программ стажировок не было: если один из наших сотрудников преподает в образовательном учреждении, и в потоке есть очень толковый студент, то со временем его курсовая работа может перерасти в нечто более связанное с нашей деятельностью.
C годами у нас появилось много образовательных программ, которые мы поддерживаем (Computer Science Center, программа магистров при АУ РАН, Лаборатория JetBrains при Математико-механическом факультете СПбГУ и пр.) и много студентов, которые хотят пройти стажировку у нас. В результате этим летом мы провели масштабный проект летних практик.
Вот что рассказывает один из стажеров о своей практике, студент Computer Science Center и Политехнического университета, Кононов Кирилл:
КИРИЛЛ КОНОНОВ:
Мой август 2013го был целиком посвящён стажировке в JetBrains. Под руководством Дмитрия Булычева я работал над индивидуальным проектом «Command Line Plugin for IntelliJ IDEA».
Всё началось с того, что однажды в моём вузе (СПбГПУ) всему курсу объявили о необходимости проходить летнюю «производственную практику». Эта процедура подразумевает месячное трудоустройство в какую-нибудь компанию, которое студенту нужно сопроводить рядом документов и форм отчётности.
На нашей кафедре есть несколько стандартных вариантов – это три завода: «ЗМК», «Аврора» и «Кризо». Туда ребят отправляют «по умолчанию», если они не изъявляют желания проходить практику в другом месте. Но все эти варианты были мне неинтересны, к тому же я слышал массу негативных отзывов о работе в этих местах. Как правило, студенты там выполняют очень примитивные задачи (наподобие сканирования бумажек) и, по большому счёту, никому не нужны.
Возникла мысль, что раз уж я учусь в CS-центре, то мне стоит взять стажировку в одной из дружественных компаний. Тем самым я решил совместить необходимое с полезным.
Введение
Был месяц март, когда я обратился к кураторам Сomputer Science Center по своему вопросу. Тогда ничего конкретного о летних стажировках не было известно, и мне предложили писать напрямую представителям компаний. Времени оставалось немного, ведь уже скоро мне предстояло подать первичный документ на кафедру.
Я хотел в JetBrains, поэтому связался с Андреем Ивановым (JetBrains COO) и в письме поведал о своем желании получить стажировку. Андрей Владимирович пригласил меня в офис на беседу. Я рассказал о себе, о вузе, о процедуре производственной практики и о своём обучении в CS-центре. Тогда же я и познакомился с Дмитрием Булычевым – он оказался готов взять меня в один из проектов.
Проект Command Line Plugin
Это был тот самый проект, который я хотел получить ещё осенью 2012-го. Но вышло так, что в Академическом университете презентации практик состоялись раньше, чем в CS-центре, и «Command Line Plugin» достался студентам из АУ – Сергею Савенко и Павлу Чаднову. Таким образом, к моменту начала моей летней стажировки уже имелся определенный прототип плагина. Мне предстояло его изучить, а затем продолжить разработку.
Вот основные пункты, которые были сделаны до меня:
- организация плагина для IDEA с необходимыми составляющими (в том числе, extension point)
- прототип архитектуры, подразумевающей позиционные аргументы
- встроенный набор из четырёх команд
- прототип возможности автодополнений
- интерфейс в виде компонента pop-up
Стоит отметить, что Сергей и Павел проделали немалую работу. Даже первый пункт сам по себе довольно емкий для разработчика, который пишет плагин впервые. Однако не всё в тогдашнем состоянии проекта было работоспособно. Более того, в обсуждении с Дмитрием мы решили во многом изменить архитектуру.
Новый вариант плагина характеризуется следующим:
- архитектура, основанная на именных аргументах
- эффективный инкрементальный парсинг
- полноценная поддержка автодополнений
- многоаспектная валидация
- история использованных команд
- интерфейс в виде устойчивого компонента
Далее я вкратце расскажу о том, как был реализован каждый из этих пунктов.
1. Именные аргументы
Использование именных аргументов позволяет обеспечить значительно большую гибкость, чем использование позиционных. Был принят следующий формат:
Всего возможно шесть вариантов – в том числе поддерживаются и длинные значения в кавычках (они могут содержать любые символы, включая пробелы).
2. Инкрементальный парсинг
Суть особенности заключается в том, что при изменении ввода парсинг производится только для аргументов на различающейся части строки. При очередном парсинге определяется первый несовпадающий символ у старой и новой строк, после чего изменению подвергаются только состояния затронутого (черная линия ниже) и последующих аргументов.
В этом примере из старого состояния будет удалён аргумент v3 вместе со своим значением, а в новое – добавлен аргумент v4 (без очищения и повторного разбора команды, аргументов v1 и v2).
Таким образом, на длинных командах с множеством аргументов достигается значительно более высокая эффективность парсинга, ведь в реальности изменение ввода практически всегда будет происходить на конце строки: пользователь стремительно набирает команду, и после каждой нажатой клавиши нет необходимости проводить полный парсинг.
3. Автодополнение
Автодополнение (Autocompletion) представляет собой возможность подстановки полного строкового значения какой-либо части текста во время пользовательского ввода.
Предлагаются варианты для дополнения:
- имени команды
- имени варианта аргумента
- значения аргумента (когда возможно)
Подсказки по первым двум направлениям очевидны: плагин имеет собственный набор команд, имеет набор команд, полученных из расширений посредством использования extension point, и для каждой команды имеет фиксированный набор вариантов аргументов.
В случае со значениями есть два варианта: completion может появиться из стандартного «провайдера» значений типа (как в примере, когда для данного типа мы можем перечислить все уместные значения) или же быть предусмотрен разработчиком команды. Второй случай реализуется, например, если значением должен являться какой-либо путь к файлу из окружения. В общем случае String дополнить не получится, но в контексте конкретной команды и конкретного варианта аргумента можно предложить подобные подсказки.
4. Валидация
Валидацией здесь называется определение корректности ввода команды вместе со всеми её аргументами.
Она включает разбор случаев:
- неверной команды, варианта или значения аргумента
- взаимоисключающих аргументов
- отсутствия обязательного аргумента
- отсутствия зависимого аргумента по отношению к уже введенному
Последние три вида разбора реализованы так, чтобы их можно было легко использовать для типовых случаев. Однако, помимо этого, разработчик команды может вручную реализовать любую более сложную логику валидации.
С точки зрения интерфейса результат валидации в каждый момент времени можно определить по состоянию кнопки «Execute» в компоненте плагина: если имеется проблема, то кнопка будет недоступной.
5. История команд
При использовании командной строки привычной является возможность возврата к уже введенным ранее командам. В рамках этой идеи плагин имеет две основные функциональности:
- движение по истории команд: сочетание клавиш Ctrl + up / down
- показ полного списка команд
Ниже приведен пример показа полного списка команд:
Важно, что история накапливается на протяжении времени жизни всей IDE (и не пропадает при закрытии компонента командной строки и открытии его в другом месте).
6. Интерфейс
В своём новом виде плагин командной строки представлен устойчивым компонентом. Он не пропадает при потере фокуса или любых других действиях, не связанных с его явным закрытием или закрытием содержащего его контейнера (в отличие от pop-up компонентов).
Компонент может быть запущен в любой визуальной области в IDE, если пользователь предварительно сделает её активной. После этого командная строка будет корректно реагировать на движения и изменения размеров в иерархии компонентов, в которую она окажется включенной.
Пример показывает стратегии поведения компонента в различных условиях. Например видно, что у него есть минимальный размер и он не выходит за границы IDE при экстремальном растяжении/сжатии окна.
Таким образом, плагин чувствует себя комфортно в окне IDE.
Развитие проекта
Вскоре после окончания стажировки мы с Дмитрием договорились о продолжении проекта, уже в рамках учебной семестровой практики от CS-центра. В качестве примерных ориентиров были приняты следующие оценки:
40% времени:
- доработка архитектурных составляющих
- улучшение интерфейса
60% времени:
- расширение набора команд
Первый пункт нужен, потому что еще остались незавершенные детали и в архитектуре, и в интерфейсе. Расширение же набора команд представляет собой следующий этап, реализация которого будет опираться на жизнеспособную инфраструктуру, сделанную ранее.
Стажировка
Теперь хотелось бы немного рассказать о том, как происходила моя работа в компании JetBrains.
В первый день августа все новые участники практики собрались на ресепшене. Мы получили бумагу о неразглашении тайн компании и вскоре отправились на мини-экскурсию. Нам показали основные объекты в экосистеме офиса и рассказали, что и как работает, кто и где сидит, как попасть на крышу, и всё остальное, что могло бы быть интересно. Далее каждый узнал, в какой комнате он будет сидеть, и все разошлись по своим местам. Началась работа.
Я попал в комнату 303 – это была переговорка на третьем этаже с чёрными стенами и жёлтыми занавесками. Помимо меня в комнате трудились ещё четверо. Когда мы пришли, рядом с нашими компьютерами уже лежали все необходимые инструменты персональной интеграции: электронный пропуск и документ со сведениями об аккаунтах, корпоративной почте и ресурсах компании.
Моими соседями оказалась команда из трех человек, работавшая над проектом «VMkit и MMTk», а также один из участников проекта, связанного с декомпиляцией JVM-байткода. Всех соседей, как и меня, курировал Дмитрий Булычев.
Первым этапом моей стажировки стало изучение имеющихся наработок, которые остались от ребят из АУ. Ещё за два дня до начала практики я нашёл одного из прошлых участников – Сергея Савенко – в социальной сети, и расспросил его о проекте. Сергей охотно ответил на мои вопросы и рассказал об устройстве основных составляющих плагина, их взаимодействии друг с другом и прочих первостепенных вещах. В дальнейшем, уже во время стажировки, это помогло мне быстрее разобраться в незнакомом коде.
На тот момент Сергей тоже проходил практику в JetBrains, и потом оказалось, что мы сидим в соседних комнатах. Правда, в офисе с ним встретились всего пару раз.
Месячное трудоустройство в компании происходило на условиях работы full-time, что подразумевало 8-часовой рабочий день. Жёсткого графика у нас не было, поэтому каждый составлял режим, исходя из собственных предпочтений. По странному стечению обстоятельств все мои соседи оказались жаворонками: они начинали работу рано – около 10 часов. Я же обычно приходил с 12 до часу, когда все были уже в сборе. Но и заканчивал гораздо позже остальных.
В последнюю неделю августа на МатМехе СПбГУ устроили «летнюю школу», в которой были задействованы многие студенты этого факультета, а также Дмитрий Булычев. Команда «VMkit и MMTk» в полном составе отправилась на занятия, и в 303й комнате нас осталось двое. Эту неделю мы работали без руководителя, что, впрочем, никак не сказалось на эффективности.
В основное время практики общение с Дмитрием происходило, как правило, по инициативе самого студента. Мы проводили встречи по мере необходимости и обсуждали все, что было актуально на тот или иной момент. Была одна глобальная задача, которую мы изначально подробно обговорили, после чего я имел достаточно самостоятельности в работе. Так что работать с Дмитрием мне понравилось. Да и вся стажировка получилась отличной!
Автор: beenom