JavaRush /Blog Java /Random-VI /Các câu hỏi phỏng vấn phổ biến về HashMap và ConcurrentHa...
furs08
Mức độ

Các câu hỏi phỏng vấn phổ biến về HashMap và ConcurrentHashMap

Xuất bản trong nhóm
Trong bản xem trước cuối cùng của tôi, tôi đã nói về “Cách HashMap hoạt động trong Java ”. Tôi đã nói về nội dung bên trong của lớp này và cách chúng phù hợp với khái niệm này. Nhưng khi tôi được hỏi về HashMap và những thứ liên quan, người hỏi không chỉ dừng lại ở khái niệm cơ bản. Trong quá trình thảo luận, nhiều hướng khác nhau được đề cập đến, cuối cùng thì tất cả đều dẫn đến thực tế là bạn thực sự hiểu những điều này hoặc bạn không hiểu. HashMap và ConcurrentHashMap những câu hỏi phỏng vấn phổ biến - 1Trong bản xem trước này, tôi sẽ cố gắng đề cập đến tất cả các chủ đề chính của câu hỏi phỏng vấn:
  1. Làm cách nào để tạo khóa cho HashMap?
  2. Sự khác biệt giữa HashMap và ConcurrentHashMap?
  3. Sự khác nhau giữa Collections.synchronizedMap(HashMap) và HashMap?
  4. Sự khác nhau giữa ConcurrentHashMap và Collections.synchronizedMap(HashMap)?
  5. Sự khác biệt giữa HashMap và HashTable?
  6. Sự khác nhau giữa HashTable và Collections.synchronizedMap(HashMap)?
  7. Tác động của các giá trị hashCode() ngẫu nhiên/cố định đối với một khóa
  8. Sử dụng HashMap trong mã không đồng bộ trong các ứng dụng đa luồng
Vậy hãy bắt đầu:
  1. Tạo khóa cho HashMap

    Một trong những nhu cầu chính là chúng ta phải trả về giá trị của đối tượng không có lỗi. Phải? Mặt khác, không rõ cách hình dung cấu trúc dữ liệu bạn đang thiết kế. Nó sẽ không thể sử dụng được. Để quyết định rằng chúng tôi đã tạo một khóa tốt, chúng tôi cần biết HashMap hoạt động như thế nào. HashMap được xây dựng trên nguyên tắc Hashing. Khóa trong mã băm được sử dụng chủ yếu kết hợp với phương thức Equals() để thêm và tìm kiếm một phần tử trong HashMap. Nếu mã băm của một đối tượng được thay đổi thành một cặp khóa-giá trị khác thì gần như không thể lấy được giá trị từ Bản đồ. Trường hợp này được gọi là rò rỉ bộ nhớ. Để tránh điều này, khóa và bản đồ phải không thay đổi được. Đây là lý do chính tại sao các lớp bất biến như String, Integer và các lớp tương tự khác là những lựa chọn tốt để tạo khóa.

    Nhưng hãy nhớ rằng tính bất biến được khuyến khích nhưng không bắt buộc. Nếu bạn muốn đặt một đối tượng có thể thay đổi làm khóa thì bạn phải đảm bảo rằng đối tượng khóa đó không thay đổi mã băm của đối tượng. Điều này có thể được thực hiện bằng cách ghi đè phương thức hashCode(). Ngoài ra, các lớp khóa phải hoạt động chính xác với các phương thức hashCode() và Equals() để tránh hành vi thực thi không mong muốn và đáng ngạc nhiên.

  2. Sự khác biệt giữa HashMap và ConcurrentHashMap

    Whatбы лучше визуализировать СoncurrentHashMap нужно рассматривать этот класс How группу HashMap’ов. Whatбы брать и класть значения пар(key-value) в HashMap необходимо вычислить хэш-code и найти правильный сегмент массива Collection.Entry. В ConcurrentHashMap отличие заключается во внутренней структуре для хранения пар key-value. ConcurrentHashMap имеет дополнительную концепцию сегментов. Будет легко понять если представить, что один сегмент эквивалентен одному HashMap[концептуально]. ConcurrentHashMap разделена на множество сегментов [по умолчанию их число равно 16] при инициализации. ConcurrentHashMap похожим потокам примерно (16) получать одновременный доступ к этому сегменту, каждый поток работает одновременно с высоким параллелизмом. Отсюда, если ваша пара key-value хранится в сегменте 10 не нужно блокировать остальные 15 сегментов дополнительно. Такая структура обеспечивает очень высокий уровень параллелизма.

    HashMap và ConcurrentHashMap những câu hỏi phỏng vấn phổ biến - 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;
        }
    }

    Thêm về điều này trong bài viết tiếp theo. Nếu bạn thấy bài viết hữu ích hãy chia sẻ với bạn bè nhé! Chúc bạn học tập vui vẻ!

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION