JavaRush /Java блог /Java Developer /Хитрые вопросы по Java, которые часто задают на собеседов...

Хитрые вопросы по Java, которые часто задают на собеседованиях

Статья из группы Java Developer
Если вы хоть раз готовились к собеседованию на должность Java-программиста или сдавали любой экзамен (не обязательно по программированию) для получения сертификата, то, скорее всего, уже успели заметить, что вопросы, которые там задают, весьма специфичны. Многие из них заставляют подумать над архитектурой языка, некоторые рассчитаны на глубокие знания. Есть и те, что больше похожи на головоломки или касаются нюансов, которые прочувствовать без практики очень тяжело. В этой статье разработчик Саранс Синг (Saraans Singh) приводит несколько таких вопросов по Java. С ответами, разумеется. Хитрые вопросы по Java, которые часто задают на собеседованиях  - 11. Что произойдет, если поместить оператор return или System.exit () в блок try/catch? Это очень популярный вопрос "на засыпку" по Java. Хитрость его в том, что многие программисты считают, что блок finally выполнится в любом случае. Данный вопрос ставит эту концепцию под сомнение, путем помещения оператора return в блок try/catch или вызова из блока try/catch оператора System.exit (). Ответ на этот каверзный вопрос: блок finally будет выполняться при помещении оператора return в блок try/catch, и не будет выполняться при вызове из блока try/catch оператора System.exit (). 2. Поддерживает ли язык Java множественное наследование? Это очень хитрый вопрос. Интервьюеры часто говорят: если язык C++ может поддерживать непосредственное множественное наследование, то почему Java не может? Ответ несколько более сложен, чем может показаться, поскольку Java поддерживает множественное наследование типов, ведь интерфейс в нём может расширять другие интерфейсы. Но множественное наследование реализаций язык Java не поддерживает. 3. В случае, когда метод генерирует исключение NullPointerException в родительском классе, можно ли его переопределить методом, генерирующим RuntimeException? Еще один каверзный вопрос, связанный с концепциями перегрузки и переопределения. Ответ: в переопределенном методе можно спокойно генерировать родительский класс исключения NullPointerException – RuntimeException, но нельзя сделать то же самое с проверяемым исключением типа Exception. 4. Как гарантировать возможность обращения N нитей к N ресурсам без взаимной блокировки? Если вы не слишком хорошо разбираетесь в написании многопоточного кода, этот вопрос будет для вас по-настоящему каверзным. Он может оказаться непростым даже для опытного программиста, не имевшего дела с взаимными блокировками и состояниями гонки. Весь трюк тут в упорядочении: предотвратить взаимную блокировку можно благодаря освобождению ресурсов в порядке, обратном порядку их получения. 5. В чем разница между классами StringBuffer и StringBuilder в языке Java? Классический вопрос по языку Java, который некоторые разработчики считают хитрым, а другие – очень простым. Класс StringBuilder появился в JDK 1.5 и единственное отличие между ними состоит в том, что методы класса StringBuffer, например, length(), capacity() или append() синхронизированы, в то время как соответствующие методы класса StringBuilder – нет. В силу этого фундаментального отличия, конкатенация строк при помощи StringBuilder выполняется быстрее, чем с помощью StringBuffer. На самом деле, использовать StringBuffer не рекомендуется, поскольку в 99% сценариев использования, конкатенация строк производится в той же нити. 6. Что вернет выражение 1.0/0.0? Приведет ли оно к генерации исключения или ошибке при компиляции? Еще один каверзный вопрос насчет класса Double. Хотя разработчики Java знают о существовании простого типа данных double и класса Double, при выполнении операций с плавающей точкой они не уделяют достаточного внимания Double.INFINITY, NaN, -0.0 и правилам, которым подчиняются связанные с ними арифметические вычисления. Ответ на этот вопрос прост: генерации исключения ArithmeticException не произойдет, будет возвращено значение Double.INFINITY. 7. Что будет, если попытаться вставить в HashMap уже имеющийся в ней ключевой объект? Этот каверзный вопрос – часть другого часто задаваемого вопроса: как работают HashMap в языке Java? HashMap – популярная тема для запутанных и каверзных вопросов по языку Java. Ответ таков: если попытаться повторно вставить ключ в HashMap, он заменит старый, поскольку класс HashMap не допускает дублирующихся ключей. А тот же ключ означает такой же хэш-код, так что он попадет в то же место в хэш-сегменте. По материалам Quora
Комментарии (23)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Сергей Смарт Уровень 51
2 августа 2022
Есть замечания к первому и второму вопросу, поправте если я не прав. К первому: разве в вопросе прозвучало наличие finally блока? Он как может быть так может и отсутствовать, тут скорее интересно выполниться ли catch. Ко второму: псевдо-множественное наследование можно реализовать с помощью вложенных классов. Интерфейсы понятно, само-собой
hidden #2595317 Уровень 45
31 января 2022
Почитал ниже и понял, что все готовы к собеседованию на отлично.
Herman Kulik Уровень 41
10 марта 2021
с исключениями все очень просто: с непроверяемыми исключениями можно переопределять методы как только угодно (их и так никто не обрабатывает) с проверяемыми исключениями должным образом следует сохранить принципы полиморфизма. Если в каком либо классе есть блок try catch, который обрабатывает исключение родителя, то исключение в классе-наследнике должно быть либо того же типа, либо рангом ниже, чтобы тоже могло быть обработано корректно.
Pig Man Уровень 41
6 января 2021
Автору очень нравится слово "каверзный". Аж 7 раз его использовал
Taras Уровень 35
10 декабря 2020
Если кого-то интересует подготовка к собеседованию то лучший вариант перепроходить материал. Повторят его как при перепрохождении курса так и просто по памяти. Есть разные сайты с уже готовыми списками/ тестами для собеседования. Вот один из telegram @javaquiz_mentor
Soros Уровень 39
21 марта 2020

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

