Книги: OCA Java SE 8 Programmer I Certification Guide

oca
Mala Gupta.
OCA Java SE 8 Programmer I Certification Guide.
Manning Publications, 2016.
Очень специфический 700-страничный талмуд. Это не учебник. Это не мануал. Не шпаргалка. Не справочник. Это многократный унылый пересказ поднабора основ языка Java, который включается в темы первой сертификации Oracle. Прописные истины и базовые знания вам будут на каждой странице повторять, повторять, повторять, повторять, повторять.
Иными словами, текст заточен на то, чтобы заточить вас ровно на сдачу сертификации, не более. И в немалой мере задачу решает. Вы вспомните / узнаете некоторые неочевидные штуки, прорешаете 140+ тестовых вопросов (включая финальный экзамен в конце), привыкнете к мысли, что ЭТО просто надо пережить, а потом забыть как страшный сон. Как минимум, узнаете, как может выглядеть упоротое тестирование.
Фигня в том, что действительно все темы глубоко не покрываются, как мне показалось, или же не был сделан акцент. При прохождении mock exams от Enthuware эти лакуны всплывают, потому не рекомендую использовать Guide как единственный источник подготовки. Обязательно в комплексе с чем-нибудь ещё.
Книга полезна только тем, кто готовится к сертификации. Остальных она может отвратить как от чтения в целом, так и от языка.

История CSSO, выводы

Так вот, выводы, коих я сделал множество. Отголоски вы можете найти в эссе этого блога, но корни в CSSO.

Во-первых, если вы не product owner, ничего вашего нет. Нет ваших решений. Нет вашего кода. Нет вашего продукта. Ни к чему не надо относиться лично. Сразу выстраивайте забор и действуйте профессионально. Профессиональная разработка — уведомить настойчивого заказчика о проблемах, убедиться, что мысль донесена и проигнорирована, зафиксировать факт и авторство, решить задачу максимально хорошо, пусть это задача категории «пилить сук, на котором сидим». Сук спилен, мы упали, лапки сломали. И что? Вы этого и хотели. Я вообще многое научился документировать хотя бы истории ради. И с большим интересом с тех пор смотрю на людей, которые ну прям настаивают на том, чтобы диалог никак не фиксировался.
Во-вторых, энтузиазм хорошо, но подменять им реальность не надо. Спустя пару лет я размышлял. Вот чем мы думали, представляя, что недавние верстальщики, едва перековываемые во фронтендеров, начнут понимать и писать не вёрстку на JavaScript? Да даже сейчас (спустя 8 лет Node.js!) встречаю множество фронтендеров, в упор не знающих и не хотящих знать Node.js. Им сайты делать, а не утилиты править. Хорошо, обнаружил Пупкин, что CSSO не так сжимает background. Один из ста Пупкиных даже до репорта дойдёт. Один из сотни дошедших в исходник посмотрит. Один из сотни посмотревших что-то там поймёт. Не потому, что тупой, но потому, что ИМ НЕ НАДО. Всегда, когда есть вероятность, что какой-нибудь аудитории не надо, считайте, что не надо никому.
В-третьих, ИМ НЕ НАДО. Нет, правда. В мире по разным оценкам от 10 до 20 миллионов разработчиков. Посмотрите список коммитеров проектов, которые вы считаете ну очень, очень популярными. На которые все должны молиться и каждую бажку забивать молотками за секунду репорта. Сюрприз. Каждый проект в пересчёте на масштаб делает очень небольшая команда людей, которым действительно не пофиг. Остальным пофиг. Всё, что вы будете начинать в одиночестве, вы будете делать в одиночестве, продолжать в одиночестве и завершать в одиночестве. Недавняя история MongoDB-драйвера на Go тому примером. Чувак 7 лет тянул на себе вполне хороший драйвер, все использовали, но драйвер закрылся потому, что чуваку надоело, а больше никого нет. Ха. Пользователей может быть миллион, но вы всё равно будете в одиночестве. Они потребители вашего продукта, не более.
В-четвёртых, чем выше порог входа вашего начинания, тем ниже вероятность соратников. Люди не читают, не учатся, не интересуются. Всё непонятное им кажется страшным. У CSSO были PEG и OmetaJS, у PhantomJS низкоуровневый код. При этом последний автор PhantomJS говорит:

Потому что, одно дело, когда есть какая-нибудь популярная библиотека, та же самая CSSO, написанная на JavaScript — популярном языке, и сейчас, что называется, каждый второй человек владеет им, — и прийти, почитать код, немного разобраться в проекте не составит труда

Ойнемогу. Виталий Слободин, что раньше CSSO разрабатывался одним человеком, что сейчас. По факту два (!) человека за 7 лет жизни утилиты. А вы говорите. Не надо в прогнозах учитывать (мечтать, фантазировать) пассионарность. Надо учитывать её отсутствие и радоваться, если с ней встречаетесь.

