JavaRush /Java блог /Random UA /Часті запитання щодо класів колекцій в Java (Частина 1)
theGrass
24 рівень
Саратов

Часті запитання щодо класів колекцій в Java (Частина 1)

Стаття з групи Random UA
Без сумніву, колекції в Java - це вкрай важлива область, і питання щодо колекцій будуть задавати на співбесідах як новачкам, так і досвідченим програмістам. Тема настільки велика, що практично неможливо покрити її цілком. І все ж, ґрунтуючись на моїх попередніх співбесідах, я спробую перерахувати якнайбільше Гарних питань, до яких ви повинні бути готові. Часті питання на класах колекцій в Java (Частина 1) - 1Питання будуть як складні так і прості, так що якщо питання здається вам занадто примітивним - не забувайте, що він відмінно підійде менш досвідченому програмісту.

Запитання у цій статті:

Загальні питання
  1. Що таке колекції Java? Перерахуйте їх переваги
  2. Розкажіть про ієрархію колекцій
  3. Чому колекції не успадковують інтерфейси Cloneableта Serializable?
  4. Чому інтерфейс Mapне успадковує інтерфейс Collection?
Запитання про списки
  1. Чому ми використовуємо списки? Які основні класи реалізують інтерфейс List?
  2. Як перетворити масив рядків на ArrayList?
  3. Як відсортувати список у зворотному порядку?
Питання про безліч
  1. Чому ми використовуємо безліч? Які основні класи реалізують інтерфейс Set?
  2. Як зберігаються елементи в HashSet?
  3. Чи може бути елемент nullдоданий в TreeSetабо HashSet?
Запитання про словники
  1. Чому ми використовуємо словники? Які основні класи реалізують інтерфейс Map?
  2. Що таке IdentityHashMapі WeakHashMap?
  3. Поясніть що таке ConcurrentHashMap? Як воно працює?
  4. Як працюють словники?
  5. Як створити добрий ключ для словника?
  6. Які уявлення вмісту надає інтерфейс Map?
  7. Коли потрібно використовувати HashMap, а коли TreeMap?
Питання про відмінності різних колекцій
  1. Назвіть різницю між Setі List?
  2. Назвіть різницю між Listі Map?
  3. Назвіть різницю між HashMapіHashTable?
  4. Назвіть різницю між Vectorі ArrayList?
  5. Назвіть різницю між Iteratorі Enumeration?
  6. Назвіть різницю між HashMapі HashSet?
  7. Назвіть різницю між Iteratorі ListIterator?
  8. Назвіть різницю між TreeSetі SortedSet?
  9. Назвіть різницю між ArrayListі LinkedList?
І ще питання
  1. Як зробити колекцію лише для читання?
  2. Як зробити потокобезпечну колекцію?
  3. Чому не існує методу Iterator.add()додавання елементів до колекції?
  4. Які є способи перебирати елементи списку?
  5. Як ви розумієте роботу якості ітератора fail-fast?
  6. Яка різниця між fail-fastі fail-safe?
  7. Як уникнути ConcurrentModificationExceptionпід час перебору колекції?
  8. Що таке UnsupportedOperationException?
  9. Які класи колекцій дають доступ до будь-якого елемента?
  10. Що таке BlockingQueue?
  11. Що таке черга та стек, перерахуйте різницю між ними?
  12. Що таке інтерфейси Comparableта Comparator?
  13. Що таке класи Collectionsта Arrays?
  14. Список використаної літератури
Не марнуючи час, приступимо до пояснень

Загальні питання

  1. Що таке колекції Java? Перерахуйте їхні переваги?

    За визначенням — колекція це об'єкт, що є групою об'єктів. Як у теорії множин - безліч це група об'єктів. Просто, чи не так? До виходу JDK 1.2, існували такі класи як Vectorі HashTable, але не було фреймворку Collection. Потім було вирішено додати підтримку структур даних, що багаторазово використовуються. Цей фреймворк був розроблений переважно Джошуа Блохом, і вперше з'явився у JDK 1.2.

    Як головні переваги ми можемо перерахувати:

    • Зменшуються витрати часу на написання коду
    • Покращується продуктивність завдяки використанню високоефективних алгоритмів і структур даних
    • Колекції є універсальним способом зберігання та передачі даних, що спрощує взаємодію різних частин коду.
    • Простота у вивченні, тому що необхідно вивчити тільки найвищі інтерфейси та підтримувані операції
  2. Розкажіть про ієрархію колекцій?

    Часті питання на класах колекцій в Java (Частина 1) - 2

    Як показано на зображенні, фреймворк колекцій містить один інтерфейс верхнього рівня - Collection, від якого успадковуються Set, Listі Queue. Нижче ми розглянемо ще безліч класів, які у цих трьох гілках. Запам'ятайте заголовок інтерфейсу Collection, це допоможе вам з багатьма питаннями.

    public interface Collection extends Iterable {
    //описание методов
    }

    Також фреймворк містить інтерфейс Map , який є спадкоємцем інтерфейсу Collection. Причину чому він не успадковує Collection, ми розберемо у четвертому питанні.

  3. Чому колекції не успадковують інтерфейси Cloneableта Serializable?

    Ну, найпростіша відповідь - "бо не треба". Функціонал, що надається інтерфейсами Cloneableі Serializableпросто не потрібен для колекцій.

    Ще одна причина — далеко не завжди потрібний підклас, Cloneableтому що кожна операція клонування споживає дуже багато пам'яті, і недосвідчені програмісти можуть витрачати її самі, не розуміючи наслідків.

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

  4. Чому інтерфейс Mapне успадковує інтерфейс Collection?

    Хороша відповідь на це питання - "бо вони несумісні". В інтерфейсі Collectionописаний метод add(Object o).

    Словники не можуть містити цей метод, тому що працюють з парами ключ/значення. Також, словники мають уявлення keySet, valueSet,яких немає в колекціях.

    У зв'язку з цими відмінностями, інтерфейс Mapне може успадковувати інтерфейс Collection, і є окремою гілкою ієрархії.

Запитання про списки

  1. Чому ми використовуємо списки? Які основні класи реалізують інтерфейс List?

    Списки в Java - це впорядкована колекція елементів. Кожен елемент має індекс, що починається з нуля. Усі індекси унікальні. Крім методів описаних в інтерфейсі Collection, списки мають власні методи, в основному для роботи з елементами колекціями за їх індексом. Можна розділити ці методи на 3 групи - пошук елемента, отримання конкретного елемента, вибір колекції і вибірка підгрупи. Всі ці операції можуть проводитись за індексом елемента.

    Основні класи, що реалізують інтерфейс Listце Stack, Vector, ArrayListі LinkedList. За більш детальною інформацією щодо них, зверніться до документації.

  2. Як перетворити масив рядків на ArrayList?

    Питання це трохи глибше ніж просто з програмування, як це бачиться новачкам. Мета його – перевірити знання кандидатом службових класів фреймворку Collection. Розглянемо два таких класи, які найбільш затребувані на співбесідах — Collectionsі Arrays.

    Клас Collectionsнадає статичні методи операцій над колекціями. Відповідно Arraysнадає статичні методи операцій над масивами.

    String[] words = {"аз", "буки", "веди", "глагол", "добро"};
    //Как вы можете обратить внимание, у нас есть массив строк String[] words.
    //В котором у нас лежат 5 строк.
    List wordList = Arrays.asList(words);
    //легким движением руки, а точнее вызовом Arrays.asList() мы превратабо наш
    //массив строк в список List wordList.

    Також хотілося б відзначити, що цей метод здатний обробляти не лише рядки, він створить список елементів будь-якого типу, якого був масив.

    Integer[] nums = {1, 2, 3, 4};
    List numList = Arrays.asList(nums);
  3. Як відсортувати список у зворотному порядку?

    Як і попереднє, це питання перевіряє ваше знання службових класівCollection

    List reversedList = Collections.reverse(list);

