Quizz for interview Flashcards

1
Q

Перечислите методы класса Object

A
equals()
hashCode()
toString()
getClass()
notify()
notifyAll()
wait()
wait(long timeOut)
wait(long timeOut, int nanos)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Зачем нужны методы equals & hashCode?

A

Метод equals() для определения способа сравнения двух объектов.
Метод hashCode() для ускорения процесса сравнения: если хеши объектов не равны, значит полное сравнение делать не нужно.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Что будет, если переопределить equals, но не переопределить hashCode?

A

Будет нарушен контракт между equals() и hashCode() :

1) Если два объекта равны, тогда они должны иметь одинаковые хеш-коды.
2) Если два объекта имеют одинаковые хеш-коды, то они могут быть не равны между собой.

В случае, если hashCode() не переопределен, то HashMap HashSet будут работать не верно - вставлять одинаковые ключи или не находить существующие.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Зачем нужны методы wait, notify, notifyAll?

A

Все методы используются в механизме многопоточности Java.

wait() - вызывается нитью в синхронизированном блоке у объекта-монитора. В результате вызова нить,которая его осуществила становиться в режим ожидания и отпускает мютекс объекта-монитора

notify() - вызывается у монитора и снимает с wait’а одну случайную нить

notifyAll() - снимает с паузы все заснувшие нити

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Как правильно клонировать объект?

A
  1. Переопределение метода clone() и реализация интерфейса Cloneable();
  2. Использование конструктора копирования;
  3. Использовать для клонирования механизм сериализации
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Зачем нужен метод finalize() и как он работает?

A

Перед удалением объекта сборщик мусора может вызвать метод finalize() (а может и не вызвать).
Метод предназначен для освобождение не Java ресурсов перед удалением объекта из памяти.
Время и факт вызова этого метода непредсказуемы и зависят от алгоритмов работы сборщика мусора.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

В чем отличие final, finally, finalize?

A

final - модификатор доступа
finally - блок конструкции try/catch/finally
finalize - метод класса Object, который вызывает сборщик мусора.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Что такое try-with-resources?

A