В-пятых, проекты одного разработчика — это всегда зона риска. Его сбивает автобус и всё. Ему надоело и всё. Он укатил на Карибы и открыл там кафе и всё. Если вам нравится библиотека X одного разработчика, а библиотека Y группы разработчиков чуть хуже, берите вторую.
В-шестых, проекты из компаний (а не сообщества) — это всегда зона риска. Компаниями управляют бюджеты, иерархии, прибыли, что-нибудь ещё. Компаниями не управляют (вы всё ещё верите маркетинговым брошюрам и статьям?) другие категории. Вы пользуетесь библиотекой, всё хорошо. Во вторник руководитель 5-го ранга решает, что разработка библиотеки не приносит прибыли. В среду команда разработки расформирована. В четверг вы думаете о том, чего дальше-то.
В-седьмых, soft skills важны и нужны, если вы хотите добиваться своего. Я конфликтен, злобен, меня раздражают многие категории населения. История CSSO научила меня тому, что разработка такого уровня в таких условиях состоит из soft skills чуть ли не на 50%. Из чего я сделал вывод больше никогда не начинать подобное в таких условиях. Право говорить людям то, что ты о них думаешь, стоит неначатого, закрытого, пошедшего не тем путём. Наиболее правильная позиция у Линуса Торвальдса. Делает нужный крутой продукт, всех посылает в лес, никому не улыбается насильно вежливо. Уважуха. Помните абзац про моё недопонимание с фронтендерами? Вот здесь оно вставало порою в полный рост.

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

История CSSO, завершение

Особняком от разработки как прошлый 2011 год CSSOv1, так и наступивший 2012 год оказались весьма насыщенными общением. Сначала вы общаетесь с десятками людей, чтобы начать проект и делать. После публикации о проекте вы общаетесь с десятками людей, объясняя вводную, собирая первые репорты и вообще торгуя вежливостью и готовностью. После популярности вы общаетесь уже с сотнями (GitHub, Twitter, mail, лично, Jabber, даже пара звонков была) людей. Такой вот постоянный поток, который надо держать [и продолжать быть вежливым]. Объём его достаточен, чтобы пойти к руководству и рассказать, мол, смотри, я 20% рабочего времени не код пишу, не думу думаю, но просто отвечаю на вопросы, даю ссылки на спецификации, выясняю детали репортов и лучусь оптимизмом. Было несколько свежим опытом.

2012 год
Январь — целый месяц багфиксов, снятия накопившегося техдолга, организационные правки. В следующие месяцы бываю в CSSO лишь набегами в среднем два-три дня в пару месяцев.
Октябрь — CSSO перешёл с парсера PeCode на Gonzales. Gonzales был очень интересным экспериментом. Я попробовал написать руками парсер, который был бы выдан воображаемым генератором парсеров воображаемой PEG. И ведь получилось. Скорость разбора увеличилась в 3..5 раз, код с позиции генератора вышел стройный и хорошо алгоритмизируемый.
Фактически это был шаг к разработке следующего поколения экосистемы вокруг идей OmetaJS. Также это был последний камень в надгробие CSSOv1.
За два года идеи и эксплуатации стало очевидным, что это поколение себя изживает. Надо избавляться от PEG. Надо писать менее монолитный продукт. Количество набранного опыта структурной минимизации следовало переделать в новое качество. Наконец, в голове накопилось немало фантазий о том, какой [крутой] стек утилит вокруг можно выстроить. Но требовался другой парсер с другим AST. Так CSSOv1 был поставлен на логическую паузу и я начал домашнюю проработку CSSOv2.
Также время, которое мне разрешали тратить на CSSOv1, неумолимо сокращалась и проект по приоритетам опустился на самое дно. Надо было писать другие утилиты.
Всплыл ещё один нюанс, который надеялись перевалить умом и сообразительностью, но в рамках CSSOv1 так и не получилось — gzip. Иногда CSSO жал файлы лучше gzip, иногда хуже. DEFLATE хорошо себя чувствует на избыточности, что в случае с CSS подарок. Это дало повод в дальнейшем ряду критиков говорить, что CSSOv1 хуже gzip, от чего я меланхолично фейспалмил и ставил галочку в чёрном блокнотике.

