☕ Вопросы интервью по Java

Вопросы 151-160 для опытных разработчиков

Вопрос 151
Объясните FailFast и FailSafe итераторы

Ответ: Fail-Fast и Fail-Safe - это два типа итераторов в Java коллекциях. Они отличаются в том, как ведут себя при модификации коллекции во время итерации.

Fail-Fast Iterator:

Выбрасывает ConcurrentModificationException если коллекция модифицируется после создания итератора (кроме вызова remove() самого итератора).

  • Выбрасывает ConcurrentModificationException при структурной модификации
  • Работает напрямую с оригинальной коллекцией
  • Используется ArrayList, HashMap, HashSet
Пример Fail-Fast:

HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");

Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
    Integer key = iterator.next();
    // Выбросит ConcurrentModificationException
    if (key == 1) {
        map.remove(1);
    }
}
                
Fail-Safe Iterator:

Работает с копией (снимком) коллекции вместо оригинала. Модификации не влияют на итерацию.

  • Не выбрасывает ConcurrentModificationException
  • Итерирует клонированную копию коллекции
  • Используется CopyOnWriteArrayList, ConcurrentHashMap
Пример Fail-Safe:

ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
map.put(1, "one");
map.put(2, "two");

Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
    Integer key = iterator.next();
    // Не выбросит исключение
    if (key == 1) {
        map.remove(1);
    }
}
                
Вопрос 152
Что такое Exception Handling (Обработка исключений)?

Ответ: Exception Handling - это механизм в Java для обработки ошибок и непредвиденных ситуаций, которые прерывают нормальный ход выполнения программы.

Причины возникновения исключений:
  • Сбой оборудования (Device failure)
  • Потеря сетевого соединения (Loss of Network Connection)
  • Ошибки в коде (Code Errors)
  • Открытие недоступного файла (Opening an Unavailable file)
  • Некорректный ввод пользователя (Invalid User Input)
  • Физические ограничения (Physical Limitations - out of disk memory)
Блоки обработки исключений:
Блок Назначение
try Содержит код, который может выбросить исключение
catch Обрабатывает конкретное исключение
finally Выполняется всегда, используется для очистки ресурсов
throw Явно выбрасывает исключение
throws Объявляет, что метод может выбросить исключение
Синтаксис Try-Catch-Finally:

try {
    // Код который может выбросить исключение
    int result = 10 / 0;
} catch (ArithmeticException e) {
    // Обработка исключения
    System.out.println("Ошибка: " + e.getMessage());
} finally {
    // Выполняется всегда
    System.out.println("Очистка ресурсов");
}
                
Вопрос 153
Сколько типов исключений может возникнуть в Java программе?

Ответ: Существует два основных типа исключений в Java:

1. Built-in Exceptions (Встроенные исключения):

Встроенные исключения предоставляются библиотеками Java и делятся на две категории:

  • Checked Exceptions (Проверяемые):
    • IOException
    • FileNotFoundException
    • SQLException
    • ClassNotFoundException
  • Unchecked Exceptions (Непроверяемые):
    • NullPointerException
    • ArrayIndexOutOfBoundsException
    • ArithmeticException
    • ClassCastException
2. User-Defined Exceptions (Пользовательские исключения):

Пользовательские исключения определяются программистами для обработки специфических ситуаций, не покрытых встроенными исключениями. Создаются расширением подходящего класса исключения:


// Пользовательское исключение
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

// Использование
try {
    int age = 10;
    if (age < 18) {
        throw new InvalidAgeException("Возраст должен быть >= 18");
    }
} catch (InvalidAgeException e) {
    System.out.println(e.getMessage());
}
                
Вопрос 154
Разница между Error и Exception

Ответ: Error и Exception - это два разных типа проблем в Java, но они часто путаются:

Характеристика Error Exception
Восстановление Невозможно восстановиться Можно восстановиться
Тип проверки Все unchecked (непроверяемые) Checked и Unchecked
Причина Проблема в окружении (JVM) Проблема в программе
Время возникновения Compile time и Runtime Runtime (в основном)
Пакет java.lang.Error java.lang.Exception
Примеры StackOverflowError, OutOfMemoryError, VirtualMachineError NullPointerException, IOException, SQLException
Примеры Error:
  • StackOverflowError - переполнение стека (бесконечная рекурсия)
  • OutOfMemoryError - недостаточно памяти
  • VirtualMachineError - ошибка JVM
  • LinkageError - ошибка связывания классов
Примеры Exception:
  • NullPointerException - обращение к null
  • IOException - ошибка ввода/вывода
  • SQLException - ошибка базы данных
  • FileNotFoundException - файл не найден
Когда использовать что?

Error: Не обрабатывайте Error в вашем коде. Это системные ошибки, которые указывают на критические проблемы в JVM или окружении.

Exception: Обрабатывайте исключения в своем коде с помощью try-catch или throws.

Вопрос 155
Объясните иерархию классов Java Exception

Ответ: Иерархия исключений Java - это структура классов, которая организует все исключения и ошибки под классом Throwable. Она помогает Java классифицировать и обрабатывать различные типы проблем во время выполнения эффективно.

Основные моменты:
  • Throwable - это корневой класс иерархии исключений
  • Он имеет два основных подкласса: Exception и Error
  • Exception включает проверяемые и непроверяемые исключения (RuntimeException и его подклассы)
Структура иерархии:

Object
↓
Throwable
↙ ↘
Error ← Unchecked      Exception
                                ↙ ↘
                      RuntimeException ← Unchecked     Other Exceptions ← Checked

Типы исключений:
Тип Описание Примеры
Error (Unchecked) Системные ошибки JVM, не подлежат обработке StackOverflowError, OutOfMemoryError
Checked Exception Исключения, которые должны быть обработаны или объявлены (throws) IOException, FileNotFoundException, SQLException
Unchecked Exception (RuntimeException) Исключения, которые могут быть обработаны или нет NullPointerException, ArrayIndexOutOfBoundsException
Примеры кода:

// Checked Exception - должен быть обработан
try {
    FileInputStream fis = new FileInputStream("file.txt");
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

// Unchecked Exception - может быть обработан или нет
try {
    int[] arr = new int[5];
    System.out.println(arr[10]);  // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Index out of bounds");
}

// Error - не обрабатывается
// StackOverflowError произойдет при бесконечной рекурсии
                
Вопрос 156
Объясните Runtime Exceptions

Ответ: Runtime Exceptions - это исключения, которые возникают во время выполнения программы и не проверяются компилятором. Они обычно результат ошибок программирования или неправильной логики.

Характеристики Runtime Exceptions:
  • Являются подклассами RuntimeException
  • Не требуют явной обработки с помощью try-catch или объявления с помощью throws
  • Возникают из-за ошибок в коде программиста
  • Проверяются только во время выполнения, а не при компиляции
Примеры Runtime Exceptions:
Исключение Описание Пример
NullPointerException Обращение к методу/полю null объекта String s = null; s.length();
ArithmeticException Математическая ошибка (деление на 0) int x = 10 / 0;
ArrayIndexOutOfBoundsException Обращение к элементу за пределами массива int[] arr = {1, 2}; arr[5];
ClassCastException Неправильное приведение типов Object obj = "text"; Integer i = (Integer) obj;
IllegalArgumentException Недопустимый аргумент метода Thread.sleep(-100);
Пример кода:

// RuntimeException - не требует обработки, но может быть обработано
public class RuntimeExceptionExample {
    public static void main(String[] args) {
        // NullPointerException
        try {
            String str = null;
            System.out.println(str.length());  // Выбросит NPE
        } catch (NullPointerException e) {
            System.out.println("NullPointerException caught!");
        }
        
        // ArithmeticException
        try {
            int result = 10 / 0;  // Выбросит ArithmeticException
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero!");
        }
        
        // ArrayIndexOutOfBoundsException
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[10]);  // Выбросит ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index out of bounds!");
        }
    }
}
                
Вопрос 157
Что такое NullPointerException?

Ответ: NullPointerException - это тип runtime исключения, которое выбрасывается, когда программа пытается использовать ссылку на объект, которая имеет значение null.

Когда возникает:
  • При обращении к методу null объекта
  • При обращении к полю null объекта
  • При получении длины null массива
  • При обращении к элементу null массива
  • При выбросе null исключения
Основное назначение:

Основное назначение NullPointerException - указать, что никакое значение не присвоено переменной ссылки. Также оно используется для реализации структур данных, таких как связные списки и деревья.

Примеры NullPointerException:

// Пример 1: Обращение к методу null объекта
String str = null;
System.out.println(str.length());  // NullPointerException

// Пример 2: Обращение к полю null объекта
class Person {
    public String name;
}
Person person = null;
System.out.println(person.name);  // NullPointerException

// Пример 3: Синхронизация на null объекте
Object obj = null;
synchronized(obj) {  // NullPointerException
    // код
}

// Пример 4: Throw null исключения
try {
    throw null;  // NullPointerException
} catch (Exception e) {
    e.printStackTrace();
}
                
Как избежать:

// 1. Проверка перед использованием
String str = null;
if (str != null) {
    System.out.println(str.length());
}

// 2. Использование Optional (Java 8+)
Optional<String> optional = Optional.ofNullable(str);
optional.ifPresent(s -> System.out.println(s.length()));

// 3. Инициализация значением по умолчанию
String str = "default";

// 4. Использование Objects.requireNonNull()
import java.util.Objects;
String str = Objects.requireNonNull(inputStr, "String cannot be null");
                
Вопрос 158
Когда выбрасывается ArrayStoreException?

Ответ: ArrayStoreException выбрасывается, когда предпринимается попытка сохранить неправильный тип объекта в массиве объектов.

Когда возникает:
  • При попытке сохранить объект несовместимого типа в типизированном массиве
  • Это runtime исключение (подкласс RuntimeException)
  • Возникает только при работе с массивами объектов, а не примитивных типов
Примеры ситуаций:
Ситуация Описание
Массив Double[] и попытка добавить Integer Integer не совместим с Double, выбросит ArrayStoreException
Массив String[] и попытка добавить Integer Integer не совместим с String, выбросит ArrayStoreException
Массив Number[] и попытка добавить String String не является подклассом Number, выбросит ArrayStoreException
Пример кода:

// Java программа для демонстрации ArrayStoreException
public class GFG {
    public static void main(String args[])
    {
        // Поскольку Double класс расширяет Number класс
        // только значения типа Double
        // могут быть сохранены в этом массиве
        Number[] a = new Double[2];
        
        // Попытка сохранить значение Integer
        // в этом массиве типа Double
        try {
            a[0] = new Integer(4);
        } catch (ArrayStoreException e) {
            System.out.println("ArrayStoreException caught!");
            System.out.println("Cannot store Integer in Double array");
        }
    }
}
                
Вывод примера:

ArrayStoreException caught!
Cannot store Integer in Double array
                
Как избежать:
  • Убедитесь, что тип сохраняемого объекта совместим с типом массива
  • Используйте Generics (List<Double> вместо массива) для типобезопасности на этапе компиляции
  • Проверяйте тип перед сохранением: if (obj instanceof Double) { a[0] = (Double) obj; }
  • Используйте Generics Lists вместо массивов когда возможно: List<Double> list = new ArrayList<>();
Вопрос 159
Какая разница между Checked Exception и Unchecked Exception?

Ответ: Checked и Unchecked Exceptions отличаются в том, как компилятор их обрабатывает. Checked исключения проверяются во время компиляции, а unchecked исключения возникают во время выполнения.

Основные отличия:
Характеристика Checked Exception Unchecked Exception
Проверка Проверяется компилятором (Compile-time) Проверяется только во время выполнения (Runtime)
Обработка Обязательно обработать или объявить с throws Опционально обрабатывать
Иерархия Наследуются от Exception (кроме RuntimeException) Наследуются от RuntimeException
Причина Обычно внешние проблемы (файлы, сеть, БД) Обычно ошибки программирования и неправильная логика
Примеры IOException, FileNotFoundException, SQLException, ClassNotFoundException NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException
Детальное объяснение:

Checked Exceptions:

  • Должны быть обработаны в try-catch блоке
  • Или объявлены в методе с помощью throws
  • Обычно связаны с внешними ресурсами (файлы, сеть, база данных)
  • Компилятор выдаст ошибку, если они не обработаны

Unchecked Exceptions:

  • Не требуют явной обработки или объявления
  • Возникают из-за ошибок в коде программиста
  • Можно обработать, но это не обязательно
  • Компилятор не требует их обработки
Примеры кода:

// Checked Exception - ОБЯЗАТЕЛЬНО обработать
import java.io.*;

public class CheckedExceptionExample {
    public static void main(String[] args) {
        // FileNotFoundException - это Checked Exception
        // Компилятор требует обработки
        try {
            FileInputStream fis = new FileInputStream("file.txt");
        } catch (FileNotFoundException e) {
            System.out.println("File not found!");
            e.printStackTrace();
        }
    }
    
    // ИЛИ объявить в методе
    public static void readFile() throws FileNotFoundException {
        FileInputStream fis = new FileInputStream("file.txt");
    }
}
                

// Unchecked Exception - ОПЦИОНАЛЬНО обработать
public class UncheckedExceptionExample {
    public static void main(String[] args) {
        // NullPointerException - это Unchecked Exception
        // Компилятор НЕ требует обработки, но можно обработать
        
        // Вариант 1: Без обработки (компилятор согласен)
        String str = null;
        // System.out.println(str.length());  // Выбросит NPE
        
        // Вариант 2: С обработкой (опционально)
        try {
            System.out.println(str.length());
        } catch (NullPointerException e) {
            System.out.println("String is null!");
        }
    }
}
                
Когда использовать:

Checked Exception: Используйте когда код может выбросить исключение из-за внешних факторов, которые вне контроля программы.

Unchecked Exception: Используйте когда исключение результат ошибки в коде, которую можно предотвратить проверками.

Вопрос 160
Какой базовый класс для Error и Exception?

Ответ: Базовым классом для Error и Exception является java.lang.Throwable.

Иерархия классов:

Object
↓
Throwable
↙ ↘
Exceptions                 Error
├─ Checked Exceptions    ├─ Virtual Machine Error
│ (IO, Compile time)          ├─ Assertion Error
│
└─ Unchecked Exceptions
  (Runtime, Null Pointer)

Определение:
  • Error: Незаконная операция, выполняемая пользователем, которая вызывает ненормальность в программе. Error возникает из-за проблем с JVM, которые мы не можем контролировать.
  • Exception: Непредвиденные события или условия, которые возникают при выполнении программы. Exception нарушает нормальный ход выполнения инструкций программы.
Ключевые моменты:
Аспект Error Exception
Базовый класс java.lang.Throwable
Тип Системная ошибка JVM Непредвиденное событие или условие
Восстановление Невозможно восстановиться Можно восстановиться
Обработка Не обрабатывается Обрабатывается или объявляется
Контроль Вне контроля программы В контроле программы
Примеры StackOverflowError, OutOfMemoryError, VirtualMachineError IOException, FileNotFoundException, NullPointerException
Throwable класс:

java.lang.Throwable - это суперкласс всех ошибок и исключений в иерархии исключений Java. Он содержит общие методы для обработки исключений:


// Методы Throwable класса
public String getMessage()              // Возвращает сообщение об ошибке
public void printStackTrace()            // Выводит trace ошибки
public String toString()                // Возвращает строковое представление
public Throwable getCause()             // Возвращает причину исключения
public StackTraceElement[] getStackTrace() // Возвращает stack trace
                
Пример использования:

public class ThrowableExample {
    public static void main(String[] args) {
        try {
            // Может выбросить Exception
            int result = 10 / 0;
        } catch (Throwable t) {  // Catching Throwable (родитель Exception)
            System.out.println("Caught: " + t.getClass().getName());
            t.printStackTrace();
            System.out.println("Message: " + t.getMessage());
        }
    }
}

// Вывод:
// Caught: java.lang.ArithmeticException
// java.lang.ArithmeticException: / by zero
// Message: / by zero
                
Иерархия Throwable:
  • Throwable
    • Exception - Можем обработать
      • Checked Exception (IOException, SQLException)
      • RuntimeException (NullPointerException, ArithmeticException)
    • Error - Не можем обработать
      • VirtualMachineError
      • LinkageError
      • AssertionError