Питання про безліч

  1. Чому ми використовуємо безліч? Які основні класи реалізують інтерфейс Set?

    Він моделює математичну множину, з теорії множин. Інтерфейс Setсхожий на List, але має деякі відмінності. Перше – це не впорядкована колекція. Отже, додавання/видалення елементів не потребує їх сортування. Головна особливість множин - унікальність елементів, тобто один і той самий елемент не може утримуватися в множині двічі.

    Дуже важливими для функціонування множин є методи equals()і hashCode()вони дозволяють порівнювати безлічі різних класів. Дві множини є ідентичними тільки якщо вони містять одні й ті самі елементи.

    Як випливає з вищевикладеного, множини не підтримують операцій заснованих на індексі елемента, як списки. Багато мають тільки ті методи, які описані в інтерфейсі.Collection

    Основними класами, що реалізують інтерфейс Set, є EnumSet, HashSet, LinkedHashSetі TreeSet. Якщо хочете дізнатися більше, почитайте відповідні розділи документації Java.

  2. Як зберігаються елементи в HashSet?

    Як ви вже в курсі, HashMapзберігає пари ключ/значення, і ключі мають бути унікальними. HashSetвикористовує цю особливість HashMapзадля забезпечення унікальності своїх елементів. У класі HashSetсловник описаний наступним чином:

    private transient HashMap<E, Object> map;
    private static final Object PRESENT = new Object();

    Отже, коли ви зберігаєте елемент у множині, воно кладе даний елемент як ключ у словник, а значенням йде об'єкт PRESENT, як описано нижче:

    public boolean add(E e) {
      return map.put(e, PRESENT) == null;
    }

    Я настійно рекомендую вам прочитати цю статтю , це допоможе вам з легкістю відповісти на всі HashMapпитання.

  3. Чи може бути елемент nullдоданий в TreeSetабо HashSet?

    Як очевидно з попередньої відповіді, методі add()немає перевірки на null. Також HashMapдозволяє один ключ null, отже, один елемент nullможе бути доданий в HashSet.

    TreeSetпрацює за тим же принципом, що і HashSet, але використовує NavigableMapдля зберігання елементів

    private transient NavigableMap<E,Object> m;
    private static final Object PRESENT = new Object();

    NavigableMapце клас-спадкоємець SortedMap, а SortedMapне дозволяє використання ключів null. Отже, TreeMapне підтримує зберігання елементів типу null. Якщо ви спробуєте додати null в TreeSet, отримайте виняток NullPointerException.