2013 год
Март — моё категорическое нежелание продолжать работу с руководителем группы, в которой оказался, закончилось намерением либо уволиться, либо ротироваться, если найдутся желающие. Желающие нашлись, но уходил (возвращался) я в мир Java на совсем другие задачи. Так CSSOv1 был поставлен уже на физическую паузу.
Апрель — объявляю на внутреннем форуме Яндекса, что больше не могу поддерживать проект. Разработка CSSO велась в рабочее время, а не была ночным хобби. Мне ясны были чувства пользователей, но после 10-часовых рабочих дней потом ещё фигачить и такой непростой проект — нет. CSSOv2 был прикопан, участвовать в играх «проект важный и полезный, но ресурс на него мы выделять не будем» я не собирался.
CSSO стремительно устаревает. Я уже занимаюсь другими задачами, поддержки проекта почти нет (лишь редкие багфиксы и несколько релизов Gonzales), желающих подхватить знамя нет ни внутри, ни снаружи, пусть и были многочисленные призывы.
В этот же период постоянно слышу от людей о том, что такой важный и интересный проект обязательно вот сейчас-сейчас кто-то возьмёт на себя и всё станет хорошо. Были попытки войти в код CSSOv1 (но входящие быстро ломались), были единичные случаи фиксов, даже нашёлся разработчик, выдавший серию фиксов, чем меня восхитил и подарил [короткую] надежду. Но и только. Стало ясно, что в текущем виде CSSO доживает своё время.
В этот же период я получил здоровенную прививку от излишнего оптимизма, доверия и прочих штук. Вроде и так был злым, а тут стал ещё злее и циничнее. Тогда было неприятно от ряда ситуаций и диалогов, но сейчас понимаю, что всё закономерно и это просто надо было пережить, чтобы больше не попадаться.
Если 2011 год был годом победы, 2012 год годом поддержки и развития, то 2013 год стал годом «да ну вас нафиг».
Август — последний коммит.

2014 год
Разработка не ведётся. CSSOv1 умирает. Прикольный период танцев на костях. То одни бенчмарки показывают, что конкуренты (а надо заметить, после выхода CSSO этот «рынок» оживился и за минимизацию взялись с новыми силами) впереди-впереди, то другие показывают, что CSSO позади-позади. И вот уже с задних рядов улюлюкают, а с передних осуждающе смотрят в моноколь.
Тогда мне демонстративно было пофиг. Ну… Кажется прям совсем вот очевидным, что проект надо было развивать, чтобы он не остался в хвосте. И если проект (любой) не развивают, он устаревает. Для этого не надо быть семи пядей во лбу, это аксиома. Божечки, неужели после года-полутора-лет заморозки конкуренты впереди?! Да неужели! Да как же это случилось-то?! Если вам не пофиг, напишите петицию, вручите рулон подписей руководству, пусть выделит бюджет на разработчика. Одного хватало же. И сейчас один, к слову. Но гораздо прикольнее было кидать тапками, пока я ходил то к одному начальнику, то к другому, выпрашивая куски рабочего времени на хотя бы багфиксы.
Надеюсь, эта история чему-то полезному научила не только меня, пусть и выводы каждый участник сделал свои, безусловно.

2015 год
В октябре за разработку берётся lahmatiy (Роман Дворнов из Авито) и CSSO получил новую жизнь. Офигенно, что нашёлся кто-то, кто уже третий год тянет хороший же проект вперёд, во всём разобрался и всё переписал. Роман, если ты это прочтёшь, знай, ты крутой.

История CSSO, продолжение

Чтобы понимать всё дальнейшее в коде CSSOv1, надо принять следующее: за основу был взят OmetaJS и PEG. Регекспы спорны в поддержке, мы видели обработку CSS на их основе и глаз вываливается. Да и, напомню, нужна была совместимость на уровне AST.
Ни код, ни стоящие за ним идеи невозможно правильно понять, если не понимать, чем выбранная основа отличается от остального мира. Я потом неоднократно наблюдал, как приходит человек, смотрит исходник и убегает в ужасе с криками «что за бублец, это не код, это ад!» Да нет, не ад, но ведь даже Википедию сначала почитать ленились.
Потому основная работа с кодом всё время существования CSSOv1 делилась на две основных ветви.
Во-первых, парсеры CSS. На старте это не казалось прям сложным, но теперь понимаю, что задача «быстрый стабильный парсер CSS на JavaScript с учётом всех версий CSS и всех хаков CSS вместе с вендорными расширениями» — такое… При этом учитывайте, что V8 и Node.js тогда ещё не включали в себя нынешнее богатство оптимизаций. Именно эта ветвь стала самой интересной, проблемной и мозгоёмкой.
Во-вторых, поиск, каталогизация и изучение того бардака, что существовал и существует в вёрстке. Легко было выстрадать блок минимизации, обложить тюнингом, а после выпуска версии узнать, что в каком-то IE на какой-то платформе всё не так. Была переработана тонна информации, в курилках и вне оных пытались симферопольские фронтендеры (всегда с готовностью помогавшие, вспоминаю с благодарностью), обрабатывались репорты пострадавших. Шёл вечный бой.
Итак, до конца 2010 года велась подготовительная работа, которая в свою очередь разделилась на следующие этапы…
Во-первых, сбор, осмысление и описание того, что, собственно, собираемся минимизировать. Понятно, также должны были уметь то же, что конкуренты, потому и их методы были собраны воедино, а в дальнейшем и улучшены.
Во-вторых, писались разные прототипы. Надо было быстро обнаружить тупиковые пути и нащупать нормальные решения. Например, один из скриптов был создан только для того, чтобы посмотреть, как Node.js ведёт себя на тысячах и миллионах узлов дерева (фигово вёл, надо заметить).
В-третьих, собирался meta CSS — «язык», состоящий из всех спецификаций и диалектов CSS, ведь именно его и надо было парсить со всеми-всеми чудесами. Кажется, в какой-то момент во всём Крыму я был единственным человеком, который совершенно не умел верстать, но CSS знал чуть ли не лучше авторов.
Таким макаром пришли к точке, после которой уже можно писать продукт.

2011 год
Февраль — первый коммит работающего CSSP. Несколько наивная и прямолинейная реализация парсера, который даже в таком виде работал быстрее, чем созданный через OmetaJS. Тогда же было принято решение писать код, который с минимальными изменениями будет работать на всех JavaScript движках. Это позволило позже сделать и вебовую версию CSSO.
Март — интенсивное наращивание мяса на кости. В общем, ничего особо интересного или интригующего. Архитектура ясна, ТЗ понятное, прототипы обстреляны, бери и делай. Некоторое заметное время отобрали сотни тестов, в будущем себя это оправдало.
Апрель — релиз ранней беты и пост на Хабре. Приняли хорошо, дальше пошла рутина и началось общение с пользователями. Заодно пришла нужда отключать (!) структурные оптимизации. Если код, который минимизировал механически, работал понятно и без багов (потому его хотели использовать), то другой пока был с багами и открытыми вопросами.
Август — упоролся и написал пробный генератор парсеров. Назвал PeCode. CSSP себя изжил, с ним можно было запускаться, но в долговременной перспективе он был слабоват. Потому появился PeCode. Честно говоря, сейчас я уже не понимаю, что именно получилось. В одном проекте я проверял много разных идей, писал очень хардкорный код и в итоге решил, что ЭТО можно считать генератором. В любом случае он был быстрее и лучше CSSP, что двинуло нас вперёд.
Сентябрь — наконец-то CSSO действительно научился работать в режиме строго без структурных изменений. Месяц интересен ещё и тем, что он был последним в непрерывной работе именно над CSSO. Дальше перерыв на три месяца, я переключился на BEM plugin к IntelliJ IDEA.
Год был замечателен тем, что CSSO зашагал по планете. Его использовали на всех континентах, его начали пробовать в production’ах уровня Yahoo! и Google. Количество установок било всё новые рекорды. Чувство (и опыт) win’а такого уровня задают в дальнейшей жизни другую, новую планку целей. Могу совершенно точно сказать, что именно CSSO дал мне основу для развития и переосмысления. Ничего не было. Приходит один чувак с идеей. Приходит другой чувак с руками. Бац, сделали. Бац, сотни тысяч установок. Ы. Дикий Запад какой-то.

История CSSO, начало

В новостях похоронили PhantomJS, пошёл листать его историю, долистал до интервью, встретил CSSO и решил поднять старые записки. С каждым годом что-то забывается, а зря.
Наблюдаю за судьбой CSSO, мне нравится происходящее, но не нравится, что стартовую кодовую базу могут понять не так, как понимаю её я. Потому вот вам история. Как водится, это взгляд с одной стороны, с других сторон всё может выглядеть иначе (более того, не может, но и выглядит).
Для альтернативно читающих сразу обозначу следующее прямым текстом…
К той версии, что вы используете, я не имею никакого отношения. Она лучше CSSOv1, быстрее, написана иначе (фактически это на 95% другой продукт). Мой последний коммит был в августе 2013 года, после чего разработка временно заморозилась и продолжилась уже другими.
Эссе о том, почему CSSOv1 такой «странный», заодно байки о том как писался. Если вам покажется, что текст о другом, не надо меня об этом уведомлять, справляйтесь самостоятельно.

2010 год
Node.js существует всего год. Едва появился npm. Мира небраузерного JavaScript почти и нет. На этом фоне Виталий Харисов поднимает тему, о которой думает не первый раз (только лишь со мною была пробная попытка на C написать хоть прототип в 2007 году) — структурный минимизатор CSS. Популярные на тот момент минимизаторы представляли собою простые «выгрызатели пробелов», потому идея была богатая: в CSS овердофига избыточности, которую можно убирать, «понимая», какие свойства перекрываются, какие блоки объединяются и т.п.
Нюанс был в том, что 1) этим никто не занимался, 2) я чистый бекендер и про CSS знал лишь то, что это ужас и содомия.
Виталя добыл добро на разработку долгостроя, поставил технические требования, а я засел за спецификации, комбинаторику, теорию парсеров (в основном вокруг PEG) и трансляторов, ну и вообще стал активно вливать в себя чарующий мир вёрстки. После первых набросков стало ясно, что таки да, реализовать это можно.
В этот момент и были заложены архитектурные решения, которые сначала подняли CSSOv1, а потом похоронили. В итоге жарких споров решили, что AST должен быть удобным для OmetaJS (потому и упомянутая выше PEG) — на массивах. Эту точку считаю поворотной.
С продуктовой точки зрения решение верное. CSSO таким образом мог быть частью цепи преобразований, звеньями которой разные утилиты на базе OmetaJS трансляторов. Тут у нас валидация, здесь обработка метаязыков, там минимизация. С технической точки зрения такой AST как сам по себе стал тормозом, так и остальные операции тормозил. Мне не удалось тогда доказать это двум главным решающим фронтендерам, но какие сложные эмоции обуревали, когда потом уже другой разработчик в CSSOv2 напрочь выпилил совместимость, сделал нормальный AST и всё стало лучше.
Но… 2010 год. Можно сказать, что никто не пишет «серверное» на NodeJS, да и вообще JavaScript. Утилиты для фронтендеров похожи на свалку хлама в непонятном состоянии на разных языках для разных операционных систем. Какого-либо open source продукта, сделанного в единой идеологии, прошедшего кровавый production, состоящего из семейства полезных инструментов, просто не было. Фактически мы стояли на целине, что в разработке очень редко бывает.
Потому тогда сложно было сказать, что правильно, а что нет. Желания и энтузиазм точно были правильными. В эти настроения корнями уходят и будущие SVGO (начинал deepsweet в 2012 году) с IMGO (начинал banzalik в 2011 году), и первые утилиты для BEM, и многое другое. Так всё и завертелось. Виталя с коллегами вовремя увидел возможность, набрались разработчики, ну и целина начала вспахиваться.
Тут надо упомянуть ещё одну «тонкость», без которой фон некоторых решений в дальнейшем не будет полным. Код писался бекендером для фронтендеров на языке фронтендеров в стиле бекендеров. Хоть меня и убрали от живых людей и процессов (уже успел поругаться с важным в песочнице человеком), это нисколько не спасало от влетающих со стороны хотелок и поправок. Некоторые были хорошими, некоторые глупыми, но всё надо было учитывать и не всегда у меня получалось сделать правильный выбор или отстоять его. Также как по природной конфликтности, так и по объективным (как сейчас оцениваю атмосферу, причины и следствия) причинам разработка велась не всегда ровно — как тогда, так и сейчас мне непросто общаться с фронтендерами, это какой-то совершенно другой мир и совершенно другая школа разработки, от которой меня знатно морщит (подозреваю, им тоже не всегда было приятно иметь со мною дело). Запомните этот абзац, он будет особо упомянут в финальной части серии в выводах.

Три проблемы MongoDB

Не скажу тут ничего нового, но хоть самому себе окончательно сформулирую причины, по которым отношусь к MongoDB с большой настороженностью. Раньше уже писал (тут), но за месяцы эксплуатации с чем-то смирился, на что-то забил, а оставшееся стало важнее.

Во-первых, дисциплину схемы данных поддерживать крайне сложно. Разработчики должны постоянно помнить, что это не RDBMS, потому десятки связанных «внешними ключами» коллекций могут решить тактическую задачу, но в стратегической перспективе вы всё сделаете неправильно (особенно с учётом пока ещё отсутствия multi-document transactions, но в 4.x вроде запилят).
Фигня в том, что так или иначе, если вы не делаете простое или специфическое приложение, вы всё равно однажды скатитесь ровно к тем самым десяткам коллекций, что в MongoDB чревато — механизмы проверки целостности данных в зачаточном состоянии. Конечно, допускаю, что вас может оставить равнодушным потенциал продолбать связность чего-то вроде клиент-счёт, но обычно это разработчиков тревожит.
Соответственно, у вас всего один вариант хранить сложные данные: огромные документы с большим уровнем вложенности, в которых всё-всё. Казалось бы, ну и ладно, это же хорошо, это вот прям MongoDB way! Не-а, переходим к следующим пунктам.

