Главная страница

Подготовка к собеседованию по JAVACORE. Ответы на вопросы по Core. Core 1 ооп что такое ооп


Скачать 80.55 Kb.
НазваниеCore 1 ооп что такое ооп
АнкорПодготовка к собеседованию по JAVACORE
Дата13.11.2022
Размер80.55 Kb.
Формат файлаdocx
Имя файлаОтветы на вопросы по Core.docx
ТипПрограмма
#785648
страница4 из 5
1   2   3   4   5

Может ли быть абстрактный класс без абстрактных методов?
В абстрактном классе может не быть ни одного абстрактного метода.
Могут ли быть конструкторы у абстрактных классов? Для чего они нужны?

Да, в абстрактном классе в Java можно объявить и определить конструкторы. Поскольку создавать экземпляры абстрактных классов нельзя, вызвать такой конструктор можно только при формировании цепочки конструкторов, то есть при создании экземпляра конкретного класса-реализации. Но представьте, что интервьюер задаст затем вопрос: а какой смысл в конструкторе, если создать экземпляр абстрактного класса все равно нельзя? Дело в том, что его всё равно можно использовать для задания начальных значений общих переменных, объявленных в абстрактном классе и используемых различными реализациями. Даже если вы не объявили никакого конструктора, компилятор добавит в абстрактный класс конструктор по умолчанию без аргументов. Без него ваш подкласс не скомпилируется, поскольку первый оператор в любом конструкторе представляет собой неявный вызов super() – конструктора суперкласса по умолчанию в языке Java.
Что такое интерфейсы? Какие модификаторы по умолчанию имеют поля и методы интерфейсов?

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

Наличие слова interface означает, что именно так должны выглядеть все классы, которые реализуют данный интерфейс. Таким образом, любой код, использующий конкретный интерфейс, знает только то, какие методы вызываются для этого интерфейса, но не более того.

Интерфейс может содержать поля, но они автоматически являются статическими (static) и неизменными (final). Все методы и переменные неявно объявляются как public.
Чем интерфейсы отличаются от абстрактных классов? В каких случаях следует использовать абстрактный класс, а в каких интерфейс?
Интерфейс описывает только поведение. У него нет состояния. А у абстрактного класса состояние есть: он описывает и то, и другое.

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

Классы могут реализовывать сколько угодно интерфейсов, но наследоваться можно только от одного класса.
Может ли один интерфейс наследоваться от другого? От двух других?

Да может. В интерфейсе-потомке все методы прописывать не надо, т.к. наследование этого не подразумевает. Но когда какой-то класс будет реализовать интерфейс потомок, то в этом классе вы должны будете написать код реализации всех методов, которые были во всей цепочке наследования интерфейса.
Что такое дефолтные методы интерфейсов? Для чего они нужны?

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

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

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

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

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

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

Несколько блоков инициализации выполняются в порядке следования в коде класса.
Блок инициализации способен генерировать исключения, если их объявления перечислены в throws всех конструкторов класса.

Блок инициализации возможно создать и в анонимном классе.
Для чего в Java используются статические блоки инициализации?

Статические блоки инициализация используются для выполнения кода, который должен выполняться один раз при инициализации класса загрузчиком классов, в момент, предшествующий созданию объектов этого класса при помощи конструктора. Такой блок (в отличие от нестатических, принадлежащих конкретном объекту класса) принадлежит только самому классу (объекту метакласса Class).
Что произойдет, если в блоке инициализации возникнет исключительная ситуация?
Для нестатических блоков инициализации, если выбрасывание исключения прописано явным образом требуется, чтобы объявления этих исключений были перечислены в throws всех конструкторов класса. Иначе будет ошибка компиляции. Для статического блока выбрасывание исключения в явном виде, приводит к ошибке компиляции.

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

для статических блоков инициализации будет выброшено java.lang.ExceptionInInitializerError;

для нестатических будет проброшено исключение-источник.

Если возникшее исключение - наследник Error, то в обоих случаях будет выброшено java.lang.Error. Исключение: java.lang.ThreadDeath - смерть потока. В этом случае никакое исключение выброшено не будет.
Что такое класс Object?
Object это базовый класс для всех остальных объектов в Java. Любой класс наследуется от Object и, соответственно, наследуют его методы.
Какие методы есть у класса Object (перечислить все)? Что они делают?
public boolean equals(Object obj) – служит для сравнения объектов по значению;
int hashCode() – возвращает hash код для объекта;
String toString() – возвращает строковое представление объекта;
Class getClass() – возвращает класс объекта во время выполнения;
protected Object clone() – создает и возвращает копию объекта;
void notify() – возобновляет поток, ожидающий монитор;
void notifyAll() – возобновляет все потоки, ожидающие монитор;
void wait() – остановка вызвавшего метод потока до момента пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;
void wait(long timeout) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;
void wait(long timeout, int nanos) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;
protected void finalize() – может вызываться сборщиком мусора в момент удаления объекта при сборке мусора.
Расскажите про equals и hashcode

