31 марта 2015

Что такое CodeFest?

Что такое CodeFest?
Можно, конечно, написать что это крупнейшая IT-шная конференция за Уралом, бла-бла-бла.

Но нет, это не то.
CodeFest можно только описать.

CodeFest это когда ты летишь в самолете набитым IT-шниками в 9 утра из Москвы нихрена не выспашись. И только потом понимаешь что, то, что этот самолет долетел с кармой всех этих (тестировщиков) людей - это уже отлично!

CodeFest это когда ты летишь в Новосибирск и у тебя в чемодане есть виски, ты летишь из Новосибирска и у тебя в чемодане опять есть виски, но уже другой и тебе противно о нем думать.

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








CodeFest это встречи со старыми знакомыми.


И с новыми


CodeFest это 4 хороших доклада из 6 в одном треке, тем более в одном треке по тестированию.

В общем CodeFest в очередной раз удался.
Хочется сказать спасибо:
Роме Ивлиеву  - за стойкость.
Тане Писчасовой - за квартирник.
Паше Сташевскому и Лене Романчук - за то что делаете офигенный трек по тестированию уже несколько лет к ряду.
Андрею Солнцеву, Леше Виноградову, Коле Чабановскому, Косте Каплинскому, Игорю Хролу, Сергею Высоцкому  - за интересные беседы в кулуарах, до/после/вместо докладов.
Всей команде организации CodeFest - без вас всего этого бы не было.

Колллективу 2GIS - за отличную атмосферу в офисе и посиделки.

Будем надеятся до встречи в следующем году.



25 марта 2015

Книга: Питер Фердинанд Друкер. Эффективный руководитель.

Эта книга стояла в списке на прочтение года три или четыре.
Зря не прочитал раньше.

Эта книга расскажет вам о фундаментальных вещах.
При том довольно простым языком - языком консультанта.
Данная книга на мой взгляд является одной из основополагающих  по части личной эффективности.
Питер Друкер первым (из тех кого я читал) обратил внимание на несколько очень важных вопросов:
1. Мы живем в эпоху организаций. Огранизации стали решать все, если не многое. (Очень интересный экскурс в размер администрации президента США до начала 20 века).
2. Научно-технический прогресс сделал работника физического труда неконкурентноспособным.
3. Конкурентноспособными стали работники труда умственного.
4. Работник умственного труда, который принимает решения и несет ответственность за результат своих решений является руководителем.
5. Эффективность организации определяется ее руководителями (по Друкеру) и этой эффективности можно научится.


В написанном выше для нашего нынешнего уровня знаний о природе организаций (хех, а прям вот так вот много мы занем, да ? :)) наверное ничего нового-то и нет.
Но, на минуточку, - первое издание книги "Эффективный руководитель" Питера Друкера было в 1967 году.

В 1967(!!!!) году этот мужик уже видел и понимал сильно больше чем его современники.
Читать. (тут мой конспект)
На один уровень с Фредериком Бруксом.
10/10.

18 марта 2015

Ретроспективы в командах: Отбор проблем и анализ

Проолжаем начатое тут и продолженное тут.

Отбор проблем.

Подошли к самому сложному моменту.
Итак перед вами доска/флипчат набитый проблемами (мнениями? домыслами?), маркер в руках, и коллектив людей которым (я надеюсь на это) не пофигу что будет дальше.

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

Традиционно, большую часть работы занимает колонка плохо.
Первое что с ней нужно сделать  - это сфотографировать на телефон, или сделать ее бекап любым другим удобным (какой интересно удобнее ?) способом.
Почему ? Потому что дальше вы будете ее корежить, и бэкап нужно иметь всегда =).

Второе - не кидайтесь сразу что-то с ней делать, остановитесь, посмотрите на нее, прочитайте все пункты/стикеры еще раз, убедитесь, что все что там написано вам и всем остальным понятно.

