› Иерархия коллекций

› Внутреннее устройство коллекций
List: ArrayList vs LinkedList
- ArrayList: Динамический массив.
- Доступ по индексу:
O(1). Вставка в конец:O(1). Вставка в середину:O(N). - При нехватке места массив увеличивается в 1.5 раза (
oldCapacity + (oldCapacity >> 1)). - Преимущество: Идеально работает с кэшем процессора (данные лежат непрерывно).
- Доступ по индексу:
- LinkedList: Двусвязный список.
- Доступ по индексу:
O(N). Вставка:O(1)(только если уже есть ссылка на ноду, иначе поиск займетO(N)). - Недостаток: Большой оверхед по памяти (ссылки prev/next), плохо дружит с кэшем CPU.
- Доступ по индексу:
Map: HashMap (Под капотом)
Массив бакетов (корзин), по умолчанию размер 16.
- Добавление
put(K, V):- Вычисляется хэш:
hash = key.hashCode() ^ (key.hashCode() >>> 16)(защита от плохих хэш-функций). - Индекс бакета:
index = (n - 1) & hash(быстрый аналог остатка от деления). - Если коллизия (бакет занят) — ключи сравниваются через
equals(). Если равны — перезапись, если нет — добавление в связный список.
- Вычисляется хэш:
- Treeification (Java 8): Если в бакете >= 8 элементов (и общий размер Map >= 64), список превращается в Красно-черное дерево (поиск ускоряется с
O(N)доO(log N)). - Resizing: При заполнении на 75% (Load Factor = 0.75) массив увеличивается в 2 раза, все элементы перехэшируются
O(N).
Set: HashSet
Под капотом использует HashMap. Элементы сета кладутся как ключи, а в качестве значений используется константа-заглушка private static final Object PRESENT = new Object();.
› Generics (Дженерики)
Обеспечивают типобезопасность на этапе компиляции.
- Raw Types (Сырые типы): Использование дженерик-класса без указания типа (например, просто
ListвместоList<String>).- Оставлены только для обратной совместимости со старым кодом (до Java 5).
- Опасность: Компилятор не проверяет типы, можно положить
Integerв список дляString, что приведет кClassCastExceptionв рантайме. Использовать в новом коде запрещено.
- Type Erasure (Стирание типов): В рантайме JVM не знает о дженериках.
List<String>превращается в сыройList, а типы заменяются наObject(или на верхнюю границуextends). Далее в рантайме происходит кастование к необходимому типу. - PECS (Producer Extends, Consumer Super): Правило для Wildcards (
?).? extends T(Producer): Из коллекции можно читать (получимT), но нельзя писать (кромеnull).? super T(Consumer): В коллекцию можно писать (Tи наследников), но при чтении получим толькоObject.
› Exceptions (Исключения)

- Иерархия:
Throwable->Error(критичные, не ловим) иException(ошибки приложения). - Checked vs Unchecked:
- Unchecked: Наследники
RuntimeException. Компилятор не требует их обрабатывать (например,NullPointerException). - Checked: Наследники
Exception. Обязательно оборачивать вtry-catchили пробрасывать черезthrows. (В современных фреймворках считаются антипаттерном).
- Unchecked: Наследники
- try-with-resources: Автоматически закрывает ресурсы (имплементирующие
AutoCloseable). Если исключение падает и вtry, и при закрытии, второе добавляется к первому как Suppressed (подавленное).
› IO / NIO
- java.io (IO): Потоки (Streams). Блокирующий ввод-вывод. Поток зависает, ожидая данных. Использует паттерн Decorator (
BufferedReader(FileReader)). - java.nio (New IO): Буферы и Каналы. Неблокирующий ввод-вывод. Один поток может управлять тысячами соединений через
Selector(мультиплексирование). Идеально для чатов и веб-сокетов.