Специальная конструкция блока try, которая гарантирует вызов метода close() у объектов созданным try(// ТУТ///).
Эти объекты должны реализовывать интерфейс AutoClosable.
Обычно используется при работе с потоками ввода вывода, которые обязательно должны быть закрыты после использования.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Чем отличаются методы wait(1000) и sleep(1000)?

A

wait(1000) - должен быть вызван на объекте-мьютексе в блоке syncronized и может быть выключен методами notify().
Используется для multi-thread-synchronization

sleep(1000) - вызывается на текущем потоке и может быть остановлен прерыванием выполнения потока
используется для time-syncronization

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

В чем отличие i++ и ++i ?

A

i++ - i сначала участвует в выражении и только потом инкрементируется

++i - i сначала инкрементируется, затем используется в выражении.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

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

A

str1.equals(str2)
потому, что строка - это всегда новый объект класса String и “==” ,будет возвращать false.
В сравнении могут быть как литералы строк, так и новые объекты класса String.
equals() - всегда сравнивает правильно.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Как правильно сравнить две строки в Java игнорируя регистр букв?

A

str1.equalsIgnoreCase(str2)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Как отсортировать список строк в алфавитном порядке?

A

Collections.sort(list)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

В какой кодировке хранятся строки в Java?

A

Строки в java хранятся в Unicode

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Как преобразовать строку в кодировку Windows-1251?

A
byte[] byte1251 = "Hello world".getBytes("windows-1251");
String outString = new String(byte1251,"windows-1251");
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Как разбить строку на отдельные слова?

A

s. split(“\s+”) - разделитель пробел(ы)

s. split(“\W+”) - разделитель любой не буквенный сивмол

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Как развернуть строку задом наперед?

A
StringBuilder sb = new StringBuilder("Строка для разворота");
String reversed = sb.reverse();
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Что происходит, когда мы пишем “A”+”b”+”C”?

A

Конкатенация.

получится строка “AbC”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Что такое mutable и immutable типы?

A

mutable - типы, чьи объекты могут изменять свое состояние в течение жизни.

immutable - типы, чьи объекты не могут изменять своего состояния в течение жизни

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Что дает типу String то, что его сделали immutable?

A
  1. Безопасность.
    String широко используется, как параметр для многих классов Java, в частности для открытия сетевых соединений, подключений к БД, открытию файлов и пр. И если бы строка изменялась, то мы могли получить доступ к объекту (файлу например), на который мы имеем право, затем изменить строку с именем (случайно или намеренно) и получить доступ уже к другому файлу.

Так же String используется в механизме загрузки файлов, и это – фундаментальный аспект. И если бы строка изменялась, то запрос на загрузку “java.io.Writer” мог бы быть изменён на “DiskErasingWriter”.

  1. Hashcode
    Из-за того, что строка не изменяется, она кэширует свой хэшкод и не вычисляет его каждый раз, когда мы его вызываем, что делает строку очень быстрой как ключ для hashmap.
  2. Многопоточность
    immutable делает экземпляры строк потокобезопасными.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Какие бывают внутренние классы?

A
  1. Внутренние
    1. локальные
    1. анонимные
  2. Статические вложенные
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Во что компилируется анонимный внутренний класс?

A

Во внутренний не статический класс

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Зачем использовать ключевое слово final при создании анонимных классов?

A

Если определяется анонимный внутренний класс и ему нужно при этом использовать объекты, определенные вне этого внутреннего класса, компилятор требует, чтобы переданные на них ссылки объявлялись неизменными (final). Без такого объявления вы получите сообщение об ошибке при компиляции программы.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Как правильно создать объект внутреннего класса?

A

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

Для создания объекта:
Outer outer = new Outer();
Innter inner = outer.new Inner();
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Как правильно создать объект вложенного класса?

A

Синтаксис создания объекта вложенного класса:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

Можно ли создавать статические методы/переменные во внутреннем классе?

A

Статические методы/переменные объявлять во внутреннем классе (не вложенном) нельзя.

Внутренние (не статические) классы, как переменные и методы связаны с объектом внешнего класса. Такие классы не могут содержать в себе статические методы и поля.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Назовите три любых внутренних класса?

A
  1. private static class Holder —вложенный класс HashMap из java.util.
  2. В интерфейсе Map есть interface Entry, который опять же в HashMap и реализуется в другом вложенном классе static class Entry implements Map.Entry.
  3. private static class IntegerCache в классе Integer.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

Как внутренние классы решают проблему множественного наследования в Java?

A

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

class Tiger extends Cat {

public void tigerRun() { }

public void startTiger(){
  TigerThread thread = new TigerThread();
  thread.start();
 }
 class TigerThread extends Thread{
  public void run() {
     tigerRun();
  }
 }
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

Чем отличаются анонимные классы, созданные на основе интерфейса и на основе класса?

A

Анонимный класс согласно JLS 15.9.5 представляют собой выражение, в котором объявление нового класса и его инициализация совмещены:

При объявлении класса будет создан новый класс, производный от указанного класса при использовании в качестве базы другого класса, или реализующий интерфейс при использовании в качестве базы интерфейса.
При инициализации будет создан новый объект и на него будет возвращения ссылка: анонимный класс является конкретным.
Таким образом, единственное отличие в анонимных классах, созданных на основе интерфейса и класса, заключается в количестве абстракных методов, которые необходимо реализовать.

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

Можно ли создать анонимный статический вложенный класс?

A

Нет, статической становится только переменная, но не класс.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

Во что компилируются анонимные внутренние классы?

A

Анонимные внутренние классы компилируются в файлы внешнийКласс$n.class. На месте внешнего класса, соответственно, название обрамляющего класса, внутри которого описывается анонимный внутренний класс. На месте n число от 1 до количества анонимных классов.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

Можно ли наследовать внутренние классы?

A

Наследовать внутренние классы от других — можно.

Наследование от внутреннего класса получается чуть сложнее, чем обычное, так как конструктор внутреннего класса связывается со ссылкой на окружающий внешний объект. Проблема состоит в том, что «скрытая» ссылка на объект объемлющего внешнего класса должна быть инициализирована, а в производном классе больше не существует объемлющего объекта по умолчанию. Для явного указания объемлющего внешнего объекта применяется специальный синтаксис:

//: innerclasses/InheritInner.java
// Наследование от внутреннего класса.
class WithInner {
  class Inner {}
}
public class InheritInner extends WithInner.Inner {
  //! InheritInner() {} // He компилируется
  InheritInner(WithInner wi) {
    wi.super();
  }
  public static void main(String[] args) {
    WithInner wi = new WithInner();
    InheritInner ii = new InheritInner(wi);
  }
}
Здесь класс InheritInner расширяет только внутренний класс, а не внешний. Но когда дело доходит до создания конструктора, предлагаемый по умолчанию конструктор не подходит, и вы не можете просто передать ссылку на внешний объект. Необходимо включить в тело конструктора выражение ссылкаНаОбъемлющийКласс.super(); в теле конструктора. Оно обеспечит недостающую ссылку, и программа откомпилируется.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q

Можно ли наследовать анонимные внутренние классы?

A

Описывая анонимный класс мы уже наследуемся от какого-то класса или реализуем какой-либо интерфейс. К анонимным классам напрямую нельзя применить слова extends или implements, но ведь никто не мешает заранее подготовиться и расширить нужный интерфейс, который будем реализовывать с помощью анонимного класса. Пример в коде ниже.

import java.awt.event.WindowListener;

public class TestExtendAnonym {
    private interface MyInterface extends Runnable, WindowListener {
    }
Runnable r = new MyInterface() {
...
//Пример того как реализовать 2 и более интерфейса в анонимном классе
}; } Наследоваться от анонимного класса нельзя.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q

Можно ли переопределять внутренние классы?

A

Переопределение внутреннего класса, как если бы он был еще одним методом внешнего класса, фактически не имеет никакого эффекта:

//: innerclasses/BigEgg.java
// Внутренний класс нельзя переопределить
// подобно обычному методу,
import static net.mindview.util.Print.*;
class Egg {
  private Yolk y;
  protected class Yolk {
    public Yolk() { print("Egg.Yolk()"); }
  }
  public Egg() {
    print("New Egg()");
    y = new Yolk();
  }
}
public class BigEgg extends Egg {
  public class Yolk {
    public Yolk() { print("BigEgg.Yolk()"); }
  }
  public static void main(String[] args) {
    new BigEgg();
  }
}
Вывод:

New Egg()
Egg.Yolk()
Конструктор по умолчанию автоматически синтезируется компилятором, а в нем вызывается конструктор по умолчанию из базового класса. Можно подумать, что при создании объекта BigEgg должен использоваться «переопределенный» класс Yolk, но это отнюдь не так, как видно из результата работы программы.

Этот пример просто показывает, что при наследовании от внешнего класса ничего особенного с внутренними классами не происходит. Два внутренних класса — совершенно отдельные составляющие, с независимыми пространствами имен.

Иными словами нельзя.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
35
Q

Какие ограничения есть у локальных классов?

A

Вначале вспомним что такое локальный класс. Это класс, описанный в блоке кода, то есть, по-простому — между кавычек {}. Наиболее часто эти кавычки являются телом метода. Но могут они быть и просто блоком, статическим блоком, телом if-ов, циклов и т.д.

Локальный класс наделён особенностями внутренних классов, но имеет отличительные черты, а именно:

он имеет доступ только к финальным полям и аргументам обрамляющего метода, а также ко всем полям обрамляющего класса, в том числе приватным и статическим;
локальный класс виден и может создаваться только в блоке, в котором описан;
у локального класса не ставится модификатор доступа;
не может иметь статических полей, методов, классов (за исключением финальных);
локальный класс, объявленный в статическом блоке может обращаться только к статическим полям внешнего класса.
Но! Начиная с Java8 мы можем обращаться в локальных классах к не финальным локальным переменным, если они не были изменены до момента инициализации класса. Также теперь стало возможным обращение к не финальным параметрам метода.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
36
Q

Может ли анонимный внутренний класс содержать статические методы?

A

Нет. У Анонимных внутренних классов, как и у внутренних классов не может быть статических полей, методов. (вспомним, что анонимные классы компилируются в обычные внутренние, а те, в свою очередь, связаны с объектом обрамляющего класса)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
37
Q

Можно ли создать объект внутреннего класса, если у внешнего класса только private конструктор?

A

Имея подобный код:

public class PrivateConst {
    private PrivateConst() {}
    public class InnerClass{
        public void f(){
            System.out.println("hello");
        }
   }
}
Напрямую, в другом классе (вне обрамляющего), конечно, создать объект InnerClass следующим способом не получится:
PrivateConst.InnerClass priv = new PrivateConst().new InnerClass();
Но! Что если у нас есть метод, возвращающий экземпляр
PrivateConst:public class PrivateConst {
    private static PrivateConst instance;
    private PrivateConst() {}
    public static PrivateConst getInstance(){
        instance = new PrivateConst();
        return instance;
    }
    public class InnerClass{}
}
В этом случае приватный конструктор нам не помеха для создания объекта InnerClass. Так же мы без проблем сможем создавать его в методах и в других внутренних классах, принадлежащих PrivateConst. 

Ответ — можно, если каким-либо способом нам удастся получить объект обрамляющего класса.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
38
Q

Можно ли объявлять внутренние классы private?

A

Да, можно.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
39
Q

Можно ли объявлять анонимные внутренние классы private?

A

Можно объявить private переменную от типа которой наследуется наш анонимный класс.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
40
Q

Сколько у класса максимально может быть внутренних классов?

A

Сколь угодно много. Ограничение особенности ОС и длинны имени файлов.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
41
Q

Назовите все состояния объекта Thread?

A
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
42
Q

В какие состояния может перейти нить, при входе в блок synchronized?

A

В RUNNABLE, если блок кода, помеченный synchronized, не занят другой нитью. Иначе наша нить получит состояние
BLOCKED и будет ждать освобождения объекта-мютекса

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
43
Q

В какое состояние перейдет нить, при вызове метода wait()?

A
Вызов этого метода переводит нить в состояние WAITING.
Метод wait() можно вызвать только внутри блока synchronized у объекта-мютекса, который был «залочен (заблокирован)» текущей нитью, в противном случае метод выкинет исключение IllegalMonitorStateException.
Object monitor = getMonitor();
synchronized(monitor){
 …
 monitor.wait();
 …
}

При вызове метода wait(), текущая нить снимает блокировку с объекта monitor, и переходит в состояние WAITING, ожидая вызова метода monitor.notify() или monitor.notifyAll() другой нитью. Как только это произойдет, нить проснется и если монитор не был занят, то захватит его и продолжит работу.
Если монитор окажется занят другой нитью, текущая нить перейдет в состояние BLOCKED.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
44
Q

В какое состояние перейдет нить, при вызове метода wait(500)?

A
Вызов этого метода переводит нить в состояние TIMED_WAITING.
По аналогии с методом wait(), wait(timeout) можно вызвать только внутри блока synchronized у объекта-мютекса, который был «залочен (заблокирован)» текущей нитью.
Object monitor = getMonitor();
synchronized(monitor){
 …
 monitor.wait(500);
 …
}

При вызове метода wait(), текущая нить снимает блокировку с объекта monitor, и засыпает на 500 миллисекунд. Объект monitor может быть захвачен другой нитью.
Через 500 миллисекунд нить проснется и если monitor не был занят, то захватит его и продолжит работу.
Если монитор окажется занят другой нитью, текущая нить перейдет в состояние BLOCKED.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
45
Q

В какое состояние перейдет нить, при вызове метода notify()?

A
Object monitor = getMonitor();
synchronized(monitor){
 …
 monitor.wait();
 …
}

После monitor.wait(), нить перейдет в состояние WAITING. Метод notify(), вызванный другой нитью у объекта monitor переведет нить из состояния WAITING в состояние RUNNABLE, если объект monitor не будет захвачен другой нитью, иначе в состояние BLOCKED.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
46
Q

В какое состояние перейдет нить, при вызове метода notifyAll()?

A

notifyAll() “пробудит” все нити. Одна из всех “спящих” (WAITING) нитей перейдет в состояние RUNNABLE, захватит монитор используемого объекта и продолжит свою работу. Остальные окажутся в состоянии BLOCKED. Как только первая “проснувшаяся” нить отпустит монитор, который все остальные ожидают, её участь повторит следующая нить (произвольная нить из состояния BLOCKED перейдет в состояние RUNNABLE). Это будет продолжаться до тех пор, пока все “пробужденные” нити не покинут состояния BLOCKED.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
47
Q

Три нити в блоке synchronized вызвали wait() у объекта-мютекса.
В какое состояние перейдут эти нити, если четвертая нить вызовет notifyAll()?

A

Две из них перейдут в состояние BLOCKED, одна в состояние RUNNABLE

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
48
Q

Чем отличается join(500) от wait(500)?

A

Несмотря на то, что и join(500) и wait(500) переведут текущую нить в состояние TIMED_WAITING, между ними существенные различия:
join(500) вызывается у нити, wait(500) вызывается внутри синхронизированного блока у объекта, по которому данный блок синхронизирован.
При вызове join(500) текущая нить будет ожидать 500 миллисекунд завершения нити, чей метод join() был вызван.
При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд.
Через 500 миллисекунд в обоих случаях нити продолжат работу.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
49
Q

Чем отличается wait(500) от sleep(500)?

A

sleep(500) вызывается у нити, wait(500) вызывается внутри синхронизированного блока у объекта, по которому данный блок синхронизирован.
При вызове sleep(500) текущая нить будет ожидать 500 милисекунд, затем продолжит свою работу.
При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
50
Q

В какое состояние перейдет нить при вызове метода yield()?

A

При вызове метода yield() – текущая нить «пропускает свой ход» и java сразу переключается на выполнение следующей нити. Нить из состояния running переходит в состояние ready. Состояния running & ready – это подсостояния состояния RUNNABLE

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
51
Q

Как пользоваться интерфейсом Comparable?

A

В интерфейсе Comparable объявлен всего один метод compareTo(Object obj), предназначенный для реализации упорядочивания объектов класса. Его удобно использовать при сортировке упорядоченных списков или массивов объектов.

Данный метод сравнивает вызываемый объект с obj. В отличие от метода equals, который возвращает true или false, compareTo возвращает:

  • 0, если значения равны;
  • Отрицательное значение, если вызываемый объект меньше параметра;
  • Положительное значение , если вызываемый объект больше параметра.

Прежде всего он удобен для сортировки упорядоченных списков (java.util.List) и массивов объектов. Если список/массив содержит элементы, реализующие этот интерфейс, то они могут быть отсортированы автоматически методами java.util.Collections.sort(List)/Arrays.sort(Object[]).

С интерфейсом Comparable связано понятие натурального упорядочивания, потому как он устанавливает натуральный порядок следования экземпляров любого класса, реализующего этот интерфейс. Иначе говоря, порядок (x, y) соответствует выполнению условия x.compareTo(y) <= 0.

Правила реализации Comparable, а вернее, его метода compareTo(Object) следующие (x и y – экземпляры класса, реализующего Comparable):

  • x.compareTo(y) возвращает -1 или 1, если x должен находиться, соответственно, раньше или позже y. Если метод возвращает 0, то порядки (x, y) и (y, x) эквивалентны.
  • Если sign(a) – функция, возвращающая -1,0,1 для а, соответственно, меньше 0, равного 0 и больше 0, то должно выполняться равенство sign(x.compareTo(y))==-sign(y.compareTo(x)). Что логично: если x идет раньше y, то y должен идти позже x, и наоборот.
  • Если x.compareTo(y) > 0 и y.compareTo(z) > 0, то x.compareTo(z) > 0 – соотношение транзитивности неравенств.
  • Если x.compareTo(y) == 0, то sign(x.compare(z)) == sign(y.compareTo(z)), для любых z.
  • Вызов x.compareTo(null) должен бросать исключение NullPointerException. В этом есть расхождение с логикой реализации equals (напомню, x.equals(null) возвращает false).
  • Если y по своему типу не может быть сравнен с x, то вызов x.compareTo(y) должен бросать исключение ClassCastException.
  • (x.compareTo(y) == 0) == x.equals(y), т.е. вызов x.compareTo(y) должен возвращать 0 тогда и только тогда, когда x.equals(y) возвращает true. Это правило непротиворечивости, и его очень важно учитывать.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
52
Q

Как пользоваться интерфейсом Comparator?

A

В интерфейсе Comparator объявлено два метода compare(Object obj1, Object obj2) и equals(Object obj).

При использовании интерфейса Comparator, логика сравнения пары объектов не прячется внутрь класса/объекта, а реализуется в отдельном классе.

Метод compare(x,y) в точности соответствует по своей сути вызову x.compareTo(y). Точно так же должны выполняться все правила, что и правила для реализации метода compareTo(Object) интерфейса Comparable.

Comparator может использоваться в любом месте, где нужна сортировка. При этом, во-первых, появляется необходимая гибкость – возможность реализации нескольких правил сортировки. А во-вторых, сортируемые объекты могут не реализовывать интерфейс Comparable. В случае, если они его все-таки реализуют, Comparator имеет приоритет.

Интерфейс Comparator определяет еще и метод equals(Object), как это ни парадоксально. Этот метод служит для сравнения самих экземпляров интерфейса Comparator и должен возвращать true только в том случае, если сравниваемые объекты обеспечивают одинаковый порядок сортировки. Однако всегда безопасно оставлять исходную реализацию Object.equals(Object) нетронутой

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
53
Q

Какие методы есть у класса Collections?

A
  1. public static boolean addAll(Collection super T> c, T… elements)

Метод добавляет элементы массива elements в коллекцию Collection super T> c. Элементы могут быть указаны по одиночке, либо как массив. Когда элементы указанны по отдельности данный метод предоставляет возможность удобно добавить все элементы в имеющуюся коллекцию:

Collections.addAll(flavors, “Peaches ‘n Plutonium”, “Rocky Racoon”);

  1. public static int binarySearch(List extends Comparable super T» list, T key)
    public static int binarySearch(List extends T> list, T key, Comparator super T> c)

Оба метода ищут в списке переданном в параметре объект переданный в параметре используя алгоритм двоичного поиска. Возвращают индекс элемента, если такой элемент в списке есть, иначе индекс первого элемента списка большего key, если все элементы меньше key, возвращает list.size().

Перед использованием данных методов списки должны быть отсортированы. В первом случае отсортированы по возрастанию в “естественном” порядке следования элементов списка (такой же, как при использовании Collections.sort(list)). Во втором случае список должен быть отсортирован по возрастанию в порядке следования, который обеспечивает переданный компаратор (такой же порядок, как при использовании Collections.sort(list, c)[здесь “с” - компаратор из параметров описываемого метода])

  1. public static Collection checkedCollection(Collection c, Class type)

Преамбула: механизм дженериков в языке обеспечивает проверку типов во время компиляции. Обычно этого и достаточно, однако бывают случаи, когда все-таки нет. К примеру мы нашу коллекцию передаем в код библиотеки, куда-нибудь на сторону, нам неизвестную, и нам очень сильно хочется, чтоб код этой “third-party library” не вставил в нашу коллекцию элемент неправильного типа. Это вот возможная проблема номер 1.

Возможная проблема номер 2 следующая. Предположим наша программа выдает нам ClassCastException, который оповещает нас о том, что в коллекцию был вставлен элемент неправильного типа. К сожалению данное исключение может вылететь в любой момент, после того, как неправильный элемент был вставлен, и обычно предоставляет нам совсем немного или вообще ноль информации об источнике проблемы.

Используя метод метод checkedCollection мы можем избавить себя от проблемы один и два, т.к. этот метод создает коллекцию проверяемую на этапе выполнения.

Решение проблемы номер два, с помощью данного метода: К примеру мы имеем вот это, и у нас вываливается ClassCastException.

Collection c = new HashSet();

Код выше можно временно заменить на:

Collection c = Collections.checkedCollection(
         new HashSet(), String.class);

При запуске программы снова мы локализуем строку кода, которая вставляет элемент неправильного типа в нашу коллекцию.

Родственные на мой взгляд методы:

public static List checkedList(List list,Class type)
public static Map checkedMap(Map m, Class keyType,Class valueType)
public static Set checkedSet(Set s,Class type)
public static SortedMap checkedSortedMap(SortedMap m,Class keyType,Class valueType)
public static SortedSet checkedSortedSet(SortedSet s,Class type)

  1. public static void copy(List super T> dest,List extends T> src)

Метод копирует элементы src в dest. индексы у копированных элементов будут совпадать.

  1. public static > T min(Collection extends T> coll)
    public static > T max(Collection extends T> coll)
    public static T min(Collection extends T> coll,Comparator super T> comp)
    public static T max(Collection extends T> coll,Comparator super T> comp)

методы возвращают минимальный\максимальный элемент в коллекции с точки зрения “естественного порядка”(интерфейс Comparable) либо порядка переданного компаратора.

  1. public static boolean disjoint(Collection> c1,Collection> c2)

Возвращает true если у коллекций нет одинаковых элементов.

7.  List  emptyList(), 
 Map  emptyMap(),
 Set  emptySet() – возвращают пустой список, карту отображения и множество соответственно;
  1. void fill(List super T> list, T obj) – заполняет список заданным элементом ;
  2. int frequency(Collection> c, Object o) – возвращает количество вхождений в коллекцию заданного элемента;
  3. List nCopies(int n, T o) – возвращает список из n заданных элементов;
  4. boolean replaceAll(List list, T oldVal, T newVal) – заменяет все заданные элементы новыми;
  5. void reverse(List> list) – “переворачивает” список;
  6. void rotate(List> list, int distance) – сдвигает список циклически на заданное число элементов;
  7. void shuffle(List> list) – перетасовывает элементы списка;
  8. Set singleton(T o),
    singletonList(T o),
    singletonMap(K key, V value) – создают множество, список и карту отображения, состоящие из одного элемента;
16. > void sort(List list),
 void sort(List list, Comparator super T> c) – сортировка списка, естественным порядком и используя Comparator соответственно;
  1. void swap(List> list, int i, int j) – меняет местами элементы списка стоящие на заданных позициях
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
54
Q

Какие методы есть у класса Arrays?

A
  1. public static List asList(T… a)

формирует список на основе массива. Массив при этом используется для внутреннего представления списка. Таким образом сохраняется связь между списком и исходным массивом:

изменения в массиве отразятся на списке:

String[] a = { “foo”, “bar”, “baz”};
List list = Arrays.asList(a);
System.out.println(list); // [foo, bar, baz]

a[0] = “aaa”;
System.out.println(list); // [aaa, bar, baz]

изменения в списке отразятся на массиве:

String[] a = { “foo”, “bar”, “baz”};
List list = Arrays.asList(a);
System.out.println(list); // [foo, bar, baz]

list.set(0, “bbb”);
System.out.println(Arrays.toString(a)); // [bbb, bar, baz]

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

Object[] a = { new Object(), new Object(), new Object()};
List list = Arrays.asList(a);
System.out.println(a[0] == list.get(0)); // true
  1. int binarySearch(параметры) – перегруженный метод организации бинарного поиска значения в массивах примитивных и объектных типов. Возвращает позицию первого совпадения;
  2. void fill(параметры) – перегруженный метод для заполнения массивов значениями различных типов и примитивами;
  3. void sort(параметры) – перегруженный метод сортировки массива или его части с использованием интерфейса Comparator и без него;
  4. static T[] copyOf(T[] original, int newLength) –заполняет массив определенной длины, отбрасывая элементы или заполняя null при необходимости;
  5. static T[] copyOfRange(T[] original, int from, int to) – копирует заданную область массива в новый массив;
  6. List asList(T… a) – метод, копирующий элементы массива в объект типа List.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
55
Q

Как называется сортировка, которая используется при вызове Collections.sort()?

A

Из документации:
Реализация является адаптированным вариантом сортировки списка для Python Тима Петерса (TimSort). Данная реализация сбрасывает список в массив, сортирует массив, затем проходит по списку и перезагружает каждый элемент списка из соответствующего элемента массива. Это позволяет избежать сложности n*n log(n), которая возникла бы при попытки отсортировать связный список напрямую

Из вики:
Timsort — гибридный алгоритм сортировки, сочетающий сортировку вставками и сортировку слиянием, опубликованный в 2002 году Тимом Петерсом. В настоящее время Timsort является стандартным алгоритмом сортировки в Python, OpenJDK 7 и реализован в Android JDK 1.5. Основная идея алгоритма в том, что в реальном мире сортируемые массивы данных часто содержат в себе упорядоченные подмассивы. На таких данных Timsort существенно быстрее многих алгоритмов сортировки.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
56
Q

Что такое канкаренси?

A

Concurrency – это библиотека классов в Java, в которой собрали специальные классы, оптимизированные для работы из нескольких нитей. Эти классы собраны в пакете java.util.concurrent. Их можно схематично поделить по функциональному признаку следующим образом:

1 Concurrent Collections— набор коллекций, более эффективно работающие в многопоточной среде нежели стандартные универсальные коллекции из java.util пакета. Вместо базового враппера Collections.synchronizedList с блокированием доступа ко всей коллекции используются блокировки по сегментам данных или же оптимизируется работа для параллельного чтения данных по wait-free алгоритмам.

  1. Queues — неблокирующие и блокирующие очереди с поддержкой многопоточности.
    - Неблокирующие очереди заточены на скорость и работу без блокирования потоков.
    - Блокирующие очереди используются, когда нужно «притормозить» потоки «Producer» или «Consumer», если не выполнены какие-либо условия, например, очередь пуста или переполнена, или же нет свободного «Consumer»’a.
  2. Synchronizers — вспомогательные утилиты для синхронизации потоков. Представляют собой мощное оружие в «параллельных» вычислениях.
  3. Executors — содержит в себе отличные фреймворки для создания пулов потоков, планирования работы асинхронных задач с получением результатов.
  4. Locks — представляет собой альтернативные и более гибкие механизмы синхронизации потоков по сравнению с базовыми synchronized, wait, notify, notifyAll.
  5. Atomics — классы с поддержкой атомарных операций над примитивами и ссылками.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
57
Q

Какие классы из «канкаренси» ты знаешь?

A

ConcurrentHashMap — В отличие от Hashtable и блоков synhronized на HashMap, данные представлены в виде сегментов, разбитых по hash’ам ключей. В результате, для доступа к данным лочится по сегментам, а не по одному объекту. В дополнение, итераторы представляют данные на определенный срез времени и не кидают ConcurrentModificationException.

AtomicBoolean, AtomicInteger, AtomicLong, AtomicIntegerArray, AtomicLongArray — Что если в классе нужно синхронизировать доступ к одной простой переменной типа int? Можно использовать конструкции с synchronized, а при использовании атомарных операций set/get, подойдет также и volatile. Но можно поступить еще лучше, использовав новые классы Atomic*. За счет использования CAS, операции с этими классами работают быстрее, чем если синхронизироваться через synchronized/volatile. Плюс существуют методы для атомарного добавления на заданную величину, а также инкремент/декремент.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
58
Q

Как устроен класс ConcurrentHashMap?

A

основные преимущества и особенности реализации ConcurrentHashMap:

  • Карта имеет схожий с hashmap интерфейс взаимодействия
  • Операции чтения не требуют блокировок и выполняются параллельно
  • Операции записи зачастую также могут выполняться параллельно без блокировок
  • При создании указывается требуемый concurrencyLevel, определяемый по статистике чтения и записи
  • Элементы карты имеют значение value, объявленное как volatile
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
59
Q

Что такое класс Lock?

A

Для управления доступом к общему ресурсу в качестве альтернативы оператору synchronized мы можем использовать блокировки. Функциональность блокировок заключена в пакете java.util.concurrent.locks.

Вначале поток пытается получить доступ к общему ресурсу. Если он свободен, то на поток на него накладывает блокировку. После завершения работы блокировка с общего ресурса снимается. Если же ресурс не свободен и на него уже наложена блокировка, то поток ожидает, пока эта блокировка не будет снята.

Классы блокировок реализуют интерфейс Lock, который определяет следующие методы:
void lock(): ожидает, пока не будет получена блокировка
boolean tryLock(): пытается получить блокировку, если блокировка получена, то возвращает true. Если блокировка не получена, то возвращает false. В отличие от метода lock() не ожидает получения блокировки, если она недоступна
void unlock(): снимает блокировку
Condition newCondition(): возвращает объект Condition, который связан с текущей блокировкой
Организация блокировки в общем случае довольно проста: для получения блокировки вызывается метод lock(), а после окончания работы с общими ресурсами вызывается метод unlock(), который снимает блокировку.

Объект Condition позволяет управлять блокировкой.

Как правило, для работы с блокировками используется класс ReentrantLock из пакета java.util.concurrent.locks. Данный класс реализует интерфейс Lock.

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// класс для работы с Lock API. Переписан с приведенной выше программы,
// но уже без использования ключевого слова synchronized
public class ConcurrencyLockExample implements Runnable{
private Resource resource;
private Lock lock;
    public ConcurrencyLockExample(Resource r){
        this.resource = r;
        this.lock = new ReentrantLock();
    }
    @Override
    public void run() {
        try {
            // лочим на 10 секунд
            if(lock.tryLock(10, TimeUnit.SECONDS)){
            resource.doSomething();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //убираем лок
            lock.unlock();
        }
        // Для логгирования не требуется потокобезопасность
        resource.doLogging();
    }

}

Как видно из программы, мы используем метод tryLock(), чтобы убедиться в том, что поток ждет только определенное время. Если он не получает блокировку на объект, то просто логгирует и выходит.

Еще один важный момент. Необходимо использовать блок try-finally, чтобы убедиться в том, что блокировка будет снята, даже если метод doSomething() бросит исключение.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
60
Q

Что такое итератор?

A

Представленный в релизе JDK 1.2 языка Java интерфейс java.util.Iterator обеспечивает итерацию контейнерных классов. Каждый Iterator реализует методы next() и hasNext() и дополнительно может поддерживать метод remove(). Итераторы создаются соответствующими контейнерными классами, как правило методом iterator().

Метод next() переводит итератор на следующее значение и возвращает указываемое значение итератору. При первоначальном создании итератор указывает на специальное значение, находящееся перед первым элементом, поэтому первый элемент можно получить только после первого вызова next(). Для определения момента, когда все элементы в контейнере были перебраны, используется тестовый метод hasNext(). Следующий пример демонстрирует простое использование итераторов:

Iterator iter = list.iterator();
//Iterator iter = list.iterator(); в J2SE 5.0
while (iter.hasNext())
    System.out.println(iter.next());

Для коллекции типов, поддерживающей подобное, метод итератора remove() удаляет последний ‘посещенный’ элемент из контейнера. Почти все остальные типы модификации контейнера во время итерации являются небезопасными.

Кроме того, для java.util.List существует java.util.ListIterator со схожим API, но позволяющем прямую и обратную итерации, обеспечивая определение текущего индекса в списке и переход к элементу по его позиции

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
61
Q

Что такое mutex?

A

Мютекс – это специальный объект для синхронизации нитей/процессов. Он может принимать два состояния – занят и свободен. Если упростить, то мютекс – это boolean-переменная, которая принимает два значения: занят(true) и свободен(false).

Когда нить хочет монопольно владеть некоторым объектом, она помечает его мютекс занятым, а когда закончила работу с ним – помечает его мютекс свободным.

Мютекс прикреплен к каждому объекту в Java. Прямой доступ к мютексу есть только у Java-машины. От программиста он скрыт.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
62
Q

Что такое монитор?

A

Монитор – это специальный механизм (кусок кода) – надстройка над мютексом, который обеспечивает правильную работу с ним. Ведь мало пометить, что объект – занят, надо еще обеспечить, чтобы другие нити не пробовали воспользоваться занятым объектом.

В Java монитор реализован с помощью ключевого слова synchronized.

Когда мы пишем блок synchronized, то компилятор Java заменяет его тремя кусками кода:
В начале блока synchronized добавляется код, который отмечает мютекс как занятый.
В конце блока synchronized добавляется код, который отмечает мютекс как свободный.
Перед блоком synchronized добавляется код, который смотрит, если мютекс занят – то нить должна ждать его освобождения.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
63
Q

Что такое дедлок?

A

Дедлок – это ситуация, когда два и более нитей заблокированы, ждущие друг друга. Дедлоком также называется взаимная блокировка.

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

Бывают взаимные блокировки порядка синхронизации (решаются назначением порядка);

Взаимная блокировка между объектами (различные объекты пытаются получить доступ к одним и тем же синхронизированным блокам);

Ресурсная взаимоблокировка (при попытке получить доступ к некоторым ресурсам, которые может использовать одновременно только один поток).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
64
Q

Какие вы знаете стратегии, предотвращающие появление дедлоков?

A

Интерфейс Lock и его реализации доступные в пакете java.util.concurrent.locks позволяют попытаться занять монитор, связанный с экземпляром данного класса методом tryLock (возвращает true, если удалось занять монитор).

Также есть стратегия применения открытых вызовов, то есть вызывать методы других объектов вне синхронизированного блока.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
65
Q

Могут ли возникнуть дедлоки при использовании методов wait-notify?

A

Дедлоков можно избежать за счет разумного использования synchronized, volatile, монитора (wait(), notify(), notifyAll()),а если копать глубже, то используя классы java.utils.concurrent: вместо обычных коллекций - многопоточные варианты (ConcurrentHashMap, например); если нужен более сложный способ синхронизации потоков — различные CyclicBarrier, CountDownLatch.

Если грамотно использовать wait – notify, то дедлоки возникнуть не должны.)))

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
66
Q

Что чаще используется: notify или notifyAll?

A

зависит от ситуации

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
67
Q

Метод wait рекомендуется использовать с конструкциями if или while?

A

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

if (some condition){
obj.wait()
}
…, а

while (some condition){
obj.wait()
}
Зачем это надо. Дело в том, что notify может вызвать кто угодно. Просто по ошибке, от которой никто не застрахован. В том случае из опыта, о котором я рассказывал выше, мы взялись за переделку именно для того, чтобы избежать такой возможности. Просто спрятали объект, на котором происходит синхронизация. И доступ к нему имел только наш код. Это хорошая практика, но не всегда возможно, к сожалению. Так вот, если поток ждет выполнения некоторого условия – вариант с while надежнее. Если поток пустили по ошибке – он опять проверит условие и, если надо, будет ждать дальше.

Кроме того, не исключена возможность и простого выхода из ожидания без вызова notify. Некоторые «гуру» утверждают, что VM может выйти из состояния ожидания самопроизвольно. И более того, периодически это наблюдается.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
68
Q

Что происходит после вызова метода notifyAll?

A

Пробуждает все нити, которые ждали на этом мониторе.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
69
Q

Какие выгоды получает объект, если он immutable?

A

Immutable объект — это объект, состояние которого после создания невозможно изменить. В случае Java это значит что все поля экземпляра у класс отмечены как final и являются примитивами или тоже immutable типами.

Простейший пример immutable класса из JDK это String. Любые методы, которые вы вызовите на строке (например description.toLowerCase()) вернут новую строку, а не модифицируют исходную

Ключевое слово final для объектных типов гарантирует неизменяемость лишь ссылки, но не самого объекта. Например, если у вас есть final-ссылка на ArrayList, вы тем не менее можете добавлять в него новые элементы или изменять существующие.

В случае же immutable-объекта объект после окончания конструктора не изменяется вообще. Одного лишь модификатора final для этого недостаточно, необходимо, чтобы все подобъекты были тоже неизменяемыми. Вы в принципе можете держать внутри ссылку на изменяемый объект, но обращаться с ним так, чтобы он не менялся.

Использование неизменяемых объектов даёт много выгод. Например, о таком объекте намного легче судить в ситуации, когда во многих частях программы есть ссылка на него (для изменяемого объекта, любая часть программы может вызвать мутирующую функцию в практически любой момент времени и из любого потока).

Но то, что для нас важно в контексте вопроса — неизменяемые объекты не требуют синхронизации при многопоточном доступе. Вот собственно и вся рекомендация: используйте неизменяемые объекты, и вам не придётся думать о том, что нужно, а что не нужно синхронизировать. Единственная возможная проблема — если вы внутри ещё не отработавшего конструктора публикуете ссылку на объект, через которую к нему может получить доступ кто-нибудь ещё, и увидеть объект в изменяющемся состоянии! (Это бывает не так уж и редко. Например, иногда программист хочет добавить объект в конструкторе в коллекцию всех объектов данного типа.)

Обратите внимание, что для полей неизменяемого объекта вы практически обязаны использовать final! Дело в так называемой безопасной публикации. Смотрите. Инструкции в Java-программе могут быть переставлены как оптимизатором, так и процессором (у Java достаточно слабая модель памяти). Поэтому, если не предпринимать специальных действий, окончание работы конструктора и присвоение значений полям может быть переставлено (но невидимо в рамках текущего потока)! Использование final гарантирует, что такого не произойдёт.

В случае многопоточного программирования преимущества immutable классов очевидны: после создания объекты можно передавать другим потокам и они всегда будут в актуальном состоянии. Т.е. вам не надо проверять не устарело ли состояние вашего экземпляра и не модифицировал ли его другой поток пока вы с ним работаете. Например, у вас есть метод bill(Date endDate), в нём вы наивно проверяете соответствие endDate каким-то предварительным условиям и начинаете с ней работать. В этот момент другой поток может изменить endDate, например установит её глубоко в прошлое. Последствия могут быть самыми удивительными.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
70
Q

Что такое «thread-safe»?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
71
Q

Что такое «happens-before»?

A

«Выполняется прежде» (англ. happens before) — отношение строгого частичного порядка (арефлексивное, антисимметричное, транзитивное), введённое между атомарными командами (++ и – не атомарны!), придуманное Лесли Лэмпортом и не означающее «физически прежде». Оно значит, что вторая команда будет «в курсе» изменений, проведённых первой

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
72
Q

Что такое JMM?

A

Java Memory Model

это набор правил:

Правило № 1: однопоточные программы исполняются псевдопоследовательно. Это значит: в реальности процессор может выполнять несколько операций за такт, заодно изменив их порядок, однако все зависимости по данным остаются, так что поведение не отличается от последовательного.

Правило № 2: нет невесть откуда взявшихся значений. Чтение любой переменной (кроме не-volatile long и double, для которых это правило может не выполняться) выдаст либо значение по умолчанию (ноль), либо что-то, записанное туда другой командой

Правило № 3: остальные события выполняются по порядку, если связаны отношением строгого частичного порядка «выполняется прежде» (англ. happens before).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
73
Q

Какое исключение вылетит, если вызвать wait не в блоке synchronized?

A

Основная причина вызова wait и notify из статического блока или метода в том, что Java API обязательно требует этого. Если вы вызовете их не из синхронизированного блока, ваш код выбросит IllegalMonitorStateException.
Более хитрая причина в том, чтобы избежать состояния гонки между вызовами wait и notify.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
74
Q

Какие приоритеты нитей бывают?

A

Для оптимизации параллельной работы нитей в Java имеется возможность устанавливать приоритеты нитей. Нити с большим приоритетом имеют преимущество в получении времени процессора перед нитями с более низким приоритетом.

Работа с приоритетами обеспечивается следующими методами класса Thread:

public final void setPriority(int newPriority)

Устанавливает приоритет нити.

public final int getPriority()

Позволяет узнать приоритет нити.

Значение параметра в методе setPriority не может произвольным. Оно должно находиться в пределах от MIN_PRIORITY до MAX_PRIORITY . При своем создании нить имеет приоритет NORM_PRIORITY .

MIN_PRIORITY = 1.
NORM_PRIORITY =5.
MAX_PRIORITY = 10.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
75
Q

Можно ли остановить нить, снизив ее приоритет до 0?

A

Нет
Программисты в основном полагаются на факт того, что нить останавливается сама, как только заканчивает выполнять методы run() или call(). Для остановки вручную, программисты пользуются преимуществом volatile boolean переменной и проверяют её значение в каждой итерации, если в методе run() есть циклы, или прерывают нити методом interrupt() для внезапной отмены заданий.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
76
Q

Зачем нужен класс ThreadGroup?

A

ThreadGroup представляет собой набор нитей, которые так же могут содержать в себе другие группы потоков. Группа нитей образует дерево, в котором каждая другая группа нитей имеет родителя (кроме исходной). Поток имеет право доступа к данным из своей группы нитей, но не имеет такого доступа к другим группам или к родительской группе потоков

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
77
Q

В какой группе нитей состоит main-thread?

A

нить main состоит в группе main, которая в свою очередь состоит в группе system, являющейся корневой группой (её parent == null).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
78
Q

Что такое паттерн ThreadPool?

A

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

Как правило, существует гораздо больше задач, чем потоков. Как только поток завершит свою задачу, он будет запрашивать следующую задачу из очереди, пока все задачи не будут завершены. Поток может затем прерваться или заснуть. Количество используемых потоков, это параметр, который может быть настроен, для обеспечения наилучшей производительности. Кроме того, число потоков может быть динамическим на основе количества возникающих задач. Например, веб-сервер может добавлять потоки, если запросы многочисленных веб-страниц приходят и может удалить потоки, когда этих запросов становится меньше. С увеличением размера пула потоков увеличивается использование ресурсов компьютера. Алгоритм, используемый для определения того, когда создавать или уничтожать потоки, будет иметь влияние на общую производительность: - Создать слишком много потоков значит тратить ресурсы и время впустую.

Уничтожить слишком много потоков и больше времени будет потрачено позже снова для их создания - Создание потоков слишком медленно, может привести к снижению производительности клиента.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
79
Q

Зачем нужен класс ThreadPoolExecutor?

A

public class ThreadPoolExecutor extends AbstractExecutorService

ExecutorService это выполняет каждую представленную задачу, используя один возможно из нескольких объединенных в пул потоков, обычно сконфигурированное использование Executors методы фабрики.

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

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

  • Executors.newCachedThreadPool() (неограниченный пул потоков, с автоматическим восстановлением потока),
  • Executors.newFixedThreadPool(int) (пул потоков фиксированного размера) и
  • Executors.newSingleThreadExecutor() (единственный фоновый поток), которые предварительно конфигурируют настройки для наиболее распространенных сценариев использования.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
80
Q

Сколько способов создать нить вы знаете? (Thread, Runnable, Callable)

A

На уровне языка есть два способа создания нити. Объект класса java.lang.Thread представляет собой нить, но ей требуется задача для исполнения, которая является объектом, реализующим интерфейс java.lang.Runnable. Так как класс Thread реализует интерфейс Runnable, вы можете переопределить метод run() унаследовав ваш класс от Thread или реализовав в нём интерфейс Runnable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
81
Q

Для чего используется класс Future?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
82
Q

В чем преимущества Callable над Runnable?

A

Callable параметризуемый тип, т.е можно указать тип возвращаемого методом call() значения
Callable может выбрасывать исключение не оказывая влияния на другие выполняющиеся задачи

Метод run интерфейса Runnable вообще не допускал выбрасывания контролируемых исключительных ситуаций, а выброс неконтролируемой (runtime) исключительной ситуации приводил к остановке потока и всего приложения

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
83
Q

Можно ли отменить выполнение задачи, если использовать класс Future?

A

У Future есть метод Future.cancel(boolean), который должен отменить выполнение задачи. Но если задача уже начала выполняться, вызов Future.cancel(true) на самом деле не остановит ее.

Потоку, в котором выполняется задача, всего лишь рекомендуется прекратить выполнение. К тому же, мы не имеем даже возможности узнать выполняется ли задача в данный момент или нет. Есть, метод Future.isDone(), но опять мимо, он возвращает true не только когда задача завершила выполнение, а сразу после вызова Future.cancel(), даже если задача все еще выполняется (ведь Future.cancel(true) не останавливает задачу которая уже начала выполняться).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
84
Q

Что такое autoboxing?

A

Автоупаковка — это механизм неявной инициализации объектов классов-оберток (Byte, Short, Character, Integer, Long, Float, Double) значениями соответствующих им исходных примитивных типов (соотв. byte, short, char, int, long, float, double), без явного использования конструктора класса.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
85
Q

Зачем используется autoboxing?

A

Насколько ты помнишь, в Java есть как типы, унаследованные от класса Object, так и примитивные типы. Но, как оказалось, такая удобная вещь как коллекции и generic’и могут работать только с типами, унаследованными от Object.

86
Q

Альтернативы autoboxing?

A

альтернатива autoboxingу это использование примитивных типов, так как использовние autoboxinga снижает производительность. Вывод: использовать autoboxing только там где это необходимо.

87
Q

Типы-обертки для примитивных типов mutable или immutable?

A

Immutable, так как примитивные объекты тоже immutable. Чтобы работать как с Mutable типом есть класс MutableInteger, и.т.д.

88
Q

Как примитивные типы приводятся к непримитивным аналогам?

A

автоупаковка является механизмом для скрытого преобразования примитивных типов данных в соответствующие классы-оболочки (объекты). Компилятор использует метод valueOf() чтобы преобразовать примитивные типы в объекты, а

Автоупаковка преобразует логический тип boolean в Boolean, byte в Byte, char в Character, float в Float, int в Integer, long в Long, short в Short. Распаковка происходит в обратном направлении.

89
Q

Как непримитивные типы приводятся к примитивным?

A

методы IntValue(), doubleValue() и т.д., чтобы получить примитивные типы из объекта (то есть обратное преобразование)

90
Q

Как сравниваются примитивные и непримитивные типы?

A

В Java есть два способа сравнивать объекты на равенство, == и метод equals().

== используется для примитивных типов. Для объектов «==» это исключительно сравнение ссылок. Для остальных случаев нужно использовать метод equals(). Кроме того метод hashCode() служит (в теории) для той же цели. Хорошим тоном считается, если вы переопределили equals() и hashCode(). После инициализации неких объектов a и b должно выполняться правило:

Если выражение a.equals(b) вернет true, то a.hashCode() должен быть равен b.hashCode().

91
Q

Всегда ли создается новый объект при операции autoboxing?

A

Когда мы присваиваем переменной типа Integer значение типа int, при этом вызывается метод Integer.valueOf: функция valueOf не всегда создает новый объект типа Integer. Она кэширует значения от -128 до 127.

Если передаваемое значение выходит за эти пределы, то новый объект создается, а если нет, то нет.

Если мы пишем new Integer(), то гарантированно создается новый объект. Если мы вызываем Integer.valueOf(), явно или при autoboxing, то этот метод может вернуть для нас как новый объект, так и отдать объект из кэша, если переданное число лежит в диапазоне от -128 до 127.

92
Q

Как работает кэширование при операции autoboxing?

A

Когда мы присваиваем переменной типа Integer значение типа int, при этом вызывается метод Integer.valueOf: функция valueOf не всегда создает новый объект типа Integer. Она кэширует значения от -128 до 127.

93
Q

Для каких типов и/или значений работает кэширование?

A

Кэширование работает для следующих значений: true, false, byte, char в диапазоне от \u0000 до \u007f, int или short в диапазоне от -128 до 127.

94
Q

Что произойдет, если поместить оператор return или System.exit () в блок try/catch?

A

блок finally будет выполняться при помещении оператора return в блок try/catch, и не будет выполняться при вызове из блока try/catch оператора System.exit ()

95
Q

Поддерживает ли язык Java множественное наследование?

A

Java поддерживает множественное наследование типов, ведь интерфейс в нём может расширять другие интерфейсы.
Но множественное наследование реализаций язык Java не поддерживает.

96
Q

В случае, когда метод генерирует исключение NullPointerException в родительском классе, можно ли его переопределить методом, генерирующим RuntimeException?

A

в переопределенном методе можно спокойно генерировать родительский класс исключения NullPointerException – RuntimeException, но нельзя сделать то же самое с проверяемым исключением типа Exception

97
Q

Как гарантировать возможность обращения N нитей к N ресурсам без взаимной блокировки?

A

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

98
Q

В чем разница между классами StringBuffer и StringBuilder в языке Java?

A

методы класса StringBuffer, например, length(), capacity() или append() синхронизированы, в то время как соответствующие методы класса StringBuilder –
нет.
В силу этого фундаментального отличия, конкатенация строк при помощи StringBuilder выполняется быстрее, чем с помощью StringBuffer.
На самом деле, использовать StringBuffer не рекомендуется, поскольку в 99% сценариев использования, конкатенация строк производится в той же нити

99
Q

Что вернет выражение 1.0/0.0? Приведет ли оно к генерации исключения или ошибке при компиляции?

A

генерации исключения ArithmeticException не произойдет, будет возвращено значение Double.INFINITY.

100
Q

Что будет, если попытаться вставить в HashMap уже имеющийся в ней ключевой объект?

A

если попытаться повторно вставить ключ в HashMap, он заменит старый, поскольку класс HashMap не допускает дублирующихся ключей. А тот же ключ означает такой же хэш-код, так что он попадет в то же место в хэш-сегменте

101
Q

Что такое NaN?

A

Not a Number
К операциям, приводящим к появлению NaN в качестве ответа, относятся:

  • все математические операции, содержащие NaN в качестве одного из операндов;
  • деление нуля на нуль;
  • деление бесконечности на бесконечность;
  • умножение нуля на бесконечность;
  • сложение бесконечности с бесконечностью противоположного знака;
  • вычисление квадратного корня отрицательного числа[1];
  • логарифмирование отрицательного числа.
102
Q

Как получить бесконечность в Java?

A

В Java тип double имеет специальные значения для понятий «плюс бесконечность» и «минус бесконечность». Положительное число, разделенное на 0.0, дает «плюс бесконечность», а отрицательное – «минус бесконечность». Этим понятиям соответствуют специальные константы типа Double:

public static final double POSITIVE_INFINITY = 1.0 / 0.0;
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

103
Q

Как проверить, что в результате вычисления получилась бесконечность?

A

Все сводится к выводу System.out.println()

104
Q

Что такое битовая маска?

A

Битовая маска — это когда хранится много различных логических значений (true/false) в виде одного целого числа. При этом каждому boolean-значению соответствует определенный бит.

105
Q

Где применяют битовые маски?

A

В основном там, где надо компактно хранить много информации об объектах. Когда хранишь много информации об объекте, всегда наберется пара десятков логических переменных. Вот их всех удобно хранить в одном числе. Именно хранить. Т.к. пользоваться им в работе не так уж удобно.

106
Q

Как установить бит в единицу в битовой маске?

A

Здесь использовал метод Integer.toBinaryString(), дабы проверить себя, а вдруг)

public class BitMask {

public static void main(String[] args) {
    int a = 9;

   a |= (1<<2); // установить в 1 бит 2

    System.out.println(Integer.toBinaryString(a) + " "+ a);
} } Вывод такой:

1101 13

107
Q

Как установить бит в ноль в битовой маске?

A

public class BitMask {

public static void main(String[] args) {
int a = 15;

a &= ~(1«2); // установить в 0 бит 2
System.out.println(Integer.toBinaryString(a) + “ “+ a);

} } Вывод:

1011 11

Я взял число 15, так как на нем более наглядно видно, куда устанавливается 0.

108
Q

Как получить значение определенного бита в битовой маске?

A

public class BitMask {

public static void main(String[] args) {
int a = 15;

 a &amp;= ~(1<<2); // установить в 0 бит 2

 int c = a &amp; (1<<2); // узнаем про 2 бит
 int d = a &amp; (1<<3); // узнаем про 3 бит
System.out.println(Integer.toBinaryString(a) + " "+ a + " " + c +" "+ d);

} } Вывод:

1011 11 0 8

C 0 все понятно, на том месте и вправду 0. А переменная d возвращает значение запрашиваемого бита (в 10-ой системе).

109
Q

Что такое ленивое вычисление выражения?

A

В ленивых вычислениях ни один параметр не вычисляется, пока в нем нет необходимости. Программы фактически начинаются с конца и работают от конца к началу. Программа вычисляет, что должно быть возвращено, и продолжает движение назад, чтобы определить, какое значение для этого требуется. В сущности каждая функция вызывается с promise’ами для каждого параметра. Когда для вычисления необходимо значение, тогда выполняется promise. Поскольку код выполняется только тогда, когда необходимо значение, это называется вызов по необходимости (call-by-need). В традиционных языках программирования вместо promise’ов передаются значения, это называется вызов по значению(call-by-value).

110
Q

Чем отличается использование && и & для типа boolean?

A

&& — это логическое «и». (В этом случае имеют место ленивые вычисления: некоторые вычисления опускаются, когда результат и так ясен)

& — это побитовое «и» (Если применить этот оператор к переменным типа Boolean, то ленивых вычислений происходить не будет)

111
Q

Может ли объект File соответствовать файлу, которого еще нет?

A

Да.

Объект класса File является абстрактным представлением файла и пути к нему. Он устанавливает только соответствие с ним, при этом для создания объекта неважно, существует ли такой файл на диске. После создания можно выполнить проверку, вызвав метод exists, который возвращает значение true, если файл существует. Создание или удаление объекта класса File никоим образом не отображается на реальных файлах. Для работы с содержимым файла можно получить экземпляры File I/O Stream.

Объект File может указывать на каталог (узнать это можно путем вызова метода isDirectory ). Метод list возвращает список имен (массив String ) содержащихся в нем файлов (если объект File не указывает на каталог – будет возвращен null )

112
Q

Как преобразовать объект File к типу Path?

A

Метод toPath();

113
Q

Зачем нужен класс Files?

A

Взяли за основу класс File, добавили в него немного нового, переименовывали методы, а в конце еще и разделили на два. Так что теперь есть два новых класса – Path и Files.

Path – это, фактически новый аналог класса File, а Files – это утилитный класс (по аналогии с классами Arrays & Collections), в него вынесли все статические методы класса File. Так «правильнее» с точки зрения ООП

114
Q

Какие классы для архивации вы знаете?

A

Для работы с архивами в спецификации Java существуют два пакета – java.util.zip и java.util.jar соответственно для архивов zip и jar. Различие форматов jar и zip заключается только в расширении архива zip. Пакет java.util.jar аналогичен пакету java.util.zip, за исключением реализации конструкторов и метода voidputNextEntry(ZipEntry e) класса JarOutputStream.

115
Q

Как добавить директорию в архив?

A
try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream("c:/archive.zip"))){
     out.putNextEntry(new ZipEntry("myfolder/"));
} catch (IOException e){
     e.printStackTrace();
}
116
Q

Зачем нужны Properties?

A

Properties – это файл свойств. Структура его: ключ – значение. Для работы с такими файлами в Java есть класс Properties, он унаследован от HashTable

117
Q

В каком виде хранятся данные в файле .properties?

A

Ключ – значение.

118
Q

Можно ли изменять данные в объекте Properties после загрузки их из файла?

A

Если он унаследован от HashMap, тогда можно, только потом нужно будет изменения в этот файл отписать. Для этого есть метод setProperty.

119
Q

Зачем нужен класс FileReader?

A

Класс для чтения символов файлов. Конструкторы этого класса предполагают, что кодировка символов дефолтная и дефолтный размер буфера являются подходящими. Чтобы задать эти значения самостоятельно, следует построить InputStreamReader над FileInputStream. FileReader предназначен для считывания потоков символов

120
Q

Зачем нужен класс FileWriter?

A

Класс для записи символов файлов. Конструкторы этого класса предполагают, что кодировка символов дефолтная и дефолтный размер буфера являются приемлемым. Чтобы задать эти значения самостоятельно, следует построить OutputStreamWriter над FileOutputStream. Является ли файл доступен для записи, зависит от используемой платформы. Некоторые платформы разрешают держать файл для записи только одним FileWriter (или другого объекта записи файла), в одно время. FileWriter предназначен для записи потоков символов. Для написания потоков необработанных байтов, используйте FileOutputStream.

Эти классы (FileReader и FileWriter) специально ориентированы для работы с текстом и строками.

121
Q

Зачем нужен RandomAccessFile?

A

RandomAccessFile — класс пакета Java IO API, он позволяет перемещаться по файлу, читать из него или писать в него, как вам будет угодно. Вы также сможете заменить существующие части файла, речь идет о обновлении содержимого файла, а точней о обновлении фрагмента файла. Это невозможно сделать с помощью FileInputStream или FileOutputStream, но RandomAccessFile даст вам эту возможность.

122
Q

Что будет если файл, откуда читает RandomAccessFile, не существует?

A

Будет FileNotFoundException

123
Q

Что будет если файл, куда пишет RandomAccessFile, не существует?

A

Создаст новый и запишет в него.

124
Q

Зачем нужен класс StringReader?

A

Чтобы читать строку потоком.

Представляет собой поток символов, чей источник называется строкой

125
Q

Зачем нужен класс StringWriter?

A

Чтобы писать строку потоком.

Поток символов, собирающий свой поток в буфер строк, которые затем могут быть использованы для создания строки.

126
Q

Зачем нужен класс ByteArrayStream?

A

Итак, ByteArrayInputStream и ByteArrayOutputStream.

Эти классы по сути чем-то похожи на StringReader и StringWriter.

Только StringReader читал символы (char) из строки (String), а ByteArrayInputStream читает байты из массива байт (ByteArray).

StringWriter писал символы (char) в строку, а ByteArrayOutputStream пишет байты в массив байт у него внутри.
При записи в StringWriter строка внутри него удлинялась, а при записи в ByteArrayOutputStream его внутренний массив байт тоже динамически расширяется

127
Q

Зачем нужен класс PrintStream? Назовите места, где он используется?

A

Класс PrintStream был придуман для читабельного вывода информации. Он практически весь состоит из методов print и println.

128
Q

Зачем нужен DynamicProxy?

A

В Java есть специальный класс (java.lang.reflect.Proxy), с помощью которого фактически можно сконструировать объект во время исполнения программы (динамически), не создавая для него отдельного класса.

129
Q

Как работает RMI?

A

RMI расшифровывается Remote Method Invokation – удаленный вызов методов. Или другими словами RMI – это механизм, который позволяет объекту в одной Java-машине вызывать методы объекта в другой Java-машине, даже если они находятся на разных компьютерах, в разных странах, на разных сторонах земного шара.

Традиционный подход к выполнению кода на других машинах, разнесенных по сети может смутить из-за своей нудной и склонной к ошибкам реализации. Лучший способ рассмотреть эту проблему состоит в предположении, что некоторые объекты располагаются на другой машине, и что вы можете посылать сообщения этим удаленным объектам и получать результат, как будто они располагаются на вашей локальной машине. Это упрощение в точности является тем, что позволяет делать Удаленный Вызов Методов (RMI) в Java.

130
Q

Объекты каких типов можно передавать по RMI?

A

Объекты должны имплементировать интерфейс Serializable

Remote method Invocation — механизм, который позволяет вызывать метод удалённого объекта. Согласно ему, все операции по подготовке и передаче данных инкапсулируются в вызываемом методе клиентского объекта-заглушки (stub). Сам же вызов метода ничем не отличается от вызова метода обычного локального объекта, за небольшим исключением:

  • локальные объекты передаются по значению (копии);
  • при передаче удалённого (Remote) объекта, если он экспортирован, передаётся stub этого объекта;
  • передаваемые объекты должны быть Serializable;
    кроме всех прочих исключительных ситуаций, при вызове удалённого метода может возбуждаться исключение RemoteException (ошибки маршализации/демаршализации, передачи данных и другие возможные ошибки протокола);

Так же нужно отметить, что при вызове метода мы работаем с удалённым интерфейсом, а не с удалённым классом

131
Q

Что такое JSON?

A

JSON (JavaScript Object Notation) — простой формат обмена данными, основанный на подмножестве языка программирования JavaScript.

132
Q

В чем отличия Java и JavaScript?

A

Это 2 разных языка программирования, несмотря на схожесть их названий. Оба они имеют С-подобный синтаксис. Отличия следующие:

  • Java реализует ООП подход, основанный на классах, JavaScript — на прототипах;
  • Java имеет статическую типизацию, JavaScript — динамическую типизацию;
  • Java загружается из скомпилированного байт-кода; JavaScript интерпретируется напрямую из файла
133
Q

В чем отличия JSON и XML?

A

JSON — формат обмена данными.

XML — язык разметки (в котором можно задать синтаксис, структуру, типы данных и вообще их модель).

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

134
Q

Какие фреймворки для работы с JSON вы знаете?

A
  • Jackson от FasterXML
  • JSON.simple от Yidong Fang
  • GSON от Google
  • JSONP от Oracle
135
Q

Какие фреймворки для работы с XML вы знаете?

A
  • JAXB (входит в J в JDK)

- Xstream

136
Q

Какие аннотации Jackson вы знаете?

A

@JsonAutoDetect — ставится перед классом. Сообщает Jackson, что необходимо использовать поля этого класса при записи или чтении. В скобках можно задать параметр (fieldVisibility = JsonAutoDetect.Visibility.ANY ), для настройки видимости полей, которые будут использоваться (по умолчанию используются только public поля).

@JsonIgnore — ставится перед полем. Сообщает Jackson, что данное поле нужно игнорировать при чтении/записи.

@JsonProperty — Ставится перед полем, getter’ом или setter’ом. Позволяет задать другое имя поля при сериализации.

@JsonWriteNullProperties — Ставится перед классом. Поля объекта, которые равны null не будет игнорироваться.

@JsonPropertyOrder — Ставится перед классом. позволяет определить порядок, в котором поля java объекта будут сериализованы в JSON.

@JsonDeserialize — Ставится перед полем. Позволяет определить класс, в который десериализуется JSON объект. Например из java массивы и списки сериализуются в массивы, и при десериализации можно выбрать, что именно мы хотим получить.

137
Q

Какие аннотации JAXB вы знаете?

A

@XmlRootElement — Ставится перед классом. Указывает на то, что этот объект может быть, элементом самого верхнего уровня, т.е. все остальные элементы лежат в нем.

@XmlType — Ставится перед классом. Добавляет в XML-схему дополнительную информацию. Можно указать некоторые атрибуты, например порядок элементов имя и тд.

@XmlElement — Ставится перед полем. Позволяет задать имя xml-элемента, значение по умолчанию и т.д.

@XmlAttribute — Ставится перед полем. Поле будет представлено как XML-атрибут.

@XmlElementWrapper — Ставится перед полем, либо геттером. Позволяет создать обрамляющий тэг для группы элементов.

@XmlJavaTypeAdapter — Ставится перед классом. В скобках указывается вспомогательный класс-адаптер, необходимый для маршилизации/демаршализации данного класса.

@XmlEnum — Ставится перед enum. В скобках можно указать тип, в котором будут представлены значения enum.

@XmlEnumValue — Ставится перед значением enum. Позволяет задать специальное значение для данного значения enum.

138
Q

В чем отличие сериализации и десериализации в JSON?

A

сериализация - это перевод объекта в строку

десериализация - это перевод строки в объект

139
Q

Что лучше JSON или XML? Почему?

A

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

140
Q

Что такое DTO?

A

DTO (Data Transfer Object) — паттерн проектирования содержащий данные без какой-либо логики для работы с ними. DTO обычно используются для передачи данных между различными приложениями, либо между слоями внутри одного приложения. Их можно рассматривать как хранилище информации, единственная цель которого — передать эту информацию получателю.

141
Q

Что такое сборка мусора?

A

Это механизм уничтожения ненужных объектов. Ненужные объекты — это неиспользуемые объекты. Существует два способа поиска таких объектов: подсчёт ссылок и трассировка. В первом случае с каждым объектом связывается некоторая переменная, которая хранит количество ссылок на этот объект. Если это количество опускается до нуля, то объект считается мёртвым. Во втором случае сборщик мусора идёт по ссылкам объектов из корневых точек до конца (до значения нулл), обходя всё это дерево. Объекты, до которых он не может добраться из корневых точек, считаюся мёртвыми. Корневыми точками считаются все активные нити, метод main, аргументы метода main(), а также все статические переменные класса, в которой находится метод main().

Определение объектов, пригодных к уничтожению - это только первая часть работы сборщика мусора. Вторая часть - это собственно их удаление и работа с памятью. Здесь используется гибридный подход. Вся доступная для объектов память разделяется на три области: область молодых объектов, область старых объектов и область перманентных объектов (это классы, метаданные, интернированные строки и т.д.). Первая область разделяется ещё на три подобласти: на Eden и suvivor space 1 и 2. В Eden хранятся все только созданные объекты. В остальных двух зонах хранятся объекты, выживщие после последней сборки мусора. Сборщик мусора работает со всей этой областью (областью молодых объектов) следующим образом. Во время очередной сборки мусора он находит живые объекты в области Eden и копирует их во вторую область выживших. После этого он в первой области также ищет живые объекты и копирует их либо в вторую область выживших, либо, если они уже достаточно “старые” - область старого поколения. После этого он очищает область Eden и первую область выживших. Дальше он считает вторую область выживших первой. И всё, на это сборка мусора заканчивается для этой области.

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

142
Q

Когда вызывается метод finalize?

A

Перед уничтожение объекта сборщиком мусора. Также можно вручную запустить вызовы этого метода у всех недостижимых объектов, для этого надо вызвать метод System.runFinalization() или Runtime.getRuntime().runFinalization().

Но это не гарантирует вызов метода finalize

