Junior Java Developer – вопросы на собеседовании
ITVDN: курсы программирования
Видеокурсы по
программированию

Выбери свою IT специальность

Начать бесплатно
ITVDN logo
Видеокурсы по
программированию

Выбери свою IT специальность

Начать бесплатно

В этой статье мы рассмотрим 25 наиболее часто встречающихся вопросов на интервью для новичков в программировании на Java. Все это реальные вопросы на собеседовании Java Junior Developer.

 

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


Нет, статический метод в Java мы не можем переопределить. Мы можем только скрыть его.

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



Статический метод в Java не может быть переопределен по таким причинам:

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


Когда вы запустите программу выше, вы получите следующий результат:

Hello...Good morning
Hello...Good morning
Hello...everyone

Согласно правилам переопределения методов, вызов метода разрешается во время выполнения по типу object. Таким образом, в нашем примере выше d.hello (), во втором вызове, должен вызывать метод hello () класса DisplayMessage, поскольку ссылочная переменная класса Display ссылается на объект DisplayMessage, но вызывает hello () самого класса Display. Это происходит потому, что выполнение статического метода разрешается во время компиляции.

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



Можно ли выполнить перегрузку метода main() в Java?

Достаточно распространенный по языку Java вопрос на интервью.

Да, вы можете перегрузить метод main() в Java.

В Java можно выполнить перегрузку метода main(), но когда мы запустим нашу программу, JVM будет искать общедоступный статический void main (String [] args) и выполнит этот метод.

Перегрузка метода main() в Java:

Когда вы запустите программу выше, вы получите такой результат:

Inside main(String[] args)

Видно, что метод main() у нас перегружен, но все же JVM вызывает метод с подписью public static void main (String [] args).

Обратите внимание, что JVM считает var args public static void main (String... args) таким же, как public static void main (String [] args).

Если мы хотим вызвать именно перегруженный метод, то вам нужно вызвать его из метода main с сигнатурой public static void main (String [] args).

Например:


Когда вы запустите программу выше, вы получите такой результат:

Inside main(String[] args)
Inside main(Integer args)
Inside main(Integer arr)

Как видите, мы вызвали перегруженные методы из main() с помощью аргумента String [].



Можем ли мы в Java переопределить приватные методы?

В Java мы не можем переопределить private методы, так как они видны только классу-владельцу.



Каков базовый класс для всех классов в Java?

java.lang.Object - это базовый класс для всех объектов.



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

Среди важных методов класса object выделяют:

  • hashcode - в качестве возвращаемого значения имеет хеш-значение объекта;
  • equals - сравнивает ссылки на объекты;
  • wait -  текущий поток ожидает, пока не будет вызвано notify или notifyAll;
  • notify - пробуждает один поток, который ожидает блокировки;
  • notifyAll - пробуждает все потоки, ожидающие блокировки;
  • toString - обеспечивает представление объекта в виде строкового значения;
  • clone - этот метод применяется для клонирования объекта;
  • finalize - этот метод вызывается, когда объект подвергается обработке сборщиком мусора.



Какие два метода вам нужно переопределить при помещении пользовательского объекта в качестве ключа для HashMap?

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

 

В чем отличия в Java между HashMap и HashSet?

HashMap

В HashMap реализован интерфейс Map, который выполняет сопоставление некого ключа со значением. Он не синхронизирован и не является потокобезопасным. Не допускаются дублирующиеся ключи, а также null ключи и null значения.

HashSet

В HashSet реализован интерфейс Set, не допускающий дублирования значений. Он не синхронизирован и не является потокобезопасным.



Выше employeeSet будет иметь 2 элемента, так как Set не допускает повторяющихся значений.
Метод add применяется для добавления элементов в HashSet. Если этот метод возвращает true, тогда элемент добавляется успешно, но, если возвращается false – это значит, что вы пытаетесь вставить дублирующее значение.

public boolean add(Object o)


Одна из главных особенностей HashSet - объекты, которые мы собираемся добавить в HashSet, должны реализовывать методы Hashcode() и equals(), чтобы мы могли проверять наличие дублирующихся значений. Если мы добавляем пользовательские объекты в HashSet, то мы должны переопределить методы Hashcode() и equals() в соответствии с нашими потребностями. Если HashMap и HashSet не будут переопределены, объект будет принимать реализацию по умолчанию, что может быть нежелательно.

HashMap vs HashSet:

 

Можем ли мы иметь абстрактный класс без какого-либо абстрактного метода в нем?


Да, вы можете иметь абстрактный класс без создания какого-либо абстрактного метода.

 

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


Переменные с модификатором transient (нерезидент) применяются при сериализации.

Если вы не хотите делать сериализуемую переменную, вы можете сделать ее переменной с модификатором transient.

Transient переменная - это переменная, значение которой не будет сериализоваться во время сериализации объекта. А при десериализации - вы получите значение по умолчанию для этих переменных.


Допустим, у вас есть класс Country, и вы не хотите сериализовать атрибут населения, поскольку он будет меняться со временем, поэтому вы можете объявить атрибут населения как transient, и он больше не будет сериализован.

 

Можете ли вы вызвать метод start() дважды в Java?

Нет, вы не можете вызвать метод start() дважды. Это вызовет llegalStateException.

После того как поток был запущен, он не может быть запущен снова. Если вы попытаетесь снова запустить поток, он выдаст исключение IllegalThreadStateException

Давайте разберемся с помощью примера:

Когда вы запустите программу выше, вы получите такой результат:

Thread is runningException in thread "main"
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:705)
at org.arpit.java2blog.StartThreadAgainMain.main(StartThreadAgainMain.java:16)

Как вы можете видеть, когда мы пытались запустить поток во второй раз, он вызывал исключение IllegalThreadStateException.

Если вы попытаетесь снова запустить поток, он выдаст исключение IllegalThreadStateException

 

Почему String неизменяемый (immutable) в Java?

В Java класс String неизменяемый. Если вы возьмете словарное значение слова «immutable», это означает, что он не может быть изменен с течением времени, соответственно строка не может быть изменена в Java.


Давайте разберемся с примером.

Как видите, значение str1 не изменилось. Она создала другой объект String со значением «Hellojava2blog», но не изменил String str1.

Это объясняет, что String является неизменяемым по своей природе.
Теперь давайте разберемся, каковы потенциальные причины сделать String неизменной в Java.

Пул строк:


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

Потокобезопасность:


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

Безопасность:


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

Хэш-значение кэша:


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

Загрузка классов:


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

 

Знаете ли вы, как сделать класс неизменным (immutable)? Можете ли вы предоставить шаги для этого?

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


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

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

Неизменяемые объекты по умолчанию являются потокобезопасными.

Шаги для создания неизменяемого класса:

  • Финализируйте свой класс:

Если вы финализируете свой класс - ни один класс не сможет его расширить, следовательно, не сможет переопределить методы этого класса.

  • Пометьте все переменные класса модификаторами доступа private и final:

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

  • Скажите «нет» методам-мутаторам:

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

  • Выполните клонирование изменяемых объектов при возврате из метода получения:

Если вы вернете клон объекта из метода get, то вернется объект. При этом, ваш оригинальный объект останется без изменений.

 

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

Да, у нас может быть статический метод в интерфейсе из Java 8.

 

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

Нет, вы не можете объявить конструктор финальным.

 

 

В чем разница между StringBuffer и StringBuilder?

Что такое Java ClassPath?


ClassPath - это переменная окружения, которую виртуальная машина Java (JVM) использует для определения местоположения всех классов, используемых программой.
Например: jre / lib / rt.jar имеет все классы Java, и вам также необходимо включить файлы jar или файл классов, которые используются программой.

 

У вас есть список пользовательских объектов? Как вы можете их отсортировать?


Вам необходимо использовать интерфейс Comparable или Comparator для сортировки списка пользовательских объектов.

 

Что такое модификатор volatile в Java?


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

 

Назовите два разных способа вызвать сборщик мусора?

System.gc() или Runtime.getRuntime().gc().

 

Что такое маркерный интерфейс в Java? Можете ли вы привести несколько примеров маркерного интерфейса?


Маркерные интерфейсы - это те интерфейсы, которые не содержат в себе никаких методов и полей.
Примерами интерфейсов маркеров являются: Serializable, Cloneable, Remote.

 

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

String str1= new String("John");
String str2= new String("John");

 

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

 

Можете ли вы провести различие между проверяемым исключением (Checked Exception) и непроверяемым исключением (Unchecked Exceptions)?

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

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


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

Проверяемые исключения - это те исключения, которые проверяются при компиляции. Если вы не обработаете их, вы получите ошибку компиляции.

Используя блок try и catch вы можете поместить код ошибки в блок try и перехватить исключение в блоке catch.

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


Непроверяемые исключения - это те исключения, которые не проверяются во время компиляции. Java VM не будет «ругаться», если вы не обработаете такие исключения.

Если вы выполните код выше вы получите:

Exception in thread "main" java.lang.NullPointerException
at org.arpit.java2blog.NullPointerExceptionExample.main(NullPointerExceptionExample.java:7)

 

В чем разница между ArrayList и LinkedList? Как вы решите, какой из них вам нужно использовать?

Один из распространенных вопросов интервью: «В чем разница между ArrayList и LinkedList». Прежде чем мы действительно увидим различия, давайте кратко рассмотрим оба.

ArrayList:

  • ArrayList – является реализацией интерфейса List.
  • ArrayList не синхронизирован (поэтому не является потокобезопасным).
  • ArrayList реализован с использованием массива в качестве внутренней структуры данных. Его можно динамически изменять.

LinkedList:

  • LinkedList является реализацией интерфейса List и интерфейса Deque.
  • LinkedList не синхронизируется.
  • LinkedList реализован с использованием двусвязного списка в качестве внутренней структуры данных.

 

Свойство

ArrayList

LinkedList

Внутренняя структура данных

Использует динамический массив для хранения элементов внутри.

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

Скорость выполнения

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

Если нам нужно вставить или удалить элемент в связанном списке, это займет O(1), так как он внутренне использует двусвязный список.

Поиск

В ArrayList поиск выполняется быстрее, т.к. он использует массив, основанный на индексах. Сложность - O(1).

Поиск в LinkedList идет медленнее, т.к. он использует двусвязанный список. Сложность равна O(n).

Интерфейсы

ArrayList реализует только интерфейс List, поэтому его можно использовать только как List.

LinkedList реализует интерфейсы List, Deque, поэтому его можно использовать как List, Stack или Queue.

Когда использовать ArrayList и LinkedList?

Это на самом деле зависит от нашей потребности.
Если нам требуется произвести большое количество вставок или удалений, то нам следует использовать LinkedList. Если у нас имеется мало вставок или удалений, но выполняется много поисковых операций, то тогда нам следует использовать ArrayList.

 

В чем разница между wait и sleep в Java?

Один из распространенных вопросов на интервью Java разработчика: «В чем разница между wait и sleep в Java?». Прежде чем мы действительно увидим различия, кратко ознакомимся с обоими.
 

 

sleep vs wait:

 

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

Вы можете использовать Java Thread Join() для достижения этого сценария.

Без использования метода Join:

 

 

Когда вы запускаете программу выше, вы получите следующий результат:

Main thread ends here
T2 in run method
T1 in run method
T3 in run method

С помощью метода Join:

Когда вы запустите программу выше, вы получите следующий результат:

T2 in run method
T3 in run method
T1 in run method
Main thread ends here

Как видите, основной поток завершается последним в этом сценарии.

 

 

Итоги

Мы с вами рассмотрели 25 распространенных вопросов на собеседовании на должность Junior Java Developer. 

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

С нашей стороны, ITVDN.com предлагает комплексную программу подготовки Java разработчика, включающую в себя видео курсы по Java и сопутствующим технологиям. 

Рекомендуем вам также ознакомиться с серией видео «Подготовка к собеседованию в IT компании. Вопросы и ответы. Хитрости. Трюки.»

 

По материалам статьи.

КОММЕНТАРИИ И ОБСУЖДЕНИЯ
СТАТЬИ ПО СХОЖЕЙ ТЕМАТИКЕ
ВИДЕО КУРСЫ ПО СХОЖЕЙ ТЕМАТИКЕ

Стань профессионалом, используя все возможности обучения на ITVDN

Стартовый
подписка

Все видео курсы на 3 месяца за 49.99 $

0
Базовый
подписка

Все видео курсы на 6 месяцев за 89.99 $

1
Премиум
подписка

Все видео курсы на 12 месяцев за 169.99 $

2
Notification success