Памятка рекрутеру

Совершенно не считаю рекрутеров бесполезными людьми, они полезные, нередко адекватные и разумные (в той же пропорции, в которой адекватность встречается в социуме), но раз за разом умудряются совершать одни и те же ошибки, что потихоньку выбешивает. Дайте ссылку на это эссе знакомому IT-рекрутеру, пусть проникнется.

Во-первых, не надо мне звонить. НЕ НАДО. ЗВОНИТЬ НЕ НАДО, БЛИН ВАШУ. Разговор голосом в отношениях «разработчик vs рекрутер» — это финальная стадия отношений, не стартовая. Во время вашего звонка я могу быть фиг знает где, услышать фиг знает что (если вообще захочу), вы всё равно весь текст вакансии мне не расскажете (а если расскажете, я треть не услышу) и т.д. Внезапно звонящий рекрутер звучит как стопицотый телефонный спамер, вносимый в чёрный список, не более. Если у вас есть мой номер телефона, у вас должен быть и email. Как вы, блин, вообще представляете себе процесс? Оу, звонит незнакомая девушка, тарабанит два-три предложения, а я «уря! хотеть к вам сходить прям сейчас вечером нет сейчас хотеть берите аааа»? Нет, правда?
Во-вторых, читайте резюме. Рекрутер, предлагающий мне вакансию фронта, изумляет до невозможности. Рекрутер, спрашивающий, какой у меня стаж и опыт, тоже. Рекрутер из Екатеринбурга, удивлённый «ой, а вы не в Е.?», удивил взаимно. Вы потратите пять минут на человеко-кандидата, но избежите кучи нелепостей, после которых у разработчика подозрения, что всё у них так, потому нафиг надо.
В-третьих, почта. Офигенное изобретение человечества, позволяющее рекрутеру дать мне 1) много нужной информации, 2) возможность вдумчиво исследовать вакансию. Погуглю контору. Посмотрю на карте офис. Прикину требования к себе. Вдруг у меня знакомые есть в конторе, им напишу, спрошу. Вот только после этого процесса что-то внятное отвечу. Не потому, что я сноб и зануда (хоть я сноб и зануда). Потому, что вакансий много, рекрутеров много, у меня есть выбор. Если рекрутер не осиливает в этот выбор доложить свой лист текста, для меня это точно не трагедия, просто я не нужен этому рекрутеру, а этот рекрутер мне.
В-четвёртых, общение, личность, социализация, всё такое. Пункт со звёздочкой, да. Письма из шаблона убогие («Уважаемый(я) Сергей», ага). Рекрутер, общающийся не со мною, но с анонимным ресурсом, от найма которого рекрутер получит копеечку, скучен и ничем не выделяется на общем фоне. С таким же успехом могу HeadHunter полистать. Особенно несчастно выглядит на фоне рекрутеров, с которыми сложились товарищеские отношения. Разница в том, что они начинали не шаблоном. Попробуйте написать простое человеческое письмо. Не надо стихами, не надо клоунады. Простое человеческое. Можно даже без полной вакансии сразу. Устроит «Сергей, привет. Знаю, что не в поиске работы, но не считаю лишним обменяться контактами, если вы не против. Вы всё так же джавист, специализацию не сменили?» и т.п. Я общительный и отвечу. А рекрутер мне ответит. А я. Но вот именно с человеческим общением у рекрутеров не складывается, сплошной равнодушный поток.

А так-то ребята и девчата нужную работу делают, аки пчёлки, цветочки опыляющие.

Главный рефакторинг

Посмотрел вчера на код после джуниора, сделал всего один рефакторинг и тут же удалил 380 строк. Задумался, вспоминая последние 10..15 рефакторингов, что делал. По сути все они были одним и тем же: убийство копипасты. Нет, иногда копипаста не плохо. Иногда она даже нужна и является элементом архитектуры. Но часто она всё-таки фу и бяка. И один из skill’ов, что разработчик должен натачивать в себе с первого же молочного зуба — чутьё на плохую копипасту и практику её уничтожения. Если этого нет, нет и хорошего разработчика, даже не надейтесь.

Более культурно это нынче называется DRY (Don’t repeat yourself) и за последние лет двадцать каждый уважающий себя учебник рекомендует следовать этому принципу (ещё до того, как его сформулировали).
Например, [Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts. Refactoring. Addison-Wesley, 1999]: «Number one in the stink parade is duplicated code. If you see the same code structure in more than one place, you can be sure that your program will be better if you find a way to unify them».
Например, [Steve McConnell. Code Complete. Microsoft Press, 2004]: «Duplicated code almost always represents a failure to fully factor the design in the first place». (на деле у него примерно такой же текст уже в 1998 году был.
Например, [Robert C. Martin. Clean Code. Prentice Hall, 2008]: «Every time you see duplication in the code, it represents a missed opportunity for abstraction. .. Find and eliminate duplication wherever you can».

Почему это важно? Даже вот не с позиции абстракций и прочего, но сугубо прагматично кодерски.
Во-первых, вы мешаете JIT’у и прочим оптимизациям. Если исходник в одном месте и часто вызывается, у него гораздо больше шансов на автоматическую оптимизацию, чем у того же исходника в двадцати местах с размазанными вызовами.
Во-вторых, вы мешаете коллегам изучать код не только увеличенным объёмом текста и пустыми ожиданиями «раз оно двоится, может, не просто так», но и тем, что в IDE не получится тыцнуть в один метод и найти его использование.
В-третьих, вы очевидно мешаете исправлять этот код. Я и в самом деле сегодня вынужден был заменить 20+ копипаст. Предположим, правил бы багу. Мне пришлось бы править её в 20+ местах, после чего генератор копипасты был бы упомянут в разных позах и разных занятиях. Не говоря уж о том, что в случае баги я мог бы в одном-двух местах её и не исправить, пропустив. В общем, беда.
В-четвёртых, вы мешаете делать рефакторинг. Довольно часто бывает так, что после выноса копипасты становится очевидным следующий шаг. А потом ещё один. Рефакторинг похож на падающие доминошки, после одной каки чистятся ещё десять и в конце красивый компактный понятный код. А когда перед глазами портянки, сложно сразу уцепить возможность улучшения.

В общем, дорогие джуниоры, учитесь это самое. Даже если у вас в телах if’а повторы, уже повод почесать репку. Чешите репку чаще, оно полезно.

Лучшие ошибки софта VII

Довольно смешная (не смешная для авторов, конечно) ошибка произошла несколько лет назад. Игра Aliens: Colonial Marines вышла в феврале 2013 года и быстро получила шквал критики. Ну очень сырой продукт выпустили. Нещадно бажило всё, от графики до AI. И вот спустя четыре с хвостиком года обнаружился символ, исправление которого привело к наизаметнейшему улучшению поведения монстров. Достаточно было заменить ошибочное «Teather» на верное «Tether». Тестирование? Не, не слышал.

Автомобильная индустрия вовсю напичкивает машины сложным софтом, потому очередная проблема не удивляет. Но масштаб последствий интересный. Итак, Fiat Chrysler Automobiles NV отзывает около 4.8M автомобилей в США по причине баги в круиз-контроле. Вернее, с ним-то всё хорошо. Просто при схождении звёзд в 15 моделях этот контроль потом не выключить, да ещё и замыкание происходит. В общем, веселье, если ты не за рулём.

Затрудняюсь оценить ущерб, но ошибка классическая, хоть в учебники. В 1978 году с помощью NASA начали исследовать озоновые дыры над Антарктикой. Датчики собирают данные, софт анализирует, дыры находятся. Уря-уря. Пока в 1985 году совсем другие ребята не обнаружили, что огромная дырень прошла мимо программы исследований просто потому, что в код влепили ограничение на верхние границы. Мол, если значение такое-то, то оно шибко толсто, так не бывает, явно ошибка датчиков. Оказалось, бывает и не такое.

На дне у Ларнаки с 1980 года лежит большой и красивый кораблик MS Zenobia. А лежит он там потому, что в софте, управляющем закачкой балластной воды, выстрелила бага, закачавшая слишком много воды слишком не вовремя. Жертв нет. Как и Зенобии. Зато дайверам раздолье, внесено в карты годных мест.

Долго колебался, добавлять эту историю или нет. Решил добавить, т.к. можно считать примером того, с какой стороны в софт может прилететь проблема и как легко всё испортить, не учитывая все векторы «атаки». На юге Финляндии 12 апреля 1997 года поезда не ходили целый час. Всё потому, что на клавиатуру упала скрепка. Упала под пробел и, как понимаю, накрыла контакты. Дальше я не понял причины (машина запрашивала логин три дня и переполнила винт?), но в итоге сигналы на железке были переведены автоматикой в «стоп». Ну всё и остановилось. В общем, учитывайте и такие случаи, да.

Книга: Getting Started with SQL

lrg (1)
Thomas Nield.
Getting Started with SQL: A Hands-On Approach for Beginners.
O’Reilly, 2016.
Есть особая категория книг — помогающие переступить порог входа. Обычно в них нет откровений, нет сакральности, просто текст, который написан так доступно и так деликатно к измождённому учёбой мозгу, что после прочтения уже не страшно, можно идти дальше.
Вот эта такая. Всего 100+ страниц, базой SQLite, рассматривается самый ходовой набор SQL. Совсем немножко захвачена тема дизайна схемы базы данных, но тем, кто вообще никогда, и так норм.
Книга годная, советую тем, кто впервые сталкивается с SQL и хочет оперативно подхватить основы.

Инфраструктура стартапа

// По другому поводу написал конспект современной инфраструктуры, но получилось достаточно цельно, потому и за эссе сойдёт.
Развитие инфраструктуры идёт в сторону «делать больше, платить меньше». В общем, как и везде на рынке технологий. Небольшие компании не могут позволить себе сотни тысяч долларов ежемесячно, да и большие давно стараются ужаться в подобных расходах (один лишь GitHub на 1K пользователей в год начинается от 15М рублей), потому прогресс идёт вполне ожидаемым путём.
Под инфраструктурой далее подразумеваю всё, что обеспечивает процесс разработки и эксплуатации продукта, а не части самого продукта. Потому, например, Nginx в тренде, но это не инфраструктура.
Упомянутые названия считаю современным [хайповым] трендом. Иначе говоря, если собрать в небольшую толпу десятка два 20..30-летних разработчиков, из толпы будет доноситься то, что опишу ниже. Безусловно, существуют организации, живущие на другом софте, но речь не про них.
Каталог ниже также можно рассматривать, как первый набросок для первых обсуждений в начинающем стартапе. О, у нас есть N копеек и два человека, что мы можем из этого соорудить, чтобы продержаться десять лет до первого миллиона копеек? Если с этой позиции смотреть, так нынешний софт в какой-то мере представляет собою конструктор Лего. Кубики умеют работать друг с другом, редко являются обязательными, конструкцию по мере нужды можно наращивать и даже местами заменять с адекватной миграцией данных, ежели руки прямые. Я как-то прикидывал, нынче при действительно прямых руках можно чуть ли не всю инфраструктуру размазать за $150 в месяц. Не на сто человек, да, но мелкий коллектив вполне. Хорошие времена.

Нулевой круг: хостинг особо упомяну.
В тренде аутсорсинг и облачность. Соответственно, массово выбирают тех, кто на нормальном уровне за нормальные деньги предоставляет все те услуги, которые предоставлялись бы собственной серверной с отрядом админов, железячников, ноков и завхозов. Влёт можно назвать [в порядке убывания универсальности] Amazon AWS, Microsoft Azure, Google Cloud Platform. Это очень разные платформы со своей спецификой каждая, потому равными назвать не могу. Просто разные. Если нужно «в два клика» что-нибудь захостить, есть DigitalOcean. Сервисов на порядок (если не два) меньше, чем у того же AWS, но с задачей справляется.

Первый круг: VCS и Issue tracker.
VCS. Исходный код и прочее надо где-то хранить и обеспечить общину возможностью совместной работы с ним. Совместная работа нынче подразумевает активную вовлечённость, социальность, частично геймификацию, интеграцию со всем на свете. В тренде GitHub, GitLab, Bitbucket. Все три решения сделаны поверх git.
Issue tracker. Весело, молодо и задорно жить без тикетов или обходиться цветными бумажками на доске, но рано или поздно, а команда из этих штанишек вырастает. Задачи надо где-то описывать, обсуждать, отслеживать статус, строить графы зависимостей, получать срезы состояния и прочее. Тут устроить зоопарк проще, т.к. каждый год кто-нибудь пытается повторить успех JIRA (ведущий ледокол рынка трекеров, с каждым релизом бьющий рекорды неудобства). В спину ей дышат Bugzilla (для совсем олдскульных), YouTrack. С ощутимой натяжкой можно упомянуть Trello, но они всё-таки про другое. Но если далеко от системы карточек на доске уходить не хочется, то и Trello сойдёт.

Второй круг: общение, мониторинг и логи.
Общение. Команды часто распределённые (особенно если вы стартап и вам дешевле нанять двух senior’ов из Мордовии, чем одного московского middle), потому тема «где нам обсуждать работу?» поднимется быстро. Важной характеристикой решения является возможность видео на команду. Тут тоже бардак, т.к. долго не было единого продукта, решающего все задачи разработки (закрытые групповые каналы, архив, конференции, plugin’абильность, модные боты и т.п.). Потому у вас сейчас два варианта: устраивать конструктор из Skype / Jabber (ссылка на протокол) / Telegram или использовать Slack. Особняком варианты для knowledge base — что-то для хранения коллективных знаний. Тут у каждого своё, хоть одну из сотни Wiki поднимай, хоть один из вариантов по подписке, хоть закрытый репозиторий на GitHub. «Моделей» слишком много на любой вкус.
Мониторинг. В какой-то важный для команды момент количество тихо упавших сервисов начнёт действовать на нервы, после чего срочно вспоминают о нужде мониторинга живости машин и софта на них. Тут тоже не особо много боевых альтернатив. Частые метрики снимаются либо в Prometheus, либо в Influx. Событийный мониторинг есть смысл делать через всё тот же Zabbix. Приятные глазу графики как смотрели, так и будем смотреть в Grafana. А всякие стектрейсы и прочие ошибки можно отправлять в Sentry.
Логи. Весь софт пишет мегагигабайты логов, об которые ушатаешься ходить на каждую машину и грепать файл за файлом. Потому человечество придумало ELK stack (Elasticsearch, Logstash, Kibana). Держать в инфраструктуре эту триаду — та ещё головная боль, но иметь возможность удобно оперировать логами с кластеров… бесценно.

Последний круг: Continuous integration, Continuous delivery и остальное.
Темпы современной жизни диктуют темпы и разработке. Продукты надо делать быстро. Скорость часто бьёт по качеству, потому элементы CI/CD включают в себя также и максимальное исключение человеческого фактора — автоматизация проверок кода, автоматизация сборок, выкаток. В этой области раздолье и зоопарк полный. На деле же основной проблемой будет совсем не софт, но внедрение разработчикам в головы нужды в CI. Например, там тесты писать надо, а это же таааак скуууучно.
В этом же разделе решения, которые могут примениться раньше, могут позже, могут прямо-явно не относиться к CI/CD, но здорово его облегчают. В общем, список того, чем занимаются, когда хотят сделать всё правильно и есть возможность.
Контейнеры. Удобнее куда-нибудь доставить и где-нибудь поднять уже готовое приложение со всеми конфигами, файликами и прочим. Как минимум, это быстрее. На сцену выходит Docker, царь контейнерного хайпа. Лишь избранные знают и думают о других решениях. На самом деле вполне стоит и подумать, т.к. Docker не панацея и для ряда задач имеет смысл прикинуть альтернативы.
Оркестровка. Нравится это слово в контексте «хорошо, давайте управлять всеми этими контейнерами на этих инстансах в этих облаках». Тут поле боя, на котором рубятся Swarm с Kubernetes. Правда, тут снова тема Docker, но чё уж, мода. Сюда же Nomad для спартанцев.
Сборка и тесты. Так лаконично свёл CI в две задачи. На деле, конечно, решается гораздо больший спектр. Навскидку тут можно назвать три продукта: Jenkins, TeamCity, Travis CI (ваш выбор, если open source). Каждый со своими чудесами, своими лицензиями и ценами. Но вряд ли вы обойдётесь без них при внедрении CI в инфраструктуру. Писать скрипты запуска и сборки по крону занятно, спору нет, но лучше не надо.

Уверен, я не назвал десятки решений, которые вы считаете очень важными или лучшими или ещё какими-нибудь. Это нормально. Их назовёт кто-нибудь другой. Часть из них я просто не знаю. Часть не подходит небольшим командам (у вас целый департамент админов, это круто). Часть… кхм (знаю бойцов, живущих в IRC, им норм). Наконец, 35 ссылок в одном эссе — пока рекорд тут, ставлю запятую.

Оэрмаина не Баззия

То, с чего началось: «Не надо писать в резюме опыт работы с базой XYZ, если весь ваш опыт заключается в CRUD через ORM. Приводит к неловкости на собеседовании».
Если прищурить глаз, что такое ORM? Слой абстракции, который позволяет вам работать с объектами вашей предметной области, не задумываясь особо о том, как они хранятся, как выбираются и т.д. Собственно, потому ORM’ы и появились — разработчики тратили мегатонну ресурса на то, чтобы даже простой CRUD сделать — схему напиши, модель напиши, методы напиши, result set в объект разбери, объект в тот же INSERT расчлени… И так на каждую писюльку. Пальцы устают.
Заодно сбоку появились механизмы миграции, больше декларативщины и т.д. Откройте мануалы к Hibernate или Django, там всё есть.
Вроде бы круто, не? Круто. Только теперь разработчик умеет работать с ORM, не умея работать с базой данных. Иначе говоря, ORM’ы и сделаны для того, чтобы тебе не надо было уметь, а ты человек, потому не умеешь и не хочешь уметь то, что не применяешь прям каждый день.

Первый пример. Фигня в том, что ORM бывают не оптимальны. И баги там бывают. И вообще всякое бывает. Написали вы код, красивый, умный. Выкатили на тестинг. Работает. Выкатили на прод. Работает. Проходит неделя. Работает на 5% медленнее. Проходит месяц. Бывают провалы на 20% деградации. Почему?
Включается дебаг запросов. Вытаскивается результат ORM-генерации. По нему смотрится план выполнения. Находятся проблемные участки. Осмысляется причина проблемности. Устраняется.

Другой пример. На фронте страничка. На страничке график за пять лет. По сути надо вывести результат серии агрегированных запросов по двадцати таблицам и 20M строк, размазанных по этим таблицам. Задача за рамками CRUD, очевидно. Тем более, отработать должно не дольше 500ms. Надо заметить, что в современных ORM часть подобных задач вполне решаема, но только часть. В ряде случаев вы получите прямолинейный JOIN на всё поле данных, от чего база будет кряхтеть, а пользователь минуту смотреть на спиннер. Ваши действия?
Написать в итоге правильный оптимальный запрос на SQL, после чего либо перенести его в ORM с сохранением характеристик, либо из ORM сырым и дёргать, бывает. Некоторую часть таких запросов оптимальными можно сделать только со знанием конкретной базы данных.

Третий пример. Вы наплодили тысячу классов в модели. ORM пожал плечами и создал тысячу таблиц. Он ведь инструмент, а не заменяющая мозг штука. Молоток не отпихивает неправильный гвоздь, лупит куда сказали. Бац, всё просело. Ну вот просто адово медленно работает. И?
Схему базы данных тоже надо проектировать. И делать это с учётом множества факторов. Просто набросать кучу классов и надеяться, что прокатит, получается не всегда. И снова ORM тут не помощник, скорее, добавляет дополнительные факторы для учёта.

Фактически каждая задача в области хранения данных в базах сводится к набору из трёх переменных: { фреймворк, язык[и] запросов, база данных }. Например, { Hibernate, SQL, PostgreSQL }. Или { Spring Data, MongoDB QL / JavaScript, MongoDB }. Если значение (требуемый уровень знаний) переменной превышает ваш уровень, задачу в оптимальный с внешней точки оценки срок вы сделать не можете.
Отмечу: не оцениваю эту тему с позиции хорошо / плохо знать / не знать. Каждый сам задаёт себе границы полезности. Проблема в другом.
Предположим, у вас в резюме в опыте работы указаны «Московский метрополитен» и «вагоны Еж-3 и Еж-6 последние два года». Что думать читающему резюме? Какой опыт от вас ожидать и какие вопросы для проверки задавать? Вот, что я подумаю (простите дурака с уникальным ходом мысли): о, этот боец разбирается в вагонах! Ура.
Приходит боец. Многолетний опыт спуска по эскалатору, знает названия станций, знает особенности первых и последних вагонов некоторых линий. Начинаю разминку о вагонах. За 15..30 минут собеседования выясняется, что опыт заключается в том, что вагоны этих моделей перемещали человека от A до B. Человек заходит. Некоторое время ждёт. Выходит. Всё.
Так. Хорошо. Зачем в резюме указал? Формально говоря, опыт есть без сомнения. Только это опосредованный опыт, да ещё такого объёма, что совершенно бесполезен в употреблении другими людьми. Ровно так же звучат рядом стоящие Hibernate и MySQL, если MySQL для вас тот же вагон метро из аналогии выше. Почему бы тогда не указать в опыте, скажем, ПНО 63-12-8? Рязанский завод ЖБИ №2 выпускает плиты перекрытия, по которым вы ходите в домах. На плитах слой бетона, слой заливки, гидроизоляция, паркет. Кое-где штробили проводку. Всё это не вы, впрочем. Весь ваш «опыт» — вы по ним ходите. Эдак десятки страниц резюме можно забить.
Почему-то знание лишь одной трети от набора заменяет в голове знание всей триады. О, если я знаю ORM, я знаю SQL и базы данных. Да нет, конечно же.

Хочу ещё пройтись по мнению «это специальные знания, требования к которым надо особо указывать в вакансии». Возможно. Правда, я пока не готов с этим согласиться. Бекендер — разработчик, часто имеющий дело с базами данных. Вы можете смотреть на мир через любую любимую призму, но вот я открыл HeadHunter, вбил [Java backend] и нажал Enter. Читаем (попутно умиляясь подмесу совсем не Java) первые десять вакансий (цитирую прям копипастой подряд из каждой):

  • Опыт работы с базами данных: SQL, MySQL, JDBC, Oracle и т.д.
  • Понимание SQL, NoSQL, реляционных, объектных БД, blob и других решений для хранения данных.
  • Понимать, во что выливаются операции с ActiveRecord, оценивать эффективность получающегося SQL.
  • Знание принципов работы баз данных и опыт работы с MySQL/PostgreSQL, умение писать сложные SQL запросы.
  • реляционные СУБД, понимание принципов проектирования БД, отличное знание SQL
  • опыт использования NoSQL баз данных (Cassandra, Hazelcast).
  • Уверенное знание SQL (Транзакции, оптимизация запросов, планировщик запросов и т.д.) .. Знание PostgreSQL(9.x), .. Hibernate.
  • Опыт работы с базами данным .. SQL, .. MongoDB, Spring Data Reactive.
  • Опыт работы с БД SQL .. с MS SQL
  • Разработка с использованием одной из следующих БД: PostgreSQL, MySQL, AWS DynamoDB, Amazon Aurora; Опыт оптимизации БД и запросов к БД (SQL или NoSQL).

Скажите, вот по вашему ощущению объективной реальности… слова «знание», «опыт», «использование» и «понимание» означают «я работал с базой только через ORM»? Есть ли у вас ощущение, что от бекендеров ожидается незнание SQL и баз данных? Как всё-таки будет понимать ваше резюме читатель, если это резюме бекендера и в нём упоминается «опыт с MySQL»?

Пролистал следующие десять вакансий подряд. Картина точно такая же. Более того, вакансия «Специалист по тестированию» включает в себя «знание SQL» даже не в дополнительных требованиях. Переведу: индустрия не ожидает от бекендера раздельного знания одной из трёх переменных выше. Если ты позиционируешь себя бекендером, ты должен знать фреймворк (да хоть JDBC) AND язык (SQL) AND базу данных (XxxSQL). Не OR из мечт о лёгкой работе. Именно AND.
Вернусь к началу и доведу до абсурда. 2018 год. Россия. Вакансия, состоящая лишь из слов «Java, middle+, backend». Резюме, состоящее лишь из слов «Java, backend, MySQL». Скажите (таки полистав HeadHunter), сколько всё-таки человек из нанимающих будут трактовать это как приглашение не знать базы данных и не знать SQL? Сколько всё-таки человек из нанимающихся на позицию middle+ будут под словом «MySQL» подразумевать незнание SQL и MySQL? Да, не ноль. Иначе бы не было этого эссе. Но и даже не один из десяти, что радует.
Завершу цитатой Мартина Фаулера:

I’ve often felt that much of the frustration with ORMs is about inflated expectations. Many people treat the relational database «like a crazy aunt who’s shut up in an attic and whom nobody wants to talk about». In this world-view they just want to deal with in-memory data-structures and let the ORM deal with the database. This way of thinking can work for small applications and loads, but it soon falls apart once the going gets tough. Essentially the ORM can handle about 80-90% of the mapping problems, but that last chunk always needs careful work by somebody who really understands how a relational database works.

Вот между ORMonlybody и этим somebody есть разница. Постарайтесь её понять.

Опыт в годах

Не всегда получается звуками из рта объяснить, почему при рассмотрении разработчика пишут требуемый опыт в годах и нафига вообще это измерять годами, ведь я, Вася Пупкин, в свои N лет знаю десять языков, на доске решаю любую задачу за пять минут и вообще дерзкий пацан.

Сначала вводная и рамочная.
Вас нанимают для того, чтобы сделать продукт. Затасканное слово, но таки да. Продукт — что-то, чем люди могут пользоваться, желательно, без боли. Продукты бывают разного уровня: для себя, внутренние, массовый рынок, под заказ по ТЗ, гиперответственные (военка, космос, медицина, транспорт, энергетика).
У продукта разные стадии. Задумка, прототипирование, [мучительная] разработка, доводка, релиз, эксплуатация, поддержка, развитие[, закрытие]. Сроки у этих этапов… Ну, зависит от, конечно. Но субъективно с потолка средний продукт до релиза делается год-два, доводится год, живёт до переписывания два-пять лет. Но это с потолка. Важно понять: продукты делаются до состояния продукта долго. Можно за выходные нахакатонить меленькое мобильное приложеньице или каркас какой-нибудь библиотечки с братвой, но это будет творение хакатона, а не «этим софтом мы отгрызём 1% планеты у Google».
Чтобы из кода сделать продукт, часто надо сделать интересные 10% работы и неинтересные 90%. Например, однажды боец месяц писал тесты. Каждый рабочий день мерно покрывал модуль. Если мне не изменяет, там за тысячу тестов перевалило, к ним ещё и отдельно документация была написана прикольными табличками входа-выхода. Или вот у вас база, в ней 100+ таблиц, надо написать обвязку для CRUD. Интересно? Нет. Но надо. На такую работу могут уйти месяцы жизни. Приходите в офис. Садитесь. 8 часов пишете код, который почти такой же писали вчера, неделю назад и будете писать следующую неделю. Восхитительно.
Таким макаром кто наиболее интересен работодателю? Ну, помимо прорывных гениев, внезапными озарениями двигающих за пару дней человечество вперёд. Интересны, очевидно, разработчики, которые могут начать продукт, сделать его и продолжить. Иными словами, те, у кого набита достаточно чугуниевая жопа, чтобы год-два-три сидеть на ней ровно, доводя начатое до конца.
Искусство аналогий: вы собираете караван из Москвы до Владивостока. Ехать долго, муторно, машины разные (автобусы, грузовики, седанчики, даже два велосипедиста). Нужны водители. Которых в Москве за руль усадишь, через год во Владивостоке от руля отковыряешь. Я вам расскажу, чего вы на этом маршруте не хотите.

Во-первых, «чёт я устал, у меня апатия». Машина Васи едет медленнее, Вася всё унылее. Проехали треть маршрута, минус боец. Вася так далеко от столицы не забирался, предела своих возможностей не знал. Фигово, что узнал так рано и на вашем маршруте.
Без аналогии: знать свои пределы важно. Но вы не можете узнать их вне опыта. Одни марафонцы, другие спринтеры. Одни могут год копать поле и вскопать, но не могут рывком за неделю без сна выложиться в месячную норму. Другие могут рывком выложиться, но сдаются через месяц монотонной работы. Собсно, пока не начнёшь бежать марафон, не узнаешь, сможешь ли, захочешь ли добежать. Нужны оба типа, но вы на старте хотите знать, куда кого поставить. Марафонец — тот, кто уже пробежал хоть один марафон до финиша, уже пережил этот опыт, осмыслил и даже вот хочет ещё. Боец, не переживший это, понятия не имеет, что такое раз за разом брать себя за воротник, открывать десятое дыхание и копать траншею дальше без перманентного нытья и всхлипываний. У кого больше вероятность такого опыта, у Васи с годом работы или у Пети с пятью?

Во-вторых, «мне разонравились автобусы, я теперь люблю самокаты». Вася выходит из автобуса и на обочине начинает изучать самокатное дело. Середина маршрута. Автобус Васи взят на ремень, едва тащится без водителя за бандой. Чудесно. Оказывается, Вася ещё не закончил поиски себя и своего дао на великом пути Дао, потому пока-пока.
Без аналогии: в разработке много специализаций и редко кто прям с порога выбирает действительно своё. Первые годы состоят из проб. Сегодня я люблю C, завтра Python, послезавтра бегаю за хайповым машинным обучением, через год обожаю базы данных, а вообще геймдев крутой, но виртуальная реальность рулит. Ой, нет, мобильные приложения. Хочу писать под железо! Блиииин, как круто ботов делать! Аааа! Конечно, интересно наблюдать за этими юношескими горячими метаниями со стороны, но вам работу работать надо. Кто кажется надёжнее, Вася с годом Python или Петя, который уже пять лет джавист?

В-третьих, «за окном скучно, дайте мне красивые пейзажи». Вася в позе, Васе не сказали, что между Москвой и Владивостоком лежит постядерная пустошь. Все водители знают by default, Вася не знал. Выбегает из автобуса, оскорблённой походкой ловит попутки в Москву. Там красиво, там огни. Треть маршрута.
Без аналогии: всё больше людей, для которых работа должна быть интересным развлечением. Если в работе есть рутина, это плохая работа, надо её бросить. Потому нанимающие нередко внимательно изучают количество лет на разных работах. Вот Петя, за пять лет шесть мест сменил. Вот Саша, за пять лет два места. Кто с большей вероятностью умеет в рутину и в скучные пейзажи за окном?

В-четвёртых, «меня все обижают!» Вася открывает мир. Продавец сигарет может не улыбнуться. Лидер колонны может гавкнуть в мегафон. Велосипедисты вообще матерятся, покрытые пылью в хвосте самосвала. Сменщик Васи моется раз в месяц, потому всё, невыносимые условия, Вася убегает в закат. Середина маршрута, паренёк держался изо всех сил.
Без аналогии: тонкая душевная организация прекрасна, но коммерческая / промышленная разработка — это область решения задач, нахождения оптимумов, работа в окружении людей, столкновение интересов и т.д. Сам мечтаю на старости лет иметь работу, при которой тихонько сижу в углу сычиком и кноплю код без споров, договоров, объяснений, выслушиваний, дипломатии и всякого такого, но большинство работ не такие. Потому… хочется, чтобы нанимаемый Вася уже обкатался в бою и не дрожал трепетной ланью под каждым злобным зырком или после внезапного синего экрана смерти. Чем больше лет в резюме, тем толще нервы, логика простая.

В-пятых, «а что такого?!» Начало маршрута. У Васиного автобуса летние шины. На дворе зима. А что такого? Треть маршрута. Отваливается дверь справа. А что такого?! Середина маршрута. Выпадает лобовуха. А ЧТО ТАКОГО?! Через пару метров двигатель глохнет. Вася в недоумении.
Без аналогии: уважение правил техники безопасности приходит с годами. К некоторым и вовсе не приходит (привет перебегающим шесть полос автобана). Уважение, понимание и следование заветам всяких code style guide и вообще содержание кода в постоянной чистоте — оно тоже приобретается не сразу. Да, мастер должен всегда собираться. Да, должны быть тесты. Да, документация. Да, это мусор. И это. И вон то тоже мусор. Да, эта тысяча строк нафиг не нужна, блин, убери уже говно из-под ног, в автобус зайти невозможно без противогаза. Чем дольше разработчик работает, тем больше он видит примеров отдалённых косяков из-за всяких «и так сойдёт», «а что такого» и классического «я потом уберу!» Соответственно, если не рандом в черепе, у шестилетнего Пети код будет хотя бы чище, чем у двухлетнего Васи.

Фигня человеческой головы в том, что словами до нас почти не доходит. Только до самой ментальной элиты хватит слов «ЗАКРЫТО», чтобы не дёргать ручку. Вот когда подёргают раз пять, а потом и на другой двери, да ещё разочек, вот тогда закрепится «надпись ЗАКРЫТО не просто так». Сам не раз наблюдал. У нас на районе как-то на месяц закрылся Дикси. На двери было шесть (!) разных табличек и наклеек с «ЗАКРЫТО». Один фиг подходили, читали (!!!) и дёргали дверь.
Разработчики люди. У них такая же голова, пусть чуть другой формы. Потому в ночных фантазиях нанимателя поля пашут бойцы, которые уже наигрались, уже наискались, уже перебесились, уже не рыдают в подушку от грубого слова, уже насмотрелись на травмы за станком, уже обкатались под танками. Да, другие тоже нужны. Всех к делу пристроить можно. Но иногда очень хочется просто собрать караван, усадить вот этих суровых дальнобоев и через год получить письмо «мы на месте, чего дальше?» Детское наивное желание, да.

Книга: Информационные технологии в СССР

aab2ea96887a7168249c05cbf9131473
Ревич Ю.В., Малиновский Б.Н.
Информационные технологии в СССР. Создатели советской вычислительной техники.
БХВ-Петербург, 2014.
Ревич взял за основу книгу Малиновского «История вычислительной техники в лицах», расширил, [заметно] дополнил. Получился вполне хороший сборник биографий основного пантеона советского вычтеха.
Есть два нюанса.
Во-первых, речь почти только о «железячниках», конструкторах, делавших именно компьютеры. Программисты вне темы книги.
Во-вторых, авторы стараются быть положительно-нейтральными, так скажем. Лишь изредка прорываются штуки вроде письма Ревичу: «Опыт внедрения Эльбрус-1» от того, кто над этим Эльбрусом в 1982 году всем телом бился. Т.ч. срывания покровов нема, они в других статьях и книгах. Просто ровные истории о.
Книга годная, читать было интересно. Получил много поводов подумать и порыскать по другой литературе.

 

Мои учителя

Любой нормальный программист учится постоянно с первой же клавиатуры. Ненормальных надо учить. И у каждого своё понимание объёма «учить». Вспоминаю тех, кого считаю учителями, и считаю, что подхватил у них правильное, применяю правильно и «учу» правильно. Имена далее с потолка, мало ли. Кому надо, себя узнают.

Ваня (мой первый лид) смотрел с недоумением. Мне было 18 лет, не знал C, попал в контору по знакомству с директоратом, денег первые месяцы не получал и не просил, хотел учиться правильной разработке. Все мои дурацкие фантазии о какой-либо заботе были разбиты. Получил разработку небольшого (программируемый софтовый калькулятор) коммерческого проекта в одно рабочее рыльце. Получил лида, который жёстко придерживался правила «умный сам научится, а дурака учить — время зря тратить». Получил первый опыт прямого общения с заказчиком, да ещё и на английском (тогда я влепил в письмо чудесное слово «fitches» вместо «features», ведь все вокруг говорили «фичи»!). Получил первый опыт стороннего тестирования — Ваня подходил, с закрытыми глазами проводил полной ладонью по клавиатуре и порождаемый этим хаос раз за разом валил моё приложение в корки. Корки были болью, ибо кто писал на C под MacOS 7/8, тот танков не боится. Ваня пожимал плечами и уходил. Ревью кода проходил раз в месяц в режиме «ты чем думал, когда эту х..ню написал? а это вообще п….ц, а не код». Всё усугублялось тем, что при отсутствии информации об API MacOS я в процессе наваял свою библиотеку control’ов. Думали, выкинем этот ужас, но заказчик вдруг захотел ТАКОГО, что только кастомное рисование и спасло.
В итоге метод Вани сработал. Я написал и сдал свой первый коммерческий проект. Ваня получил оффер и уехал в США в один из мировых top-10 руководителем. Что важно? Если ты хочешь научиться программировать, тебе не нужен учитель. Есть книги. Есть компиляторы. Есть сотни часов теории и практики. Человек извне нужен лишь для того, чтобы корректировать вектор, дабы ученик не упоролся в совсем уж идиотию (ну и явно показать, что каждую итерацию ты делаешь хрень, а не стабильный продукт, да). Ване не было пофиг. Слегка злобный, едкий и честный мужик, которого откровенно тошнило при взглядах на меня и на мой код. Но Ваня НЕ МЕШАЛ. Ученик хочет учиться? Так учись, кто не даёт-то. Хочешь программировать? Вот компьютер, программируй. Нужна нянька? Вернись в детский сад, няньки в нём остались, освободи место тем, кому нянька не нужна. Хочешь за свою работу получать деньги? Делай работу так, чтобы было за что платить деньги. Честно, откровенно, справедливо.
Урок #1: если хочешь учиться, будешь учиться и без нянек; если не учишься, просто не хочешь, иди в жопу тогда, в чём проблема?

Петя задолбал занудством и педантичностью. До меня не сразу дошло, что это я идиот, прямо скажем, но потом дошло. Тогда ещё не было принято фигачить прототипы в продакшен и отстаивать это как вариант нормы. Если ты катил в прод туфту, которая валилась с пятисоткой, ты криворукий олень, а не спешащий навстречу рынку хипстер. Всё просто. Петя рулил проектами на 10..20 человек с планами на 1..2 года. Опять же, это я сейчас понимаю, что организовать наше стадце так, чтобы мы уложились хотя бы приблизительно в годовой план… Дай мне такую задачу, убегу с паническими криками. А Петя справлялся. Пожалуй, то очень важное, чему у него научился (опять же, не меня учили, но достаточно было смотреть на крутого чувака внимательно) — ДОКУМЕНТИРУЙ. ЧИТАЙ МАНУАЛЫ. ПЕРЕПРОВЕРЯЙ СЕБЯ. ПЕРЕПРОВЕРЯЙ ЗАКАЗЧИКА. ВСЁ ПЕРЕПРОВЕРЯЙ. Тогда это раздражало. Сейчас хочется извиниться за свою тупость, но как-то уже и не к месту, много лет прошло. Петя, ты был прав.
Урок #2: без бумажки не только ты какашка, но и твой код, и твой сервис, и вообще всё.

Олег работал тестировщиком. Спокойный боец, даже флегматичный. Торкнуло меня однажды, когда мы в очередной раз сидели ночью, я катил релиз за релизом, а Олег заворачивал из-за багов релиз за релизом. Мы очень устали, была ответственность, всё такое. Олег как-то… всё так же спокойно и с пониманием проверял, возвращал, проверял, возвращал… И снова только позже, рефлексируя, я посмотрел на ситуацию со стороны. Стало стыдно. Разработчик, легко относящийся к своим багам, он… как бы так сказать… я совершенно точно не считаю такого разработчика хорошим. Никакой. Обычный. Возможно, плохой. Но точно не хороший. Твои баги часто бьют по другим людям. Вместо того, чтобы сидеть с девушкой в кафе, лежать с женой на диване, пить вкусное вино, гулять в красивом лесу или просто спать, другой человек тратит свою жизнь на твои косяки. Ты поленился подумать? Тестировщик сидит лишние часы. Поленился проверить? Менеджеру лишние циклы с тикетами. Поленился не быть мудаком? Пользователи исходят истошными кликами на неработающем софте. Фактически ты вор чужого времени, обычный раздолбайский разработчик за свою жизнь умудряется угробить и чужую, если просуммировать все убитые из-за него часы. Потому, если не хочешь быть редисом, становись специалистом, баги которого вызывают хотя бы интерес, а не фейспалм класса «опять этот криворукий, как же заманал».
Урок #3: твои баги влияют на всех и на всё; заядлый багодел крайне вреден, его надо искоренять.
Также Олег молча своей работой показал мне, что разработчик не пуп земли. Не будь тестировщиков, мы со всей своей гениальностью катили бы заказчикам такой кошмар, что из судов не вылезали бы. Не будь техписов, фиг бы кто понял, что за бред мы в очередной раз выдаём за удобный юзерфрендли суперпродакт. Не будь менеджеров, уже через неделю лебедь, рак и щука казались бы верхом организации. Не будь лидов (бьющих дубинкой по задранным лбам)… вот тут не уверен, кстати, потому замнём для ясности. Короче, не будь их всех, разработчики были бы тоже не нужны в том виде и качестве, в котором они есть сейчас — изнеженные капризные создания, вокруг которых всё должно улыбчиво вертеться в темпе вальса.
Урок #4: тестировщик очень нужен.

Игорь, под руководством которого я впервые сделал что-то, что включил во внутреннее «сперва добился», закрепил во мне ощущение: хороший руководитель НЕ МЕШАЕТ. Да, это риск. Легко продолбать момент, когда прям вот надо было коршуном пасть на жертву и помешать творить зло (собсно говоря, на это я пару раз напоролся и до сих пор размышляю о том, когда же всё-таки авторитарно бить по рукам). Но в то же время это в какой-то мере… правильное деяние с точки зрения человечности? Когда не вмешиваюсь, молча говорю что-то типа «считаю тебя взрослым зрелым специалистом, которому я могу доверить реализацию проекта без постоянного контроля, потому не подведи, пожалуйста». Постоянный контроль убивает творчество, мысль, инициативу. А так… заодно и воспитывает ответственность.
Урок #5: нет ничего круче самостоятельности.
Евлампий, Ефим и Егор в свою очередь примерно в тот же период жизни и осмысления показали мне, что плохой руководитель почти всегда мешает. И почти всегда тому причиной два кита: 1) некомпетентность, 2) страх потери контроля. Как и все неудачные в своих проявлениях люди, эти тоже учителя. Просто научили не быть (не стать) таким же. Спасибо.
Урок #6: внимательно смотри на плохих специалистов и учись у них не быть ими.