Второе с плюсом (только для фасилитатора) - попробуйте проанализировать есть ли или могут ли быть связи между проблемами.
Если есть хоть малейшее подозрение что да - надо привлекать весь коллектив к анализу.
Даже если описанные проблемы кажутся независимыми - то лучше все равно задать вопрос всем.
Тут можно просто прямо послать вас читать замечательную статью Хенрика Книберга про Root-Cause Analysis, и я конечно это сделаю, но надо дополнить.
В любой команде есть определенная емкость терпения/сил/времени/бюджетов для решения любых проблем. И эти бюджеты очень плохо переносят дефициты.
С одной стороный эта емкость ограничивается заказчиком/владельцем продукта который вряд ли одобрит улучшайзинг на политерации, а с другой отсутствие поставки ценности для заказчика - это очень сильный демотиватор для команды.
Поэтому выявление корневой причины и анализ причинно-следственных связей - важен, потому что точное и точечное улучшение лучше чем генеральная уборка во всех углах.

Окей, для простоты картины представим, что взаимосвязей между проблемами у вас нет и они изолированы.

Третье - выбираем проблемы. Тут опять же есть место для социальных игр, про которые я писал ранее.
Я предпочитаю голосование точечками - каждый участник ретроспективы ставит точку (или магнитную точку, такие тоже есть в канцелярских магазинах) напротив той проблемы, которую считаает самой важной для решения.
У каждого члена команды есть право поставить три точки. Почему три ? Опять же правило по-умолчанию.
Если ваша команда настолько крута в области улучшений своего собственного процесса - то можете взять хоть 7.
Только аккуратно - предпочтительно внедрять улучшения по-одному, чтобы понимать какое улучшение какой эффект дает. Если у вас три улучшения в разных областях или даже два из них пересекаются, то отделить эффект одного от другого довольно просто. Если у вас их 7 - то уже сложно.

Второй аспект который касается количества отбираемых проблем для решения состоит в том что это только те проблемы которые вы ХОТИТЕ решить, но не факт что решите. и что еще
хуже не факт, что решите ДО КОНЦА. Это ваши эксперименты с вашим собственным процессом работы, которые вы сами над собой, коллегами и процессом будете ставить. И не факт, что эксперименты будут успешными. Вполне возможно что их придется откатывать, при том делать это не после следующей ретроспективы, а "на горячую", в процессе основной деятельности.

Процесс голосования довольно важный момент - на нем можно увидеть есть ли у команды единодушное мнение о главных проблемах, или это мнение размыто.
Опять же, это отличный момент для фасилитатора "попробовать продавить" решение "главной" проблемы команде  - только помните что делать это нужно не на первой ретроспективе и ОЧЕНЬ аккуратно.

И опять же - выбор проблем - это место для возникновения социальных игр. За этим надо следить.
Если чью-то "типа маленькую проблему" запихивают в угол или под ковер, то ее можно попробовать "продавить" под соусом улучшений в другой области.

Итак, голосование завершено, топ-3 проблем собран, переходим к следующему этапу, предварительно сделав фото доски.


Анализ проблем.

Берем проблему с наибольшим количеством голосов и пишем в верхней части доски/флипчарта.
Дальше начинаем анализ проблемы любым удобным вам способом.
Тут я хочу сослаться на книгу Дэвида Стрейкера - она будет являться отличным методическим пособием для вас на этой стадии - в ней есть кусочек методологии в связке с инструментом (стикерами).

Достаточно часто бывает так, что проблема "проседает" под тяжелым взором всех участников команды - это значит что все чего им не хватало для решения этой проблемы - это собраться вместе и поговорить. Радуйтесь - вы только что получили +1 в карму фасилитатора. Эту "просевшую" проблему нужно разложить на таски и впихнуть в бэклог.

В процессе анализа проблем у вас и ваших коллег/подчиненных будет возникать куча вопросов, домыслов или предположений.
Скорее всего на поверхность всплывут еще и факты.
С этим всем нужно работать. Во-первых факты нужно отделить от всего остального - они сами по себе.
Предположения, домыслы, гипотезы  лучше всего организовать в какую-то схему - mind-map, дерево по Стрейкеру, блок-схему (блок-схема иногда офигенно работает, только большая получается).
Это позволит вам держать перед глазами как отдельные домыслы/гипотезы, так и взаимосвязи между ними  а также альтернативные ветки.
Что важно на данном этапе - это то чтобы задачи которые будут являться конечными узлами,например, mind-map-а были простыми, исчислимыми и довольно рутинными.

Во-вторых следует понимать, что не всегда проблему можно взять штурмом - составив схему предположений/гипотез вы не всегда пройдясь по ней сможете точно понять, что вам нужно делать.

