понедельник, 31 марта 2008 г.

Соседи

У нас на этаже - 5 квартир. Мы с краю, а бижайшие к нам соседи - странные люди. С некоторого момента тётка с нами вообще не разговаривает. Почему - не знаю. Невоспитанная, видимо. Вот сегодняшний пример...
Выходим с утра с Мишкой, а Юля пока одевается в квартире. Ну Мишка уже к лифту подходит, а я пока дверь закрываю. Тут соседке приспичило и она решила выйти, а так как дверь её квартиры открывается наружу, то она её попала по мне. Я с ней, как это полагается, поздоровался, а она даже не извинилась. Я пошёл к Мишке. Стоим у лифта, ждём Юлю. Выходит эта тётка в халате и общую железную дверь на распашку оставляет. К соседям, видимо, собралась. Мишка (сам, причём) решает, что дверь надо закрыть, и захлопывает её. Тётка тут напряглась, видимо, и позвонила к себе в квартиру (в звонок). Вглядывает её сын и она кричит ему, чтобы он открыл дверь. Ну он дёрнул было замок, а дверь-то открыта. Ну он её приоткрыл и в непонятках ушёл в квартиру. А тётка поехала на лифте к соседям.
Я не знаю, что она хотела этим сказать мне, но если бы она не вернулась раньше, чем Юля вышла, то я бы всё равно закрыл дверь на ключ. И ей пришлось бы опять звонить сыну, вытаскивать его в общий тамбур, чтобы дверь открыть. Не в моих правилах дверь нараспашку открытой держать.
Остальные соседи более-менее нормальные люди. Даже сын этой тётки. По крайней мере он здоровается при встрече. А она от нас вызывающе так нос воротит. Почему - не знаю. И такие соседские отношения немного напрягают Юлю. Мне то что! Я пуленепробиваемый. Я на эту тётку давно положил 8===Э

пятница, 28 марта 2008 г.

Java Puzzle 80: Further Reflection

Что напечатает следующая программа, которая создаёт новый экземпляр объекта используя reflection?
public class Outer {
public static void main(String[] args) throws Exception {
new Outer().greetWorld();
}
private void greetWorld() throws Exception {
System.out.println(Inner.class.newInstance());
}
public class Inner {
public String toString() {
return "Hello world";
}
}
}

Программа напечатает Exception stack trace. А всё потому, что для вложенных (не статических!) классов не действует правило создания конструктора без параметров. В этом случае автоматически добавляется параметр, имеющий тип внешнего класса. Перепишем метод правильным образом:
  private void greetWorld() throws Exception {
Constructor c = Inner.class.getConstructor(Outer.class);
System.out.println(c.newInstance(this));
}

Обратите внимание, что в этом случае можно создать вложенный класс, для которого не установлен экземпляр внешнего класса. Надо только передать null вместо this. Автор рекомендует вообще не использовать reflection для создания экземпляров вложенных классов. Я бы сказал по другому: не используйте то, в чём не разбираетесь.
Тут автор ссылается на раздел 18 своей предыдущей книги Эффективное программирование: старайтесь использовать статические члены класса, когда это возможно.

Java Puzzle 79: It's a Dog's Life

Следующий класс моделирует жизнь домашнего животного. В самом задании забавная игра слов: обычно собаки бегают на заднем дворе (run in the backyard), а наша будет выполняться в фоновом режиме (run in the background). Что программа напечатает?
public class Pet {
public final String name;
public final String food;
public final String sound;
public Pet(String name, String food, String sound) {
this.name = name;
this.food = food;
this.sound = sound;
}
public void eat() {
System.out.println(name + ": Mmmmm, " + food);
}
public void play() {
System.out.println(name + ": " + sound + " " + sound);
}
public void sleep() {
System.out.println(name + ": Zzzzzzz...");
}
public void live() {
new Thread() {
public void run() {
while (true) {
eat();
play();
sleep();
}
}
}.start();
}
public static void main(String[] args) {
new Pet("Fido", "beef", "Woof").live();
}
}

Компилятор найдёт метод с именем sleep в классе Thread и перестанет искать дальше. А так как метод sleep должен принимать параметры, то компилятор тут и ругнётся. Эта проблема называется затенением (shadowing) и описана в спецификции (JLS 6.3.1). Почему так было сделано - история умалчивает. Чтобы программа скомпилировалась можно самому разрезолвить этот метод: Pet.this.sleep(). Но в данном случае лучший совет - не переопределяйте класс Thread, а реализуйте интерфейс Runnable и используйте его для создания нити:
  public void live() {
new Thread(new Runnable() {
public void run() {
while (true) {
eat();
play();
sleep();
}
}
}).start();
}

Великий Пост

Несколько дней назад покупали в Карусели кисель для Мишки. А на нём наклейка, что продукт рекомендуется в великий пост. Я ещё пошутил, что написали бы, что освящено...
И что бы вы думали! Сегодня Юля в магазине купила упаковку морской капусты, на которой круглая наклейка с надписью: Освящено священником Александром из церкви Св. Вмч. Георгия Победоносца в Купчино. Во дают!

четверг, 27 марта 2008 г.

Michael Pinnella


Вот и ещё один альбом был куплен только потому, что в Кайласе НЕТ свежих дисков: Enter By The Twelfth Gate (2004). Это инструментальный альбом клавишника группы Symphony X. В нём отсутствуют какие бы то ни было элементы хэви-метал. После первого прослушивания альбом оставил какие-то непонятные впечатления. Я даже решил убрать его подальше, но послешав его ещё пару раз почувствовал, что альбом очень и очень неплох. Слушать его приятно, а какие-то претензии могут возникнуть лишь к звуковому решению. И программированные барабаны не слишком портят впечатление от пластинки.

Нет вдохновения

Что-то я давненько ничего не сочинял. В голове один мотив про бегемота из Смешариков, которые Мишка ежедневно смотрит. Вот на этот мотив и сочинилось:
    Если ты хочешь стихи сочинять,
    То для начала учись рифмовать.
    Выбери тему стиха и мотив...
    И начинай сочинять креатив!
Или позитив. Кому как нравится...

Культурный тест

Раз уж и Стас и Юля прошли тест, то и я тоже попытался. Забавно, что у нас совершенно разные результаты:
Поздравляем!!! Вам ближе славянская культура
Вы по-настоящему русский человек! Вам вполне комфортно в России, и это очень хорошо, когда человек живет в обществе, ценности которого разделяет. image
Пройти тест

Supaplex

Помнится в общаге любил играть в Supaplex. Это такая игра под DOS в стиле Boulder Dash. Но потом, при переходе на Windows NT я забыл про эту игру, так как не работает она под Win32 API. И вот выясняется, что есть ещё фанаты, которые портировали её под Windows XP. Встречайте - WinPlex:

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

среда, 26 марта 2008 г.

Blizzard

Вчера вечером возвращался домой - была суровая метель. Очень сильный ветер с мелкими ледяными градинами. Получил хороший крио-массаж лица.
С утра шёл на работу - сугробы подтаяли. Под ними организовались огромные лужи, которых не видно, так как сверху всё ещё снег лежит. Пока дошёл до работы промочил ноги. Лучше промочить горло, чем ноги!
Ветер днём был не сильный. Говорят, что в Москве он был гораздо сильнее. Коты выпали осадками...
Ну а сегодня вечером опять ударил мороз и везде был лёд. Еле до дому дошёл. Заносило на поворотах ;)
Автомобилистам хреново. У нас на работе один коллега уже успел переобуться в летнюю резину. Вот ему удовольствие будет ехать в Финляндию на выходных...

понедельник, 24 марта 2008 г.

Java Puzzle 78: Reflection Infection

Рассмотрим простое применение refletion. Что напечатает следующая программа?
import java.lang.reflection.*;
import java.util.*;
public class Reflector {
public static void main(String[] args)
throws Exception {
Set set = new HashSet();
set.add("foo");
Iterator it = set.iterator();
Class type = it.getClass();
Method method = type.getMethod("hasNext");
System.out.println(method.invoke(it));
}
}

Нашли, блин, чем меня удивить! Я с такими проблемами в JavaBeans регулярно сталкиваюсь. Несмотря на то, что метод определён как public, он определён в private классе. И у пользователя просто нет прав, чтобы его вызвать. Приходится рекурсивно проходить по иерархии классов и интерфейсов и искать его пототип, который действительно разрешён к использованию. Обратите внимание, что еcли метод получить другим образом, то он будет работать:
    Method method = Iterator.class.getMethod("hasNext");

Java Puzzle 77: The Lock Mess Monster

Разберитесь-ка, как работает следующая программа:
import java.util.*;
public class Worker extends Thread {
public static void main(String[] args)
throws InterruptedException {
final Worker worker = new Worker();
worker.start();
Timer timer = new Timer(true);
timer.schedule(
new TimerTask() {
public void run() {
worker.keepWorking();
}
}, 500);
sleep(400);
worker.quit();
}
private volatile boolean stop = false;
public void run() {
while (!stop) pretendToWork();
System.out.println("Beer is good!");
}
private void pretendToWork() {
try {
sleep(300);
}
catch (InterruptedException exception) {
}
}
synchronized void keepWorking() {
stop = false;
}
synchronized void quit() {
stop = true;
join();
}
}

Беглый анализ показывает, что где-то через секунду программа напишет Beer is good! и завершит свою работу. Но на самом деле она зависает! Проблема в том, что внутренняя реализация метода join вызывает метод wait на экземпляре класса Thread, который должен быть присоединён. А вызов метода wait снимает блокировку!
Фундаментальная причина ошибочного поведения класса Worker - использование блокировки по экземпляру (synchronized методы). Не полагайтесь на поведение библиотеки - делайте собственные объекты блокировки, которые не доступны никому другому. Это напоминает раздел 15 книги Эффективное программирование Джошуа Блоха.

воскресенье, 23 марта 2008 г.

Снеговики

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

А из клиники улыбаясь за нами наблюдали охранник, гардеробщица и девчонки с рецепшн. Наши снеговики прямо напротив входа стоят на Комендантском, 17. Надеюсь, мы народу настроение хорошо подняли!

суббота, 22 марта 2008 г.

Погода

С утра была замечательная солнечная погода. Мы даже заехали на автомойку, но там была толпа автолюбителей. Ну мы и поехали грязными, так как надо было съездить по делам к определённому времени. Пока Юля занималась делами, мы с Мишкой сопели в машине на солнышке. Потом поехали к Паше с Ирой в гости, где Мишка показывал высший пилотаж в Paint:

Вечером, когда вышли от Пашки, обнаружили, что выпал снег. Машинку хорошо так залепило снегом. Мы почистились и поехали. Хорошо, что не помылись...
На обратном пути видели несколько аварий на Кольцевой. В одной аварии аж 5 машин было. Аккурат за знаком ограничения скорости 80. Народ-то подумал, что зима кончилась, и шины поменял на летние. Ну и огрёб...

среда, 19 марта 2008 г.

Alice Cooper


Заехал в Кайлас на днях, а там опять ничего нового. В этот раз мне под руку подвернулся альбом Dirty Diamonds (2005).
Не стареют душой ветераны! Вот и старина Элис Купер до сих пор пишет песни, хотя ему скоро стукнет 60 лет. Это его 24-ый альбом, но уж больно он напоминает старые диски. Сразу ностальгия охватывает...
Однако, нельзя сказать, что диск занудный. Он очень разноплановый, хотя и спокойный. Весьма позитивный и слегка старомодный. Что-то в нём есть такое...

суббота, 15 марта 2008 г.

Чеширский кот

Хороший аватар, когда злобное настроение ;)

Metallica tribute

Смотреть до конца:

четверг, 13 марта 2008 г.

Тестируем замену Skype

Написал мне тут мой бывший коллега, который проработал в STAR семь с половиной лет. Попросил потестировать его текущий проект. Можно звонить по межгороду с компа практически на любой номер. Говорит, что Эстония тоже поддерживается...
Позвонив на домашний телефон я обнаружил, что качество связи хромает, чем немало удивил его. Завтра потестирую связь с Таллинном...
Если будете тестировать - пишите результат: откуда звонили, с какого провайдера, в какой город, на домашний или мобильный, ну и про качество связи не забывайте. Говорить можно, пока, минуту. Потом связь останется бесплатной, но за просмотр рекламного ролика...

Java Puzzle 76: Ping Pong