Анатолия показала, каким полезным и нужным может быть менеджер. И, соответственно, каким идиотом на фоне будет разработчик, считающий, что менеджеры не нужны и вообще лишнее звено. Тогда же я вывел правило: если у тебя бюджет на трёх разработчиков, найми сильного разработчика и сильного менеджера, тогда сдашь сервис в срок. Тогда же в голове устаканился один из маркеров проверки разработчика на правильный опыт работы и жизни: спросить о роли менеджеров. Если снисходительно пожимает плечами, значит, пионер. Вообще это коротенький абзац, да, т.к. тема чуть ли не отдельного эссе. Наконец, я не выдержал и женился на Анатолии (нормальный разработчик нормального менеджера не отпустит далеко), потому хвалить как-то неловко.
Урок #7: менеджер очень нужен.

Наблюдение за Кимой дало понимание… даже не нужды, она очевидна… роли саппорта в жизни планеты. И снова тупоголовый тот разработчик, что относится к саппортам свысока. Если человек хорошо и тщательно выполняет эту работу, на большом продукте он стоит пары разработчиков. В конце концов, именно следствия разработческих недоделок и косяков входят волной гуано в первую линию обороны психики наших нежняшек — в саппортов. Святые люди, ейбо. Мало того, что им приходится вежливо, тактично и толково отвечать на сотни «ааааа, вы уроды, ничего не работает, верните как было! атписька!», так ещё они продолжают улыбаться и общаться с теми, кто допустил столько багов. Я бы уже после первого дня такой нагрузки настроил бы форвард на разработку, пусть наслаждаются. Но нельзя так делать почему-то. Разбегутся-с.
Урок #8: саппорты святые.