Ваша задача в таком случае - за минимальное количество времени и ресурсов максимально достоверным способом отсечь ветви не достойные дальнейшего внимания.

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

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

Итого по результатам анализа вы должны получить:
1) список задач которые прольют свет  на непонятные вам моменты (гипотезы и предположения), либо напрямую  улучшат ваш процесс
2) схему увязки этих задач в единое целое, как путь от частных задач к большому улучшению.

Схема может прижиться у вас не сразу, может и не прижиться вообще.
Но если вы пытаетесь решить большую проблему - то лучше ее иметь ее, иначе есть шанс запутаться или просто забыть о какой-то вещи.

Сформированные задачи вам нужно будет воткнуть в бэклог, но тут уже у каждого все по-своему.

Оформленные результаты ретроспективы (карту, блок-схему, список задач, прочее) нужно разослать на всех участников ретроспективы.
Опять же полезная практика - в отправляемом письме обозначить список задач и кто за них ответственный.


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

Продолжать повествование относительно данного этапа ретроспективы считаю непродуктивным, если какие-то вопросы остались неосвещенными - добро пожаловать в комменты.

16 марта 2015

Напочитать: Rest in Peace


1. Отличный блог с обзорами Key-Value хранилищ. Туда даже попал наш one-nio и MapDB про который я писал как-то.
2. Java Deadlock-и для самых маленьких.
3. Долгое время задавался вопросом - как понять какого типа файл?  Ведь расширение можно приписать какое угодно... Никак - развернутый ответ тут.
4.  Как правильно готовить REST для запуска ядерных  ракет или их продажи - аллегорично, но зато по делу.
5. Просто великолепная статья от Мартина Фаулера о паттернах проектирования для данных которые изменяются во времени. Прям даже прослезился - давно такого он не писал.
6. Как взять и упороться на Java. Если честно,то ребята молодцы - не очковать компилироваться в проде. Напишу-ка я отдельный пост даже про это.
7. Google выпустил еще одну реализацию RPC ,  на этот раз поверх  HTTP2 (описание и гитхаб).
8. О том, что MongoDB по умолчанию не защищена и что из этого следует.  А вот тут пример реальных последствий - 40,000 MongoDB databases left unsecured on the internet
9. Баловаться ThreadLocal в Java - может быть опасно. Здесь объяснят почему.
10. Сроки, бюджеты, самолеты... Насим Талеб одобряэ.
Но в реальности внедрение NextGen превратилось в настоящий кошмар, с массой задержек, ревизий и неожиданных проблем. Корпорация Lockheed Martin начала разработку софта в далёком 2002 году и должна была закончить в 2010 году.
В 2007 году систему подвергли ряду тестов и обнаружили огромное количество багов. Она путала рейсы и самолёты, а иногда воздушные суда бесследно пропадали с экрана.
Lockheed Martin попыталась исправить баги, но программа продолжала глючить. В апреле 2014 года система обрушилась в центре управления полётами Лос-Анджелеса, когда в воздушное пространство залетел самолёт-разведчик U-2 на высоте более 18 000 метров, вдвое выше высоты пассажирских самолётов, что вывело из строя логику NextGen.
Очередной дедлайн для NextGen установлен на весну 2015 года: на пять лет позже изначально планируемого срока и с превышением проектного бюджета на $500 млн, пишет Wired. 
11. О том что автоматизация тестирования Swing-овых приложений на Java уже не такая уже и суровая.
12. Живой пример того как можно сборку приложения организовать в Docker и не ставить эти всякие ваши мавены. А вот тут показано как с этим всем жить так чтобы оно шевелилось и правильно кэшировалось.
13. 5 минутное видео о том что можно делать если у вас в руках есть контейнер и система управления ими.


Ну и о главном.

The time has come to end the era of Codehaus - Codehaus закрывается.

To meet developers where they are, we ourselves migrated nearly a thousand of our own open source projects from Google Code to GitHub - Google Code закрывается.

Groovy уходит под Apache Software Foundation



02 марта 2015

Дебажимся в продакшене или как я взял и упоролся Groovy

Настоящие лиды фиксят баги на продакшене изменением параметров.
(c) один из настоящих лидов.


Все мы прекрасно знаем, что очень многое в любом приложении (да чего уж там - куске кода) определяется параметрами. Крутанул в одну сторону - работает, крутанул в другую - не работает.

