alykoff.github.io

влияние предмета наблюдения на наблюдателя посредством наблюдения

Java Core. 54 вопроса

54 вопроса на знание java core. Как-то мне пришлось на эти вопросы ответить. Надеюсь я нигде не налажал )

  1. Что такое класс Object? Какие в нем есть методы?
    Класс Object - это базовый класс. Для каждого класса Object - супер класс. Все объекты, включая массивы имплементируют методы этого класса. В нем присутствуют методы:
    • boolean equals(Object o)
    • void finalize() // вызывается сборщиком мусора, когда gc определил, что ссылок на объект больше нет.
    • Class<?> getClass() //возвращает в рантайме класс данного объекта.
    • int hashCode()
    • void notify() // просыпается одни поток, который ждет на “мониторе” данного объекта.
    • void notifyAll() // просыпаются все потоки, которые ждут на “мониторе” данного объекта.
    • String toString()
    • void wait() // Приводит данный поток в ожидание, пока другой поток не вызовит notify() или notifyAll() методы для этого объекта.
    • void wait(long timeout) // Приводит данный поток в ожидание, пока другой поток не вызовет notify() или notifyAll() для этого метода, или пока не исчет указанный промежуток времени.
    • void wait(long timeout, int nanos) // nanos - дополнительное время в наносекундах.
    • Object clone() // create and returns a copy of this object.
  2. Что такое метод equals. Чем он отличается от операции ==.
    Метод, определенный в Object, который служит для сравнение объектов на равенство. При сравнение объектов при помощи == идет сравнение по ссылкам. При сравнении по equals идет сравнение по состояниям объектов (реализация метода equals для нового созданного класса ложится на плечи разработчиков).
    • Причем равенство должно работать в обе стороны.
    • Должно выполняться условие транзитивности.
    • Для одних и тех же экземпляров результат работы метода должен быть всегда одинаков.
  3. Если вы хотите переопределить equals, какие условия должны удовлетворяться для переопределенного метода?
    См. 2). Так же должно выполняться условие, что возвращаемое значение работы метода hashCode() для объектов равных относительно метода equals() должен быть одинаковым.
  4. Если equals переопределен, есть ли какие-либо другие методы, которые следует переопределить?
    Да, есть. hashCode(). Для того, чтобы поддержать общий контракт.
  5. Для чего нужен метод hashCode?
    Этот метод используется для хэш таблиц, таких как HashMap. Контракт:
    • Когда метод hashCode() последовательно вызывают на одном и том же объекте, метод должен возвращать в этом случае одни и теже значения, при условии, что никакая информация, которая используется в equals() при сравнении не изменилась. Возвращаемый хэш код может быть различным в различных запущенных приложениях.
    • Два объекта равные по equals() должны возвращать одинаковый hashCode().
    • Не обязательно, что объекты не равные по equals() должны возвращать разные hashCode().
  6. Какая связь между hashCode и equals?
    См 5)
  7. Каким образом реализованы методы hashCode и equals в классе Object?
    В классе Object метод equals производит сравнение по ссылке, метод hashCode() генерироет hash при помощи нативного кода из адреса ссылки.
  8. Что будет, если переопределить equals не переопределяя hashCode? Какие могут возникнуть проблемы?
    Нарушится контракт. Классы и методы, которые использовали правила этого контракта могут некореектно работать. Так в для объекта HashMap это может привести к тому, что пара, которая была помещена в мапу возможно не будет найдена в ней при обращении к мапе, если использует новый экземпляр ключа.
  9. Есть ли какие-либо рекомендации о том, какие поля следует использовать при подсчете hashCode?
    Те, которые используют при определении метода equals(). Хэш код должен быть равномерно распределен на области возможных принимаемых значений.
  10. Как вы думаете, будут ли какие-то проблемы, если у объекта, который используется в качестве ключа в hashMap изменится поле, которое участвует в определении hashCode?
    Будут. При обращении по ключу, мы может не найти значение.
  11. Какие модификаторы доступа в Java вы знаете?
    • private,
    • protected,
    • package-private (default),
    • public.
  12. Какой из модификаторов более строгий: protected или package-private?
    package-private. Поле с package-private уровнем доступа будет видно только в данном пакете всем классам.Тогда как protected видно для наследников данного класса, а так же для классов находящихся в данном пакете.
  13. Если у класса-родителя есть метод, объявленный как private, может ли наследник расширить его видимость? А если protected? А сузить видимость?
    Действует общий принцип: расширять видимость можно, сужать нельзя. Private методы видны только внутри класса, для потомков они не видны. Поэтому их и расширить нельзя.
  14. Что означает ключевое слово final?
    Может быть применено к полям, методам или классам. В зависимости к какой сущности приложено данное ключевое слово - будет и различный смысл в его применении.
    • Для класса. Класс помеченный при помощи final не может иметь наследников.
    • Для метода. Метод помеченный при помощи final не может быть переопределен в классах наследниках.
    • Для поля. Поле помеченное при помощи слова final не может изменить свое значение после инициализации (инициализируется либо при описании, либо в конструкторе/статическом блоке).
    • Значение локальных переменных, а так же параметров метода помеченных при помощи слова final не могут быть изменены после присвоения.
  15. Имеет ли смысл объявлять метод private final?
    Нет, такой метод не виден для наследников, а значит не может быть ими переопределен.
  16. Какие особенности инициализации final переменных?
    см 14)
  17. Что будет, если единственный конструктор класса объявлен как final?
    К конструктору не применимо ключевое слово final.
  18. Что означает ключевое поле static?
    То, что метод, внутренний класс или поле является экземплярами класса. Так же существует static блок, который выполняется при загрузке класса.
    И немного про static-блоки, init-блоки и конструкторы и как они вызываются учитывая иерархию:
    • static-блок вызывается при загрузке класса, поэтому static-блок super-класса будет вызван раньше, чем static-блок наследника.
    • Вызов других конструкций следующий (при создании экземпляра): init-блок super-класса, конструктор super-класса, init-блок наследника, конструктор наследника. Т.к. init-блок всегда выполняется перед конструктором, а перед вызовом контруктора наследника всегда вызывается конструктор super-класса.
    • init/static блоки в рамках одного класса вызываются в последовательности определения.
  19. К каким конструкциям Java применим модификатор static?
    • К методу.
    • К внутреннему классу.
    • К полю.
    • К импортируемы классам (с 5-ой java).
  20. Что будет, если в static блоке кода возникнет исключительная ситуация?
    Если в явном виде написать любое исключение в static-блоке, то компилятор не скомпилирует исходники. Это все от того, что компилятор умный. В остальном, взаимодействие с исключениями такое же как и в любом другом месте. Если unchecked исключение вывалится в static-блоке, то класс не будет инициализирован.
    Какой эксепшн вываливается наружу при ошибке в инит/статик блоке? Для static:
    • java.lang.ExceptionInInitializerError - если исключение наследуется от RuntimeException.
    Для init:
    • exception, который и вызвал исключение, если он наследуется от RuntimeException.
    Верно для static и init:
    • java.lang.Error - если исключение вызвано Error.
    • java.lang.ThreadDeath - смерть потока. Ничего не вываливается.
  21. Можно ли перегрузить static метод?
    Перезагрузить можно, переописать нельзя.
  22. Что такое статический класс, какие особенности его использования?
    Это вложенный класс, который может обращаться только к статическим полям обертывающего его класса, в том числе и приватным. Доступ к нестатическим полям обрамляющего класса может быть осуществлен только через ссылку на экземпляр обрамляющего объекта.
  23. Какие особенности инициализации final static переменных?
    Переменный должны быть инициализированы во время объявления или в static блоке.
  24. Какие типы классов бывают в java (вложенные… и.т.д.)
    • Обычные классы (Top level classes)
    • Интерфейсы (Interfaces)
    • Перечисления (Enum)
    • Статические вложенные классы (Static nested classes)
      • Есть возможность обращения к внутренним статическим полям и методам класса обертки.
      • Внутренние статические интерфейсы могут содерать только статические мотоды.
    • Внутренние классы-члены (Member inner classes)
      • Есть возможность обращения к внутренним полям и методам класса обертки.
      • Не может иметь статических объявлений.
      • Нельзя объявить таким образом интерфейс. А если его объявить без идентификатора static, то он автоматически будет добавлен.
      • Внутри такого класса нельзя объявить перечисления.
      • Если нужно явно получить this внешнего класса - OuterClass.this
    • Локальный класс (Local inner classes)
      • Видны только в пределах блока, в котором объявлены.
      • Не могут быть объявлены как private/public/protected или static (по этой причине интерфейсы нельзя объявить локально).
      • Не могут иметь внутри себя статических объявлений (полей, методов, классов).
      • Имеют доступ к полям и методам обрамляющего класса.
      • Можно обращаться к локальным переменным и параметрам метода, если они объявлены с модификатором final.
    • Анонимные классы (Anonymous inner classes)
      • Локальный класс без имени.
  25. Каким образом из вложенного класса получить доступ к полю внешнего класса.
    Если вложенный класс не статический и поле не статическое, то можно просто обратиться к этому полю из внутреннего класса, если только у внутреннего класса не существует поля с таким же литералом, в этом случае нужно обраться через ссылку на внешний класс где-то так - OuterClass.this
  26. Какие особенности создания вложенных классов: простых и статических.
    См 24)
  27. Каким образом можно обратиться к локальной переменной метода из анонимного класса, объявленного в теле этого метода? Есть ли каке-нибудь ограничения для такой переменной?
    По его литералу. Если переменная является final, то только в этом случае к ней можно обратиться.
  28. Какие вы знаете способы запустить некоторое действие в отдельном потоке?
    1
    2
    3
    4
    
    new Thread(new Runnable() {
            public void run() {/* blah */}
    }).start();
    			
    
    1
    2
    3
    4
    
    new Thread() {
            public void run() {/* blah */}
    }.start();
    
    

    Наследовать Thread будет верным лишь в случае создания другой имплементации потока. Для выполнения какой-нибудь задачи в отдельном потоке использование наследования будет идеологически неверным.
  29. Какие вы знаете способы прекратить выполнение потока?
    • Thread.stop(); // depreceted
    • При вызове метода interrupt(), флаг прерывания устанавливается в true, после чего в потоке должен быть реализован метод его завершения (выход из метода run()).
  30. Какие ключевые слова Java, связанные с многопоточностью Вы знаете?
    • valotile - помечает объект, чтобы он не кэшировался отдельно для каждого потока. Все запросы к переменной будут направляться непосредственно в память.
    • syhcronized.
  31. Для чего используется ключевое слово syhcronized?
    Для того, чтобы код в этом блоке выполнялся в один момент времени только одним потоком.
  32. Есть некоторый метод, который исполняет операцию i++. Переменная i типа int. Предполагается, что код будет исполнятся в многопоточной среде. Следует ли синхронизировать блок?
    Следует. Инкремент/декремент - не атомарные операции.
  33. Что служит в качестве mutex, если метод объявлен synchronized?
    Экземпляр данного класса.
  34. Можно ли вызвать в разных потоках два synchronized метода одного и того же объекта?
    Оновременно нельзя. Т.к. методы объявлены как synchronized, то одноременно оперировать с объектом может только один поток, который получил lock объекта. Поэтому: если synchronized метод выполняется в первом потоке, чтобы выполнить какой-либо synchronized метод объекта во втором потоке, второй поток будет вынужден ждать пока станет доступен lock объекта.
  35. Что используется в качестве mutex, если метод объявлен static synchronized? Можно ли создавать новые экземпляры класса, пока выполняется static synchronized метод?
    Монитор класса, который контролирует доступ ко всему синхронизированному статическому коду. Можно
  36. Объясните, что такое deadlock? Приведите пример кода, который демонстрирует deadlock
    Ситуация, когда несколько потоков находятся в состоянии бесконечного ожидания в следствии ожидания освобождения ресурсов, которые сами же и занимают.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    class Entity {
            public synchronized void method1(Entity entity) {
                    entity.method2(this);
            }
    
            public synchronized void method2(Entity entity) {}
    
            public static void main(String[] args) {
                    Entity en1 = new Entity();
                    Entity en2 = new Entity();
    
                    new Thread(new Runnable() {
                            public void run() {
                                    en1.method1(en2);
                            }
                    }).start();
    
                    new Thread(new Runnable() {
                            public void run() {
                                    en2.method1(en1);
                            }
                    }).start();
            }
    }
    
    
  37. Для чего используется ключевое слово volatile?
    Не используется кэш (имется ввиду область памети в которой JVM может сохранять локальную копию переменной, чтобы уменьшить время обращения к переменной) при обращении к полю.
  38. Для чего используется ключевое слово transient?
    Для указание того, что при сериализации/десериализации данное поле не нужно сериализовать/десериализовывать.
  39. Расскажите о методах wait, notify, notifyAll. Как они применяются, когда, зачем нужны?
    • wait() - Приводит поток в ожидание, пока другой поток не вызовит notify() или notifyAll() методы для этого объекта. При этом все эти методы должны быть вызваны в блоке synchronized.
    • notify() - просыпается одни поток, который ждет на “мониторе” данного объекта.
    • notifyAll() - просыпаются все потоки, которые ждут на “мониторе” данного объекта.
    • Эти методы должны вызываться в блоке synchronized.
      Применяются для организации работы потоков. Используется один объект, который выполняет управляющую.
      Именно у него и вызываются эти методы.
      При вызове одного из этих методов блокировка на объект снимается.
  40. Какие особенности использования метода wait? При каких условиях поток может выйти из режима ожидания?
    Так же см 39).
    • Если задан параметр/параметры, определяющий время и если поток не будет разбужен в течении этого времени при помощи методов notify() или notifyAll(), тогда он будет разбужен по прошествии указанного времени.
    • Если не задан параметр/параметры, определяющие время, то поток будет разбужен только при помощи методов notify() или notifyAll().
  41. Предположим в методе run возник RuntimeException, который не был пойман. Что случится с потоком? Есть ли способ узнать о том, что Exception произошел (не заключая все тело run в блок try-catch)? Есть ли способ восстановить работу потока после того как это произошло?
    Поток будет остановлен. Нет. Нет.
  42. Какие стандартные инструменты Java вы бы использовали для реализации пула потоков?
    LinkedList, synchronized, wait(), notify()/notifyAll()
  43. Какие виды исключений в Java вы знаете, чем они отличаются?
    checked/unchecked. Если checked исключение не отлавливается, то это приводит к ошибке на этапе компиляции. Unchecked исключение - то, которое разработчик не должен допустить, т.к. имеет для этого возможность.
    Если исключение потомок RuntimeException или Error, то это unchecked исключение. Если исключение потомок Exception (и не потомок RuntimeException), то это checked исключение.
  44. Назовите несколько классов из вершины иерархии исключений в Java.
    Throwable, Error, Exception, RuntimeException.
  45. Что такое Error? В каком случае используется Error. Приведите пример Error’а.
    Используется для сигнализирования того, что произел сбой внутри JVM. Пример класс ThreadDeath.
  46. Какая конструкция используется в Java для обработки исключений?
    try - catch - finaly
  47. Возможно ли использование блока try-finally (без catch)?
    Да, если возникающее исключение не checked или checked исключение будет передано дальше по иерархии, или если оно будет поймано в ещё одном блоке try.
  48. Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?
    Выпадает, то есть, не передается по иерархии вызовов первое исключение. И оно просто не попадет в иерархию вызовов.
  49. Всегда ли исполняется блок finally?
    Только если поток ещё исполняется и JVM ещё работает к этому моменту.
  50. Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?
    Мог бы.
    1
    2
    3
    4
    5
    6
    
    try {
            System.exit(1);
    } finaly {
            System.out.println("42");
    }
    
    
  51. Предположим, есть метод, который может выбросить IOException и FileNotFoundException в какой последовательности должны идти блоки catch? Сколько блоков catch будет выполнено?
    Вначеле FileNotFoundException затем IOException. Один.
  52. Предположим вам необходимо создать свой собственный класс Exception. Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?
    Если исключение возникло из-за того, что клиент нарушал контракт, то это unchecked exeption. Если же исключение возникло по какой-нибудь другой причине, то это checked exeption.
  53. Что такое finalize? Зачем он нужен? Что Вы можете рассказать о сборщике мусора и алгоритмах его работы.
    Метод finalize() вызывается перед тем, как объект будет удален gc. Существует много различных реализаций gc. Основа работы следующая, gc помечает объекты на которых больше не ссылаются другие объекты для их удаления. Затем на одном из проходов помеченные объекты удаляются.
    Вызов finalize() не гарантируется, т.к. приложение может быть завершено до того, как будет запущена ещё одна сборка мусора. Да, можно отменить сборку объекта с помощью метода finalize(), присвоив его ссылку какому-то статистическому мето
  54. Почему метод clone объявлен как protected? Что необходимо для реализации клонирования?
    Это сигнализирует о том, что хоть метод и есть в классе Object, но если им разработчик желает воспользоваться, то его нужно переопределить. Для этого нужно реализовать интерфейс Clonable, чтобы соблюсти контракт.