- 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?
Хочу поділитися найбільш поширеними питаннями на співбесідах для 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 існують 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