Что в этом списке важно… Вас не должны учить, чтобы вы научились. Просто смотрите на людей. Наблюдайте за их работой. Не стесняйтесь спрашивать о том, как и что в их процессах работает. В десятый раз повторю то, что через раз тут пишу: учитесь самостоятельно. Нет, никто ничего вам не должен. Это ваша жизнь, вы за неё в ответе. За будущее, за свою специальность, за состояние мозга, за конфигурацию нейронов. Не мама, не папа, не бабушка и даже не цепочка лидов до боженьки. Вокруг вас всегда есть кто-то, кто умеет что-то лучше вас. Учитесь у них, достаточно иногда просто посидеть рядом. Человек не должен вас учить, чтобы быть учителем. Часто достаточно уже того, что он есть. Всегда есть что-то, что вы умеете плохо. Добудьте учебники, наточите пальцы и научитесь делать это хоть чуточку лучше.
В конце концов, попробуйте себя в разных ролях. Протестируйте продукт Альберта (и получите те же баги ещё раз пять обратно, после чего посмотрите в зеркало). Попробуйте отменеджить проект (тикеты, заказчики, формулирование ТЗ, подбивка сроков, планов, всё такое). Напишите мануал к своему сервису, дайте своей бабушке (не поняла? отличный у вас мануал). Замените саппорта на сутки. Ладно, жестоко. На час. Часа хватит. Побудьте лидом недельку (заодно поймёте, почему ответ «а потому!» не считается правильным).
PS. Ну и да, у всех (кроме Евлампия, Ефима и Егора) прошу прощения. До того, как стать умным, я был глупым. Жаль, что вы при этом присутствовали и вынуждены были из меня эту глупость своим примером изгонять. 🙂