Методы equals и hashCode тесно связаны друг с другом, и что оба этих метода желательно переопределять в своих классах согласованно.

Метод equals() необходим в Java для подтверждения или отрицания того факта, что два объекта одного происхождения являются логически равными. То есть, сравнивая два объекта, программисту необходимо понять, эквивалентны ли их значимые поля. Не обязательно все поля должны быть идентичны, так как метод equals() подразумевает именно логическое равенство.
Хэш — это некоторое число, генерируемое на основе объекта и описывающее его состояние в какой-то момент времени. Это число используется в Java преимущественно в хэш-таблицах, таких как HashMap. При этом хэш-функция получения числа на основе объекта должна быть реализована таким образом, чтобы обеспечить относительно равномерное распределение элементов по хэш-таблице. А также минимизировать вероятность появления коллизий, когда по разным ключам функция вернет одинаковое значение.
Каким образом реализованы методы hashCode() и equals() в классе Object?
Реализация метода Object.equals() сводится к проверке на равенство двух ссылок.
Реализация метода Object.hashCode() описана как native, т.е. определенной не с помощью Java кода и обычно возвращает адрес объекта в памяти.
Зачем нужен equals(). Чем он отличается от операции ==?

Метод equals() - определяет отношение эквивалентности объектов.
При сравнении объектов с помощью == сравнение происходит лишь между ссылками. При сравнении по переопределённому разработчиком equals() - по внутреннему состоянию объектов.
Правила переопределения equals()

Использование оператора == для проверки, является ли аргумент ссылкой на указанный объект. Если является, возвращается true. Если сравниваемый объект == null, должно вернуться false.
Использование оператор instanceof и вызова метода getClass() для проверки, имеет ли аргумент правильный тип. Если не имеет, возвращается false.
Приведение аргумента к правильному типу. Поскольку эта операция следует за проверкой instanceof она гарантированно будет выполнена.
Обход всех значимых полей класса и проверка того, что значение поля в текущем объекте и значение того же поля в проверяемом на эквивалентность аргументе соответствуют друг другу. Если проверки для всех полей прошли успешно, возвращается результат true, в противном случае - false.


Что будет, если переопределить equals() не переопределяя hashCode()? Какие могут возникнуть проблемы?

Классы и методы, которые используют правила этого контракта могут работать некорректно. Так для HashMap это может привести к тому, что пара «ключ-значение», которая была в неё помещена при использовании нового экземпляра ключа не будет в ней найдена.

Какой контракт между hashCode() и equals()?

Если equals дает true, то и hashCode должны быть одинаковы.
Но если хеш коды одинаковы, то equals не обязательно должен быть true.
Контракт equals
При переопределении метода equals разработчик должен придерживаться основных правил, определенных в спецификации языка Java.
- Рефлексивность
для любого заданного значения x, выражение x.equals(x) должно возвращать true.

Заданного — имеется в виду такого, что x != null
- Симметричность
для любых заданных значений x и y, x.equals(y) должно возвращать true только в том случае, когда y.equals(x) возвращает true.
- Транзитивность
для любых заданных значений x, y и z, если x.equals(y) возвращает true и y.equals(z) возвращает true, x.equals(z) должно вернуть значение true.
- Согласованность
для любых заданных значений x и y повторный вызов x.equals(y) будет возвращать значение предыдущего вызова этого метода при условии, что поля, используемые для сравнения этих двух объектов, не изменялись между вызовами.
- Сравнение null
для любого заданного значения x вызов x.equals(null) должен возвращать false.

Для чего нужен метод hashCode()?

Метод hashCode() необходим для вычисления хэш кода переданного в качестве входного параметра объекта. В Java это целое число, в более широком смыле - битовая строка фиксированной длины, полученная из массива произвольной длины. Этот метод реализован таким образом, что для одного и того же входного объекта, хэш код всегда будет одинаковым. Следует понимать, что в Java множество возможных хэш кодов ограничено типом int, а множество объектов ничем не ограничено. Из-за этого, вполне возможна ситуация, что хэш коды разных объектов могут совпасть:
- если хэш коды разные, то и объекты гарантированно разные;
- если хэш коды равны, то объекты могут не обязательно равны.