Ответ на этот вопрос прост: ... будет возвращено значение Double.INFINITY.
Разве в классе Double есть поле Double.INFINITY? В классе Double есть поля Double.NEGATIVE_INFINITY и Double.POZITIVE_INFINITY. Правильный ответ:

Выражение выражение 1.0/0.0 вернёт Double.POZITIVE_INFINITY.
hidden #1281202 Уровень 41
16 июля 2019
6 вопрос. Напишите в IDEA

Double.POSITIVE_INFINITY
и пока пишите, смотрите его значение в вспомагательном окошке (= 1.0 / 0.0). Именно это значение будет возвращенно, а не несуществующий "Double.INFINITY"
Даниил Уровень 41 Master
29 июня 2019
Третий вопрос меня вообще загнал в ступор. Вообще запутался что и куда. В итоге после метода тыка в IDEA пришёл к выводу: При переопределении метода можно исользовать такое же или более конкретное исключение (дочернее по отношению к объявленому исключению в методе который переопределяют)

public class Parent {
    protected Number method(Number i, Long l) throws IOException {
        return null;
    }
}

public class ChildClass1 extends Parent {
    @Override
    //так можно
    public Integer method(Number i, Long l) throws FileNotFoundException {
        return null;
    }
}

public class ChildClass2 extends Parent {
    @Override
    //так нельзя
    protected Integer method(Number i, Long l) throws Exception {
        return null;
    }
}
НО! Утверждение выше действительно только для ПРОВЕРЯЕМЫХ исключений. Для НЕ ПРОВЕРЯЕМЫХ можно в переопределённом методе указывать и родительский класс и дочерний

public class Parent {
    protected Number method(Number i, Long l) throws NullPointerException {
        return null;
    }
}

public class ChildClass extends Parent {
    @Override
    //так можно
    protected Integer method(Number i, Long l) throws RuntimeException {
        return null;
    }
}
Вот схема где наглядно видно где какие исключения. Так же напомню что при переопределении можно объявлять более конкретный тип возвращаемого значения (видно из моего примера) и более широкую область видимости (тоже видно на примере). С параметрами метода как не игрался, принимало только ровно такие же как и в оригинальной версии метода, никакой полиморфизм не проканал (если я чего-то не нашёл - буду рад узнать правду).
Артем Уровень 0
24 июня 2019
Ответ на 7 вопрос не верно раскрыт. Если в мапе появятся 2 объекта с одинаковым хэш кодом (такая ситуация называется коллизией), то эти объекты лягут в один и тот же бакет, просто при коллизии, к уже существующему объекту прикрепится (посредством ссылки) следующий объект с таким же хэш кодом. Так для примера, если хэш код у всех вставляемых в мапу объектов будет одинаковый то сложность операций с такой мапой будет как у связного списка. Одинаковость ключа выполняется методом equals(). Хэш код при сравнении ключа никак не участвует, он служит только для определение того, в какую карзину класть.
Виктор Шарыгин Уровень 40
28 января 2018
к уровню 40 все это уже будешь знать, если, естественно, будешь читать все рекомендованные дополнительные материалы :)