Какие бывают corner cases в программировании?
Что проверяют
Способны ли вы ещё до написания кода увидеть, где решение сломается, и проговорить это вслух. На лайв-кодинге вопрос часто звучит как «какие тесты вы бы написали к своей функции», и по ответу видно, проверяете ли вы границы по привычке или только по подсказке.
Как отвечать
Сгруппируйте случаи, так ответ звучит системно:
- пустые и крайние размеры:
nullвместо коллекции, пустой массив, один элемент, одинаковые элементы, очень большой вход, на котором рекурсия упрётся вStackOverflowError; - целые числа:
intпереполняется молча,Integer.MAX_VALUE + 1даётInteger.MIN_VALUE.Math.abs(Integer.MIN_VALUE)возвращает отрицательное число, а середина отрезка через(lo + hi) / 2переполняется, правильноlo + (hi - lo) / 2или(lo + hi) >>> 1. Для строгой арифметики естьMath.addExact; - дробные числа:
0.1 + 0.2 != 0.3,NaNне равен сам себе, деление на ноль вdoubleдаётInfinity, а вintбросаетArithmeticException. Деньги считают вBigDecimal; - строки: пустая строка, одни пробелы, символы за пределами BMP (эмодзи занимает минимум два
char, иlength()не равен числу символов), регистр с учётом локали; - коллекции:
ConcurrentModificationExceptionпри удалении внутри for-each, неизменяемыйList.of(), сравнениеIntegerчерез==, которое работает только в кэше для значений от-128до127; - время: часовые пояса, переход на летнее время, 29 февраля, конец месяца.
На собеседовании назовите пару случаев до кода, а после напишите по ним проверки. Это ценится больше, чем красивое решение, которое падает на пустом массиве.
Где спотыкаются
Путают крайний случай с нагрузочным тестом. Стресс-тест проверяет производительность, крайний случай проверяет корректность на конкретном вводе.
Лечат всё проверкой на null в начале метода, но не решают, что вернуть: пустой результат, Optional или исключение. Контракт метода важнее самой проверки.
Перечисляют общие случаи без связи с задачей. Сильнее назвать три, которые ломают именно ваш алгоритм, чем двадцать из учебника.