JavaRush /Java Blog /Random-IT /Domande popolari sulle interviste HashMap e ConcurrentHas...
furs08
Livello 11

Domande popolari sulle interviste HashMap e ConcurrentHashMap

Pubblicato nel gruppo Random-IT
Nella mia ultima anteprima ho parlato di “Come funziona HashMap in Java ”. Ho parlato degli interni di questa classe e di come si inseriscono nel concetto. Ma quando mi è stato chiesto di HashMap e cose correlate, l'interrogante non si è fermato solo al concetto di base. Durante la discussione si toccano diverse direzioni, alla fine tutto si riduce al fatto che queste cose o le capisci davvero oppure no. Domande popolari sulle interviste HashMap e ConcurrentHashMap - 1In questa anteprima, cercherò di coprire tutti gli argomenti principali delle domande dell'intervista: Argomenti trattati:
  1. Come creare una chiave per una HashMap?
  2. Differenze tra HashMap e ConcurrentHashMap?
  3. Differenze tra Collections.synchronizedMap(HashMap) e HashMap?
  4. Differenze tra ConcurrentHashMap e Collections.synchronizedMap(HashMap)?
  5. Differenze tra HashMap e HashTable?
  6. Differenze tra HashTable e Collections.synchronizedMap(HashMap)?
  7. Impatto dei valori hashCode() casuali/fissi per una chiave
  8. Utilizzo di HashMap nel codice non sincronizzato in applicazioni multi-thread
