Работали ли вы с дженериками в Java?
Что проверяют
Знаете ли вы, что дженерики работают только на этапе компиляции, и понимаете ли следствия стирания. Это отсекающий вопрос: без него не обсудить ни коллекции, ни библиотечный код, ни собственные обобщённые интерфейсы.
Как отвечать
Начните с назначения: параметр типа переносит ошибку с исполнения на сборку и убирает ручные приведения. Дальше покажите, что владеете не только List<String>, а границами и подстановочными типами:
static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (T item : src) dst.add(item);
}Это правило принято называть PECS: источник объявляется через extends, приёмник через super. Из источника можно читать, в него нельзя писать, с приёмником наоборот. Отдельно проговорите стирание и его последствия: после компиляции параметр заменяется на границу или на Object, поэтому недоступны new T(), new T[], instanceof T, статическое поле типа T и перегрузка методов, различающихся только параметром коллекции. Когда тип нужен в рантайме, его передают явно через Class<T> или через фабрику. Полезно упомянуть рекурсивную границу <T extends Comparable<? super T>>: именно так объявлены методы сортировки в стандартной библиотеке.
Где спотыкаются
Останавливаются на школьном уровне. Говорят про безопасность типов и читаемость, но на вопрос про ? super замолкают, хотя это половина повседневной работы с обобщёнными интерфейсами.
Заявляют, что дженерики бесплатны по производительности, и забывают про упаковку. Обобщение работает только со ссылочными типами, поэтому List<Integer> хранит объекты, и в горячем цикле это заметно.
Живут с сырыми типами и подавленными предупреждениями. Сырой тип выключает проверки во всём классе, а @SuppressWarnings поверх непроверенного приведения прячет будущее падение вместо того, чтобы его убрать.