143
Q

Что произойдет, если в методе finalize возникнет исключение?

A

Это исключение будет проигнорировано, и произойдёт выход из метода

144
Q

Что такое SoftReference?

A

SoftReference переводится как “мягкая ссылка”. Эта ссылка на объект, но более слабая, чем обычная ссылка (StrongReference). Объекты, на которые сущесвуют только мягкие ссылки, называются мягкодостижимыми. Такие объекты не уничтожаются в обычном случае. Но если у JVM закочиналась память, то сборщик мусоры удаляет все такие объекты

145
Q

Что такое WeakReference?

A

WeakReference — это так называемая слабая ссылка на объект. Она ещё слабее Soft-ссылки. Все объекты, на которые существуют только слабые ссылки, будут удалены при ближайщей сборке мусора.

146
Q

Что такое PhantomReference?

A

PhantomReference — это самая слабая ссылка.

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

Механизм работы с такими ссылками следующий. Если на объект не осталось больше никаких других ссылок, и у него переопределён метода finalize(), то этот метода будет вызван во время ближайшей сборки мусора. Если же этот метод не переопределён, то этот объект пропускает текущую сборку мусора, и попадает только в следующую. Во время этой (следующей) сборки мусора данный объект помещается в очередь призрачных объектов, из которой будет удалён, когда у его призрачной ссылки вызовут метод clear(). Также стоит отметить, что метода get() у призрачной ссылка всегда возвращает null (в отличие от двух других несильных ссылок, у которых он возвращает null, только если объект уже уничтожен).

147
Q

ак работает WeakHashMap? Где он используется?

A

WeakHashMap — это HashMap, у которого ключами являются слабые ссылки. Поэтому, если во время ближайшей сборки мусора будет обнаружено, что на объект существует только ссылка в WeakHashMap, то из WeakHashMap будет удалена вся пара “ключ-значение”, связанная с этим объектом.

В связи с этим данная коллекция может быть использована для хранения какой-то дополнительной, не очень важной информации об объекте. Также её удобно использоваться для хранения какой-то временной информации (которая нужная только в рамках данной операции).

148
Q

Зачем нужно передавать очередь в конструктор PhantomReference?

A

Эта очередь используется для отслеживания того, что объект больше не нужен. Может быть использовано для закрытия ресурсов, открытых данным объектом (например, удаление созданных файлов).

149
Q

Зачем нужен логгер?

A

Логгер нужен для сохранения информации о поведении программы, а также некоторых её состояниях.
Может быть использован для отладки и выявления ошибок в работе программы и сбоев.
Также логгер позволяет разработчику получать обратную связь от своей программы во время её работы.
Кроме того, при критических сбоях логгер может оперативно оповещать нужных людей (например, разработчиков, клиентов, менеджеров проектов, службу техподдержки и т.д.) об этих сбоях

150
Q

Какие настройки логгера вы знаете?

A

При настройке логгирования можно указать следующие вещи:

  • место, куда будет писаться информация (файл, консоль, база данных, сеть и т.д.)
  • сообщения какого уровня будут записываться
    вид записей в логе
  • для файлов можно указать: путь к файлу и каталогу, размер файлов, количество файлов
  • указать для каждого отдельного пакета свой уровень сообщений, которые будут писаться в лог
151
Q

Какие системы контроля версий вы знаете?

A

Git, SVN, Mercurial

152
Q

Чем отличаются SVN и Git?

A

GIT — распределенная СКВ, а SVN — нет. Другими словами, если есть несколько разработчиков работающих с репозиторием у каждого на локальной машине будет ПОЛНАЯ копия этого репозитория. Разумеется есть и центральная машина, с которой можно клонировать репозиторий. Это напоминает SVN. Основной плюс Git в том, что если вдруг у вас нет доступа к интернету, сохраняется возможность работать с репозиторием. Потом только один раз сделать синхронизацию и все остальные разработчики получат полную историю.

GIT сохраняет метаданные изменений, а SVN целые файлы. Это экономит место и время.

153
Q

Что такое GitHub? У вас есть проекты на GitHub?

A

GitHub — веб-сервис хостинга проектов с использованием системы контроля версий git, а также как социальная сеть для разработчиков. Пользователи могут создавать неограниченное число репозиториев, для каждого из которых предоставляется wiki, система issue tracking-а, есть возможность проводить code review и т.п. Кроме Git, сервис поддерживает получение и редактирование кода через SVN и Mercurial.

154
Q

Зачем нужны системы контроля версий?

A

СКВ дает возможность возвращать отдельные файлы к прежнему виду, возвращать к прежнему состоянию весь проект, просматривать происходящие со временем изменения, определять, кто последним вносил изменения во внезапно переставший работать модуль, кто и когда внес в код какую-то ошибку, и т.п.. Вообще, если, пользуясь СКВ, вы всё испортите или потеряете файлы, всё можно будет легко восстановить.

155
Q

Что такое generic? Как они реализованы в Java?

A

Generics — это параметризованные типы. С их помощью можно объявлять классы, интерфейсы и методы, где тип данных указан в виде параметра. Обобщения добавили в язык безопасность типов.

Пример реализации:

class MyClass{
  T obj;
  public MyClass(T obj){
    this.obj = obj;
  }
}
class MyClass
В угловых скобках используется T — имя параметра типа. Это имя используется в качестве заполнителя, куда будет подставлено имя реального типа, переданного классу MyClass при создании реальных типов. То есть параметр типа T применяется в классе всякий раз, когда требуется параметр типа. Угловые скобки указывают, что параметр может быть обобщен. Сам класс при этом называется обобщенным классом или параметризованным типом.

Далее тип T используется для объявления объекта по имени obj:

T obj;
Вместо T подставится реальный тип, который будет указан при создании объекта класса MyClass. Объект obj будет объектом типа, переданного в параметре типа T. Если в параметре T передать тип String, то экземпляр obj будет иметь тип String.

Рассмотрим конструктор MyClass():

public MyClass(T obj){
  this.obj = obj;
}
Параметр obj имеет тип T. Это значит, что реальный тип параметра obj определяется типом, переданным параметром типа T при создании объекта класса MyClass.

Параметр типа T также может быть использован для указания типа возвращаемого значения метода.

В именах переменных типа принято использовать заглавные буквы. Обычно для коллекций используется буква E, буквами K и V — типы ключей и значение (Key/Value), а буквой T (и при необходимости буквы S и U) — любой тип.

Обобщения работают только с объектами. Поэтому нельзя использовать в качестве параметра элементарные типы вроде int или char.

*Так же считаю нужным упомянуть generic методы. Это методы вида:

модификаторы возвращаемыйТип имяМетода(T t, …)

156
Q

Что такое стирание типов?

A

Внутри класса-дженерика не хранится информация о его типе параметре. Это и называется стиранием типов. На стадии компиляции происходит приведение объекта класса к типу, который был указан при объявлении.

157
Q

Что такое wildcard?

A

Wildcard — это дженерик вида >, что означает, что тип может быть чем угодно. Используется, например, в коллекциях, где для всех коллекций базовым типом является Сollection>.

158
Q

Расскажите про extends и super в Generic’ах?

A

Чтобы наложить ограничение на wildcard необходимо использовать конструкции типа:

? extends SomeClass — означает, что может быть использован любой класс-наследник SomeClass
? super SomeClass — означает, что может быть использован класс SomeClass, либо класс-родитель (или интерфейс) SomeClass
Это называется bounded wildcard.

Для того, чтобы определиться с выбором между extends и super был придуман метод PECS

159
Q

Как использовать wildcard?

A

Пример использования wildcard:

List> numList = new ArrayList();

160
Q

В чем отличие ArrayList и ArrayList>

A

Запись вида ArrayList называется raw type (обычный тип). Она эквивалентна записи вида ArrayList и используется для обратной совместимости, т.к. до Java 1.5 не было дженерик коллекций. По возможности такой формы записи следует избегать.

ArrayList> является супертипом для ArrayList.

161
Q

Что такое MVC?

A

MVC — это такой архитектурный подход к построению приложения. Имеет такие основные принципы:
1) Отделение модели предметной области (бизнес логики) приложения от пользовательского интерфейса;
2) Независимость Модели и синхронизация пользовательских интерфейсов за счет шаблона “Наблюдатель”;
3) Разделение Пользовательского Интерфейса на Вид и Контроллер.
Самое главное что Модель в настоящем понимании MVC это не просто данные или бизнес логика, это интерфейс взаимодействия с данными и бизнес логикой которые представляют сложную структуру классов (реализует так называемый паттерн “Фасад”) за счёт чего обеспечивается “слабое связывание” бизнес логики с пользовательским интерфейсом. За счёт того что Модель - это “Фасад”, гораздо легче реализовать паттерн “Наблюдатель” который так же обеспечивает “слабое связывание” и позволяет вести разработку и поддержку бизнес логики абсолютно ничего не зная и не завися от пользовательского интерфейса (Представления и Контроллера).
Так же Контроллер не должен на себя брать часть (или всю) бизнес логику, а просто должен обрабатывать пользовательские запросы и передавать их Модели (Фасаду).

162
Q

Что такое DAO и DTO?

A

DAO (Data Access Object) — это объект, основная задача которого сохранять данные в базу данных, а также извлекать их из неё.

DTO (Data Transfer Object) - это объект, предназначенный для транспортировки данных. Поэтому его основная задача — хранить эти данные. Никакой логики он не содержит. Кроме того, он должен быть сериализуемым, так как транспортировка объектов обычно происходит с помощью сериализации/десериализации.

163
Q

Что такое POJO?

A

POJO переводится как “объект Java в старом стиле”. Их противопоставляют EJB-объектами. Последние следуют специальной конвенции и обычно жёстко привязаны к какому-то конкретному enterprise-фреймворку (например, у них должен быть публичный конструктор без параметров, должен быть геттеры и сеттеры для полей, они должны быть сериализуемыми и т.д.).

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

164
Q

Что такое Entity?

A

Entity Bean — это объект, цель которого хранить некоторые данные. В логику такого объекта встроен механизм сохранения себя и своих полей в базу данных. Такой объект может быть уничтожен, а потом воссоздан из базы заново. Но кроме хранения данных у него нет никакой логики.

А bean в свою очередь — это особый класс, который должен выполнять следующие правила:

  • Класс должен иметь конструктор без параметров, с модификатором доступа public. Такой конструктор позволяет инструментам создать объект без дополнительных сложностей с параметрами.
  • Свойства класса должны быть доступны через get, set и другие методы (так называемые методы доступа), которые должны подчиняться стандартному соглашению об именах. Это легко позволяет инструментам автоматически определять и обновлять содержание bean’ов. Многие инструменты даже имеют специализированные редакторы для различных типов свойств.
  • Класс должен быть сериализуем. Это даёт возможность надёжно сохранять, хранить и восстанавливать состояние bean независимым от платформы и виртуальной машины способом.
  • Класс должен иметь переопределенные методы equals(), hashCode() и toString().
165
Q

Какие коллекции-списки вы знаете?

A

Все коллекции-списки реализуют интерфейс List и наследуются от абстрактного класса AbstractList. Среди них можно выделить

  • ArrayList — это список, основанный на массиве,
  • LinkedList — это классический двусвязный список.
166
Q

Какие коллекции-множества вы знаете?

A

Коллекции-множества в Java реализуют интерфейс Set и наследуются от AbstractSet.
Множества — это такие наборы данных, в которых все элементы уникальны.
Среди них в Java есть:
- HashSet - хранит свои объекты на основе хеш-кодов
- LinkedHashSet - это модифицированная первая, в ней элементы ещё к тому же располагаются в связном списке, поэтому они все расположены в порядке добавления
- TreeSet. - обеспечивает сортировку своих элементов.

167
Q

Что такое map, чем он отличается от «словаря»?

A

Map — это вид коллекций, хранящих свои элементы в виде пар “ключ-значения”. Причём все ключи должны быть уникальными.
Среди реализаций есть:
- HashMap - хранит элементы с использованием хэш-кодов ключей
- TreeMap. - хранит элементы в отсортированном по ключу порядке.

168
Q

Что такое Queue и Dequeue?

A

Очередь (Queue) — это структура данных, работающая по принципу FIFO “Первый вошёл — первый вышел”. То есть элементы в очередь добавляются с одного конца, а извлекаются — с другого.

Deque — это двусторонняя очередь. В этой очереди элементы можно добавлять как в начало, так и в конец, а также брать элементы тоже можно и из начала, и из конца очереди. Соответственно есть методы, которые позволяю положить элемент (это методы add(e) и offer(e)), и есть методы, позволяющие извлечь элемент из очереди (это такие методы, как remove() и poll()). Кроме того, есть методы, которые позволяют просто получить элемент из очереди без его удаления оттуда (это методы element() и peek()).
В интерфейсе Deque дополнительно есть методы для добавления элементов в начало и конец очереди, извлечения элементов из начала или конца, а также получения элементов из начала или конца очереди (без их удаления из очереди).

169
Q

Какие классы, реализующие интерфейс Queeue вы знаете?

A

Среди простых реализаций можно отметить ArrayDeque, LinkedList и PriorityQueue. Также существуют много классов в Concurrent Collections, которые реализуют эти два интерфейса (оба сразу или только один из них).

170
Q

Что такое дерево?

A

Дерево — это связный граф без петель и кратных рёбер. Обычно, если в дереве N вершин, то количество рёбер как минимум— N-1. Также одну вершину в дереве выбирают в качестве корня. Остальные вершины объявляют ветвями. Ветви, у которых нет своих ветвей, называются листьями дерева.
В программировании деревья используются довольно широко, и придумано уже много видов этого дерева. Одно из самых широкоприменяемых деревьев - это бинарное дерево. В этом дереве у каждого элемента имеется не больше двух потомков (то есть может быть от 0 до 2). Одной из разновидностью двоичного дерева является BST — бинарное дерево поиска. В этом дереве на элементы накладывается правило: левый потомок элемента должны быть по значению меньше его, а правый — по значению больше его или равен ему.
Также ещё существуют красно-чёрные деревья. Это разновидность двоичных деревьев поиска. В красно-чёрных деревьях вводится ещё одно свойство элемента — цвет. Цвет может быть чёрный или красный. Также каждое красно-чёрное дерево должно удовлетворять следующим требованиям:

  1. корень дерева — чёрный;
  2. узел либо красный, либо чёрный;
  3. все листья дерева — чёрные;
  4. оба потомка красного узла - чёрные;
  5. всякий путь от данного узла до любого листового узла, являющегося его потомком, содержит одинаковое количество чёрных узлов.

Эти правила позволяют добиться сбалансированности дерева. Дерево сбалансировано, когда длина пути от корня до любого листового узла отличается не более, чем на 1. (То есть по-простому, в дереве нет перекосов и длинных ветвей.)

171
Q

Что такое паттерны проектирования?

A

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

172
Q

Какие паттерны проектирования вы знаете?

A
Singleton, 
Factory, 
Abstract Factory, 
Template method, 
Strategy, 
Pool, 
Adapter, 
Proxy, 
Bridge, 
MVC
173
Q

Расскажите про паттерн Singleton? Как сделать его потокобезопасным?

A

clas Singleton {
private static volatile Singleton instance;

private Singleton() {}
	public static Singletot getInstance() {
		if (instance == null)
			synchronized(Singleton.class) {
			      instance = new Singleton();
		        }
		return instance;
	}
}
174
Q

Расскажите про паттерн Factory?

A

Factory — это порождающий паттерн. Он позволяет создавать объекты по требованию (например, при определённых условиях). Выглядит это так:

class Factory{
	public static Object1 getObject1() {
		return new Object1();
	}
	public static Object2 getObject2() {
		return new Object2();
	}
	public static Object3 getObject3() {
		return new Object3();
	}
}
175
Q

Расскажите про паттерн AbstractFactory

A

Abstract Factory — это порождающий шаблон проектирования. Согласно этому паттерну, создаётся некоторая абстрактная фабрика, служащая шаблоном для нескольких конкретных фабрик. Можно привести такой пример:

class Human {}

class Boy extends Human {}
class TeenBoy extends Human {}
class Man extends Human {}
class OldMan extends Human {}
class Girl extends Human {}
class TeenGirl extends Human {}
class Woman extends Human {}
class OldWoman extends Human {}
interface AbstractFactory {
	Human getPerson(int age);
}
class FactoryMale implements AbstractFactory {
	public Human getPerson(int age) {
		if (age < 12)
			return new Boy();
		if (age >= 12 &amp;&amp; age <= 20)
			return new TeenBoy();
		if (age > 20 &amp;&amp; age < 60)
			return new Man();
		return new OldMan();
	}
}
сlass FactoryFemale implements AbstractFactory {
	public Human getPerson(int age) {
		if (age < 12)
			return new Girl();
		if (age >= 12 &amp;&amp; age <= 20)
			return new TeenGirl();
		if (age > 20 &amp;&amp; age < 60)
			return new Woman();
		return new OldWoman();
	}
}
176
Q

Расскажите про паттерн Adaper, его отличия от Wrapper?

A

Паттерн Adapter — это структурный паттерн. Его реализация позволяет использовать объект одного типа там, где требуется объект другого типа (обычно это абстрактные типы).

При реализации паттерна Wrapper создаётся класс, который оборачивает исходный класс и реализует тот же интерфейс, который реализует исходный класс. Таким образом, это позволяет расширить функциональность исходного класса и использовать новый класс там, где ожидается использование исходного класса.
Это отличается от реализации паттерна Adapter тем, что в данном случае используется один интерфейс (тот же, что есть у исходного класса).
В паттерне Adapter же используется два интерфейса, и класс, который оборачивает экземпяр исходного класса, реализует совсем другой инферфейс, не интерфейс исходного класса.

177
Q

Расскажите про паттерн Proxy

A

Паттерн Proxy — это структурный паттерн проектирования. Он нужен для того, чтобы контролировать доступ к какому-то объекту. Для этого пишется класс по типу “обёртка”, то есть внутрь класса передаётся исходный объект, реализующий некий интерфейс, сам класс тоже реализует этот интерфейс, и в каждом методе этого класса вызывается похожий метод у исходного объекта. Реализация того же интерфейса, что и у исходного объекта, позволяет подменить исходный объект прокси-объектом. Также это позволяет, не меняя исходного объекта, “навешивать” на его методы какую-то специальную дополнительную функциональность (например, логирование, проверка прав доступа, кэширование и т.д.)

178
Q

Что такое итератор? Какие интерфейсы, связанные с итератором, вы знаете?

A

Итератор — это специальный внутренний объект коллекции, который позволяет последовательно перебирать элементы этой коллекций. Этот объект должен реализовывать интерфейс Iterator, либо ListIterator (для списков). Также, для того, чтобы перебирать элементы коллекции, коллекция должна поддерживать интерфейс Iterable. Интерфейс Iterable содержит всего один метод — iterator(), который позволяет извне получить доступ к итератору коллекции.

Интерфейс Iterator содержит следующие методы:

boolean hasNext() — проверяет, есть ли в коллекции ещё какой-то элемент

E next() — позволяет получить очередной элемент коллекции (после получения элемента, внутренний курсор итератора передвигается на следующий элемент коллекции)

void remove() — удаляет текущий элемент из коллекции

Интерфейс же ListIterator содержит такие методы:

boolean hasNext() — проверяет, существуют ли ещё один элемент в коллекции (следующий за текущим)

E next() — возвращает очередной элемент коллекции (и передвигает внутренний курсок итератора на следующий элемент)

int nextIndex() — возвращает индекс следующего элемента

void set(E e) — устанавливает значение текущего элемента void add(E e). Добавляет элемент в конец списка.

boolean hasPrevious() — проверяет, существует ли какой-то элемент в коллекции перед данным элементом

E previous() — возвращает текущий элемент коллекции и переводит курсор на предыдущий элемент коллекции

int previousIndex — возвращает индекс предыдущего элемента коллекции

void remove() — удаляет текущий элемент коллекции

void add(E e) — добавляет элемент e после текущего элемента коллекции

179
Q

Зачем нужен класс Arrays?

A
Класс Arrays — это утилитарный класс, предназначенный для разнообразных манипуляций с массивами. В этом классе есть методы 
превращения массива в список, 
поиска по массиву, 
копирования массива, 
сравнения массивов, 
получения хешкода массива, 
представление массива в виде строки 
и др.
180
Q

Зачем нужен класс Collections?

A

Класс Collections — это утилитарный класс для работы с коллекциями. В этом классе есть методы добавления элементов в коллекцию,
наполнения коллекции элементами,
поиска по коллекции,
копировании коллекции,
сравнения коллекции,
нахождения максимального и минимального элементов коллекции,
а также методы получения специфический модификаций коллекций известных типов (например, можно получить потокобезопасную коллекции или неизменяемую коллекцию с одним элементом).

181
Q

Что такое Agile?

A

Agile — это серия подходов к разработке программного обеспечения, ориентированных на использование итеративной разработки, динамическое формирование требований и обеспечение их реализации в результате взаимодействия внутри самооранизующихся рабочих групп, состоящих из специалистов разных профилей. Существует несколько методик, относящих к гибкой методологии разработки, в частности экстремальное программирование, DSDM, Scrum, FDD.

Основные концепции agile-методов:

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

Также были сформулированы основные принципы такого подхода:

  • удовлетворение клиента за счёт ранней и бесперебойной поставки ценного программного обеспечения;
  • приветствие изменений требований даже в конце разработки (это может повысить конкурентноспособность продукта на рынке);
  • частая поставка рабочего программного обеспечения (каждый месяц или каждую неделю, или даже ещё чаще);
  • тесное, ежедневно общение заказчика с разработчика на протяжении всего проекта;
    проектом занимаются мотивированные личности, обеспеченые нужные условиями работы, поддержкой и доверием;
  • рекомендуемый метода передачи информации - личный разговор (лицом к лицу);
  • работающее программное обеспечение - лучший измеритель прогресса;
  • спонсоры, разработчики и пользователи должны поддерживать постоянный темп на неопределённый срок;
  • постоянно внимание улучшению технического мастерства и удобному дизайну;
  • простота - искусство не делать лишней работы;
    лучшие технические требования, архитектура и дизайн получаются у самороорганизованной команды;
  • постоянная адаптация к изменяющимся условиям.

Основной проблемой разработки было признано то, что никто из участников ни на одном этапе не обладает всей полнотой информации о том, что делать.

182
Q

Что такое scrum?

A

Scrum — это одна из методик гибкой разработки. Она делает акцент на качественном контроле процесса разработки.
Основная особенность скрама — это разбиение процесса разработки на итерации имеющий чёткую протажённость по времени (обычно 2-6 недель; их называют “спринтами”).

“планирование спринта” — совещание на 3-4 часа.

“product owner” формирует список (“product backlog”) требований (“user story”) с приоритетами.

scrum-мастера: он проводит все совещания, следит за соблюдением всех принципов скрама, разрешает противоречия и защищает команду от отвлекающих факторов. Обычно в качестве скрам-мастера выступает кто-то из команды.

На первом совещании в начале спринта каждой задаче, даётся ещё приблизительная оценка в “абстрактных человеко-днях”, которые ещё называют “story point”.

Затем команда решает, сколько она успеет выполнить задач за время спринта.

Список отобранных задач на спринт называются “sprint backlog”, или “резерв спринта”.

Также строится диаграмма “сгорания задач”.

Также в течение спринта каждый день или через день проводятся небольшие совещания внутри команды на 5-15 минут.

Когда спринт завершается, scrum-master проводит demo, на котором демонстрируется список всего, что полностью сделано.

Затем проводится «разбор полетов» (retrospective view) — совещание тоже на пару часов.

Обычно за 2-3 спринта можно выявить основные проблемы, которые мешают команде работать эффективнее, и устранить их. Это приводит к большей продуктивности, не увеличивая нагрузку на команду. Такое было невозможным до эры гибких методологий.

Также в середине спринта, иногда еще проводят «вычесывание» — совещание посвященное планированию следующего спринта.

183
Q

Какие роли Scrum вы знаете?

A

В скрам участников делят на “свиней” и “кур”. “Свиньи” полностью задействованы в процессе, “куры” — только частично. К категории “свиней” относят следующие роли:

  1. Скрам-мастер - проводит совещания, следит за выполнением принципов скрама и пр.; это кто-то из команды (product owner не может быть скрам-мастером);
  2. Product Owner - представляет интересы конечных пользователей и других заинтересованных в продукте сторон;
  3. Команда разработки (Development Team) - кросс-функциональная команда, состоящая из специалистов разных профилей: разработчиков, тестировщиков, дизайнеров, архитекторов и т.д. Размер команды в идеале составляет от 3 до 9 человек. Команда является единственные полностью вовлечённым участником разработки и отвечает за результат как единое целое. Никто, кроме команды, не может вмешиваться в процесс разработки на протяжении спринта.

К “курам” относятся следующие роли:

  1. Пользователи (Users)
  2. Клиенты, продавцы (Stakeholders) - лица, которые инициируют проект и для кого проект будет приносить выгоду. Они вовлечены в скрам только во время обзорного совещания по спринту (Sprint Review);
  3. Управляющие (Managers) - люди, которые управляют персоналом);
  4. Эксперты-консультанты (Consulting Experts).
184
Q

Что такое спринт? Расскажите с подробностями

A

Спринт — это одна итерация цикла разработки программного обеспечения в Скраме. Обычно спринт жёстко фиксирован по времени. Продолжительность спринта выбирается на основании размера команды, специфики работы, требований, размера проекта. Чаще всего это подбирается опытным путём, на основании проб и ошибок.
В среднем спринт может быть продолжительность от 2 недель до 4 (хотя в некоторых компания его продолжительность бывает равна и 6 неделям).

Для оценки объёма работ в спринте может быть использована предварительная оценка, измеряемая в очках истории. Предварительная оценка фиксируется в беклоге проекта.

185
Q

Кто такие QA?

A

QA - Quality Assuarance - то есть “Гарантия качества”, если перевести дословно.
К этой категории относятся тестировщики. Это люди, которые выявляют в программе баги и ошибки. Для этого они используют разные средства, как ручные, так и автоматические. После выявления багов и ошибок они сообщают об этом разработчикам, и те исправляют эти ошибки.

186
Q

Кто такой product owner?

A
Product Owner (владелец проекта) — это заказчик или представитель заказчика. 
Это либо кто-то со стороны клиента (сторонняя фирма или физ.лицо), либо какой-то другой сотрудник фирмы, определяющий требования к конечному продукту и следящий за их выполнением (например, бизнес-аналитик). 

Как уже было сказано, он определяет требования к продукту и задачи, которые должна решить команда разработки, чтобы получить конечный продукт. Список требований (или задач) он оформляет в определённым порядке и с заданным приоритетом для каждого требования (задачи). Обычно он участвует в планировании спринта (перед началом спринта) и в демонстрации результатов спринта (после окончания спринта).

187
Q

Расскажите об иерархии исключений

A

Throwable.
1. Error
выбрасываются, когда возникают какие-то серьёзные ошибки в работе программы и java-машины в целом (а также в работе ОС и аппаратной части компьютера), так, что программа больше не может продолжать работать и закрывается. Это может быть недостаток памяти (OutOfMemoryError) или переполнение стека (StackOverflowError).

  1. Exception.
    могут выбраться при самых различных исключительных ситуаций.
    2.1.RuntimeException и все остальные классы. Первый класс так выделяют, потому что, во-первых, исключительные ситуации такого типа являются непроверяемые (unchecked), а, во-вторых, к данным исключительным ситуациям относятся ошибки выполнения программы. Обычно это возникает из-за несовершенства кода.
    Все остальные исключительные ситуации обычно являются следствием непредвиденного стечения обстоятельств, например, ошибки ввода-вывода.

Также исключения делятся на

  • unchecked. не проверяемые - Eror и RuntimeException
  • checked - проверяемые - все остальные
188
Q

Что делать если JVM выкинула Error?

A

Ничего, программа просто закроется. Обычно это критические ошибки, не всегда возникшие по вине программиста (например, выход из строя жёсткого диска или сбой операционной системе).

Правда, среди них есть две ошибки, которые могу следствием несовершенства кода — это StackOverflowError и
OutOfMemoryError.

Первый тип ошибок возник, при переполнении стека вызовов — то есть, когда вызывается слишком много методов и стек вызовов становится слишком большой (типичный пример — бесконечная рекурсия или рекурсия с большим количеством итераций).

Вторая ошибка — OutOfMemoryError — возникает,
когда переполняет память отведённая под объекты, то есть когда создаётся слишком много тяжеловесных объектов, и они все держатся в памяти (или когда сборщик мусора не успевает их уничтожать).

189
Q

Какие нововведения в области исключений из Java 7 вы знаете?

A
  1. Multicatching. Это когда в одном catch-блоке сразу обрабатывается несколько исключений.
    В таком случае параметр ex будет неявно иметь модификатор final. Кроме того, байт-код, сгенерированный компиляцией такого кода (с единым catch-блоком) будет короче
  2. Try-with-resources. Эта конструкция позволяет после слова try в скобках указать открываемые ресурсы, которые сами закроются после окончания конструкции try () {} catch{}. В качестве ресурса в данной конструкции может быть использован любой объект, реализующий интерфейс AutoCloseable.
    Во время закрытия ресурсов тоже может быть брошено исключение.
    В try-with-resources добавлена возможность хранения “подавленных” исключений, и брошенное try-блоком исключение имеет больший приоритет, чем исключения, получившиеся во время закрытия. Получить последние можно вызовом метода getSuppressed() от исключения, брошенного try-блоком.
  3. Rethrowing. Перебрасывание исключений с улучшенной проверкой соответствия типов.
    допустим, блок try может выкинуть два вида исключения, а блок catch обрабатывает общее исключение Exception и перевыбрасывает его, тогда в сигнатуре метода можно указать тип выбрасываемого исключения как первый и второй. компилятор разберется.
190
Q

Зачем нужны аннотации? Как ими пользоваться?

A

Аннотации используются для размещения рядом с классом, полем, методом или переменой какой-то дополнительной, служебной информации (метаданных), относящейся к ней. Чтобы указать аннотацию, надо над заголовком класса или метода, либо надо объявлением поля или переменной, написать после @ название аннотации (класса аннотации), например так:@Override

Аннотации выполняют следующие функции:

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

Кроме того, у аннотации могут быть свойства, они указывают в скобках через запятую в виде пар “ключ=значение”, где в качестве ключа выступает название свойства, а качестве значения — собственно, значение, которое должно принять это свойство

Чтобы создать свою аннотацию, надо так:
@interface CatManager
{
 Class manager();
 boolean unique();
 String name() default "Unknown Cat";
}

Зарезервировано три аннотации:

@Deprecated,
помечаются устаревшие методы и классы, нерекомендованные к использованию

@Override
ставится над переопределёнными методами класса-наследника (это позволяет контролировать связь между исходным методом и переопределённым).

@SuppressWarnings.
позволяет подавлять (не выводить) некоторые исключительные предупреждения, обычно выводимые компилятором в связи с данным методом или классом (например, что он уже устарел и нерекомендован к использованию).

191
Q

Что такое web-сервер?

A

Веб-сервер — это сервер, принимающий HTTP-запросы от клиентов (чаще всего браузеров) и выдающий им HTTP-ответы, как правило вместе с HTML-страницей, изображений, файлом, медиа-потоком и другими данными.

192
Q

Что такое Tomcat?

A

Apache Tomcat — это контейнер сервлетов, разработанный компанией Apache Software Foundation. Реализует спецификацию сервлетов и спецификацию JSP (JavaServer Pages) и JSF(JavaServer Faces). Позволяет запускать веб-приложения, содержит ряд программ для самоконфигурирования. Может выступать в качестве самостоятельного веб-сервера, в качестве контента (в сочении с Apache HTTP Server), а также в качестве контейнера сервлетов в серверах приложений JBoss и GlassFish

193
Q

Что такое сервлеты и где они используются?

A

Сервлет — это Java-класс, наследуемый от класса HttpServlet и реализующий любые из методов: doGet(), doPost(), doPut(), doDelete()init() и destroy().

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

194
Q

Какие режимы запуска приложений в IDEA вы знаете?

A

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

Обычный запуск приложения - это обычно его выполнение.
В режиме отладки же приложение можно выполнять построчно. Также в этом режиме можно ставить точки останова (breakpoints) на некоторые строчки кода (программа будет выполнять как обычно, пока не встретит такую точку; как она её встретит, она остановится).
Кроме того, этот режим позволяет смотреть значения переменных во время выполнения программы.

195
Q

Можно ли дебажить приложение/сервлет, которое запущено внутри Tomcat’а?

A

Да, это можно делать, и это можно делать даже из самой IDE.
Например, чтобы запустить отладку сервлета из IDEA, нужно сделать следующее:

  1. Зайти в настройки отладки/запуска приложения
  2. Добавить конфигурацию Remote
  3. Далее выводится страница, где нужно изменить адрес хоста, на котором находится Tomcat, и порт
  4. Открыть файл catalina.bat (для Windows) и исправить в нём строчку “set DEBUG_OPTS=”. Туда нужно дописать следующее “-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1985”. Последнее число - это адрес порта, который мы указали на шаге 3.
  5. Рестартовать Tomcat
  6. Выставить точки останова в коде в нужных местах
  7. Нажать Debug в IDEA
  8. Отправить запрос
  9. Произвести отладку из среды разработки
196
Q

Как в IDEA установить точку остановки?

A

Либо можно нажать мышкой в поле между номером строчки и началом строки, либо встать на какую-то строчку и нажать на клавиатуре ctrl+F8, либо встать на строку и вверху в меню выбрать Run -> Toggle line BreakPoint.

197
Q

Как в IDEA посмотреть список всех точек остановки?

A

Либо сочетанием клавиш ctrl+shift+F8, либо выбрать в меню Run -> View Breakpoints…

198
Q

Можно ли с помощью IDEA поменять значение переменной в процессе работы программы?

A

Да, есть такая возможность.
Это можно сделать в режиме отладки. Во время отладки нужно в окне переменных выбрать нужную переменную и нажать F2, либо щёлкнуть по переменной правой кнопкой мыши и в открывшемся меню выбрать “set value”, и ввести нужное значение переменной.

199
Q

Как в IDEA настроить отступы?

A

Нужно зайти в настройки (Settings), там выбрать Editor, потом — Code Style. Там уже можно изменить общий опции, либо изменить настройки отступов для каждого поддерживаемого формата файла.

200
Q

Как в IDEA настроить, чтобы { отображалось на той же строке, а не на новой?

A

Нужно перейти по следующему пути Settings -> Editor -> Code Style -> Java -> Wrapping and Braces, и дальше в разделе Braces Placement изменять настройки (для класса, метода, лямбда-выражений, других случаев).

201
Q

Что такое IP-адрес?

A

IP-адрес — это уникальный сетевой адрес узла в компьютерной сети, построенной на стеке протоколов TCP/IP.
В сети Интернет требуется глобальная уникальность адреса; в случае работы в локальной сети требуется уникальность адреса в пределах сети.
В версии протокола IPv4 IP-адрес имеет длину 4 байта, а в версии протокола IPv6 IP-адрес имеет длину 16 байт. Обычно IP-адрес в версии протокола IPv4 записывают в виде четырёх десятичных чисел со значениями от 0 до 255, разделённых точкой, например, 192.168.0.3.

202
Q

В чем отличие host и domain?

A

Домен — это адрес сайта или определённая зона, которая имеет своё имя, не похожее ни на какое другое имя в системе доменных имён. Домены бывают первого уровня, второго уровня, третьего уровня и т.д.
Обычно домен первого уровня не доступен обычным пользователям для регистрации (примеры доменов первого уровня - “.ru”, “.com”, “.net”). Обычно домены третьего и следующих уровней называют субдоменами.

Хост — это определённый компьютер или сервер, подключенный к локальной или глобальной сети. Хост обладает уникальным адресом в среде сервисов TCP/IP (IP-адресом).

203
Q

Какие методы в HTTP вы знаете?

A
GET, 
POST,
PUT, 
DELETE, 
OPTIONS, 
HEAD, 
PATCH, 
TRACE, 
LINK, 
UNLINK, 
CONNECT.
204
Q

Чем отличаются методы GET, POST и HEAD?

A

GET - используется для запроса содержимого указанного ресурса.
Метод GET считается упрощённой версией POST, потому как метод GET не предполагает полноценного
запроса, только URL в качестве такового.

POST - применяется для передачи пользовательских данных заданному ресурсу.

HEAD - обычно применяется для извлечения метаданных, проверки наличия ресурса (валидация URL) и чтобы узнать, не изменился ли он с момента последнего обращения. Метод HEAD аналогичен методу GET, за исключением того, что в ответе сервера отсутствует тело.

205
Q

Что такое REST?

A

REST — это архитектурный стиль взаимодействия компонентов распределённого приложения в сети.

  1. Модель “Клиент-Сервер” (означает, что сеть должна состоять из клиента и сервера; сервер - это тот, кто обладает ресурсами, клиент - тот, который их запрашивает))
  2. Отсутствие состояния (означает, что ни клиент, ни сервер не отслеживают состояния друг друга)
  3. Кеширование (клиенты и промежуточные узлы могут кешировать результаты запросов; сооответственно, ответы сервера должны иметь явное или неявное обозначение, что они кешируемые или некешируемые)
  4. Единообразие интерфейса (означает, что между клиентами и серверами существует общий язык взаимодействия, который позволяет им быть заменяемыми или изменяемыми, без нарушения целостности системы):
  • Определение ресурса (означает, что каждый ресурс должны быть обозначен постоянным идентификатором)
  • Управление ресурсами через представление (означает, что клиент хранит ресурс в виде его представления, и при желании изменения ресурса он отправляет серверу информацию о том, в каком виде он хотел бы видеть этот ресурс; сервер же рассматривает этот запрос как предложение, и сам решает, что делать ему с хранимым ресурсом)
  • Самодостаточные сообщения (каждое сообщение содержит достаточно информации, чтобы понять, как его обрабатывать)
  • Гипермедиа (означает, что клиенты изменяют состояние системы только через действия, которые динамически определены в гипермедиа на сервер)
  • Система слоёв (означает, что в системе может быть больше двух слоёв (клиент и сервер), и при этом каждый такой слой знает только о своих соседних слоях, и не знает об остальных слоях, и взаимодействует только с соседними слоями)
  • Код по требованию (означает, что функциональность клиента может быть расширения за счёт загрузки кода с сервера в виде апплетов или сценариев)

Удовлетворение этим требованиям позволяет добиться следующего:

  • Надёжность
  • Производительность
  • Масштабируемость
  • Прозрачность взаимодействия
  • Простота интерфейсов
  • Портативность компонентов
  • Лёгкость внесения изменений
  • Способность эволюционировать, приспосабливаясь к новым требованиям
206
Q

Зачем нужен класс Calendar в Java?

A

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

207
Q

Как преобразовать дату в Java к нужному формату?

A

Для этого существует удобный класс SimpleDateFormat. Экземпляру этого класс можно передать шаблон представления даты, и тогда он в таком виде будет возвращать дату (в формате строки String), либо считывать дату (из строки String).

208
Q

В чем отличие URI и URL?

A

URI расшифровывается как Uniform Resource Identifier и переводится как “унифицированный идентификатор ресурса”.
URI — это последовательность символов, идентифицирующая абстрактный или физический ресурс.

URL расшифровывается как Uniform Resource Locator. То есть это некий унифицированный указатель на ресурс, однозначно определяющий его месторасположение.
URL служит стандартизированным способом записи адреса ресурса в сети Интернет.

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

209
Q

Что такое сокеты?

A

Сокеты — это связка IP-адрес + порт, позволяющая из внешней сети однозначно идентифицировать программу на компьютере или сервере.
В Java для работы с сокетами есть два класса
Socket и
ServerSocket.

Экземпляры первого класса играют роль клиента, экземпляры второго — роль сервера.
Клиент может отправлять и принимать сообщения через сокет.
Сервер же постоянно отслеживает запросы пользователей и отвечает на них.
Для того, чтобы отправить данные через сокет, в классе Socket существует класс getOutnputStream(), возвращающий исходящий поток, с которым уже можно работать как обычно.
Для приёма информацию нужно воспользоваться методом getInputStream(), который возвращает входящий поток. Дальше с этим потоком можно работать как с обычно потом ввода.
Также стоит отметить, что при создании клиентского сокета (экземпляра класса Socket) в конструктор нужно передать ip-адрес сервера и порт, на котором он работает принимающая программа-сервер.
При создании серверного сокета (экземпляра класса ServerSocket) нужно указывать только порт, через который будет работать программа. После этого вызывается метод accept(). Этот метод ожидание подключение клиента, а после этого возвращает экземпляр класса Socket, необходимый для взаимодействия с этим клиентом. Дальше работать идёт с экземпляром класса Socket, как в первом случае (в случае клиента).

210
Q

Отличие классов Socket и URL?

A

Главное отличие в том, что класс URL предназначен для работы с URL-строкой (парсинг URL-строки), а Socket используется для соединения с удалённым сервером и отправки информации на сервер и/или приёма информации от сервера (хотя, используя класс URL, можно получить доступ к ресурсу, на который указывает сам URL; но делается это не напрямую, а через объект класса URLConnection). Также, если смотреть в общем, то Socket используется для связи с сервером (другой программой), а URL — для доступа к ресурсу (например, к файлу). Кроме того, URL и URLConnection ориентированы в основном на работу с HTTP, тогда как Socket может работать с любыми протоколами.