- 1.Вступление
- 2.Что такое JVM, JDK, JRE?
- 3.Базовые типы данных в Java
- 4.Примитивы и их обертки (boxing и unboxing)
- 5.Class vs Object
- 6.Методы класса Object
- 7.Сравнение по == и по equals
- 8.В чем разница между кучей (heap) и стековой (stack) памятью в Java?
- 9.Что такое immutable object?
- 10.String. Какие способы создания объекта String? Что такое строковый пул?
- 11.Какая разница между String, StringBuilder и StringBuffer?
Хочу поделиться часто задаваемыми вопросами на собеседованиях для Junior Java Developer. Что нужно знать, чтобы успешно их проходить?
Подготовку к собеседованию Java начнем с Java Core.
Что такое JVM, JDK, JRE?
JVM ( виртуальная машина Java) — это механизм, который обеспечивает среду выполнения Java (байт)кода.
Под каждую операционную систему есть своя реализация JVM, но все они соблюдают одну спецификацию (спека под jvm8), т. е. байткод, который мы получили после компиляции нашего кода, мы можем запустить на любой операционной системе, где есть JVM. Write once, run anywhere. JVM идет в составе JRE и устанавливается также в составе JRE.
JRE (Java Runtime Environment) — это минимальная реализация JVM и набор стандартных библиотек, необходимый для исполнения Java приложений. Для запуска Java программ надо установить JRE.
JDK (Java Development Kit) — набор инструментов для разработки на языке JAVA и JRE.
https://www.javatpoint.com/difference-between-jdk-jre-and-jvm
А вот о том, как стать джава программистом, рассказываем на курсах Java.
Базовые типы данных в Java
В языке Java существуют 8 примитивных и 1 ссылочный типы данных.
Примитивные типы — byte, short, int, long, float, double, boolean, char.
Ссылочный тип — любой инстанцируемый класс, а также массивы.
http://pages.cs.wisc.edu/~bahls/cs302/PrimitiveVsReference.html
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Рекомендуем курс по теме
Примитивы и их обертки (boxing и unboxing)
Классы-обертки преобразуют примитивы Java в ссылочные типы (объекты). Каждому примитивному типу данных посвящен класс. Они известны как классы-обертки, потому что они «оборачивают» примитивный тип данных в объект этого класса. Boxing — это процесс создания из примитива в объект-обертку, например int -> Integer, unboxing — обратный процесс
Есть три причины, по которым вы можете использовать объект Number, а не примитив:
В качестве аргумента метода, ожидающего объект (часто используется при работе с коллекциями чисел).
Использовать константы, определенные классом, такие как MIN_VALUE и MAX_VALUE, которые обеспечивают верхнюю и нижнюю границы типа данных.
Использовать методы класса для преобразования значений в другие примитивные типы и обратно, для преобразования в строки и из строк, а также для преобразования между системами счисления (десятичной, восьмеричной, шестнадцатеричной, двоичной).
https://docs.oracle.com/javase/tutorial/java/data/numberclasses.html
https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
Class vs Object
Class (класс) — это метаинформация или чертеж (blueprint), из которого создаются объекты. Он представляет собой набор свойств или методов, общих для всех объектов одного типа.
Object (Объект) — это экземпляр класса. Это базовая единица объектно-ориентированного программирования, представляющая реальные сущности. Каждое создание объекта требуется памяти.
https://docs.oracle.com/javase/tutorial/java/javaOO/classes.html
https://docs.oracle.com/javase/tutorial/java/javaOO/objects.html
https://www.w3schools.in/java-questions-answers/difference-between-classes-objects/
Методы класса Object
Object clone() — создает и возвращает точную копию (клон) этого объекта.
boolean equals(Object obj) — сравнивает на равенство c obj объектом.
void finalize() — это функция вызывается сборщиком мусора для объекта, когда сборщик мусора определяет, что на этот объект больше нет ссылок. С Java 9 является deprecated.
Class getClass() — возвращает класс Class для этого объекта.
int hashCode() — возвращает хешкод для этого объекта.
void notify — пробуждает единственный поток, ожидающий на мониторе этого объекта.
void notifyAll — пробуждает все потоки, ожидающие на мониторе этого объекта.
String toString() — возвращает строковое представления объекта.
void wait() — заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта.
void wait(long timeout) — заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта или по истечению указанного количества времени.
void wait(long timeout, int nanos) — заставляет текущий поток ждать, пока другой поток не вызовет метод notify() или метод notifyAll() для этого объекта или по истечению указанного количества времени.
Также могут спросить про контракт equals и hashCode. Рассмотрим это более подробно в блоке Java Collections.
https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html
Сравнение по == и по equals
Сравнение по «==» — сравнение по ссылкам.
Сравнение по «equals» — если переопределен equals, то это сравнение эквивалентности объектов по их полям, если нет — по ссылкам на объекты.
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)
В чем разница между кучей (heap) и стековой (stack) памятью в Java?
Stack — стековая память используется для хранения элементов с очень коротким сроком службы, таких как локальные переменные, ссылки на объекты, выделяемое каждому потоку во время исполнения. Стековая память находится в физическом (виртуальном) пространстве (RAM). Память под стек живет до возврата функции.
JVM создает отдельный стек для каждого потока, и все, что было создано в рамках одного потока, не видно другим потокам.
Для увеличения размера стека используется ключ -XSS.
При переполнении стека JVM бросает java.lang.StackOverFlowError.
Heap — память кучи выделяется для хранения объектов и классов. Куча создается во время старта JVM и живет до тех пор, пока жив JVM. Всякий раз, когда мы создаем объекты, он занимает место в памяти кучи, в то время как ссылка на этот объект создается в стеке. Для автоматического управления памятью Java предоставляет сборщик мусора, который удаляет объекты, которые больше не используются в куче (heap). Все, что создается в куче (heap), видно всем потокам, и другие потоки могут использовать, если есть ссылка на эти объекты.
Для увеличения размера кучи (heap) используются ключи Xms and -Xmx.
При переполнении кучи(heap) JVM бросает java.lang.OutOfMemoryError.
Стек и куча находятся в физическом (виртуальном) пространстве.
https://www.javatpoint.com/stack-vs-heap-java
Что такое immutable object?
Это объект, внутреннее состояние которого не меняется после того, как он был создан. API такого объекта представляет методы только для чтения.
Неизменяемые объекты особенно полезны в параллельных приложениях. Поскольку они не могут изменить состояние, они не могут быть повреждены вмешательством потоков или наблюдаться в несогласованном состоянии.
В Java все классы-обертки (Integer, Long, Boolean, Show и тд) и String являются immutable object.
https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
String. Какие способы создания объекта String? Что такое строковый пул?
В Java строки — это объект, представляющий последовательность символов или значений типа данных char. Класс java.lang.String используется для создания строкового объекта Java.
Есть два способа создания объекта String:
Используя строковые литералы — String s = “Hello world”
Используя ключевое слово new — String s = new(“Hello world”)
Первое создается в String pools, в второе в куче (heap).
Пул строк (String pool) — это область хранения в куче Java. Оно было придумано, потому что класс String является immutable, и каждое изменение объекта этого класса порождает новый объект. Каждый раз, когда создается строковый литерал, JVM сначала проверяет пул строковых литералов, если строка уже существует в пуле строк, возвращается ссылка на экземпляр в пуле строк, если строка не существует в пуле, новый объект String инициализируется и помещается в пул и отдается ссылка.
Так же есть метод intern, который позволяет записать строку, которая была создана оператором new в String pools.
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Какая разница между String, StringBuilder и StringBuffer?
Java предоставляет три класса для представления строки: String, StringBuffer и StringBuilder. Класс String является неизменяемым классом, тогда как классы StringBuffer и StringBuilder являются изменяемыми.
StringBuffer синхронизирован, то есть потокобезопасен. Это означает, что два потока не могут одновременно вызывать методы StringBuffer. Но за счет этой синхронизации он менее эффективен, чем StringBuilder который не потокобезопасный.
Все три класса реализуют интерфейс CharSequence.
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html
https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html
https://docs.oracle.com/javase/8/docs/api/java/lang/CharSequence.html