-
Є чудова стаття з топом запитань та відповідей для них. Деякі питання перетинаються з поданим вище списком (250+), тому ці питання пропускатимуться, щоб не дублювати зайвий раз інформацію.
-
Питання представлені українською, але оскільки більшість учасників JavaRush російськомовні (та й я більшою мірою теж), відповіді будуть російською.
-
Відповіді будуть короткими, оскільки якщо розписувати дуже докладно, відповіді деякі питання можуть потягнути окрему статтю. Та й на співбесідах настільки докладні та об'ємні відповіді не потрібні, адже у вас вашого інтерв'юера є лише година на те, щоб опитати вас за необхідними темами (а, як ви пам'ятаєте, тим вистачить). Для любителів покопати глибше я залишатиму посилання.
Питання та відповіді рівня Junior
Загальні питання
1. Які знаєте шаблони проектування? Розкажіть про два шаблони, які використовували у роботі.
Шаблонів є безліч: почати знайомство з ними можна з цієї статті. Ну а для тих із вас, хто хоче докладно ознайомитися з ними, рекомендую прочитати книгу Head First. Паттерни проектування” . З її допомогою ви зможете детально і в легкій формі вивчити базові патерни проектування. Говорячи про шаблони проектування, які ви можете навести як приклади на співбесіді, на думку приходять:- Builder - шаблон, що часто використовується, альтернатива класичному створенню об'єктів;
- Патерн Стратегія , який за своєю суттю представляє поліморфізм. Тобто, у нас є один інтерфейс, але поведінка програми змінюватиметься в залежності від того, яку саме реалізацію цього інтерфейсу передали у функціонал (зараз стратегія практично скрізь використовується в java-додатках).
- Factory - в ApplicationContext (ну або в BeanFactory);
- Singleton - всі біни за промовчанням синглтони;
- Proxy - по суті все в спрингу так чи інакше використовує цей патерн, наприклад АОП;
- Chain of responsibility - патерн, за концепцією якого працює Spring Security;
- Template - використовується в Spring Jdbc.
Java Core
2. Які типи даних є в Java?
Java має примітивні типи даних:- byte - цілі числа в межах -128 до 127, важить 1 байт;
- short - цілі числа в межах -32768 до 32767, важить 2 байти;
- int - цілі числа -2147483648 до 2147483647, важить 4 байти;
- long - цілі числа в межах 9223372036854775808 до 9223372036854775807, важить 8 байтів;
- float - числа з плаваючою комою в межах -3.4E+38 до 3.4E+38, важить 4 байти;
- double – числа з плаваючою комою в межах -1.7E+308 до 1.7E+308, важить 8 байтів;
- char - одиночні символи в UTF-16, важить 2 байти;
- boolean значення true/false , важить 1 байт.
3. Чим об'єкт відрізняється від примітивних типів даних?
Перша відмінність: кількість пам'яті, що займається: примітиви займають дуже мало, адже вони містять лише власне значення, тоді як об'єкти можуть містити дуже і дуже багато різних значень: як примітивів, так і посилань на інші об'єкти. Друга відмінність: Java це об'єктно-орієнтована мова, тому в ній все працює через взаємодію між об'єктами, і примітиви тут не сильно вписуються (власне, тому Java - це не 100% об'єктно-орієнтована мова). Третє, що з другого: оскільки Java орієнтована взаємодія між об'єктами, в цих об'єктів є багато різних механізмів управління. Наприклад, конструктори, методи, винятки (які працюють у першу чергу з об'єктами) тощо. Власне, щоб примітиви могли якось вплутатися (працювати) у цьому об'єктно орієнтованому середовищі та були придуманіобгортки (wrappers) для примітивних типів ( Integer , Character , Double , Boolean ...)4. Чим відрізняються передача параметрів за посиланням та значенням?
Примітивні поля зберігають своє значення: наприклад, якщо ми задали int i = 9; поле i зберігає значення 9 . Коли ми маємо посилання на об'єкт, це означає, що ми маємо поле з посиланням на об'єкт, або іншими словами - зі значенням адресаи об'єкта в пам'яті.Cat cat = new Cat();
Виходить, поля з посиланням на об'єкт теж зберігають значення , значення адресаи пам'яті. Тобто cat зберігає значення адресаи об'єкта new Cat() у пам'яті. Коли ми передаємо параметр у певний метод, відбувається копіювання його значення. У випадку з примітивом копіюватиметься значення примітиву. Відповідно, у методі вестиметься робота з копією, при зміні якої оригінал не торкнеться. У випадку з типом посилань копіюватиметься значення адресаи пам'яті, відповідно, адресаа буде все тим же, як і об'єкт, на який він вказує. І якщо ми будемо змінювати об'єкт за цим новим посиланням, він буде змінений і для старої (адже вони обидві вказують на той самий об'єкт).
5. Що таке JVM, JDK, JRE?
JVM - Java Virtual Machine - це віртуальна машина, яка запускає Java байткод, попередньо створений компілятором. JRE - Java Runtime Environment - по суті, це середовище для запуску java-додатків, що містить JVM , стандартні бібліотеки та інші компоненти для запуску аплетів та додатків, написаних мовою програмування Java. Тобто JRE - пакет всього необхідного для запуску скомпільованої Java-програми, але при цьому не містить інструментів і утиліт, таких як компілятори або відладчики для розробки додатків. JDK - Java Development Kit - розширений набір JREтобто середовище не тільки для запуску, але і для розробки java-додатків. JDK містить все, що є в JRE, плюс різні додаткові інструменти - компілятори та відладчики, які потрібні для створення програм на Java (також містить java-доки).6. Навіщо використовують JVM?
Як говорилося вище, Java Virtual Machine - це віртуальна машина, яка запускає Java байткод, попередньо створений компілятором. Тобто JVM не розуміє вихідний код Java. Тому спершу відбувається компіляція .java файлів, які після компіляції мають розширення вже .classі які і які представлені у вигляді того самого байта коду, який розуміє JVM. JVM для кожної OC своя, тому отримавши файли в байт коді, JVM виконує його, адаптуючи під ОС, де це відбувається. Власне, через різні JVM версії JDK (або JRE) відрізняються для різних ОС (під кожну з них потрібна своя JVM). Згадаймо, як відбувається розробка іншими мовами програмування. Ви розробляєте програму, потім її код компілюється в машинний код конкретної ОС, і потім ви можете його запускати. Іншими словами, під кожну систему потрібно писати різні версії програми. У той час як на Java завдяки подвійній обробці коду (компіляція і обробка байт коду JVM), ви можете користуватися перевагами кросплатформенності. Ми створабо код, перекомпілювали його в байткод, перенесли його на будь-яку ОС, і вже місцева JVM і запускає код. Це і є легендарна властивість Java.пишеш одного разу, запускаєш де завгодно . Докладніше про це - у статті " Компіляція та виконання Java-додатків під капотом ".7. Що таке bytecode?
Як і говорив вище, компілятор перетворює Java-код в проміжний — bytecode (файли з розширенням .java в файли з розширенням .class). Байткод багато в чому нагадує машинний код, лише він використовує набір інструкцій не реального процесора, а віртуального. При цьому він може включати ділянки, орієнтовані на використання JIT-компілятора, що оптимізує виконання команд під реальний процесор, на якому запущена програма. JIT-компіляція, звана ще компіляцією на льоту - це технологія, яка збільшує продуктивність програми, що використовує байткод, через компіляції байткоду в машинний або інший формат під час роботи програми. Як ви могли здогадатися, JVM і використовує JIT-компілятор, коли запускає байткод. Давайте поглянемо на приклад bytecode:Чи не надто читаємо, чи не так? Ну так це і не для нас інструкція, а для JVM. Ось стаття , яка допоможе краще розібратися в цьому питанні.8. Які ознаки JavaBean?
JavaBeans - Java-клас з дотриманням певних правил. Ось кілька правил для написання JavaBean :-
Клас повинен містити порожній (без параметрів) конструктор з відкритим доступом модифікатором доступу public . Цей конструктор дає можливість створювати об'єкт даного класу без зайвих проблем (щоб не було зайвої метушні з параметрами).
-
Доступ до внутрішніх полів класу здійснюється через методи get і set , які мають бути стандартними. Наприклад, якщо поле name , то getName і setName тощо. буд. Це, своєю чергою, дозволяє різним інструментам (фреймворкам) без ускладнень автоматично визначати й оновлювати зміст bean-ов.
-
Клас повинен містити перевизначені версії методів equals() — hashCode() та toString() .
-
Клас повинен бути серіалізується, тобто повинен мати інтерфейс маркер - Serializable або імплементувати інтерфейс Externalizable . Це потрібно для того, щоб стан об'єкта bean можна надійно зберігати, зберігати та відновлювати.
9. Що таке OutOfMemoryError?
OutOfMemoryError – одна з критичних помилок під час виконання програми, пов'язана з роботою віртуальної машини Java (JVM). Викликається в тих випадках, коли JVM не може виділити об'єкт, тому що на нього не вистачає пам'яті і збирач сміття не може виділити більше пам'яті. Деякі види OutOfMemoryError :-
OutOfMemoryError: Java heap space — об'єкт не може бути розміщений у купі Java через брак пам'яті. Помилка може спричинити витік пам'яті або те, що розмір купи за промовчанням недостатній для поточної програми.
-
OutOfMemoryError: GC Overhead limit exceeded - через те, що обсяг даних ледве поміщається в купу, збирач сміття працює весь час, а програма Java працює дуже повільно, і як результат - перевищується межа накладних витрат збирача сміття і програма падає з цією помилкою.
-
OutOfMemoryError: Requested array size exceeds VM limit — вказує на те, що програма спробувала виділити пам'ять для масиву, розмір якого перевищує розмір купи, що, знову ж таки, може бути через недостатню кількість виділеної пам'яті за замовчуванням.
-
OutOfMemoryError: Metaspace - у купі закінчилося місце, виділене для метаданих (метадані - це інструкції класів, методів).
-
OutOfMemoryError: request size bytes for reason. Out of swap space - стався деякий збій при спробі виділення пам'яті з купи і як наслідок - брак пам'яті в купі.
10. Що таке стек трейс? Як його одержати?
Стек трейс (Stack Trace) - це список класів та методів, які були викликані до цього моменту програми. Викликати стек трейс у певній точці програми можна так:StackTraceElement[] stackTraceElements =Thread.currentThread().getStackTrace();
Таким чином, ми отримаємо масив стек трейс елементів, розташованих у порядку LIFO — Last In First Out . У Java, як правило, коли говорять про стек трейсу, то мається на увазі стек трейс, який виводиться в консолі при виникненні помилки (або виключення). Отримати стек трейс винятків можна так:
StackTraceElement[] stackTraceElements;
try{
...
} catch (Exception e) {
stackTraceElements = e.getStackTrace();
}
Ну і якщо ми говоримо про виведення стек трейсу виключення в консолі:
try{
...
} catch (Exception e) {
e.printStackTrace();
}
Також, якщо у нас виникне помилка, unchecked виняток або checked , яке ми не обробимо, а тільки будемо прокидатися, то при падінні програми ми отримаємо автоматично стек трейс винятків у консолі. Невеликий приклад стектрейс виключення в консолі: Детальніше про Stack Trace можете почитати ось тут . На цьому питанні ми сьогодні і зупинимося.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