JavaRush /Java блог /Random UA /Розбір запитань та відповідей із співбесід на Java-розроб...
Константин
36 рівень

Розбір запитань та відповідей із співбесід на Java-розробника. Частина 8

Стаття з групи Random UA
Практика чи теорія? Що важливіше? Багато хто скаже, що, звичайно, практика важливіша. Мовляв, практикуйтеся до упору і буде вам щастя. Смію з цим не погодитись. Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 1На співбесідах ніхто і не дізнається, наскільки ви круті у практиці. Вас будуть запитувати на весь зріст саме з теорії. І лише потім, коли ви пройдете всі кола співбесід та потрапите на проект, ви застосуєте ваші практичні скіли. Ви можете заперечити: іноді дають тестове завдання та практика таки потрібна. Не сперечаюся, їх іноді дають, але в тому й річ, що Іноді, а от теоретична співбесіда проходить ЗАВЖДИ. Відчуваєте різницю? Тому у вас має бути твердий теоретичний фундамент під ногами, зміцненням якого ми сьогодні й продовжуватимемо займатися. А саме – ми продовжимо розбір питань, які часто ставлять на співбесідах

71. Що буде, якщо ми не перевизначатимемо метод toString() для Enum?

Припустимо, у нас є наступне enum :
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;
}
Виведемо в консолі студента, викликавши в нього toString() :
System.out.println(Role.STUDENT.toString());
Результат у консолі:
STUDENT
Тобто за умовчанням toString() для enum -а - назва константи.

72. Чи можна вказувати конструктор усередині Enum?

Так звичайно. Саме через конструктор і задаються значення внутрішніх змінних enum. Як приклад до попереднього enum додамо два поля – ageFrom та ageTo – щоб позначити вікові рамки для кожної ролі:
public enum Role {
   STUDENT(5,18),
   TEACHER(20,60),
   DIRECTOR(40,70),
   SECURITY_GUARD(18,50);

   int ageFrom;
   int ageTo;

   Role(int ageFrom, int ageTo) {
       this.ageFrom = ageFrom;
       this.ageTo = ageTo;
   }
}

73. У чому різниця між == та equals()?

Це одне з найпоширеніших питань на співбесідах Java-розробника. Почнемо з того, що ми порівнюємо прості значення ( int , char , double …), ми робимо це через == , оскільки змінні містять конкретні значення і ми можемо їх порівняти. Та й примітивні змінні є повноцінними об'єктами — не успадковуються від Object і мають метод equals() . Коли ми говоримо про порівняння змінних, які посилаються на об'єкти, то == буде порівнювати лише значення посилань — той самий об'єкт вони посилаються чи ні. І навіть якщо один об'єкт буде ідентичний іншому, порівняння через == дасть негативний результат (false ), адже це інший об'єкт. Як ви зрозуміли, для порівняння змінних змінних використовується метод equals() . Це один із стандартних методів класу Object , який потрібний для повноцінного порівняння об'єктів. Але відразу слід уточнити: для правильної роботи цього методу його потрібно перевизначити, написавши, як саме мають порівнюватися об'єкти цього класу. Якщо ви не перевизначите метод, за умовчанням він порівнюватиме об'єкти по == . У IntelliJ IDEA можна перевизначати його автоматично (засобами IDEA) -> alt + insert , у вікні, що з'явилося, вибираємо equals() and hashCode()-> вибираємо, які поля класу повинні брати участь -> і вуаля, автоматична імплементація методів виконана. Ось приклад того, як виглядатиме автоматично згенерований метод equals для найпростішого класу Cat з двома полями - int age та String name :
@Override
public boolean equals(final Object o) {
   if (this == o) return true;
   if (o == null || this.getClass() != o.getClass()) return false;
   final Cat cat = (Cat) o;
   return this.age == cat.age &&
           Objects.equals(this.name, cat.name);
}
Якщо говорити про різницю == і equals для enum -ів, її особливо немає. Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 2Адже enum зберігає константи, і навіть порівнюючи через == аналогічні значення, ми отримуватимемо true , оскільки посилання будуть завжди на ті самі об'єкти. Ну і при використанні equals у нас також буде правильно відпрацьовувати функціонал, тим більше, якщо ви зайдете в тіло методу equals для enum -а, побачите, що в класі Enum реалізація методу наступна: Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 3Тобто всередині - добре добре порівняння за посиланнями! Підсумовуючи: для enum порівняння і через ==, та через equals коректне.Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 4

74. Що робить метод ordinal() у Enum?

При виклику методу int ordinal() на елементі enum -а ми отримаємо порядковий номер із нуля цього значення у ряді перерахувань. Давайте використовуємо даний метод на одному елементі з попереднього розглянутого enum - Role :
System.out.println(Role.DIRECTOR.ordinal());
Відповідно, в консолі виведеться:
2

75. Чи можна використовувати Enum c TreeSet або TreeMap у Java?

Використання enum типів у TreeSet та TreeMap припустимо. І ми можемо написати:
TreeSet<Role> treeSet = new TreeSet<>();
treeSet.add(Role.SECURITY_GUARD);
treeSet.add(Role.DIRECTOR);
treeSet.add(Role.TEACHER);
treeSet.add(Role.STUDENT);
treeSet.forEach(System.out::println);
І в консолі буде виведено:
STUDENT TEACHER DIRECTOR SECURITY_GUARD
Ми дістали висновок за алфавітом. Справа в тому, що якщо ми використовуємо елементи enum -а для значень TreeSet або як ключі для TreeMap , елементи сортуються за їх природним порядком (по порядку, в якому вони задані в enum ). Розуміння цих особливостей допомагає нам писати код якісніше.Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 5

76. Як пов'язані методи ordinal() і compareTo() в Enum?

Як було зазначено раніше, ordinal() повертає порядковий номер значення у списку перерахувань. Також у розборі попереднього питання ви побачабо, що елементи перерахувань, потрапивши, наприклад, TreeSet (відсортована безліч) приймають порядок, в якому вони оголошені в enum . І як знаємо, TreeSet і TreeMap сортують елементи у вигляді виклику вони методу compareTo() інтерфейсу Comparable . З цього можна зробити припущення, що клас Enum імплементує інтерфейс Comparable , реалізуючи його метод compareTo() , всередині якого використовується ordinal()для завдання порядку сортування. Зайшовши в клас Enum , бачимо підтвердження цього: Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 6І тіло самого методу: Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 7Метод ordinal() тут не викликається. Натомість використовується змінна ordinal — порядковий номер елемента у перерахуванні. Сам метод ordinal()Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 8не більше ніж геттер для змінної ordinal .

77. Напишіть приклад EnumM

У питаннях розглянутих вище я вже наводив приклади enum -ів і не бачу сенсу дублювати код (наприклад, номер 72 про конструктор в enum).

78. Чи можна використовувати Enum у switch case?

Можна й треба! Оглядаючись на свою практику, зазначу, що одним із найчастіших місць застосування enum є логічні конструкції типу switch . У такому випадку ви можете передбачити всі можливі варіації case , і після прописання логіки для всіх значень enum -а використання оператора default може навіть не знадобитися! Адже якщо ви використовуєте String або числове значення, наприклад типу int , вам може прийти не передбачене значення, що в свою чергу неможливо з використанням enum -а. Як би виглядав switch для розглянутого раніше прикладу:
public void doSomething(Role role) {
   switch (role) {
       case STUDENT:
           // некая логика для STUDENT
           break;
       case TEACHER:
           // некая логика для TEACHER
           break;
       case DIRECTOR:
           // некая логика для DIRECTOR
           break;
       case SECURITY_GUARD:
           // некая логика для SECURITY_GUARD
           break;
   }
}

79. Як отримати всі наявні значення в екземплярі Enum?

Якщо потрібно отримати всі екземпляри перерахування, є метод values() , який повертає масив усіх доступних значень певного enum -а в природному порядку (у порядку завдання enum ). Приклад:
Role[] roles = Role.values();
for (Role role : roles) {
   System.out.println(role);
}
У консолі буде висновок:
STUDENT TEACHER DIRECTOR SECURITY_GUARD

Stream API

80. Що таке Stream в Java?

Java Stream - відносно новий спосіб взаємодії з потоком даних, який у свою чергу дозволяє зручніше і компактніше обробляти великі дані, а також розпаралелювати обробку даних між якоюсь кількістю потоків, що може дати приріст у продуктивності у функціоналі, що використовує. Більш глибоко цю тему двома словами не розповісти, тому я залишу тут посилання на статтю, яка вам може зануритися в цю тему.Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 9

81. Назвіть основні властивості транзакцій

Тема називається — Stream API, але при цьому питання щодо транзакції. Хмм… Спершу давайте розберемося, що таке транзакція. Транзакція — це група послідовних операцій із базою даних, що є логічну одиницю роботи з даними. Транзакція може бути виконана або цілком і успішно, дотримуючись цілісності даних і незалежно від інших транзакцій, що паралельно йдуть, або не виконана взагалі, і тоді вона не має жодного ефекту. Отже, транзакції мають чотири основні властивості, які скорочено називають ACID . Давайте розберемо, як розшифровується кожна буква цього скорочення: A - Atomicity - атомарність— ця властивість гарантує, що жодна транзакція не буде зафіксована в системі частково. Будуть або виконані її підоперації, або виконано жодної ( все або нічого ). С - Consistency - узгодженість - властивість, що гарантує, що кожна успішна транзакція зафіксує лише допустимі результати. Тобто, це гарантія того, що при успішній транзакції будуть виконані всі правила, обмеження, які пред'являє система до конкретних даних, інакше транзакція не буде виконана і дані в системі повернуться до попереднього стану. I - Isolation - ізольованість— властивість, яка говорить про те, що під час виконання транзакції паралельні транзакції не повинні впливати на її результат. Ця властивість ресурсозатратна, тому зазвичай вона виконується частково, допускаючи певні рівні ізоляцій, які вирішують певні ізоляційні проблеми. Докладніше ми це обговоримо у наступному питанні. Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 10D – Durability – стійкість – дана властивість гарантує, що якщо користувач отримав підтвердження від системи, що транзакція виконана, він може бути впевнений, що зроблені ним зміни не відміняться через будь-який збій. Тобто ви можете бути впевнені, що який-небудь збій операційної системи нічого не зробить з вашими даними, якщо ви вже отримали підтвердження успішного виконання вашої транзакції.

82. Які рівні ізоляції транзакцій?

Як я сказав раніше, забезпечення пункту ACID ізольованості – ресурсозатратний процес. Тому ця властивість виконується частково. Існують різні рівні ізольованості, і чим цей рівень вищий, тим це сильніший удар по продуктивності. Перед тим як перейти до рівнів ізоляцій транзакцій, нам потрібно розглянути різні проблеми недостатньої ізольованості транзакцій :
  • фантомне читання - при повторному виклику однієї і тієї ж вибірки (одного і того ж запиту) в рамках однієї транзакції отримані дані різняться, що відбувається через вставки даних іншою транзакцією;

  • неповторне читання - при повторному виклику однієї і тієї ж вибірки (одного і того ж запиту) в рамках однієї транзакції отримані дані різняться, що відбувається через зміни (update) та видалення даних іншою транзакцією;

  • брудне читання — процес читання даних, доданих чи змінених транзакцією, яка згодом підтвердиться (відкотиться), тобто. читання недійсних даних;

  • втрачене оновлення - при одночасному зміні одних і тих же даних різними транзакціями втрачаються всі зміни, крім останнього (нагадує проблему "стан гонки" у багатопотоковому середовищі).

Рівні ізоляцій транзакцій таки характеризуються тим, від яких проблем ізольованості вони захищають. Розглянемо у вигляді таблиці рівні ізоляцій і те, від яких проблем вони захищають:
Рівень ізоляції Фантомне читання Неповторне читання Брудне читання Втрачене оновлення
SERIALIZABLE + + + +
REPEATABLE READ - + + +
READ COMMITTED - - + +
READ UNCOMMITTED - - - +
NONE - - - -
І не забувайте зворотний бік медалі: чим більшим буде рівень ізоляції, тим довше відпрацьовуватимуть транзакції (при паралельному виконанні кількох транзакцій). Якщо виникло бажання глибше копнути цю тему, ось чудова стаття , з якої можна розпочати.

83. Яка різниця між Statement і PreparedStatement?

І тут не дуже плавний перехід на особливості технології JDBC . Отже, спочатку давайте розберемося, що взагалі таке Statement . Це об'єкт, який використовується для формування запитів SQL. У JDBC використовується три його види - Statement , PreparedStatement і CallableStatement . CallableStatement ми сьогодні розглядати не будемо: поговоримо про різницю між Statement і PreparedStatement .
  1. Statement використовується для виконання простих SQL запитів без вхідних параметрів, що динамічно вставляються. PrepareStatement використовується з можливістю динамічної вставки вхідних параметрів.

  2. Для завдання параметрів PreparedStatement вхідні параметри в запиті прописуються як знаки питання, щоб замість них потім вставити деяке значення за допомогою різних сеттерів, таких як setDouble() , setFloat() , setInt() , setTime() …. У результаті ви не вставите в запит дані не типу.

  3. PreparedStatement “перекомпільований” і використовує кешування, тому його виконання може відбуватися трохи швидше, ніж запит із об'єктів Statement . Через війну SQL запити, які виконуються часто, з метою поліпшення продуктивності створюють як об'єктів PreparedStatement .

  4. Statement вразливий до SQL ін'єкцій, в той час як PreparedStatement запобігає їм. Докладніше про усунення SQL ін'єкцій та інших best practices у безпеці Java читайте у цій статті .

Якщо ви поклали початок у вивченні технології з'єднання Java програми з Базою даних - JDBC, раджу почати з цієї статті . Що ж, зараз ми сьогодні і зробимо зупинку.Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 8 - 11
Інші матеріали серії:
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