Следующая программа содержит синхронизированные статические методы. Что она напечатает? Гарантируется ли её результат от запуска к запуску?
public class PingPong {
public static synchronized void main(String[] args) {
Thread thread = new Thread() {
public void run() {
pong();
}
};
thread.run();
System.out.print("Ping");
}
static synchronized void pong() {
System.out.print("Pong");
}
}

Начнём с того, что синхронизировав статические методы мы добились того, что результат программы гарантируется от запуска к запуску. Но почему она пишет PongPing вместо PingPong?
Типичная ошибка и простая невнимательность. Для запуска отдельного потока надо вызывать метод start, а не метод run. В нашем случае всё действие происходит на одном потоке.
Будьте внимательны!

Java Puzzle 75: Heads or Tails?

Поведение приведённой ниже программы меняется при переходе на Java 5. Почему? Как будет себя вести программа на версиях 1.4 и 5?
import java.util.Random;
public class CoinSide {
private static Random rnd = new Random();
private static CoinSide flip() {
return rnd.nextBoolean()
? Heads.INSTANCE
: Tails.INSTANCE;
}
public static void main(String args) {
System.out.println(flip());
}
}
class Heads extends CoinSide {
private static Heads INSTANCE = new Heads();
public String toString() {
return "heads";
}
}
class Tails extends CoinSide {
private static Tails INSTANCE = new Tails();
public String toString() {
return "tails";
}
}

Начнём с версии 1.4 - программа не скомпилируется. Поведение условного оператора (?:) раньше было более ограничивающим. Он требовал, чтобы обе части были одинакового класса или один класс был бы подклассом другого. А в нашем примере это не так.
После версии 5 стало дозволено немного больше. Результат условного оператора имеет наиболее общий класс (в нашем случае - CoinSide). В большинстве случаев все классы имеют общий тип - Object.
Надо будет проверить ещё с примитивными типами. Будет ли работать auto-boxing?
Авторы рекомендуют всегда использовать последний релиз Java-платформы, так как в последние релизы включены многие улучшения, делающие жизнь программистов легче.
А вот о новых багах, особенно регрессиях, авторы молчат... ;)

среда, 12 марта 2008 г.

Google Pages: No JNLP

Хотел использовать Google Pages, чтобы размещать на нём свои Java-приложения, включая пресловутую Reversy. Однако, они отображают JNLP файлы, как текстовые XML.
Обнаружил способ, как заставить сервер понимать JNLP - надо в папку положить файл .htaccess, в котором есть следующая строка:
AddType application/x-java-jnlp-file .jnlp
Это прекрасно сработало на локальном сервере, но не работает с Google! Этот файл автоматически переименовывается при загрузке - убирается точка. Надо писать в службу поддержки, хотя я год назад писал туда сообщения о багах, но мне так ничего и не ответили...

Bloc at SillyBull

Хорошая головоломка, но короткая...

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

Kellermann Center

Сейчас офис Сан в Питере расположен в офисном центре, фасад которого вы можете видеть на шестикилограммовом торте:

Тут ещё есть...

Авангард разгоняется

Была новость, что Авангард увеличивает скорости на существующих тарифах в два раза. Я уже писал как измерить скорость Интернет. Вот я и решил измерить скорость и сравнить её с последними измерениями. Это измерения из дома (ADSL) до ближайшего сервера в Санкт-Петербурге:

А так выглядит скорость до Сан Франциско:

Ускорения нет! Более внимательное прочтение новости показало, что это касается всех абонентов, кроме выбравших тарифные планы 300К и 600К.
Блин! Надо посчитать деньги и переоформиться что-ли...

пятница, 7 марта 2008 г.

Java Puzzle 74: Identity Class

Как определить класс Enigma, что бы следующая программа выдавала false? Переопределять метод equals нельзя!
public class Conundrum {
public static void main(String[] args) {
Enigma e = new Enigma();
System.out.println(e.equals(e));
}
}

А подсказка в том, что перегружать можно ;)
class Enigma {
public boolean equals(Enigma e) {
return false;
}
}

Если два перегруженных метода принимают разные параметры, то они должны иметь идентичное поведение! И ещё, эта головоломка была бы не возможна, если бы переменная e была бы типа Object:
    Object e = new Enigma();

Java Puzzle 73: Your Privates Are Showing