Правила переопределения метода hashcode()

хэш-функция получения числа на основе объекта должна быть реализована таким образом, чтобы обеспечить относительно равномерное распределение элементов по хэш-таблице. А также минимизировать вероятность появления коллизий, когда по разным ключам функция вернет одинаковое значение.
Контракт hashCode
Для реализации хэш-функции в спецификации языка определены следующие правила:
- вызов метода hashCode один и более раз над одним и тем же объектом должен возвращать одно и то же хэш-значение, при условии что поля объекта, участвующие в вычислении значения, не изменялись.
- вызов метода hashCode над двумя объектами должен всегда возвращать одно и то же число, если эти объекты равны (вызов метода equals для этих объектов возвращает true).
- вызов метода hashCode над двумя неравными между собой объектами должен возвращать разные хэш-значения. Хотя это требование и не является обязательным, следует учитывать, что его выполнение положительно повлияет на производительность работы хэш-таблиц.
Есть ли какие-либо рекомендации о том, какие поля следует использовать при подсчете hashCode()?

Вызов метода hashCode один и более раз над одним и тем же объектом должен возвращать одно и то же хэш-значение, при условии что поля объекта, участвующие в вычислении значения, не изменялись.
При подсчете хеш-кода необходимо использовать уникальные, лучше примитивные поля, такие как id или uuid. Причем, если эти поля задействованы при вычислении hashCode, их задействовать и при выполнении equals. Более общий совет: выбирать поля, которые с большой долью вероятности будут различаться. Хеш-код должен быть равномерно распределен на области возможных принимаемых значений.
Если у объекта, который используется в качестве ключа в hashMap изменится поле, которое участвует в определении хеш-кода, то могут возникнуть проблемы с поиском значения по ключу.
Могут ли у разных объектов быть одинаковые hashCode()?

Да, могут. Метод hashCode() не гарантирует уникальность возвращаемого значения. Ситуация, когда у разных объектов одинаковые хэш коды называется коллизией. Вероятность возникновения коллизии зависит от используемого алгоритма генерации хэш кода.
Почему нельзя реализовать hashcode() который будет гарантированно
уникальным для каждого объекта?

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

Даже если хэш-код по умолчанию может быть основан на внутреннем адресе объекта, он не идентичен внутреннему адресу.
Чем a.getClass().equals(A.class) отличается от a instanceOf A.class

this.getClass() == that.getClass() проверяет два класса на идентичность, поэтому для корректной реализации контракта метода equals() необходимо использовать точное сравнение с помощью метода getClass().

Используя оператор instanceof, можно узнать, от какого класса произошел объект. Этот оператор имеет два аргумента. Слева указывается ссылка на объект, а справа — имя типа, на совместимость с которым проверяется объект.
Исключения

Что такое исключения?

Исключения представляют собой объекты, которые позволяют обработать исключительную ситуацию. Исключительная ситуация— это ошибка, происходящая во время выполнения программы (так называемая ошибка времени выполнения).
Исключительные ситуации можно обрабатывать с помощью блока try/catch/finally.

- Рассмотрим, как он работает. В блок try помещается код, в котором может содержаться исключительная ситуация. Он работает либо до возникновения исключительной ситуации, либо при успешном выполнении до конца блока try.

- В блоке catch выполняются некие операции при возникновении исключительной ситуации определенного типа (в параметрах блока — в круглых скобках — указывается тип возможного исключения — т.е. класс, который обрабатывает исключительную ситуацию).
Блок catch может делать все, что угодно: вызывать необходимый класс-исключение при помощи создания его объектов с использованием ключевого слова throw (это фактически искусственная передача выполнения нужному нам блоку catch), а может и сам производить какие-либо действия.
В блоке finally выполняются определенные восстановительные операции. Он обычно предназначен для освобождения памяти, выделенной под объект. Восстановительные операции будут выполняться независимо от того, возникло исключение (теперь мы будем именно так называть исключительные ситуации) в блоке try или нет.
Блок finally может отсутствовать.

Конструкция try/catch/finally может быть вложенной.

Опишите иерархию исключений.

Исключения делятся на несколько классов, но все они имеют общего предка — класс Throwable, потомками которого являются классы Exception и Error.
Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память доступная виртуальной машине.
Исключения (Exceptions) являются результатом проблем в программе, которые в принципе решаемы, предсказуемы и последствия которых возможно устранить внутри программы. Например, произошло деление целого числа на ноль.

1   2   3   4   5


написать администратору сайта