Category: Java

Python или Java? Хм… а может Groovy?

На DOU новый холивар Что выбрать бывшему учёному — Python или Java?

Хочу оставить позицию младшего научного сотрудника и переквалифицироваться в разработчика. Всё высшее образование было профильным — информатика. Коммерческого опыта в программировании нет, только эксперименты и учебные проекты. В последнее время предпочитаю писать их на Python, для него есть хорошие научные библиотеки.
Цель — найти позицию разработчика, которая могла бы мне дать начальный опыт. В перспективе — вывести на более наукоёмкие позиции (анализ данных, машинное обучение, обработка естественных языков).
Город большого значения не имеет, особых требований по начальной зарплате нет — лишь бы хватало на съёмную квартиру и проживание.
Работу начну искать где-то с весны, поэтому остаётся время на подготовку. Осталось решить, в каком направлении мне развиваться.
Некоторые соображения (рынок я знаю плохо, поэтому можете смело поправлять):
1) По Java вакансий намного больше, чем по Python. Кроме того, можно официально подтвердить знания Java, сдав какой-нибудь начальный экзамен Oracle — это может привлечь внимание HR.
2) С другой стороны, в Java есть множество неизвестных мне корпоративных технологий и фреймворков, в которых можно надолго утонуть. В Python с этим проще — если я освою базовый Django (может, Flask, Bottle) и сделаю на них несколько личных проектов, то это должно покрыть начальные требования.
3) Java — это в основном аутсорс, Python — это в основном продуктовые компании (или у меня сложилось такое впечатление).
Что будет лучшим стартом, если мне хочется дорасти до профессиональной работы с анализом данных, прогнозированием, построением рекомендательных систем и т.п.?

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

Пока единственный известный мне настоящий специалист по Data Science поработавший в Германии на суперкомпьютере, работал таки на Java, и я вообще сомневаюсь как что-то действительно большее Hello world можно написать на Python.
Хотя, конечно, хорошие программисты могут писать на чём угодно.

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

И всё таки лучше не забывать что Питон обманчиво кажется простым: он довольно своебразен и уводит в свою вселеную.

Мне кажется, что пока лучше выбирать JVM, как платформу. Если не будет хватать возможностей Java то можно попробовать другие JVM языки: тот же JPython, Scala или Groovy.

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

В случае, если захочется большей выразительности, DSL или динамики то есть Groovy — великолепный язык программирования, обратно совместимый с Java и обладающий наверное всеми теми качествами за которые тут так сильно хвалят Питон.

На Groovy кстати есть даже всякий научный софт, например GroovyLab:

GroovyLab is a MATLAB-like scientific programming environment based on Groovy with extensive plotting support, default access to the best Java scientific libraries, user-friendly interface, easy installation of toolboxes, Computer Algebra support and many other features.

Вообщем, могу сказать точно что выбрав джаву не прогадаешь
joseph-ducreux-meme-disregard-python-acquire-java-080b2b


Не поленитесь, и почитайте ещё несколько очень важных моих статей для начинающих программистов, студентов и джуниоров.
Также не забудьте вступить в группу IT Juniors куда я пытаюсь собирать ссылки на другие полезные статьи для вас и анонсы курсов и интернатуры в компаниях.

toString() contract

Today I read great article of Fabian Kessler Java toString(): the Program Logic vs. Debug Dilemma.

In short, it is not obvious how to override method and what exactly means «string representation of object»:

Hrm. So there are mainly 2 uses:
String representation: toString() returns the object’s value «as string» as close as possible.
It is absolutely required to override toString(), and to do it in this way.

Debug information: the object’s values for the human.
For example IntelliJ IDEA’s default toString() template generates this kind.
It’s just nice to have.

JavaDoc says:

Returns a string representation of the object. In general, the
toString method returns a string that
«textually represents» this object. The result should
be a concise but informative representation that is easy for a
person to read.
It is recommended that all subclasses override this method.

Quotation from the «Effective Java» book:

One important decision you’ll have to make when implementing a toString
method is whether to specify the format of the return value in the documentation.
It is recommended that you do this for value classes, such as phone numbers or
matrices. The advantage of specifying the format is that it serves as a standard,
unambiguous, human-readable representation of the object. This representation
can be used for input and output and in persistent human-readable data objects,
such as XML documents. If you specify the format, it’s usually a good idea to pro-
vide a matching static factory or constructor so programmers can easily translate
back and forth between the object and its string representation. This approach is
taken by many value classes in the Java platform libraries, including BigInteger ,
BigDecimal , and most of the boxed primitive classes.

I found that most of code that I saw uses some unwritten «toString() contact». The contract mostly based on difference between Entity and Value objects.

1. «String typization» mechanism

The Delphi programming language has a great conception of Variant type. It is difficult to me to explain this in few words. It is like an universal container for the primitive types.

This is like a def keyword in Groovy: it mean any type. But any primitive type, not an basic Object.
And there is convention like a «Groovy Truth» how one primitive type should be converted to another.

Unfortunately Java hasn’t Variant type, so it uses String as it replacement. Hence, any primitive type you can convert to sting presentation: numbers, dates and boolean.
This is called StringlyTyped pattern and actually it makes code understanding painfully.

String typization

That’s why we should look on toString() as on data converter «as string».
And it should work only with Value classes and primitive datatypes wrappers, i.e. Integer, Boolean, Double, Date, Phone Numbers etc.

Important thing here is that this resulting string representation of value can be parsed verse to get an original value.

2. Serialization

In more common sense toString() it is a kind of serialization.
Even more, toString() can return JSON on CSV value.
But you should remember that deserialization is not granted by method contract.
That’s why you should use standard approach and implement Serializable interface.

But you still can use toString() as serialization for basic types that already contains written toString(), parse() and valueOf() methods.

3. Human readable representation of object

Another thing is when we need to show the object to a user. In this case it may be better to create another method called like a getDisplayName(), getTitle() or getCaption().

For example User class can contain getFullName() that return First Name and Second Name with space between them.

public class User {
   String firstName;
   String lastName;
   
   String getFullName() {
       return firstName + " " + lastName;
   }
}

Why it is better? First of all human readable names can be different and one string representation method may be not enough.

For example lets take a look on Facebook. In the private mail conversation between two users we can just write first name. At the public profile page we can display «First name + (nickname) Second name».

Also, usually this kind of display names can be localized. For example name of month or book title.

4. Log/Debug representation

In all other cases toString() used for logging or debug output. Just to make developer life easier.

The Groovy has a helpful @ToString annotation that generates this method in runtime.
For example class User can contain toString() method that return user login or email:

@ToString(includeNames = true, includes = 'email,firstName')
class User {
   String email
   String firstName
}

...

def user = new User(email: "admin@example.com", firstName: "Administrator")
assert user.toString() == "User(email:admin@example.com, firstName:Administrator)"

...
log.info("User ${user} logged in")

Here log.info() will call toString() method that is not good. I’m totally agree with Fabian and such method should be named toDebug() or dump(), but not toString().

But you should always remember that logging can cause problems for security and performance.
Not always you need to write to log everything that object contains.
For example if a hacker got an access to logs he can see a lot of stuff like user password and other credentials or even credit card number.
So you should take care to exclude from logs sensitive information.
Always mask credit card numbers and users personal info.

Another big problem is log injection vulnerability when some XSS scripts from logs can be executed in dashboard. Please read carefully OWASP Logging Cheat Sheet

Conclusion

Using this conventions may make your code better and safer.
I would be very thankful if you share conventions from your experience 🙂

[Grails] SEQUENCE generator name

Если у доменного объекта не указан способ генерации айдишника тогда Hibernate подбирает его сам. Это называется native стратегия.

Если вы используете не уродскую MySQL, а настоящую базу данных типа PostgreSQL, Oracle или Firebird, то генерация айдишников будет происходить через SEQUENCE.

При генерации БД название для сиквенсов генерируется автоматически и выглядят они примерно так: SYSTEM_SEQUENCE_99A7416D_98E6_485C_8568_1DD6C99BF31C. Т.е. нейминг стратегия мягко говоря неадекватная.
Из-за неё возникает несколько проблем.

Во первых из названия такого сиквенса не понятно для какой именно он таблицы.

Во вторых, я сталкивался с проблемой когда при следующем релизе через database migration накатываются изменения и возникает необходимость сбросить сиквенс, то не ясно по какому имени к нему обращаться.

Как решать?

Переопределить нейминг

Первый вариант создать свой диалект внутри которого прописать правильную генерацию имени сиквенса.
По уму стоило бы всё таки пропатчить эту паскудную генерацию имени сиквенсов в самом хибернейте. Ставлю пивашку тому кто это сделает 🙂

Указать имя сиквенса явно

Для того чтобы обойти эту проблему можно в мапинге домена явно указать имя сиквенса:

class Book {
    String title

    static mapping = {
        id generator: 'sequence', params: [sequence: 'book_seq']
    }
}

Теперь для таблицы book будет создан сиквенс book_seq.

Естественно, если вы вдруг решите запустить приложение на БД в которой нет сикенсов то отгребёте ошибку типа такой org.hibernate.MappingException: org.hibernate.dialect.MySQL5InnoDBDialect does not support sequences.

Так что такое решение не годится для использования если вам не известная используемая БД, например в плагинах.

Правильное решение

Я сначала подумал что на этом тупик, но пролистав документацию хибернейта дальше обнаружил что решение уже есть.
Если вкратце, то начиная с версии 3.2.3 в хибернейте появился SequenceStyleGenerator который в отличии от нейтив, позволяет указать опции одновременно и для SEQUENCE генератора и для Table не падает с ошибкой на старте.

class Book {
    String title

    static mapping = {
        id generator: 'org.hibernate.id.enhanced.SequenceStyleGenerator', params: [sequence_name: 'book_seq']
    }
}

В документации сказано что ещё следует включить новые генераторы. Для этого в DataSource.groovy нужно добавить опцию

hibernate.id.new_generator_mappings = true

Но если честно, то всё и без этого заработало 🙂

Теперь в MySql рядом с таблицей book создалась таблица book_seq с одной строкой и одним полем next_val которая имитирует сиквенс.

Проблемы OpenJDK или в очередной раз про идиотизм Orcale

Ну для начала лекция для тех кому интересно въехать в курс дела:

У меня к OpenJDK есть такие претензии:
1. Название, я поначалу подумал «ну вот ето JDK а мне на сервер достаточно только JRE» и искал OpenJRE 🙂
2. Сайт: посмотрите на сайт Mono http://www.mono-project.com/ — красивый, всё ясно куда нажимать. А теперь посмотрите на это уродство http://openjdk.java.net/ . Я не дизайнер, и неприхотливый но даже меня тошнит. А ведь это же маркетинг!
4. Почему IDEA упорно не дружит с ним? Это меня настораживает — вы говорите что OpenJDK на 99% соответсвует обычной OracleJDK, но идея пишет что будут проблемы с графикой. Это правда? В чём причина? Напишите JetBrains чтобы они убрали это сообщение.
5. Где версия под Windows?
6. Отправлять патчик по мылу это прошлый век — перенесите проект на GitHub!

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

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

Ruby, Ruby, Ruby, Ruby! And do ya, do ya, do ya, do ya!

Просто несколько вещей которые бесят постоянно. Можно расписывать их много, но тут я акцентирую внимание на том что уровень вхождения в Яву выходит большим из-за банального разгильдяйства Oracle. Неожиданно, но они совсем не учитывают что платформу нужно ПРОДАВАТЬ, и очень важен маркетинг. А ведь ещё «корпорацией бабла» называются 🙂

JDK, JRE — WTF?

JDK содержит в себе полную JRE + SDK (компилятор, декомпилятор, дебагер и.т.д). Тем не менее, вместо того чтобы ставить отдельно SDK, всегда приходится полностью выкачивать JDK содержащий JRE.
Самое интересное, что теперь у нас есть OpenJDK, и несмотря на JDK в названии он же и JRE. Я окончательно запутался.

Is Java open soure?

Принято считать, что Java открытая платформа. Что можно считать открытой платформой? Сам язык Java, насколько я в курсе это вполне проприетарная технология. Открытые исходные коды — это ещё не значит что это открытая платформа. Например разработка Android ведётся в строжайшем секрете и ты не знаешь чем тебя удивит Google в следующей версии. Но так-то исходники открывают, да.
Изначально SUN не хотела выкладывать исходники Java из-за того что те содержали какой-то патентированый код. Я не очень понимаю почему это было большой проблемой. Можно было выложить то, что можно, а запатентированный код либо переписать, либо выделить в отдельный модуль. В принципе так вроде и сделали в результате чего получилась OpenJDK. Но тут есть ключевой момент: OpenJDK — это отдельный проект. Его нужно отдельно расскручивать, у него отдельный сайт, своё сообщество и, что потенциально опасно, свой код который может начать отличатся от того что внутри оракловой JDK. И тут сразу возникает следующий вопрос…

OpenJDK == Oracle?

На конференциях парни из Oracle утверждают что OpenJDK это на 99.9% тоже что и Oracle JRE, и что они вообще билдятся из одних исходников. Тем не менее, IntelliJ упорно отказывается работать с OpenJDK и запугивают проблемами с производительностью. Наверное тут дело в криворукости JetBrains, но всё равно настораживает.
Тем не менее, все продолжают использовать именно OracleJDK

Oracle принципиально не делает дистрибутива для Debian, а только для своей Solaris.
А в Ubuntu выпилили этот пакет, в результате каждый раз установка джавы превращаются в пляску с бубном: нужно прописать сторонний PPA, в котором инсталятор Java, который за тебя выкачивает её из сайта Oracle и устанавливает. Естественно такой пакет из стороннего PPA нельзя использовать как зависимость в своём пакете.

  1. На сайте Оракла чёрт ногу сломит, всё страшное и некрасивое. Ещё и вымагают регистрацию. Никакой заботы о пользователях, никакого маркетинга.
  2. Почему-то инсталятор сам не прописывает переменную JAVA_HOME и JDK_HOME. Что ему, жалко что-ли? Вообще переменные окружения это большое зло, может уже пора искоренить их вовсе?
  3. Успех платформы во многом зависит от наличия пакетного менеджера в поставке с ней. В Ruby есть gem, в NodeJS — npm. В яве ничего.
  4. Туториалы на оф. сайте стары как мир, без подсветки синтаксиса и никакого интерактива.

Как так получилось что откровенно поганая платформа Ruby стала такой модной и популярной? Умелый маркетинг.
Посмотрите на сайт например Mono, он выглядит приятней и опрятней, пускай это аутсайдерский проект, но даже там пытаются хоть ка кто для людей сделать.
Я уже молчу про прямого конкурента Java — платформу .NET.
На сайте много всячины и сразу же баннер на Visual Studio.
А теперь гляньте на Web 1.0 сайт явы. Фу!
Кстати, тоже самое касается самого языка программирования.
Если MS в целях маркетинга впихнул всё нужное и ненужное в C#, то в Яве даже самые нужные фичи добавляют с огромным скрипом. Вот например, лямбд все ждут уже десятилетие, и вот уже наконец в восьмой Яве будут.
Конечно, Ява по философии консервативна и стремится быть минималистичной, но не до такой же степени чтобы ждать пятой версии для for each циклов.

Когда то ява была прорывом, и очень потенциальной технологией.
Но тянули до последнего с открытием исходников, забили на дистрибьюцию, забили на десктопы, оконные программы смотрятся ужасно, просрали рынок аплетов который теперь заполонил поганый Flash, поругались с MS, а теперь ещё и с Google.

Маркетинг господа. Если вы ещё не поняли, то в постиндустриальной эпохе это самое главное.

[Заметка] Статический анализ кода на Java: Sonar и Maven

Вкратце о том как подключить Sonar к вашему проекту на Maven.
Чтобы ваш проект попал в сонар по дефолту достаточно просто выполнить команду

mvn sonar:sonar

Проблема в том что для выполнения этой команды сонару нужно знать дополнительно несколько вещей, а именно:

  • Язык вашего проекта: sonar.language
  • Адрес сайта сонара: sonar.host.url
  • Настройки БД сонара: sonar.jdbc.url, sonar.jdbc.driver, sonar.jdbc.username,sonar.jdbc.password

Язык вашего проекта и адрес сайта это публичная информация и указываем их прямо в pom.xml файле:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
...
    <properties>
        <sonar.language>java</sonar.language>
        <sonar.host.url>http://sonar.example.com:9000/</sonar.host.url>
    </properties>
...
</project>

Настройки БД не должны быть видны народу поэтому мы устанавливаем их в settings.xml

<profile>
   <id>sonar</id>
   <activation>
      <activeByDefault>true</activeByDefault>
   </activation>
   <properties>
      <sonar.jdbc.url>jdbc:postgresql://localhost/sonar</sonar.jdbc.url>
      <sonar.jdbc.driver>org.postgresql.Driver</sonar.jdbc.driver>
      <sonar.jdbc.username>user</sonar.jdbc.username>
      <sonar.jdbc.password>password</sonar.jdbc.password>
   </properties>
</profile>

После этого запускаем
mvn sonar:sonar
Ещё годная статья по теме

Почему я советую знакомым студентам учить Java?

Недавно снова наткнулся на вопрос «почему Java а не что то другое?». Я уже отвечал на форуме, теперь достал и оформил в виде статьи с акцентом почему я советую знакомым студентом учить Java.
Я не очень опытный специалист и здесь будет много субъективного мнения, и конечно же тема очень обширная и холиварная, но я хочу собрать все свои мысли в одном месте.
Вкратце суть статьи:
Учить нужно то, за что платят (т.е во что вкладывают) деньги, а больше платят за Java. Там и инновации, и широкий спектр решений и технологий.
Java нацелена на разработку больших проектов, поэтому её любят большие корпорации.
А платят за Java больше чем например за C#, в который тоже вбухивают деньги, потому что стоимость разработки и сопровождения ниже: много бесплатных инструментов, библиотек обкатанных временем, средства разработки и она кроссплатформенная и можно использовать бесплатный Linux, обратно совместимая, предсказуемая и надёжная.

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

Начнём с анализа текущих дел

Сейчас массовый софт работает в трёх основных областях:

  • Desktop приложения (офисы, АРМы, студии, системы документоборота, антивирусы), т.е. требующие установки на компьютер.
  • Web приложения сюда мы отнесём все сайты и онлайн сервисы (wikipedia, gmail). Многих она притягивает потому что не требуется установка ПО и данные остаются доступными в сети.
  • Мобильные приложения
  • Игры, особенно мобильные и броузерные для социальных сетей.
  • Embeded — встроенные системы (драйверы, контроллеры)

Примерно прикинем популярность по трендам индексатора американских сайтов работы indeed.com:

Веб самый популярный, а embeded совсем мал. Mobile и игры для социальных сетей растут как на дрожжах, это очень хорошо видеть если посмотреть тренд относительного прироста:

Embeded я убрал из-за странного дёрганого тренда.

А теперь график по языкам:

Тут несколько нюансов:

  • Для большего драматизма я добавил любимый но мертвый Delphi.
  • Также по Си из-за однобуквенного названия график выходит неоправданно завышенным, я использовал C Developer, тренд хоть кажется адекватным.
  • Objective-c подозрительно маленький тренд, чаще пишут iOS developer.
  • JavaScript (не путать с Java!) раньше имел ограниченное применение для небольших клиентских сценариев в броузере, но сейчас стал активно использоваться для создания игр и даже для серверного программирования.

Основные области применения Java это большие web приложения, банковские desktop приложения и мобильная разработка для Android. Т.е. она сразу попадает в три популярные категории.

Ну и собственно зарплаты по данным опроса DOU.ua
75 перцентиль midle разработчиков в Киеве. Справа шкала количества анкет.

 

Причины такой позиции Java

  • Строгая, статическая типизация что значительно уменьшает число ошибок и улучшает сопровождаемость кода, особенно если ещё использовать статический анализатор. При этом в яве есть ограниченные возможности динамического программирования через магию рефлексии и аннотаций. Но тем не менее есть её диалект Groovy который динамический и почти полностью совместим с ней на уровне синтаксиса. На нём кстати есть отличный Rails подобный фреймворк.
  • Java на рынке с 1995 года, обкатана и существуют сотни решений и технологий.
  • Что немаловажно является по сути упрощённым C++ который учили все в институтах и поэтому переход на неё проходит менее болезненно.
  • Язык прост, предсказуем, и минималистичен. Новые фичи вводятся очень осторожно, иногда даже черезчур долго (например замыкания).
  • Синтаксис Java является чем то вроде linva franca поэтому авторы книг часто выбирают её для примеров кода.
  • Мощные IDE, в частности Idea вообще вершина эволюции средств разработки и стоит в разы дешевле чем Visual Studio Ultimate для C# (700$ против 13300$).
  • Даже если кто и быдлокодит, это будет относительно легко разгрести через средства рефакторинга в IDE.
  • Кроссплатформенность, работает буквально на всём: от суперкомпьютеров до смарткарт и что особенно приятно на бесплатном Linux и FreeBSD.
  • Существуют около 350 гигабайт библиотек доступных в репозитории Maven. Для всего всего всего. И они в большинстве своём открытые, да.
  • В следствии очень дешёвая разработка.
  • Очень много программистов. Java самый популярный язык. Есть официальная сертификация программистов OSCJP.
  • Открытая стандартизация JSR, спецификации Java EE.
  • Компилируется в байт код, а не требует полной интерпретации как например Ruby и Python, что ускоряет работу. А благодаря оптимизирующему JIT компилятору может приближаться по скорости к нативному коду.
  • И последняя но далеко не последняя по важности: Полная обратная совместимость по API и ABI ещё с самых первых версий. Седьмая Java это всего лишь минорная версия, т.е. 1.7. Ни один другой язык не может похвастаться такой обратной совместимостью, даже C#.

 

Вывод

Остальные платформы и языки тоже хороши и востребованы и некоторые из них сейчас переживают бум. На их фоне Java выделяется самой сильной позицией и неплохими, пускай не самыми большими зарплатами. Но поскольку Java используется в корпоративном секторе и все проекты на ней большие то практически полностью отсутствует возможность фриланса на ней. Например количество вакансий на самой популярной фриланс бирже oDesk по запросу Spring (самый популярный веб фреймворк для Java) совсем не впечатляет.
Поэтому многим из тех кто хочет начать карьеру программиста но живут в городах где не устроится программистом прийдётся подаваться на фриланс и педалить на гнусном PHP.

«Есть всего два типа языков программирования: те, на которые люди всё время ругаются, и те, которые никто не использует.»

(c) Бьёрн Страуструп, автор C++

И Ява тоже далека от идеала. Кстати комментарий из этой статьи:

>> Ведь основная цель java была в облегчении жизни нам — простым разработчикам.
Это вас кто-то обманул. Главное преимущество джавы — надежность и предсказуемость. Ценой многократных, по сравнению с другими языками, усилий разработчиков.

Но это не самое важное, а главное «Вы должны писать на языке, который делает вас счастливее» (Пэт Аллан).

P.S. Наткнулся на очень толковое обсуждение где очень толковые специалисты высказали своё ведение проблемы.
Обратите внимание, я не призываю выбирать Джаву как первый язык программирования, в этом есть определённая опасность.

Ещё одна статья Какой язык программирования выбрать


Не поленитесь, и почитайте ещё несколько очень важных моих статей для начинающих программистов, студентов и джуниоров.
Также не забудьте вступить в группу IT Juniors куда я пытаюсь собирать ссылки на другие полезные статьи для вас и анонсы курсов и интернатуры в компаниях.

Dev database

HQSQL крут тем что сама БД в файл сохраняется как SQL скрипт который её создаёт и начиняет данными.

Это очень удобно, не нужно дополнительного клиента чтобы посмотреть содержимое БД.
Можно ложить его в VCS и отслеживтаь изменения.

А вот H2 так не умеет, у него БД имеет бинарный формат. Это кстати странно, потому что H2 разрабатывал автор HQSSQL, и вообще H2 значит Hipersonic 2.
Ну, ну конечно, можно дампится в SQL и его уже ложить под контроль VCS, но зачем лишние телодвижения?

Мысли про компараторы

Компараторы возвращают отрицательное значение (не важно какой величины, чаще -1) если элемент меньше, нулевое если они на одном уровне, и положительное если уровнем больше.

Можно сделать более продвинутый компаратор который с учётом величины чем который бы позволил более эффективно использовать сравнение.
Например элемент который меньше на -3 сразу переместить ниже элемента который меньше на -2.

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

Реинкарнация первоапрельской библиотеки Google Annotations Gallery

На первое апреля 2010 года пару сотрудников Google выпустили прикольную библиотеку смешных аннотаций для Ява проектов Google Annotations Gallery.
Она произвела фурор, но к сожалению дальше проект никто не стал развивать.
Некоторые пользователи начали предлагать новые смешные аннотации и попросили сделать библиотеку доступной через репозиторий Maven.
Парочку новых аннотаций было таки добавлено и проект, хоть не маневизированый но был позже добавлен в репозиторий мавена.

Лично я испытываю страсть к аннотациям поэтому эта библиотека меня особенно заинтересовала.

Поскольку проект мёртвый и хоть исходники открыты внести свою лепту в него проблематично из-за соборной модели хостинга code.google.

Поэтому я его форкнул себе в репозиторий на GitHub, мавенизирировал и сегодня выложил в центральный репозиторий мавена под своим groupId.
Базарная модель GitHub больше подходит к этому проекту и я надеюсь что теперь это заведёт проект по новой.

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

    <dependencies>
        <dependency>
            <groupid>com.github.stokito</groupId>
            <artifactid>gag-annotations</artifactId>
            <version>1.0.1</version>
        </dependency>
    </dependencies>

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

Что вы делаете когда натыкаетесь на говнокод? Бурчите, проклинаете индусов или молча его рефакторите. Это очень круто если у вас есть возможность отрефакторить его, на самом деле это очень большая роскошь и просто порефакторить вам либо не дадут вовсе либо заставят откатить перед ревью и комитом.
В итоге агрессия и недовольство накапливается, и это проблема о которой хорошо написано в статье Как интерфейс без обратной агрессии вызывает в людях ярость.

Комментарии очень важны, они позволяют разработчикам высказывать своё мнение, отмечать сложные места для будущего рефакторинга.
Есть ещё тудушки но как это не парадоксально на многих моих проектах они были запрещены!

В отличии от обычных комментариев аннотация является стандартной вещью которую можно найти автодополнением и которая проверяется компилятором.

А это значит что теперь по таким аннотациям можно делать полноценный поиск в проекте и даже более того, они могут служить маркерами для статических анализаторов кода (например Sonar) чтобы стать метрикой.

Таким образом наличие такой библиотеки действительно повысит качество кода и сделает разработчиков счастливее.

Я всегда хотел подобный инструмент.

Присоединяйтесь, форкайте 😉

[Перевод] Способы сравнения объектов дат в Java

Аннотация от переводчика

Статья вкратце затрагивает трудности работы с датами в Яве на простом примере сравнения дат. Рассчитана для начинающих программистов которые уже более менее знакомых с работой с датами в Java.

Итак, давайте обрисуем проблему — сравнение объектов Date в Java известный источник ошибок.
Это появляется в стандартном коде, но также бывает и в тестирующем коде, где нам регулярно нужно создавать объекты Date которые отмечают определенный момент времени на который потом будем ссылаться в сравнении.

Старый добрый устаревший и не рекомендуемый путь

В тестирующем коде я не переживал что использую устаревшие (deprecated) методы. Поэтому я использовал старый конструктор Date чтобы инициализировать даты, после чего я сравнивал их с другим объектами дат через метод сравнения equals():

Date date = new Date(112, 5, 3);
Date userCreatedDate = user.getCreatedDate();
if (userCreatedDate.equals(date)) { // Если даты равны…
  // делаем что нибудь…
}

Преимущества: это лаконично. Недостатки: это весьма не очевидно и вам нужны хорошие знания Java API чтобы знать что первый параметр это год минус 1900 и второй это индекс месяца который начинается с ноля для Января. И это сюрприз когда вы узнаёте что последний параметр это просто… просто день месяца.

Канонический способ

Начиная с Java 1.1 в Java API был добавлен класс Calendar чтобы разделить момент во времени (т.е. дату) от её представления в специфическом справочнике (календарь). Следующий фрагмент кода (snippet) это способ получения такого же результата как выше.

Calendar calendar = Calendar.getInstance();
calendar.set(YEAR, 2012);
calendar.set(MONTH, JUNE);
calendar.set(DAY_OF_MONTH, 3);

Это не только более многословно, тут также есть ошибка: часы, минут и остальное не равно нолю (берётся от момента непосредственного создания календаря), поэтому сравнение через equals() будет возвращать false. Вот правильный код:

Calendar calendar = Calendar.getInstance();
calendar.set(YEAR, 2012);
calendar.set(MONTH, JUNE);
calendar.set(DAY_OF_MONTH, 3);
calendar.set(HOUR_OF_DAY, 0);
calendar.set(MINUTE, 0);
calendar.set(SECOND, 0);
calendar.set(MILLISECOND, 0);

По меньшей мере это ухудшает краткость 😉

Apache Commons Lang

Apache Commons изначально предоставляет различные утилитные библиотеки которые облегчают разработку в Java. Одна из таких библиотек Apache Commons Lang которая предоставляет функционал который заслуживает быть частью Java API. В нашем случае класс DateUtils позволит нам сократить код сохранив при этом его читаемость:

Calendar calendar = Calendar.getInstance();
calendar.set(YEAR, 2012);
calendar.set(MONTH, JUNE);
calendar.set(DAY_OF_MONTH, 3);
calendar = DateUtils.truncate(calendar, DAY_OF_MONTH); 

Даже лучше, DateUtils позволяет нам работать непосредственно с объектами Date в таком альтернативном виде:

Date date = new Date();
date = DateUtils.setYears(date, 2012);
date = DateUtils.setMonths(date, JUNE);
date = DateUtils.setDays(date, 3);
date = DateUtils.truncate(date, DAY_OF_MONTH);

Обратите внимание что он оставляет параметры нетронутыми, достигая неизменяемости (immutability) по принципа функционального программирования.
Преимущества: мы используем стандартное Java API.
Недостатки: да никаких. И ещё, не будет ли полностью своеобразный DSL казаться чем-то более подходящим?

Joda Time

Последний вариант это использование библиотеки Joda Time, которая нацелена стать заменой для Date и Calendar. Она также породила JSR-310 — новый и улучшенный API для манипуляции с датой и временем, который должен стать частью Java 8 (он был изначально запланирован для Java 7). Joda Time стоит посвятить отдельную статью (или даже мини-руководство). Для наших текущих нужд следующий фрагмент кода может выгодно заменить наш изначальный:

DateMidnight dm = new DateMidnight(2012, 6, 3);

Если сравнивать с первым примером, такой код кажется чище и лаконичней. И ещё, параметры самоописывающие, нет реальной нужды регулярно проверять JavaDocs чтобы узнать как инициализируется год. Кроме того, семантика имён классов ясна. И наконец, метод toDate() даёт нам мост к стандартному Java API.

Заключение

Вывод делайте сами. Лично я обычно использую Apache Commons Lang, но в последнее время склоняюсь к Joda Time. Архив с примерами кода доступен для скачивания тут в виде Maven проекта под Eclipse.

Автор: Nicolas Fränkel
Оригинал Ways of comparing Date Objects in Java.