Во-вторых, механизм локов. Реально проблема, когда дело доходит до лока на уровне документа (почти всегда). Если кратко без нюансов и минимально для понимания, во время изменения документ залочен целиком.
Представим, что вам хватило мудрости создать документ «дом». В котором «квартиры». В которых «жильцы». Если ваш сервис раз в час переписывает «дом» целиком, жить можно. Если «дом» меняется несколькими сервисами в десятки потоков из разных источников… Пока вы меняете семейный статус Петрова, запись рождения Иванова и удаление Сидорова из пятой квартиры будут ждать в очереди.
На графиках очень красиво выглядят пики, когда звёзды сходятся и при [условно] 100RPS на «дом» последние изменения накатываются через 10 секунд, например. Шутки шутками, но т.к. такие лаги аукаются во всём остальном, становится грустно.

В-третьих, как ни странно, но у MongoDB очень бедный язык запросов внутри документов. Они чуть ли не в каждом релизе улучшают и дополняют, но если вам надо получить квартиры, в которых за последние пять лет произошло возгорание на кухне, в котором участвовал Фёдоров с условной судимостью… Такое стоит неоднократно пережить на собственном опыте.
Зачастую вам проще просто найти «дом», вытащить его целиком и вне MongoDB пройтись по документу. Соответственно, получаем дополнительную нагрузку что на базу, что на код. Не ок.

Потому совет всё тот же: сначала делайте сервис на RDBMS. MySQL и PostgreSQL давно уже взрослые и крепкие базы. Когда сервис заработает, поживёт и вам станет яснее реальная нагрузка и вообще вектор развития, тогда вы сможете достаточно просто мигрировать на MongoDB. Вот мигрировать с MongoDB на RDBMS врагу не пожелаю.
При всём этом MongoDB неплохая база, если использовать её правильно. Плохо, что использовать её неправильно слишком легко.

Бедные junior’ы

Чёт казалось, что достаточно ясно упомянул кейсы, когда junior’ов есть смысл нанимать (и их нанимают), при этом [напрасно] понадеялся, что продолжение этих кейсов не менее ясно, заинтересованные не поленятся хотя бы HeadHunter «погуглить» (ох, сложно-то как вбить там junior Java, ага). Но нет. Потому первое весеннее эссе 2018 года: куды податься беднягам без опыта.

Но сначала важное (даже ключевое). Набор вами опыта и вообще лично вы — не проблема работодателя. Рынок ещё не дошёл до стадии, на которой на каждого просто человека все бросаются, носят на руках и посыпают розами. Другие бойцы как-то извернулись и набрали опыт. Может, им повезло. Может, согласились на плохие условия. Или решили, что поспать можно и потом. Всякое бывает. В любом случае хватит считать себя вселенским подарком, с которым должны тетешкаться взрослые дяди. Не хватает чего-то (ума, усидчивости, самодисциплины, самоорганизации)? Значит, не будет и хорошей работы. Она будет у тех, у кого хватает и / или кто поработал над собой.
Иначе получается занятная ситуация. Скажем, чтобы пройти в олимпийскую сборную по отжиманиям, надо отжиматься 200 раз. А вы можете только 50 раз. Но в сборную очень хочется! Там и люди сильные, и награды, и вообще форма красивая. Что сделает толковый человек? Начнёт каждый день отжиматься, найдёт доступный спортзал, пойдёт работать грузчиком. Через год отожмётся 201 раз и хмыкнет, мол, фигня вопрос. Что делает каждый N-й дохляк? Начинает критиковать требования сборной (200? да вы офигели! да никто так не может! да что за дискриминация дохляков!). Отказывается начинать с нуля — грузчиком работать западло, в зале пыльный пол и доски скрипят, да и вообще мне никто не платит за отжимания. Терзает причину и следствие — нет, вы сначала дайте мне форму, награды и деньги, а 200 раз отжиматься я научусь потом.
Так вот это не работает. Чем раньше поймёте и посмотрите на мир иначе, тем вам же лучше.

Список ниже я составил по:

  • собственному опыту и по озвучиваемому в беседах опыту коллег;
  • вакансиям как на сайтах агрегаторов, так и прямых работодателей;
  • последним строчкам резюме, которые приходят на почту — иными словами, смотрю, с чего начинали живые люди.

Есть и другие варианты. Люди попадают на первую работу по знакомству (и тогда в резюме между строк читаешь «админил комп в киоске дяди Вахтанга»), например. Некоторые (таких мало, впрочем) активно фрилансят. У некоторых вообще загадка загадочная (первая же работа «Ведущий разработчик»). Всякое бывает. Но опишу массовые варианты.

Итак, традиционные потребители плохо отжимающихся вот такие…
Бадишопы. Термин размытый и давно уже означает не только лишь схему «чувак официально передаётся в аренду другому работодателю». По факту сотни и тысячи разработчиков сгребаются в одно ведро, менеджеры токуют и сгребают сотни заказчиков в другое ведро, потом сбиваются проектные команды, делают проекты и всё. Три основных признака бадишопа: 1) не делают собственный софт, 2) жополиард разработчиков с большой текучкой, 3) широкая заявленная экспертиза («мы делаем гвозди и ракеты»). Правда, эти ребята тоже начали считать деньги, похоже, потому открытых junior вакансий у топовых бегемотов почти и нет. Есть подозрение, что разумнее выходить на них письмом кадровикам или через знакомых в этих фабриках пота.
Госструктуры. В той же Почте России есть вакансии, у которых требуемый опыт от 1 года. Если вы из какого-нибудь специфического вуза (тот же МАИ), можно на год распределиться внутрь отрасли инженером. Даже в библиотеках бывают вакансии. Вы ни фига не заработаете на этой работе, конечно. Но это будет год стажа, что уже плюс к вакансиям, у которых «от года» строго соблюдается. Правда, тут заковыка: всё-таки большинство открытых мест с цензом на уже поработавших. Но исключения бывают.
Стартапы. Довольно часто вакансии джуниоров находятся с текстами «в новый проект». Вполне хороший вариант, если вы оформляетесь с трудовой. У стартапов огромный риск не получить в итоге ни копейки, но зато вы получите нужную стартовую запись стажа. Также риск бестолковости кадрового вопроса: бывают требования к джуниорам такие, что не каждый middle подходит. В общем, тут постоянно угадайка. В самом крутом варианте вы попадаете в хороший коллектив, в нём набираетесь опыта, в нём и остаётесь на N лет.
Толстячки. Чем толще контора (от бадишопов до Яндекс / Mail.ru), тем больше в ней рутинной скучной простой работы, на которую нет смысла брать сильных специалистов. Часто это всяческая автоматизация тестирования, для которой бывают вакансии без опыта работы вообще. Современная автоматизация вполне включает в себя Python, Java и остальное разработческое, потому языковый опыт, если не будете тупо делать ровно по тикетам, вы получите.

В целом намного проще искать работу, если вы не ленивы, адекватны и явно занимаетесь, чтобы попасть в профессию. Пробиваетесь на живое собеседование, изумляете собеседующих знанием языков, алгоритмов и технологий, объясняете жизненную позицию («я джуниор, хочу у вас работать, набираться опыта реальной работы», а не «я наглый невежа, ничего не знаю, хочу много бабла, чешите мне спинку, договоримся, кароч») — вуаля. Не получилось раз, другой, десятый. Получится на двадцатый.
Повторюсь, вы всё ещё убыточны. Ни один работодатель не рассматривает вас как полноценную боевую единицу. Ваша задача: показать, что именно вы тот джуниор, у которого путь от «этот чувак только ломает и отвлекает» до «это наше молодое дарование» занимает заметно меньше, чем у всех джуниоров мира, при этом вы не застрелитесь, справитесь, обучитесь и начнёте жечь напалмом. Чтобы это показать… очевидно, надо сначала потрудиться.
Чего я точно не знаю, так это как искать работу, если вы пинали балду и ни в чём не разбираетесь. Толковый junior — не отсутствие мозга и знаний, но отсутствие опыта. Если к 20+ годам вы не удосужились ничего выучить полезного / нужного / востребованного, а в голове опилки, ну… ну молодец. Только нафига тогда в разработку идёте? Дальше точно не будет легче.

Книги: Java: The Legend

java (1)
Ben Evans.
Java: The Legend. Past, Present, and Future.
O’Reilly, 2015.
Прочёл давно больше для коллекции (что написано вокруг Java), но вдруг заметил, что ничего о ней не написал.
Небольшая брошюра из бесплатной серии O’Reilly на пару дней в метро. Рассказ о том, как появилась Java, зачем, чего в ней хорошего, куда всё едет и шагает.
Читать можно тем, кому Википедии мало и хочется чуть больше. Остальным не вижу смысла. Оно уже и года на три устарело (наивная надежда на выход Java 9 в 2016 году, ха), и написано не так технически детально, как хотелось бы. Совершенно проходной текст, в котором любопытны лишь первые страниц 20 (собственно, история).

Junior — роскошь