Идея этой головоломки - дать понять, что private члены класса не настолько приватные, как принято думать. Например, при использовани сериализации по-умолчанию все private поля класса становятся частью экспортируемого API. Ну и задача состоит в том, чтобы написать в некоторой библиотеке что-нибудь приватное так, чтобы перестал компилироваться клиент, который использует эту библиотеку. Авторы предлагают раскомментировать строчку в следующей программе:
package library;
public final class Library {
// private static class String {}
public static String newString() {
return new String();
}
}
package client;
import library.Library;
public final class Client {
private String str = Library.newString();
}

Ну или в следующей:
package library;
class AbstractLibrary {
public static final int ANSWER = 42;
}
public final class Library extends AbstractLibrary {
// private static final int ANSWER = 6 * 7;
}
package client;
import library.Library;
public final class Client {
private int answer = Library.ANSWER;
}

Вывод: переиспользование имён опасно, избегайте сокрытия и затенения...

JavaFX

В Sun разработали JavaFX Script. И делают сейчас JavaFX. Это некая сборка, которая включает в себя полноценный JRE и скрипт. Основная фишка в том, что бы был аналогичный пакет JavaFX Mobile, способный работать на телефонах и встраиваемых устройствах. Сейчас существует open-source версия, которая работает как интерпретатор. В разработке находится компилятор, но по синтаксису он отличается от интерпретаторной версии, так как сильно не доработан. Да и технические проблемы есть...
К чему это всё? Так меня попросили писать демки для JavaOne именно для компиляторной версии. Сколько я матюков сложил, пока не вкурил эту разницу в синтаксисе. Документации ещё нигде нет. Приходится идти по этому минному полю, где шаг вправо или шаг влево - exception. Сейчас портировал вот эту демку под JavaFX. У меня она выглядит почти так же, но Дюк летает медленнее. И задержки при появлении элементов нет. Но для обучения - сойдёт. Сейчас работаю над демо для Java Media Component, который Кирилл разрабатывает под Linux. Ну и пытаюсь сделать Reversy, как всегда при изучении нового языка. Только я понял, что этот скрипт не предназначен писать программы. С его помощью можно быстро наваять GUI, а вот логику придётся писать на Java.
Кстати, JavaFX Script базируется на Scene Graph, достаточно мощной библиотеке для создания GUI с использованием двумерной графики. Демки, созданные с использованием Scene Graph можно посмотреть тут. Swing-компоненты можно легко вращать, трансформировать и масштабировать. Хоть это никому в GUI не нужно, зато какой WOW эффект!

Медицина, панимаиш

Сегодня с утра ездили в отделение клиники семейной медицины, чтобы оформить карту для детского сада. За полчаса прошли всех врачей, сдали анализы. Отношение к посетителям - просто супер! Даже бахилы бесплатно. Однако пришлось отдать 2000 р.
Расположены они на пр. Большевиков, д. 22, кор. 5. Дом находится на задворках Бонча, там где должны были построить информационный центр, а построили несколько жилых домов, под названием "Изумрудный город". Въезд с Большевиков, через пустырь и, далее, шлагбаум.

В среду ездили к аллергологу на Суворовский пр., д. 4. Детская поликлиника №19 (по корпоративной страховке от УралСиб). Врач оказался хороший, несмотря на то что мы опоздали на полчаса. Но регистратура!..
Сначала я им позвонил из пробки на ПлАНе, что мы встряли и задерживаемся. Мне грубо так сказали, что придётся стоять в общей очереди. Ладно. Но когда мы приехали и отмечались в регистратуре, на нас наехали, что мы опоздали. На оправдание, что пробки в центре, нам сказали, что все так отмазываются. И что сейчас к аллергологу толпа детей придёт, а мы должны по очереди всех пропускать. Но никто так и не пришёл за тел полчаса, что Юля провела у доктора. Мы с Мишкой были там всего пару минут и пошли шляться по клинике. Короче, страховая медицина стала теперь напоминать обычную бесплатную. Хотя не везде. Наш доктор, что к Мишке с рождения приписан, вполне нас устраивает...

Кстати, насчёт пробок. В выходные нам нужно полчаса, чтобы добраться от Рыбацкого до Суворовского. А в эту среду мы ехали полтора часа. Встали в пробке на Бакунина и пешком добежали пару кварталов. В общем, утром в рабочий день в центр на машине соваться не стоит...