Запитання про словники

  1. Чому ми використовуємо словники ( Map)? Які основні класи реалізують інтерфейс Map?

    Словники – спеціальний тип колекції, яка використовується для зберігання пар ключ/значення. З цієї причини він не є спадкоємцем інтерфейсу Collection. Словник надає методи для додавання пар ключ/значення, видалення, пошуку та перебору за уявленням даних, що надаються словником.

    Основні класи реалізують інтерфейс Map: HashMap, Hashtable, EnumMap, IdentityHashMap, LinkedHashMapі Properties.

  2. Що таке IdentityHashMapі WeakHashMap?

    IdentityHashMapсхожий за HashMapодним винятком — для порівняння об'єктів використовується порівняння покажчиків на об'єкти, якщо покажчики не рівні (вказують на об'єкти, що лежать за різними адресаами), отже, об'єкти вважаються різними.

    IdentityHashMapє досить рідко використовується. Хоча він реалізує інтерфейс Map, він порушує один з основних принципів пристрою Map, який вимагає використання методу equals()для порівняння об'єктів.

    IdentityHashMapвикористовується тільки в тих випадках, коли потрібно порівняти об'єкти за їх адресаами.

    WeakHashMapце реалізація інтерфейсу Map, що містить слабкі посилання елементи. Тобто, якщо за межами WeakHashMapне залишилося жодного посилання на його елемент, цей елемент видаляється збирачем сміття. Клас призначений для використання з об'єктами, у яких метод equals()перевіряє ідентичність об'єктів за допомогою оператора ==. Після того як елемент буде видалений збирачем сміття, він вже не може бути відновлений, і на превеликий подив програміста знайти його у словнику більше не вийде.

  3. Поясніть що таке ConcurrentHashMap? Як воно працює?

    Взято з офіційної документації:
    Реалізація словника повністю підтримує багатопотокове додавання/видалення/пошук елементів. Цей клас слід тим самим специфікаціям як і Hashtable, і містить методи відповідні методам Hashtable. Однак, хоча всі операції є потокобезпечними, операція з вибірки елементів не блокує таблицю, і взагалі немає можливості заборонити доступ до таблиці. Цей клас сумісний з Hashtableусім крім питань багатопоточної синхронізації.

  4. Як працює hashmap?

    Найважливіше питання, яке швидше за все буде поставлене на співбесіді програмісту будь-якого рівня. Ви повинні добре розбиратися в цій темі, і не тільки тому що це питання, що найбільше задається, але і тому що розуміння пристрою hashmapдозволяє вам легше розібратися в інших особливостях роботи колекцій.

    Відповідь на це питання дуже велика, і повністю її можна прочитати в цій статті - як працює hashmap . А зараз просто запам'ятайте що HashMapпрацює на основі хешування. Словник, за визначенням, це об'єкт, який пов'язує ключі та значення. Для зберігання таких структур він використовує внутрішній клас Entry.

    static class Entry implements Map.Entry
    {
    final K key;
    V value;
    Entry next;
    final int hash;
    ...//Еще много кода тут
    }

    Змінні keyта valueслужать для зберігання ключа та значення. А самі об'єкти Entryлежать у масиві.

    /**
    * Размер таблицы меняется по необходимости,
    * и обязательно должен быть дорівнює степени двойки
    */
    transient Entry[] table;

    Індекс потрібного елемента в масиві обчислюється за хеш-кодом ключа. Більше інформації можна отримати за посиланням на початку відповіді.

  5. Як створити добрий ключ для словника?

    Наступне гарне питання, яке зазвичай ставлять слідом за питанням про функціонування HashMap. Отже, головне обмеження — ключ має бути таким, щоб потім ним можна було отримати зі словника значення. Інакше у його використанні просто немає сенсу. Якщо ви розумієте як функціонує hashmap, ви знаєте, що його робота сильно залежить від методів hashCode()і equals()об'єктів-ключів.

    Як випливає з вищевикладеного, хороший ключ повинен давати той самий hashCodeзнову і знову, незалежно від того скільки разів він запитується. Також, однакові ключі, при виклику методу equals()повинні повертати true, а різні — false.

    З чого випливає, що найкращими кандидатами на роль ключа є незмінні класи.

    Можете почитати ще за адресаою .

  6. Які уявлення вмісту надає інтерфейс Map?

    Інтерфейс Mapнадає три уявлення збережених даних:

    • безліч усіх ключів
    • безліч усіх значень
    • безліч об'єктів Entry, що містять у собі і ключ і значення

    Переміщатися ними можна за допомогою ітераторів.

  7. Коли потрібно використовувати HashMap, а коли TreeMap?

    HashMapце дуже широко використовуваний клас, і ви знаєте. Отже, я обмежуся тим, що скажу, що в ньому зберігаються пари ключ/значення і він дозволяє проводити над ними багато операцій.

    TreeMapце особливий різновид HashMap. Різниця в тому, що ключі зберігаються TreeMapвпорядковано. За умовчанням застосовується "природне сортування". Перевизначити сортування можна надавши екземпляр класу Comparator, метод compareякого буде використаний для сортування ключів.

    Зверніть увагу, що всі ключі, додані до словника, повинні реалізовувати інтерфейс Comparable(це необхідно для сортування). Більше того, всі ключі повинні бути взаємно сумісними: k1.compareTo(k2)не повинен викликати ClassCastExceptionдля тих, k1хто k2зберігається у словнику. Якщо користувач спробує покласти в словник ключ, який порушує цю умову (наприклад, рядковий ключ у словник, де всі ключі типу Integer), метод put(Object key, Object value)повинен викликати ClassCastException.

Оригінал статті
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