.. а не ресурс разработки Junior — человек, которому вы не можете выдать задачу сложностью выше некоторого уровня, если хотите, чтобы задача была решена в нужные вам сроки. Таким макаром в разных монастырях один и тот же человек может быть ранжирован не одинаково. В Кукусофте он middle, в Почтоваре он junior, а в учреждении для общественного воспитания детей дошкольного возраста и вовсе senior. Зависит от задач и сроков.
Ещё три исходящих пункта.
Раз. Джуниор (впрочем, как и любой другой) интересен тогда, когда для него есть фронт задач его уровня. Иными словами, стоимость их решения адекватна.
Два. Джуниор интересен тогда, когда из него хотят и могут [почти] любой ценой сделать что-нибудь другое. Характерно для больших компаний, выращивающих себе кадры, особенно штучные (тот же ШАД Яндекса примером).
Три. Джуниор интересен тогда, когда интересен не задачами и не ростом. Бывают занятные схемы. Скажем, вы аутсорсер, по контракту оплачивают работу с учётом занятых на проекте голов, выгодно эти головы набрать и демонстрировать. Это Вася. У него димплом МГУ, он джавист, уважаемый Джон Смит, похлопайте Васе и перечислите нам очередной транш. Что там за знания у Васи, чем он реально занят… никого не волнует. Такие схемы обсуждать не будем, достаточно того, что оно бывает и к разработке не относится.

Ещё ремарка про стоимость джуниоров. Давайте на пальцах следующую формулу зарплаты изобретём (почти по рынку, хоть для красоты округлил): J(unior) = n, M(iddle) = 2*J, S(enior) = 2*M. Это вот зарплата. Но работодателя интересует стоимость решений. Если junior делает софт 4 месяца, а senior тот же софт за 1 месяц, видим смешное: junior выпустил продукт на три месяца позже при senior’ной стоимости решения.
Слишком чистенько. На деле живые джуны делают ещё дольше и требуют ещё больше вложений. Они перетягивают на себя внимание middle+ (code review, консультации). Плохо интегрируются с нужной бюрократией (тексты коммитов, тикеты в JIRA). Плохо понимают командную работу (тусить в изоляции, забив на состояние мира вокруг — штатное состояние). Понимание ответственности на нуле (для них часто по воображаемым последствиям примерно равны «мама, я застелил постель» (не застелил) и «Аристарх Петрович, я протестировал все изменения перед выкаткой» (не все, не протестировал)), что добавляет рандома в production.
Всё это вместе с исправлением, обучением и банальным надзором замедляет работу остальных, что влияет на стоимость уже их решений. И, что прикольно, всё это в какой-то момент может оказаться пустотой — то вдруг оказывается, что чувак не подходит профессии. Или у него прошло увлечение и теперь он хочет на лыжах кататься. Или просто зайку не ценят и потому зайка уходит в монастырь. Или начитался про успешные стартапы и уходит в загул пилить Super Duper ToDo Tracker, который обязательно поглотит рынок.

Также нередко джуниоров, если они прям юные, надо учить:

  • жить («Сань, давай в будний вечер ты не будешь бухать до похмелья с утра, тебе два критикала срочно разрулить»),
  • общаться («Олег, заказчик не твой друзяшка со двора, давай не бычить и вообще полезно быть вежливым»),
  • взрослеть («Стёп, ты же обещал? Обещал. Не выполнил и знал заранее, что не выполнишь. Давай в следующий раз ты подойдёшь и скажешь заранее, что не успеваешь, чёт придумаем»)
  • и матереть («Филь, вот чего ты молча в пол смотрел? Тебя Иваныч сожрать собирался шоле? Нет. Голову поднять, факты озвучить, логикой задавить, в глаза смотреть спокойно, задачу не ты просрал, не тебе отвечать»).

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


Теперь подумайте и себе честно ответ: нафига всё это работодателю? Обычной софтварной конторе от гаражика до «это здание всё наше». Не приюту. Не благотворительному фонду. Не школе для одарённых детей. Не яростной молотилке кадров, в которой в день сто страниц копипасты. Вот нафига? Middle и senior выгоднее. Головняка с ними заметно меньше. Рандома в проде заметно меньше. Ставить их на путь истинный тоже проще, бойцы уже биты жизнью, могут гонор в карман спрятать и таки сделать то, что надо, а не «я так вижу». Прогноз работы с ними тоже проще — если до middle добрался, есть куда толкать и выращивать. Потому в общем случае джуниоров не нанимают. Убыточно. Проблемно. Результат не спрогнозировать. Нафиг надо.
Исключения бывают, безусловно (особенно когда у исключения «глаза горят», учебники от зубов отлетают и в анамнезе годный код на GitHub’е, тут прям удовольствие смотреть, как талант раскрывается). Но меня подбешивает, когда на голубом глазу говорят «а чё, ну наберите роту джуниоров, воспитайте, вот вам и будут кадры». Нет, спасибо. Сами набирайте. Все люди хорошие, братья, друзья и ромашки, но иногда полезнее тикеты вовремя закрывать, а не переоткрывать по десять раз, выполняя гражданский долг матери Терезы.
PS. Конечно, вы не такой junior. Это какие-то другие такие. А вы самый умный, самый хороший, самый клёвый junior в мире.