23 января 2012 г.

Подготовка к собеседованию на java-программиста-2 (уровень Middle)

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

В чем отличие между static synchronized и просто synchronized?

Использование слова synchronize на static-методе помечает весь класс как synchronize, т.е. такая запись:
synchronized static void foo() {
    ...
}
равнозначна такой:
static void foo() {
    synchronized(SomeClass.class) {
        ...
    }
}
А такая:
synchronized void foo() {
    ...
}
такой:
void foo() {
    synchronized(this) {
        ...
    }
}
Что значит synchronized(this)?

Семантически этот код:
public void blah() {
  synchronized (this) {
    // do stuff
  }
}
эквивалентен этому:
public synchronized void blah() {
  // do stuff
}
Однако synchronized(this) использовать не рекомендуется. Почему? Об этом можно почитать тут .

Какие модификаторы доступа устанавливаются по умолчанию при описании интерфейсов и какие вообще бывают модификаторы доступа у интерфейсов?

Все члены интерфейса по умолчанию являются public.

Методы, объявленные в составе интерфейса, неявно получают признак abstract. В соответствии с принятым соглашением подификатор abstract в объявлении не указывается.

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

Другие модификаторы доступа в интерфейсах не доступны.

Что вернет hashCode(), если его не перегружать?

Адрес объекта в памяти.

Как реализовать множественное наследование в Java?

Множественное наследование реализуется через внутренние классы. Предположим, у вас есть классы Parent1 и Parent2, от которых вы хотите унаследоваться. Тогда код мог бы выглядеть так:
public classs MyClass {
 SParent1 p1 = new SParent1();
 class SParent1 extends Parent1 {}
 
 SParent2 p2 = new SParent2();
 class SParent2 extends Parent2 {}
}
Теперь у экземпляров класса MyClass будут методы и Parent1 и Parent2.

Что означают ключевые слова volatile и transient.

Определение переменной с ключевым словом volatile(«изменчивый») означает, что значение переменной будет изменяться несколькими потоками.

Переменная помеченая словом transient не будет сериализоваться и соответственно при десериализации её значение будет установлено значением по умолчанию.

Условия сериализации объектов?

Свойства класса должны быть сериализуемы и класс должен реализовывать маркирующий интерфейс Serializable. Не лишним будет вспомнить про serialVersionUID и его значение по умолчанию.

Можно ли передать объект в synchronized?

Да. Например очень популярна вот такая несложная конструкция:
private final Object _SyncObject = new Object();
...
public void run() {
...
  synchronized(_SyncLock) {
    ...
  }
...
}
Работа со ссылками (weak и strong reference).

Об этом можно почитать тут.

Как сделать ArrayList синхронизированым в одну строку?
List<Record> s_list = Collections.synchronizedList(list);
Контракт между equals и hashCode.

Если equals возвращает true, то hashCode должен вернуть одно и то же значение. Обратное не верно.

Каким условиям должен отвечать объект, чтобы с ним можно было работать в TreeSet?

Чтобы работать с TreeSet нужно чтобы классы коллекции реализовывали интерфейс Comparable.

Если объект этот интерфейс не реализует, но нужно обеспечить его работу в TreeSet, то компаратор пишется отдельно и передается конструктору TreeSet как аргумент.

Будет ли вызван код в блоке finally() если в try вызывать System.exit(0)?

Нет.

Декартово произведение двух таблиц в sql

При декартовом произвеедении каждая строка из первой таблицы соединяется с каждой строкой второй таблицы. Делается это так:
SELECT Laptop.model, Product.model
FROM Laptop CROSS JOIN
Product;
Расскажите про декларативные транзакции.

Об этом я уже писал тут.

Удачи!

2 комментария:

  1. Что вернет hashCode(), если его не перегружать?
    Адрес объекта в памяти.

    Не совсем так..По-умолчанию он выдает случайное число, вызванное нейтивным методом, реализованный на алгоритме "Park-Miller RNG".

    в openJDK 7 для HotSpot JVM
    hotspot/src/share/vm/runtime/synchronizer.hpp

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

    С помощью ключа командной строки -XX:hashCode=n (где n от 0 до 5).
    0 – Park-Miller RNG (по умолчанию)
    1 – f(адрес, глобальное_состояние)
    2 – константа 1
    3 – последовательный счетчик
    4 – адрес объекта
    5 – Thread-local Xorshift

    ОтветитьУдалить

Примечание. Отправлять комментарии могут только участники этого блога.