Знаем и пользуемся этим. За что иногда хочется оторвать руки.
В большинстве случаев параметры получаются один раз на старте приложенияи и могут быть переопределены только после его рестарта. Однако есть случаи когда параметры необходимо переопределять в runtime и для этого тоже есть инструменты.

Лирическое отступление: Если последняя фраза (про переопределение параметров в runtime) вас смутила, повергла в шок или просто удивила - идите и смотрите как это делается у Netflix на примере Archaius. Дальше вам читать может быть без пользы.

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

Я говорю «трудно» потому, что ничего невозможного нет, и для этой задачи в Java например есть OSGI.  Вот с этой строчки вы бы наверное уже могли бы на меня накинутся, но потерпите - я и сам не фанат OSGI и прекрасно отдаю себе отчет о том, чего стоит использование таких вот решений и как придется переколбасить архитектуру приложения.

Не хочется OSGI но хочется крутить логику ? Ну ок, тогда читаем дальше.
А читать-то собственно и немного. Идите на гитхаб, я уже все слепил.

Что там ?  Там стандартная Jetty c одним сервлетом который принимает один параметр (строковый) и возвращает вам его в некоем обработанном виде. Обработки ошибок и всего что там по идее должно быть там нет.

При запуске приложения нужно указать в аргументы путь к файлику с кодом в котором собственно находится логика (примеры файликов в папке resources).


Дальше собственно самое интересное.

Берем листинг номер 1, сохраняем в файлик, скармливаем приложению на старте - и, вуаля, у нас с вами есть какая-то логика, которая просто будет нам возвращать строку которую передали в приложение.



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



Как это работает ?

Работает это на дефолтных возможностях Groovy по парсингу кода.
Ключевой является вот эта строчка кода
   

Тут Groovy грузит исходный код из файла и компилирует его.
Внимание! ClassLoader от Groovy кэширует сорсы, так что не стоит удивляться если что-то не прогрузилось, а стоит использовать параметр метода parse которые говорит кэшировать или нет.
Приведение объекта содержащего логику к интерфейсу изначально было сделано сугубо из-за простоты такого подхода, но после,  в процессе размышлений я пришел к выводу что так и надо : хочешь менять логику - потрудись хотя бы выделить под нее интерфейс и реализовать его!

Ограничения решения.

Первое и самое главное ограничение - это то что ваша «сменяемая» логика не может тащить за собой зависимости на код которого нет в рантайме. То есть если вы в альтернативной версии логики хотите попользоваться другой библиотекой,эмммм скажем для нарезки изображений, то вы должны протащить ее (при деплое приложения) заблаговременно. Если вас не устраивает подобного рода ограничение - то вам нужно идти на … OSGI.

Второе ограничение решения  - слабая устойчивость к конфигурационным ошибкам.
Если кто-то скормит в такое место некорректную логику (некомпилируемый код), то логика вашего приложения в этой точке не будет работать. Совсем. Что из этого следует для вас - придумайте сами. Можно предпринять какие-то методы защиты - кэшировать предыдущее значение, откатываться к нему в случае чего, автоматически откатываться на реализацию логики по умолчанию и прочее, но фундаментально это проблемы не решает - это решение плохо защищено. Отсюда вывод и рекомендация - использовать подобного рода решения только для проведения экспериментов и/или дебага.

Третье - Groovy сильно медленнее чистой Java. Если вы хотите вставить это в нагруженный/частоиспользуемый кусок кода, то искренне надеюсь, что вы это делаете по нужде (дебаг) или из профессионального любопытства (контроллируемый эксперимент в полевых условиях). Вывод - окончание эксперимента/отладки должно привести к убиранию такой разводки в коде.

Преимущества решения.


Преимущество первое - реальный боевой код кругом, реальное окружение, реальные данные (если не боитесь их повредить/потерять).
Второе - писать такую логику можно прямо в окружении проекта, потом просто копировать  код и подсовывать в приложение.
Преимущество третьв (хипстерское)  - синтаксический сахар грувей. Но лично я к нему прохладен.


К исследованию возможности такого решения меня побудили вот эти статьи на хабре (раз и два).

Матчасть.
P.S. и не упарывайтесь, пожалуйста.
P.P.S да, я знаю что есть Java 8 , а в ней Nashorn и все такое. Просто я не люблю JS.