23 апр. 2016 г.

22 - 23 апреля 2016 JPoint

Только что закончилась очередная java конференция, на этот раз JPoint. 

Эти доклады я посетил (удаленно):

Это была не самая продуктивная конференция с точки зрения получения новых знаний или "возгорания" интереса к чему-либо. 

Было интересно послушать про котлин, также большие ожидания были от доклада Николая Алименкова про тестирование, но, к сожалению, время неожиданно закончилось, и успели обсудить только банальные вещи. Хотя была одна интересная деталь - узнал об инструменте тестирования по скриншотам: веб или мобильное приложение запускается на разных устройствах, и в определенные моменты делаются скриншоты и сравниваются с оригинальными (сделанными при первом прогоне). Такой подход позволят видеть такие баги, как, например, съехавшая на пиксель картинка.  

Очень неоднозначно восприняли доклад про ORM, там спикер раскритиковал практически все: Spring, Hibernate, Hadoop и что-то еще за несоответствие ООП. Собственно, и критика ORM заключалась в этом же. Конечно, была предложена альтернатива, но будет ли это удобнее - большой вопрос. Несомненно доклад очень смелый. 

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

Ну а в целом впечатление от конференции хорошее, не пожалел, что пошел.

21 мар. 2016 г.

Классный бесплатный сервис Continuous Integration

Коллега посоветовал классный бесплатный сервис http://semaphoreci.com/ в связке с bitbucket для простой и удобной организации непрерывной интеграции и автоматического деплоя. 

До этого, если мне приходилось организовать что-то подобное, я просто поднимал TeamCity на том же сервере, где расположено приложение. По мержу в мастер происходила автоматическая сборка и деплой на сервер в случае удачи. Существенный минус этого способа - это то, что сборка тратит ресурсы боевого сервера, и вообще, в принципе может его положить. Если выносить все это на отдельный сервер, то это увеличивает расходы. 

Если проект приносит деньги, то разумеется, оплатить дополнительные ресурсы это не проблема. Но если это не так, то приятно иметь бесплатную систему.

20 мар. 2016 г.

19 марта JBreak Новосибирск

19 марта был на конференции java разработчиков JBreak

Посетил эти доклады:

  • Владимир Красильщик, Luxoft. Что надо знать о логировании прагматичному Java‑программисту
  • Александр Маторин, СберТех. Неочевидные Дженерики();
  • Алексей Рагозин, Deutsche Bank. Практическое профилирование Java-приложений
  • Олег Анастасьев, Одноклассники. Распределенные системы в Одноклассниках
  • Владимир Ситников, NetCracker. Производительность вашего OpenSource
  • Тагир Валеев. Stream API: рекомендации лучших собаководов
  • Кирилл Толкачёв и Александр Тарасов, Альфа‑Банк. Твой личный Spring Boot Starter
Сама конференция была разделена на 3 зала. Доклады в первых двух залах были, в принципе, типичными для J* конференций. В третьем зале, в основном, звучали мини-доклады на довольно специфичные темы от спонсоров конференции. Может быть там и было интересно, но я для себя решил, что мне полезнее и интереснее будет на обычных докладах.  

С каждого доклада я вынес для себя что-то полезное и интересное. С наибольшим интересом слушал доклады про Stream API и Дженерики.

Приятно, что не было никакого дефицита еды и очередей в перерывах. При этом стоимость билетов начиналась от 1500 рублей. 

Порадовали спонсоры: luxoft и сбербанк технологии. За контактные данные давали кучу корпоративных сувениров и производили розыгрыш более крупных призов. 

Организаторы пообещали, что через год будет JBreak опять. Хотелось бы, чтобы в следующем году конференция расширилась: больше людей, шире выбор докладов.

29 февр. 2016 г.

Хакатон 2gis - проект akademo

26 - 28 февраля 2016 года я принял участие в городоском хакатоне от 2gis и усилиями команды был выпущен продукт: akademo.ru.



akademo - это проект о Новосибирском академгородке, который поможет найти интересное место для времяпровождения. Основное его планируемое преимущество перед другими сервисами - это локальная ориентированность и удобная фильтрация.  

Базовый workflow:

  1. Установить слайдеры в необходимое положение
  2. Выбрать понравившееся место на карте или справа с списке
  3. Нажать на фото, чтобы посмотреть более подробную информацию о месте.

Наша команда состояла из двух человек. Суммарно перед нами стояли такие задачи:

  • frontend (с версткой)
  • backend
  • контент
  • дизайн
Первые две задачи были моей зоной ответственности, о них я и расскажу.

5 февр. 2016 г.

Система сборки проекта spring boot используя gradle, gulp, bower и npm

Недавно понадобилось запрототипировать один проект. Это должно быть приложение с сервером на spring boot и клиентским js application. Поскольку был избыток времени, я решил поиграться с системами сборки, обеспечив простую и легкую разработку проекта. Для этого пришлось скомбинировать gradle, npm, bower и gulp.


9 дек. 2015 г.

GWT простил NPE

Сегодня разбирался с интересной ошибкой. Во время отладки GWT кода словил NullPointerException, хотя на всех комплексах и на бою данной ошибки не наблюдалось. Проблемы были в этом участке кода:
if (someEnum.equals(SomeEnum.SOME_VALUE)) {
    a = "Hello world";
}
По некоторым причинам someEnum вдруг оказался null, что приводило к NPE. Сразу появилась мысль, что gwt позволяет компилировать equals для enum в знак равенства. Собственно, так и оказалось, но чтобы убедиться в этом пришлось сделать отладочную detailed-compiled сборку, покопаться в javaScript и найти тот самый участок кода:
someEnum == (ru_package_SomeEnum_$clinit__V() ,ru_package_SomeEnum_SOME_1VALUE) 
&& 
(a = $intern_12224);
Видно, что этот код уже позволяет значение null. Заодно узнал об операторе запятая, которого нет в java, но есть в javaScript.

Ну а по-хорошему, в gwt коде правильнее было бы написать так:  
if (SomeEnum.SOME_VALUE.equals(someEnum)) {
    a = "Hello world";
}

5 дек. 2015 г.

Ractive JS

Развиваясь в бэкенде, я сильно запустил фронтенд, который тоже необходимо как-то знать, чтобы быть способным сделать более-менее завершенное приложение. Для этого я решил поиграться с Bootstrap и освоить современный js фреймворк. Сначала выбор пал на angular, как самый часто используемый на текущий момент инструмент. Однако, просмотрев пару видеоуроков, немного влившись в тему, я понял, что это уже не "тренд", фреймворк обладает значительным числом недостатков, практически все ругают его за производительность. (UPD: Потом, конечно, понял, что ractive не заменит и пятой части ангуляра, но как первый mvc js фреймворк сойдет) Одновременно с этим друг указал мне на другую, более простую и удобную технологию: Ractive JS. Возможно, для начала это будет лучше. Нескольких вечеров мне хватило, чтобы освоить этот фреймворк, впчеталения, конечно, положительные, хотя сравнить то и не с чем.

Если про angular есть много статей, роликов на ютубе, даже целые видео курсы на русском языке, то единственный источник информации про ractivejs - это документация и tutorial. Документация приятная, написана простым человеческим языком.

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

Чтобы начать использовать фреймворк, можно не читая документацию, просто начать обучение тут. Шаг за шагом вам объяснят основные фичи технологии. Само обучение построено так: дан исходный код, ставится задача, рассказывается как ее решать. Вам остается лишь прямо в браузере в редакторе решить эту задачу. Там же можно запустить решение и убедиться, что все работает как надо. Решение никто не проверяет и оно не является необходимым условием для прохода на следующий уровень. Если лень решать, а хочется просто поиграться с готовым решением, то для этого есть специальная кнопка "Fix me". Все обучение реально пройти за 2 -3 часа. 

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

UPD: Не прошло много времени, конечно же нашел! И в принципе, это было очевидно. У Ractive JS особый способ рендеринга. Грубо говоря, сначала рендериться все приложение, а затем начинает работу ractive. По своим темплейтам он строит структуру, называемую как "параллельный DOM", а затем привязывает её к настоящему DOMу. Этот подход, который, конечно, имеет свои преимущества, создает сложности при интеграции фреймворка в существующее приложение: нельзя просто так взять и выкинуть часть DOMа. Angular, например, не обладает таким недостатком и легко интегрируем практически в любое приложение. 

10 нояб. 2015 г.

Как нанять программиста за 10 дней

"Как нанять программиста за 10 дней" - единственный не технический доклад на highload 2015, который я посетил. Доклад читал Александр Зиза, а проходил он в зоне IT директоров. Мне кажется, Александр думал, что читает его для нанимателей, но как минимум 50% слушателей были нанимаемыми :).  В любом случае, полезно. 

Александр составил график типичной карьеры, который выглядел примерно так:


Higload 2015. Посещенные доклады.

В предыдущем посте я рассказал общие впечатления о конференции, а здесь оставил то, что осталось в голове от прослушанных докладов. Кстати, по объему и качеству описания можно определять насколько мне был понятен и интересен доклад :)

Highload++ 2015

2-3 ноября 2015 года я посетил конференцию highload о технологиях для одновременного обслуживания миллионов пользователей. Ведущие российские и зарубежные специалисты делились своими знаниями в течении двух дней в Крокус-Экспо-Центре в Москве. 


























26 окт. 2015 г.

Method must be called before the component is rendered gxt 2.3.1

Столкнулся с проблемой в gxt 2.3.1: При событии onRender для родительского компонента не обязательно все child-компоненты, уже isRendered. Это выражается Assertion Error с сообщением: "Method must be called before the component is rendered"

Не пробовал более новые версии gxt, возможно, там этой проблемы уже нет, а в этой по-быстрому можно решить проблему не просто вешая listener на родительский компонент, а собирая событие со всех компонентов.

      RenderCollector.create()
                .addComponent(parentComponent)
                .addComponent(childComponent1)
                .addComponent(childComponent2)
                .addComponent(childComponent3)
                .addComponent(child1OfchildComponent1)
                ...
                .addListener(listener)
                .build();

Устройство класса RenderCollector очень простое: запустить listener тогда, когда все компоненты будут isRendered.

22 окт. 2015 г.

Jokerconf день первый

16 - 17 октября в Санкт-Петербурге прошло одно из самых ярких java мероприятий года - конференция Joker 2015. Я принял в нем участие в качестве удаленного слушателя и решил здесь оставить то, что осталось в голове после докладов.

В режиме онлайн в первый день я побывал на следующих докладах:
  • Евгений Борисов - Spring Puzzlers: тонкости и нюансы работы Spring 
  • Алексей Зиновьев - Как укротить буйного в отделении: смирительные Java-рубашки для MongoDB
  • Алексей Рагозин - Что должен знать о сетях каждый Java-разработчик?
  • Виктор Полищук - Legacy: как победить в гонке

Евгений Борисов - Spring Puzzlers: тонкости и нюансы работы Spring 

На мой взгляд это был самый интересный доклад. Свою роль сыграли как и способ изложения, так и, конечно, популярность темы доклада. Первая часть доклада была посвящена тонкостям использования BeanPostProcessor и аспектов, затем поговорили об особенностях использования проксированных объектов. В конце доклада было рассказано о том, почему нужно "любить" интерфейсы и об особенностях различных способах задания spring конфигурации. Мне очень понравился стиль изложения, этот доклад смотивировал меня поискать и посмотреть другие видеоролики с участием Евгения Борисова и самому открыть Idea, чтобы своими руками пощупать некоторые нюансы. 

Алексей Зиновьев - Как укротить буйного в отделении: смирительные Java-рубашки для MongoDB
Этот доклад был довольно далек для меня, т.к. я пока использовал только классические sql СУБД. Как видно из названия, доклад был посвящен различным инструментам для работы с MongoDB, а также что делать, если в проекте используется несколько СУБД, с которыми хочется работать как с одной. Алексей рассказал подробно о различных вариантах, об их особенностях. Забавно, что в конце он дал совет не использовать MongoDB, ну а уж если вляпались.... то доклад будет полезен:). 

Алексей Рагозин - Что должен знать о сетях каждый Java-разработчик?
В этом докладе было рассказано об особенностях работы с TCP в java. Основная мысль, что если мы что-то делаем в коде, связанное с TCP, то это не обязательно происходит мгновенно. Например, если закрыть сокет, то реально он закроется только тогда, когда отправит все данные, а пока соединение будет оставаться в буфере. Если существует лимит соединений, то можно попасть в плохую ситуацию, когда сокет старый вроде бы закрыт, а новый открыть невозможно.  То же самое с write, ОС не будут тут же отправлять тот байт, который записали в outputstream. К счастью, существуют настройки, которые могут установить желаемое поведение во всех вышеописанных случаях.
Во второй части доклада Алексей рассказал про Congestion контроль. При отправке данных существует некий буферный размер, после отправки которого нужно подтвердить получение данных. Этого требует TCP, поскольку в его спецификации указано, что он гарантирует получение данных. Меньше буфер - меньше вероятность потери, больше буфер - увеличивается скорость передачи. Congestion алгоритм как раз таки управляет размером этого буфера. Алгоритмы бывают разные, все сложные, но был показан типичный пример: сначала буфер экспоненциально растет начиная с малого значения, затем когда появляются потери, буфер скачкообразно падает, а потом уже растет линейно, потом опять падет при потерях и т.д..
Затем Алексей привел интересную ситуацию, когда первый утренний запрос может проходить несколько минут, а второй уже обычное время. Дело в том, что TCP соединение бесконечно, причем для этого не обязательно даже обмениваться пакетами. Соответственно, если один конец падает, то второй об этом узнает только когда попытается отправить пакет, а точнее, когда после ожидания таймаута не получит ответ. Бывает так, что целый день работали, заполнили пул TCP соединений, а за ночь firewall их разорвал, поскольку никакие пакеты через них не передаются. Утром же мы по очереди берем соединения из пула, ждем таймаута, и только когда все соединения из пула закончатся, будет создано новое работающее соединение. Т.е. в итоге время ожидания будет таймаут*размер пула. Разумеется, зная причину, это проблему тоже можно решить.
В конце доклада было уделено время другому протоколу - UDP. Протокол без гарантий доставки, который может быть использован, например для передачи быстро устаревающих данных. Однако чаще всего, используя UDP надо быть готовым к дублированиям, данным не по порядку, ошибкам и т.д, и могут потребоваться в какой-то степени велосипеды. Также нужно быть осторожным в одновременном использовании UDP и TCP: первый может положить второго.

Виктор Полищук - Legacy: как победить в гонке

Виктор заметил, что любой проект рано или поздно становиться legacy, но legacy бывает разным. Можно с нуля написать проект на известных старых технологиях, и он сразу же станет legacy, причем аккуратным, все понятным, работающим legacy. Другой вариант: написать на новых "хипстерских" технологиях, получая удовольствие от того, что ты первый, но потом эти технологии могут устареть, поменяться подход и в итоге это уже станет legacy, которого все будут сторониться. Но это не значит, что нужно всегда использовать устаревшие, проверенные технологии, ИМХО, зависит от проекта.
И вообще, legacy, это значит проект успел устареть, значит этот проект жил какое-то время, а это успех. Legacy это работающий код, которым довольны клиенты и в принципе это не плохо.
Конечно, всему есть мера, после этого Виктор показал примеры ужасного кода, типа универсального компаратора, который сравнивает все подряд и других подобных ужасов. Причем, по его словам, этот код был в проекте на протяжении нескольких лет, разработчики видели его, но никто не удосужился исправить. Лично мое мнение, что они правы: работает - не трогаем. Но как только есть возможность, то конечно, такое нужно устранять (с тестированием).

18 окт. 2015 г.

Как установить teamcity на сервер

Teamcity - отличный бесплатный инструмент Continius Integration от JetBrains. Ниже небольшой мануал по его установке на debian.

Для работы teamcity необходима БД:

sudo apt-get install mysql-server mysql-client
sudo service mysql start
sudo mysql -u root -p

Затем в этой базе данных надо сделать несколько SQL запросов, чтобы создать БД для teamcity 

CREATE DATABASE teamcity CHARACTER SET utf8 COLLATE utf8_general_ci
CREATE USER 'teamcity'@'localhost' IDENTIFIED BY 'teamcitypass';
GRANT ALL PRIVILEGES ON teamcity.* TO teamcity@localhost;

Установка teamcity будет производится не из репозитория, а вручную. Для этого надо скачать и распаковать архив с официального сайта jetbrains:

cd /opt
sudo wget http://download-cf.jetbrains.com/teamcity/TeamCity-9.1.3.tar.gz
sudo tar xfz TeamCity-9.1.3.tar.gz 


После этого остается запустить Teamctiy через скрипт запуска:

sudo sh /opt/Teamcity/bin/runAll.sh start

По умолчанию, порт Teamcity 8111, поэтому сразу после запуска нужно открыть в браузере [ваш_ip]:8111 и закончить установку. 

В процессе первого запуска teamcity попросит jdbc driver mysql, его надо положить в каталог, который там будет указан.

cd [требуемый каталог]
sudo wget http://cdn.mysql.com/Downloads/Connector-J/mysql-connector-java-5.1.36.zip
sudo apt-get install unzip
sudo unzip mysql-connector-java-5.1.36.zip
sudo mv mysql-connector-java-5.1.36/mysql-connector-java-5.1.36-bin.jar mysql-connector-java-5.1.36.jar

4 окт. 2015 г.

Собственный виртуальный сервер с нуля

Иногда бывает удобно для каких-то целей иметь собственный домашний сервер. Мне он нужен для следующих целей:
  • Самообразование. Своими руками что-нибудь сломать сконфигурировать 
  • Выложить свои наработки чтобы с кем-нибудь поделиться
  • Инфраструктура разработки. 
  • Возможность всегда добавить что-нибудь еще.
Ранее роль сервера у меня выполнял старый ноут, но такое решение создавало несколько проблем (как и любой сервер дома)
  • Пожароопасность
  • Регулярные отключения электроэнергии, частые падения, как следствие
  • Сложно увеличить ресурсы.
Просмотрев цены на виртуальные сервера, я был приятно удивлен, что эти услуги не стоят нескольких тысяч рублей в месяц, а самый простой сервер может обойтись в 200 рублей в месяц. После недолгого изучения я нашел вот этот сервис, на котором и создал виртуальный сервер.

В этом посте я расскажу, как с нуля поднять виртуальный сервер, на котором будет:
  • java
  • tomcat
  • apache

29 сент. 2015 г.

Документирование в виде диаграмм прямо в коде

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