Что произойдёт при обходе LinkedHashMap, созданного с accessOrder = true, если во время итерации вызвать get() по существующему ключу?
В режиме accessOrder даже get переносит запись в конец — это структурная модификация, итератор бросит ConcurrentModificationException.
- В режиме порядка вставки get и замена значения безопасны
- Документированное, но неожиданное поведение
- Обходить с чтением — копия ключей или режим вставки
А ещё Особенно коварно в LRU-кэше с логированием при обходе
Подробно
Неожиданная, но задокументированная деталь: в режиме порядка доступа get перемещает запись в конец списка, что для итератора неотличимо от изменения структуры. В режиме порядка вставки (по умолчанию) такой проблемы нет — там структурной модификацией считается только добавление или удаление, а замена значения по существующему ключу безопасна. Практический вывод для LRU-кэша: не вызывайте get внутри цикла обхода той же карты, а если нужно снять срез, сначала скопируйте ключи.
Что хотят услышать
- Почему get — структурное изменение в accessOrder.
Частые ошибки
- Считать любой get безопасным во время итерации.
- Забывать, что в режиме вставки put по существующему ключу структурной модификацией не является.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Ничего особенного: get только читает и не меняет коллекцию
- ✗Итерация начнётся заново с первого элемента
- ✓get переставляет запись в конец, и итератор бросит ConcurrentModificationException
- ✗Запись будет перемещена в конец, а итератор её пропустит без каких-либо ошибок
Что спросят дальше
- Что вообще считается структурной модификацией карты?
- Как безопасно снять снимок содержимого во время активной работы с картой?
Разбор темы
- LinkedHashMap и LRU-кэш
Порядок вставки против порядка доступа, связанный список поверх HashMap и реализация LRU через removeEldestEntry.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.