
P.S. Автор сонета — Виктор Пелевин. Что-то из раннего.
124 дн. назад

P.S. Автор сонета — Виктор Пелевин. Что-то из раннего.
124 дн. назад
В каждом языке есть свои маленькие секреты и хитрости, о которых иногда полезно знать. Решил завести себе небольшой цикл для таких хитростей касательно Явы. Ну что ж, поехали!
Есть код. Нужно ответить, что он выведет.
Integer a = 200;
Integer b = 200;
System.out.println(a == b);
Здесь все просто. Выведет False. Для тех, кто в танке и читают книжки невнимательно, объясню.
Ява сравнивает примитивные типы (byte, short, int, long и т.д.) и объектные (Byte, Short, Integer и Long, соответственно) по разному. У примитивных типов проверяется их значение. У объектных типов проверяется указывают ли они на один и тот же объект. А так как мы создали два разных объекта (пусть даже и с одинаковыми значениями), проверка возвращает False.
Теперь немного изменим наш код. Всего лишь уберем по паре нулей у целых чисел. Что выведет?
Integer a = 2;
Integer b = 2;
System.out.println(a == b);
Не буду томить с ответом, выведет — True. Опять же — почему? Чтобы ответить на этот вопрос нужно знать как устроена Ява, а точнее JVM.
Устроена JVM так, как ни странно, что любит оптимизировать и кешировать. По-этому для нужд производительности виртуальная машина кеширует объекты для часто встречающихся примитивов (чисел от -127 до 127, некоторых символов, true и false). Другими словами, когда мы пишем:
Integer a = 2;
новый объект не создается, а берется уже готовый. Откуда? Из кеша. Это естественно повышает производительность наших программ и дает повод для гордости программистам, которые причастились к этой великой тайне.
Мораль этой истории проста — избегать сравнения объектных типов, соответствующим стандартным примитивам. Лучше приводить их вручную через type casting, а потому уже сравнивать их значения. Так кошернее.
131 дн. назад
Так как я профессиональный блоггер и зарабатываю себе этим на жизнь, я прекрасно понимаю, что блог без картинок — это как прийти в кинотеатр, а там ни сидений, ни попкорна, ни Пепси-Колы. Так что показываю здесь футболку, которая вчера успешно попала мне в руки:

Футболка изображает Чувака (он же Dude) из фильма «Большой Лебовски». В одной руке у него шар для боулинга, в другой — коктейль «Белый Русский» (водка, кофейный ликер и сливки).
С размером футболки немного не угадал, но в целом доволен.
131 дн. назад
Посмотрел недавно видео с Google TechTalk. Видео было про эффективное пользование текстовым редактором. Если быть точнее, редактором Vim. Это такой маньяческий редактор. Если вы не знаете, что это такое, не читайте дальше, выключите компьютер и ложитесь спать.
Суть выступления сводилась к тому, что мы очень часто пользуемся текстовым редактором. И очень часто пользуемся им не совсем эффективно. Всегда существует какая вещь, которая отнимает у нас время. Это может быть поиск слова, исправление опечаток, набор одного и того же длинного слова и так далее. Автор предлагает избавляться от таких вещей. И для этого приводит простой алгоритм:
Первый пример (всего их в презентации было семь, но я ограничусь одним) касался проблемы поиска слова. Допустим нам нужно найти все места, где встречается какая-нибудь переменная «argc». Разберем этот случай по вышеприведенному алгоритму.
Я пишу «/argc» и нажимаю «n» нужное мне количество раз, как и большинство других пользователей.
Я должен вводить имя переменной. А оно не всегда бывает коротким. К тому же я могу это имя неправильно напечатать. И тогда мне придется исправлять ошибку или печатать заново. Плюс мне еще нужно нажимать некоторое количество раз «n» или «Shift-n», чтобы пройтись по всем найденным словам.
Для этого естественно нужно просмотреть справочное руководство или заглянуть в книгу, но оно того стоит. Допустим, мы спросили у друга и он нам подсказал:
На этом все. Такой вот небольшой и поучительный пример. И таких примеров очень много. И дело не ограничивается только Вимом. Взять тот же Firefox.
Сколько раз вы тянулись мышкой в угол экрана, чтобы найти что-нибудь в Гугле? Ctrl+K и этого можно больше не делать.
А чтобы ввести новый адрес? Ctrl+L там же рядом находится.
А сколько раз тянулись мышкой на кнопку «Назад» или «Вперед»? Alt-«Cтрелка влево» и Alt-«Cтрелка вправо».
Сколько раз мышкой вы разворачивали на полный экран открытое терминальное окно с Midnight Commander. F11.
Таких примеров много. И, в конце концов, это some sort of fun. Насколько быстро ты можешь сделать то, что у большинства отнимает лишнее время. Попробуйте, может и вам понравится.
P.S. Кстати, та презентация называлась «Семь полезных привычек по эффективному использованию Vim». И седьмой привычкой была некоторая мета-привычка по вырабатыванию полезных привычек. Ага, представьте себе, таки-да. В общем, ищите, учитесь и получайте от этого удовольствие)
Комментарии [2]
144 дн. назад
Твиттер твиттером, но и про блог забывать не стоит. Вот решил сюда кое-что написать. Решил написать про Ant. Такой себе небольшой урок, которого будет достаточно, чтобы понимать и самому пользоваться этой небольшой, но очень полезной программой.
Ant – это утилита для сборки java-программ. Это ее основное назначение. Она использует инструкции, определенными в файле build.xml, для того, чтобы собирать программу (компилировать, копировать куда надо и так далее). В Unix аналогом такой программы является команда make и написанный для нее makefile. В общем-то, здесь можно провести такую аналогию:

Естественно знать, что такое make и makefile необязательно. Но с этого с этого можно сделать вывод, что понимая суть ant и build.xml вам уже не нужно объяснять, что такое make и makefile. И в обратную сторону, зная, что такой make и makefile, вам не нужно объяснять, для чего нужен ant и build.xml. Синтаксис у них совершенно разный, и по-этому такое понимание практических навыков вам никаких не даст, но все-таки это лучше, чем ничего. Но сейчас не об этом.
Для тех, кто не сталкивался ни с make, ни с ant мы уже сказали, что Ant – собирает программу. А как именно, определенно в файле build.xml. И этого вполне достаточно, чтобы начать.
h2 Написание первого, простого build.xml и компиляция нашей программы
Синтаксис build.xml вполне прост. Вот так выглядит обычный build файл:
<project name="My Sample Application" default="compile" basedir=".">
<target name="target" description="Some text here">
</target>
</project>
Один проект — один build.xml. При объявлении проекта мы должны указать его имя (name), команду, выполняемую по умолчанию (default) и папку, относительно которой высчитываются относительные пути (basedir). Проект может состоять из нескольких команд (Target). Каждый Target может состоять из нескольких действий (Actions).
Действием может быть копирование файлов из одной папку в другую, компилирование файлов, удаление, извлечение javadoc и так далее. Разработчики могут также создавать и свои собственные действия, и таким образом расширять Ant.
Напишем Target для компиляции. Взяли клавиатуру, и написали. И вот, что получилось:
<project name="My Sample Application" default="compile" basedir=".">
<target name="compile">
<javac destdir="./build/classes" srcdir="./src">
</javac>
</target>
</project>
Здесь мы объявили Target с именем compile. Внутри него находится действие javac, которое принимает как параметры папку с исходными текстами, и папку в которую будет записан результат в виде .class файлов.
Для того, чтобы вызвать наше действие следует выполнить ant в командой строке. При вызове ant мы можем передать какой build файл использовать, и какую команду следует выполнить. Если этого не сделать, то по умолчанию ant будет использовать build.xml, который находится в текущей папке и Target по умолчанию, указанный в нем.
Т.е. нам достаточно написать:
:/path/to/project$ ant
или
:/path/to/project$ ant compile
или
:/path/to/project$ ant -buildfile build.xml compile
Сегодня уже вряд ли найдешь сколько-нибудь сложное приложение, которое бы не использовало сторонние библиотеки. Мы можем указать Ant какие библиотеки стоит использовать следующим образом:
<path id="libs.dir">
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</path>
<target name="compile">
<javac destdir="./build/classes" srcdir="${src.dir}">
<classpath refid="libs.dir" />
</javac>
</target>
Строка <classpath refid=“libs.dir” /> указывает, что необходимо подключить дополнительные библиотеки и что находятся они по адресу libs.dir. Чуть выше мы определили, что такое это самое libs.dir.
Здесь следует сделать отступление и сказать, что в Ant присутствует некоторая концепция типов данных. Подробнее о них стоит рассказать в отдельной статье, но пока стоит запомнить, что такие вещи как путь, списки файлов, упорядоченные или неупорядоченные, – все есть некоторый объект со своим типом, который можно использовать в действиях. Одним из примеров таких типов есть path, внутри которого используется другой тип fileset для представления списка файлов.
В прошлых примерах мы использовали путь ./build/classes для указания папки, в которую мы хотим скомпилировать наши классы. В больших build.xml файлах, в которых содержаться намного больше разных Targets велика вероятность, что эта же строка понадобиться нам еще где-либо.
По-этому хорошей практикой считается определение таких параметров отдельно от самих Targets. Приведу весь build.xml для примера:
<project name="My Sample Application" default="compile" basedir=".">
<property name="build.classes.dir" location="./build/classes" />
<property name="src.dir" location="./src" />
<path id="libs.dir">
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</path>
<target name="compile">
<javac destdir="${build.classes.dir}" srcdir="${src.dir}">
<classpath refid="libs.dir" />
</javac>
</target>
</project>
Здесь есть еще один тонкий момент. Значения свойства могут быть присвоены как с помощью location атрибута, так и с помощью value. Разница между ними в том, что если location содержит путь к папке или файлу, разделитель между папками (/ или \) будет подставляться правильно в зависимости от того, под Виндовс или под Линуксом запущен Ant. Это просто удобно. Не придется при случае переименовывать все пути, как однажды пришлось мне на своей работе. Хотя вроде бы умные люди писали, а такой мелочи, наверное, не знали.
То, что я тут рассказал хватит, чтобы делать 60-70% основной работы. Конечно, лучше знать больше. Возможно, в следующей статье расскажу подробнее на тему типов данных (path, fileset и так далее) и все, что с ними связано. Еще хотелось бы рассказать и про автоматизацию тестов с помощью Ant. Но время покажет как все получится.