Quindi iniziamo:
  1. Generazione di una chiave per una HashMap

    Una delle esigenze principali è che dobbiamo restituire il valore dell'oggetto senza errori. Giusto? Altrimenti non è chiaro come immaginare la struttura dati che stai progettando. Sarà impossibile da usare. Per decidere che abbiamo creato una buona chiave dobbiamo sapere come funziona una HashMap. HashMap si basa sui principi dell'hashing. La chiave nel codice hash viene utilizzata principalmente in combinazione con il metodo equals() per aggiungere e cercare un elemento nell'HashMap. Se il codice hash di un oggetto viene modificato in un'altra coppia chiave-valore, è quasi impossibile ottenere il valore dalla mappa. Questo caso è chiamato perdita di memoria. Per evitare ciò, la chiave e la mappa devono essere immutabili. Questo è il motivo principale per cui classi immutabili come String, Integer e altre classi simili sono buone scelte per creare una chiave.

    Ma ricorda che l'immutabilità è consigliata, ma non obbligatoria. Se vuoi rendere la chiave un oggetto mutabile, devi assicurarti che l'oggetto chiave non modifichi il codice hash dell'oggetto. Questo può essere fatto sovrascrivendo il metodo hashCode(). Inoltre, le classi chiave devono funzionare correttamente con i metodi hashCode() ed equals() per evitare comportamenti di esecuzione indesiderati e sorprendenti.

  2. Differenze tra HashMap e ConcurrentHashMap

    Per visualizzare meglio ConcurrentHashMap, è necessario considerare questa classe come un gruppo di HashMap. Per prendere e inserire i valori delle coppie chiave-valore in una HashMap, è necessario calcolare il codice hash e trovare il segmento corretto dell'array Collection.Entry. La differenza con ConcurrentHashMap è la struttura interna per la memorizzazione delle coppie chiave-valore. ConcurrentHashMap ha il concetto aggiuntivo di segmenti. Sarà facile capirlo se immagini che un segmento equivale a una HashMap [concettualmente]. ConcurrentHashMap è suddiviso in molti segmenti [il valore predefinito è 16] quando inizializzato. ConcurrentHashMap circa (16) thread simili accedono a questo segmento contemporaneamente, ogni thread viene eseguito simultaneamente con elevata concorrenza. Pertanto, se la coppia chiave-valore è memorizzata nel segmento 10, non è necessario bloccare ulteriormente i restanti 15 segmenti. Questa struttura fornisce un livello molto elevato di parallelismo.

    Domande popolari sulle interviste HashMap e ConcurrentHashMap - 2

    Другими словами Concurrent HashMap использует множество замков и каждый замок управляет одним сегментом структуры. Установки данных в определенном сегменте заблокированы для получения в этом сегменте так синхронизированы операции обновления. При получении данных, чтения на лету используется без синхронизации. Если считывать данные на лету то сегмент блокируется и запись производится в синхронизированный блок.

  3. Различия между HashMap и Collection.synchronizedMap(HashMap)

    Все на самом деле просто! HashMap не синхронизирована и Collection.synchronizedMap(HashMap) возвращает упакованные методы HashMap которые являются синхронизированными get и put методами.

    Фактически, Collection.synchronizedMap(HashMap) внутренне созданного внутреннего класса SunchronizedMap содержащего пары key-value передающиеся в HashMap How аргумент. Такой пример внутренних классов ничего не меняет в первоначальных параметрах HashMap и является fully независимым.

  4. Различия между ConcurrentHashMap и Collections.synchronizedMap(HashMap)

    Оба являются синхронизированными versionми HashMap c различиями в функциональности и внутренней структуре. Как указано выше ConcurrentHashMap состоит из внутренних сегментов, которые могут рассматриваться How независимые HashMap’ы концептуально. Все эти сегменты могу быть заблокированы отдельными потоками выполняемыми одновременно. Таким образом несколько потоков могу одновременно получить/положить пары key-value из ConcurrentHashMap без блокирования/ожидания друг друга.

    Из Collections.synchronizedMap() мы получаем синхронизированную версию HashMap и доступ в блокировании образом. Это означает то что если несколько потоков пытаются получить доступ к synchronizedMap в одно и тоже время им будет позволено взять/положить пары key-value по одному синхронизированному образу.

  5. Различия между HashMap и HashTable

    Этот вопрос также является простым. Главное различие в том что HashTable синхронизирован а HashMap нет. Если вас спросят по другим причинам то скажите им что HashTable является наследием класса (часть JDK 1.0) который был произведен в рамках коллекции реализовав интерфейс Map позже. В нем все еще есть вещи которых нету в HashMap такие к примеру How Enumerators(счётчики). Другой незначительной причиной является то что HashMap поддерживает ключ со meaningм null.(Отображаемый How пустая область памяти). HashTable не поддерживает ключ со meaningм null и вызывает исключение NullPointerException, при попытке его задать.

  6. Различия между HashTable и Collection.synchronized(HashMap)

    До сих пор вы возможно только знали об их сходствах. Оба являются синхронизированными versionми коллекций. Оба имеют синхронизированные методы внутри. Оба блокируют потоки и заставляют ждать когда можно взять/положить что-либо в коллекцию. Так в чем же различия? Хорошо! Нет основных различий для указанных выше причин. Производительность обоих одинакова. Единственное что различает их это то что HashTable наследуемый класс он получил свои дополнительные функции такие How Enumerators(счетчики).

  7. Влияние случайных/фиксированных значений для значения ключа.

    Влияние в обоих случаях будь то фиксированное meaning or случайное будет иметь одинаковый результат и это необъяснимое поведение. Большое meaning имеет место в HashMap где поставить пару key-value и где восстановить. Если положение an object ключа меняется каждый раз то его положение будет рассчитываться каждый раз разными способами. Таким образом an object хранящийся в HashMap будет потерян навсегда с минимальной возможностью восстановления. Поэтому значения ключей являются неизменными и каждый раз возвращают уникальные значения.

  8. Использование HashMap в несинхронизированном codeе многопоточных приложений.

    — в худшем случае это может вызвать бесконечный цикл.

    — Да.

    — Ты был прав это действительно может привести к бесконечному циклу. Ты спросишь: "Как?"

    — Хорошо! Вот причина!

    HashMap имеет концепцию повторного хеширования, когда достигает своего верхнего предела. Это процесс создания новой области памяти и копирования туда существующих элементов. Допустим Поток A положил пару key-value в Map и повторное хеширование началось, в то же время поток Б начал манипулировать с областью памяти используя операцию put(положить). Во время повторного хеширования существует возможность для создания циклической зависимости где элемент находящийся в ссылочном листе [в любой области памяти] может указывать на любой предыдущий узел в ту же область памяти. Это приведет к бесконечному циклу так How code повторного хеширования содержит в себе while(TRUE) {//получаем следующий узел} который будет работать бесконечно.

    Посмотрите внимательно на этот code содержащий метод передачи использующий операцию повторного хеширования:

    public Object get(Object key) {
        Object k = maskNull(key);
        int hash = hash(k);
        int i = indexFor(hash, table.length);
        Entry e = table[i];
    
        //While true is always a bad practice and cause infinite loops
    
        while (true) {
            if (e == null)
                return e;
            if (e.hash == hash && eq(k, e.key))
                return e.value;
            e = e.next;
        }
    }

    Подробней об этом в следующей статье. Если вы нашли статью полезной пожалуйста поделитесь с друзьями! Счастливого обучения!

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION