Рус Укр
Питання на співбесідах для Java розробників-початківців, частина 1

Питання на співбесідах для Java розробників-початківців, частина 1

  • 23 червня
  • читати 10 хв
Парвізджон Розіков
Парвізджон Розіков Старший експерт з технологій в Crypterium, Викладач Комп'ютерної школи Hillel.

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

https://www.w3schools.com/java/java_wrapper_classes.asp

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

https://www.azul.com/blog/what-is-java-heap-size/

https://www.javatpoint.com/java-heap

Що таке 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.

String_interning

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

Рекомендуємо публікацію по темі