понедельник, 23 ноября 2009 г.

Некоторые заметки о прохождении интервью при устройстве на работу в Праге

Некоторые заметки о прохождении интервью при устройстве на работу в Праге.
"... Устраивался я на должность Ведущего Разработчика J2EE."
"Сениор — 50000-80000крон (1800-3000евро), Архитект или Тим Лидер около 85000крон (3200евро)."
"1.Чем отличается абстрактный класс от интерфейса? (Да, такие вопросы тоже задают)
2.Для чего в классе Object есть метод hashCode() и как он связан с методом equals()?
3.Вы строите кэш. Вам нужно удалять из кэша некоторые объекты при каждой сборке мусора. Как это сделать?

4.Как восстановить значения transient членов класса после десериализации?
5.Различия между паттернами Adapter и Proxy. Какую из них в каком случае лучше применять.
6.Для чего нужен Session Facade?
7.Всегда задают вопросы по Collection Framework и по потокам и синхронизации. Типа какие списки синхронизированы, а какие нет, отличие Hashtable от HashMap, что и в каком случае лучше для перфоманса.
8.Какие виды xml парсеров вы знаете и чем они концептуально отличаются. Какой из них лучше использовать и когда.
9.Типы WSDL и чем они отличаются друг от друга.
10.Как эффективнее всего построить синхронизированную Collection из обычной.
11.Как ни странно, но вопросов по EJB обычно не задают. Мне попадались только самые элементарные и скучные, про их виды и способы применения.
12.Отличие yield() от sleep().
13.Что означает и для чего нужен модификатор volatile?
14.Каким образом можно изменить состояние thread на WAITING?
15.Как релизовать динамическую смену дата соурса в 24/7 системе без редеплоя?"
Из 15 - 5 вопросов касаются многопоточности (#7, #10, #12, #13, #14).
Из 15 - 2 вопроса касаются паттернов (#5 - GoF, #6 - j2ee patterns).
Из 15 - 1 вопрос касается слабых ссылок (#3)

9 комментариев:

  1. чесно говоря на вопросы

    3.Вы строите kэш. Вам нужно удалять из kэша неkоторые обьеkты при kаждой сборkе мусора. Kаk это сделать
    4.Kаk восстановить значение transient членов kласса после десериализации?

    Ответа не знаю. Если можно обьясните

    ОтветитьУдалить
  2. На #3 - необходимо использовать Слабые Ссылки (http://kharkovconcurrencygroup.blogspot.com/2009/11/pjp_23.html).
    - java.lang.ref.SoftReference - GC убирает в случае если заканчивается свободная память, т.е. прежде чем бросить OutOfMemoryError
    - java.lang.ref.WeakReference - GC убирает при каждом прохождении кучи.

    P.S. естественно "каждое прохождение кучи" - это образное выражение. В коллекторах с многими потоками, работающими в фоне(parallel+concurrent) - нет какого особенного момента очистки. Терминология взята от stop-the-world коллекторов.

    ОтветитьУдалить
  3. А что с 4 вопросом?
    Насколько я понимаю: никак, если их значения не завязаны на сериализованную часть объекта?

    ОтветитьУдалить
  4. 4 - по идеи никак, иначе теряется смысл от transient

    ОтветитьУдалить
  5. На удивление, такая возможность есть, причем !!!не одна!!!. В дальнейшем все ответы я разобъю на ожидаемые и неожиданные:)
    P.S. Ответов Огромное Количество, я приведу несколько иначе пришлось бы рассматривать все ньюансы Serialization API.

    ОтветитьУдалить
  6. В моем понимании, если вопрос передан абсолютно точно("4.Kаk восстановить значение transient членов kласса после десериализации?"), то ответ предполагает, что мы(именно мы) будем его восстанавливать, т.е. нами будут написаны строчки с явным присвоением этому полю. В таком случае ожидаемый ответ, видимо, использовать readObject() и в нем сделать присвоение. Как я понимаю назначение транзиентных полей:
    1) поле возможно вычислить по значениям других нетранзиентных полей
    2) поле - кэш, результат каких-то вычислений (скажем данные из файла)
    3) мы это поле храним в своем формате

    Приведу пример только третьего:
    class Answer implements Serializable {
    public transient int trans;

    private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    oos.writeByte((byte) trans);
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    trans = ois.readByte();
    }
    }

    class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    // create
    Answer angel = new Answer();
    angel.trans = 42;
    // write
    ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(angel);
    oos.flush();
    oos.close();
    byte[] ser = baos.toByteArray();
    // read
    Answer satan = (Answer) new ObjectInputStream(new ByteArrayInputStream(ser)).readObject();
    System.out.println(satan.trans);
    }
    }

    ОтветитьУдалить
  7. Вот неожиданное решение (фактически мы отменили действие ключевого слова transient):
    class Answer implements Serializable {
    public transient int trans;

    private static final ObjectStreamField[] serialPersistentFields
    = {new ObjectStreamField("trans", int.class)};

    }

    class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    // create
    Answer angel = new Answer();
    angel.trans = 42;
    // write
    ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(angel);
    oos.flush();
    oos.close();
    byte[] ser = baos.toByteArray();
    // read
    Answer satan = (Answer) new ObjectInputStream(new ByteArrayInputStream(ser)).readObject();
    System.out.println(satan.trans);
    }
    }

    ОтветитьУдалить
  8. Можно использовать Externalizable и тогда transient вообще теряет свою власть:

    class Answer implements Externalizable {
    public transient int trans;

    public Answer() {
    }

    public void writeExternal(ObjectOutput out) throws IOException {
    out.writeInt(trans);
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    trans = in.readInt();
    }
    }

    class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    // create
    Answer angel = new Answer();
    angel.trans = 42;
    // write
    ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(angel);
    oos.flush();
    oos.close();
    byte[] ser = baos.toByteArray();
    // read
    Answer satan = (Answer) new ObjectInputStream(new ByteArrayInputStream(ser)).readObject();
    System.out.println(satan.trans);
    }
    }

    ОтветитьУдалить
  9. Неправильно, но работает! Я бы назвал ЭТО "шизоидное туннелирование":

    enum Answer {
    AA, BB, CC;
    public transient int trans;
    }

    class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    // create
    Answer angel = Answer.AA;
    angel.trans = 42;
    // write
    ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(angel);
    oos.flush();
    oos.close();
    byte[] ser = baos.toByteArray();
    // read
    Answer satan = (Answer) new ObjectInputStream(new ByteArrayInputStream(ser)).readObject();
    System.out.println(satan.trans);
    }
    }

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