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

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

Вопрос 161
Необходимо ли, чтобы каждый try блок был обязательно следован catch блоком?

Ответ: Нет, это не обязательно. Try блок может быть обязательно следован catch блоком ИЛИ finally блоком. Finally блок — это блок, который выполняется независимо от того, выброшено исключение или нет.

Возможные комбинации:
Комбинация Описание Валидная
try { } catch { } Try с catch блоком ✅ Да
try { } finally { } Try с finally блоком (без catch) ✅ Да
try { } catch { } finally { } Try с catch и finally блоками ✅ Да
try { } throws Try без catch/finally (только throws в методе) ✅ Да
try { } Try без catch и finally ❌ Нет
Примеры кода:

// Вариант 1: Try-Catch
try {
    int x = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Error: " + e.getMessage());
}

// Вариант 2: Try-Finally (без catch)
try {
    FileInputStream fis = new FileInputStream("file.txt");
} finally {
    System.out.println("Cleanup resources");
}

// Вариант 3: Try-Catch-Finally
try {
    int[] arr = new int[5];
    System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Index out of bounds!");
} finally {
    System.out.println("This always executes");
}

// Вариант 4: Try-Throws (в методе)
public void readFile() throws FileNotFoundException {
    FileInputStream fis = new FileInputStream("file.txt");
}
                
Назначение Finally:

Finally блок используется для очистки ресурсов (закрытие файлов, соединений БД, и т.д.), которые должны быть закрыты независимо от того, возникло исключение или нет.

Вопрос 162
Что такое Exception Propagation?

Ответ: Exception Propagation — это процесс, при котором исключение передается (распространяется) снизу вверх по стеку вызовов (call stack). Если исключение не обработано в одном методе, оно передается в вызывающий метод, и так далее вверх по стеку.

Как это работает:
  1. Исключение возникает в методе A
  2. Если оно не обработано (нет try-catch), оно передается в вызывающий метод B
  3. Если не обработано в B, передается в метод C
  4. И так продолжается вверх по стеку
  5. Если достигает главного метода (main) без обработки, программа завершается
Пример Exception Propagation:

public class ExceptionPropagation {
    
    // Метод 1 - выбрасывает исключение
    public static void methodA() {
        int x = 10 / 0;  // ArithmeticException!
    }
    
    // Метод 2 - вызывает methodA (исключение пройдет сюда)
    public static void methodB() {
        methodA();  // Исключение propagates отсюда
    }
    
    // Метод 3 - вызывает methodB (исключение пройдет сюда)
    public static void methodC() {
        methodB();  // Исключение propagates отсюда
    }
    
    public static void main(String[] args) {
        try {
            methodC();  // Исключение может быть обработано здесь
        } catch (ArithmeticException e) {
            System.out.println("Caught in main: " + e.getMessage());
        }
    }
}

// Stack trace показывает путь распространения:
// at ExceptionPropagation.methodA()
// at ExceptionPropagation.methodB()
// at ExceptionPropagation.methodC()
// at ExceptionPropagation.main()
                
Unchecked Exception Propagation:

Unchecked исключения (RuntimeException) автоматически propagate вверх по стеку без необходимости объявления throws.

Checked Exception Propagation:

Checked исключения требуют либо обработки (try-catch), либо объявления в методе с помощью throws для propagation.


// Checked Exception - необходимо объявить throws
public static void readFile() throws IOException {
    // IOException будет propagate вверх
    FileInputStream fis = new FileInputStream("file.txt");
}

public static void main(String[] args) {
    try {
        readFile();  // IOException может быть обработано здесь
    } catch (IOException e) {
        System.out.println("File error: " + e.getMessage());
    }
}
                
Вопрос 163
Что произойдет, если поместить System.exit(0) в try или catch блок? Выполнится ли finally блок?

Ответ: System.exit(int) имеет возможность выбросить SecurityException. Если возникает исключение безопасности, то finally блок будет выполнен. В противном случае JVM закроется при вызове System.exit(0), и finally блок НЕ будет выполнен.

Сценарии:
Сценарий Результат
System.exit(0) выполнен без SecurityException Finally НЕ выполнится, JVM закроется
System.exit(0) выбросил SecurityException Finally ВЫПОЛНИТСЯ, программа продолжит работу
Пример 1: Обычный случай (SecurityException не выброшен):

public class SystemExitExample {
    public static void main(String[] args) {
        try {
            System.out.println("In try block");
            System.exit(0);  // JVM закроется, finally не выполнится
        } catch (Exception e) {
            System.out.println("In catch block");
        } finally {
            System.out.println("In finally block - НЕ будет выполнено!");
        }
    }
}

// Вывод:
// In try block
// (Программа завершится - finally не выполнится)
                
Пример 2: С SecurityException:

// Если SecurityManager установлен и выбросит SecurityException
public class SystemExitWithSecurity {
    public static void main(String[] args) {
        // Установка SecurityManager, который не позволит exit
        System.setSecurityManager(new SecurityManager() {
            @Override
            public void checkExit(int status) {
                throw new SecurityException("Exit not allowed");
            }
        });
        
        try {
            System.out.println("In try block");
            System.exit(0);  // Выбросит SecurityException
        } catch (SecurityException e) {
            System.out.println("In catch block: " + e.getMessage());
        } finally {
            System.out.println("In finally block - ВЫПОЛНИТСЯ!");
        }
    }
}

// Вывод:
// In try block
// In catch block: Exit not allowed
// In finally block - ВЫПОЛНИТСЯ!
                
Вывод:

✅ Finally выполнится, только если System.exit(0) выбросит исключение (SecurityException).

❌ Finally НЕ выполнится, если System.exit(0) успешно завершит JVM.

Вопрос 164
Что вы понимаете под Object Cloning и как это достичь в Java?

Ответ: Object Cloning — это процесс создания точной копии существующего объекта в Java. Клонированный объект имеет такое же состояние (значения полей), но это отдельный экземпляр в памяти.

Как достичь Object Cloning:
  • Класс должен реализовать интерфейс Cloneable
  • Переопределить метод clone(), предоставленный классом Object
  • Вызвать метод clone() для создания копии объекта
Важные моменты:
  • Cloneable — это маркер-интерфейс (не содержит методов)
  • Если класс не реализует Cloneable, выбросит CloneNotSupportedException
  • По умолчанию clone() выполняет shallow copy (поверхностное копирование)
  • Для deep copy нужна явная кастомизация
Пример: Shallow Clone (по умолчанию):

// Шаг 1: Реализация Cloneable
class Student implements Cloneable {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Шаг 2: Переопределение clone()
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();  // Shallow copy
    }
    
    public void display() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

// Шаг 3: Использование
public class CloneExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student original = new Student("Alice", 20);
        
        // Создание копии
        Student cloned = (Student) original.clone();
        
        original.display();  // Name: Alice, Age: 20
        cloned.display();    // Name: Alice, Age: 20
        
        // Это разные объекты в памяти
        System.out.println(original == cloned);  // false
    }
}
                
Пример: Deep Clone (глубокое копирование):

class Address implements Cloneable {
    private String city;
    
    public Address(String city) {
        this.city = city;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Person implements Cloneable {
    private String name;
    private Address address;
    
    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }
    
    // Deep clone - копирует и вложенные объекты
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        // Deep copy вложенного объекта
        cloned.address = (Address) this.address.clone();
        return cloned;
    }
}
                
Shallow Clone vs Deep Clone:
Характеристика Shallow Clone Deep Clone
Примитивные типы Копируются значения Копируются значения
Ссылки на объекты Копируются ссылки (указывают на один объект) Копируются самі объекты
Использование памяти Меньше (быстрее) Больше (медленнее)
Изменение вложенных объектов Влияет на оригинал Не влияет на оригинал
Вопрос 165
Как исключения влияют на программу, если они не обработаны?

Ответ: Исключения отвечают за резкое прерывание выполнения программы. Код, написанный после возникновения исключения, не выполняется, если исключение не обработано.

Влияние необработанного исключения:
  • Программа резко прерывается (abnormal termination)
  • Код после возникновения исключения не выполняется
  • Выводится stack trace (трассировка стека вызовов)
  • Используемые ресурсы могут остаться без очистки
  • Программа завершается с ошибкой
Пример необработанного исключения:

public class UnhandledExceptionExample {
    public static void main(String[] args) {
        System.out.println("Program starts");
        
        // ArithmeticException возникает
        int result = 10 / 0;  // ИСКЛЮЧЕНИЕ!
        
        // Эта строка НЕ выполнится
        System.out.println("Result: " + result);
        
        System.out.println("Program ends");  // НЕ выполнится!
    }
}

// Вывод:
// Program starts
// Exception in thread "main" java.lang.ArithmeticException: / by zero
//     at UnhandledExceptionExample.main(UnhandledExceptionExample.java:8)
// (Программа завершилась с ошибкой)
                
Пример обработанного исключения:

public class HandledExceptionExample {
    public static void main(String[] args) {
        System.out.println("Program starts");
        
        try {
            int result = 10 / 0;  // ИСКЛЮЧЕНИЕ, но обработано!
        } catch (ArithmeticException e) {
            System.out.println("Error caught: " + e.getMessage());
        }
        
        // Эта строка ВЫПОЛНИТСЯ (программа продолжает работу)
        System.out.println("Program continues");
        
        System.out.println("Program ends");
    }
}

// Вывод:
// Program starts
// Error caught: / by zero
// Program continues
// Program ends
                
Проблемы необработанных исключений:
Проблема Описание
Резкое прерывание Программа завершается неожиданно
Утечка ресурсов Файлы, соединения БД могут остаться открытыми
Потеря данных Несохраненные данные теряются
Плохая пользовательский опыт Пользователь видит техническую ошибку вместо понятного сообщения
Сложность отладки Stack trace может быть неинформативным
Best Practices:
  • Всегда обрабатывайте проверяемые (checked) исключения
  • Обрабатывайте распространенные unchecked исключения
  • Используйте finally для очистки ресурсов
  • Используйте try-with-resources для автоматического закрытия ресурсов
  • Логируйте исключения для отладки
Вопрос 166
Какое использование final keyword?

Ответ: Final keyword используется для создания non-virtual функций. По умолчанию все функции в Java являются virtual (переопределяемыми), поэтому для создания non-virtual функций используется final keyword.

Использование Final Keyword:

Final keyword может быть применен к трем типам элементов:

Применение Описание Результат
Final методы Предотвращает переопределение методов в подклассах Метод не может быть переопределен (non-virtual)
Final классы Предотвращает наследование класса Класс не может быть расширен
Final переменные Делает переменную константой Значение не может быть изменено после инициализации
1. Final методы:

Метод помеченный как final не может быть переопределен в подклассах:


class Parent {
    // Final метод - не может быть переопределен
    public final void display() {
        System.out.println("Parent display");
    }
}

class Child extends Parent {
    // ОШИБКА КОМПИЛЯЦИИ!
    // @Override
    // public void display() {  // Cannot override final method
    //     System.out.println("Child display");
    // }
}
                
2. Final классы:

Класс помеченный как final не может быть расширен (унаследован):


// Final класс - не может быть расширен
public final class ImmutableClass {
    private String value;
    
    public ImmutableClass(String value) {
        this.value = value;
    }
}

// ОШИБКА КОМПИЛЯЦИИ!
// class Child extends ImmutableClass {  // Cannot extend final class
//     // ...
// }

// Примеры final классов в Java:
// String, Integer, Long, Boolean, Double и т.д.
                
3. Final переменные:

Переменная помеченная как final становится константой и не может быть изменена:


public class FinalVariableExample {
    // Final переменная уровня класса
    public static final double PI = 3.14159;
    
    // Final переменная уровня экземпляра
    private final String name;
    
    public FinalVariableExample(String name) {
        this.name = name;  // Инициализация один раз
    }
    
    public void example() {
        // Final локальная переменная
        final int MAX_VALUE = 100;
        
        // Попытка изменить вызовет ошибку компиляции
        // MAX_VALUE = 200;  // ОШИБКА: cannot assign a value to final variable
        
        // Попытка изменить поле
        // this.name = "NewName";  // ОШИБКА: cannot assign a value to final variable
    }
}
                
Преимущества Final Keyword:
  • Безопасность: Предотвращает нежелательное переопределение методов
  • Производительность: Компилятор может оптимизировать final методы и переменные
  • Immutability: Final переменные помогают создавать неизменяемые объекты
  • Четкость намерений: Показывает, что метод/класс не должен быть переопределен
  • Потокобезопасность: Final переменные часто используются в многопоточных программах
Virtual vs Non-Virtual методы:
Характеристика Virtual метод (обычный) Non-Virtual метод (final)
Переопределение ✅ Может быть переопределен ❌ Не может быть переопределен
Полиморфизм ✅ Использует dynamic dispatch ❌ Использует static dispatch
Производительность Немного медленнее (lookup в runtime) Быстрее (компилятор знает точный метод)
Гибкость ✅ Высокая ❌ Низкая
Примеры final классов в Java SDK:
  • java.lang.String
  • java.lang.Integer
  • java.lang.Boolean
  • java.lang.Double
  • java.util.Collections
Вопрос 167
Какое назначение keywords final, finally и finalize?

Ответ: Final, Finally и Finalize — это три разных ключевых слова/методов в Java, которые могут звучать похоже, но имеют совершенно разные назначения.

Сравнительная таблица:
Keyword/Метод Тип Назначение Применение
final Keyword Делает переменные/методы/классы non-overrideable Переменные, методы, классы
finally Block Выполняется всегда в try-catch, независимо от исключения Exception handling (try-catch-finally)
finalize() Method Вызывается перед удалением объекта Garbage Collector Очистка ресурсов перед GC
1. FINAL Keyword:

Final — это keyword, используемый с переменной, методом или классом, чтобы они не могли быть переопределены/изменены.

Пример Final переменной:

// Java Program to use final keyword
import java.io.*;

class GFG {
    // Main function
    public static void main(String[] args) {
        final int x = 100;
        x = 50;  // ОШИБКА КОМПИЛЯЦИИ!
    }
}

// Output:
// ./GFG.java:6: error: cannot assign a value to final variable x
//     x=50;
//     ^
// 1 error
                
Пример Final метода:

class Parent {
    final void display() {
        System.out.println("Parent display");
    }
}

class Child extends Parent {
    // ОШИБКА КОМПИЛЯЦИИ!
    // void display() {  // Cannot override final method
    //     System.out.println("Child display");
    // }
}
                
Пример Final класса:

public final class FinalClass {
    // Этот класс не может быть расширен
}

// ОШИБКА КОМПИЛЯЦИИ!
// class Child extends FinalClass {  // Cannot extend final class
// }
                
2. FINALLY Block:

Finally — это блок кода, используемый с try-catch в обработке исключений. Код в finally блоке выполняется независимо от того, выброшено исключение или нет.

Пример Finally блока:

// Java Program to implement finally
import java.io.*;

class GFG {
    // Main function
    public static void main(String[] args) {
        int x = 10;
        
        // try block
        try {
            System.out.println("Try block");
        }
        // finally block
        finally {
            System.out.println("Always runs even without exceptions");
        }
    }
}

// Output:
// Try block
// Always runs even without exceptions
                
Пример Finally с исключением:

public class FinallyWithException {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;  // ArithmeticException
            System.out.println("Try block");
        } catch (ArithmeticException e) {
            System.out.println("Catch block: " + e.getMessage());
        } finally {
            System.out.println("Finally block - ВСЕГДА выполняется!");
        }
    }
}

// Output:
// Catch block: / by zero
// Finally block - ВСЕГДА выполняется!
                
3. FINALIZE() Method:

Finalize — это метод, который вызывается непосредственно перед удалением/уничтожением объектов, которые подходят для Garbage Collection, для выполнения очистки.

Пример Finalize метода:

package whatever;  // do not write package name here
import java.io.*;

class GFG {
    public static void main(String[] args) {
        System.out.println("Main function running");
        System.gc();  // Вызов Garbage Collector
    }
    
    // Here overriding finalize method
    public void finalize() {
        System.out.println("finalize method overridden");
    }
}

// Output:
// Main function running
// (finalize может быть вызван GC перед удалением объекта)
                
Более подробный пример Finalize:

class Resource {
    private String name;
    
    public Resource(String name) {
        this.name = name;
        System.out.println("Resource created: " + name);
    }
    
    @Override
    protected void finalize() throws Throwable {
        try {
            System.out.println("Finalize called for: " + name);
            // Cleanup: закрытие файлов, БД соединений и т.д.
            System.out.println("Resource cleanup: " + name);
        } finally {
            super.finalize();
        }
    }
}

public class FinalizeExample {
    public static void main(String[] args) {
        Resource r1 = new Resource("Resource1");
        Resource r2 = new Resource("Resource2");
        
        r1 = null;  // Eligible для GC
        r2 = null;  // Eligible для GC
        
        System.gc();  // Предлагаем JVM запустить GC
        System.out.println("Main completed");
    }
}
                
Детальные отличия:
Характеристика final finally finalize()
Введен в Java версии Java 1.0 Java 1.0 Java 1.0
Тип Keyword (модификатор) Block (блок кода) Method (метод)
Область использования Переменные, методы, классы Exception handling (try-catch) Garbage collection
Является ли опциональным Опционально Опционально (но рекомендуется) Опционально (deprecated)
Гарантия выполнения Во время компиляции Во время выполнения (гарантировано) Во время выполнения (не гарантировано)
Best Practices:
  • Final: Используйте для создания immutable объектов и предотвращения нежелательного переопределения
  • Finally: Используйте для очистки ресурсов (файлы, соединения БД). Рекомендуется использовать try-with-resources вместо finally
  • Finalize: DEPRECATED! Используйте AutoCloseable интерфейс или try-with-resources вместо finalize()
⚠️ Важно: Метод finalize() считается deprecated (устаревшим) с Java 9. Вместо него используйте:
  • AutoCloseable интерфейс
  • Try-with-resources statement
  • Explicit cleanup методы
Вопрос 168
Какая разница между this() и super() в Java?

Ответ: this() и super() — это специальные ссылки в Java, которые используются для обращения к методам и переменным. Хотя они звучат похоже, они имеют совершенно разные назначения.

Сравнительная таблица:
Характеристика this() super()
Представляет Текущий экземпляр класса Текущий экземпляр родительского класса
Вызов конструктора Вызывает конструктор того же класса Вызывает конструктор базового класса
Доступ к методам Обращается к методам того же класса Обращается к методам родительского класса
На что указывает Указывает на текущий экземпляр класса Указывает на экземпляр суперкласса
Пример this():

class Student {
    private String name;
    private int age;
    
    // Конструктор 1
    public Student() {
        this("Unknown", 0);  // Вызов другого конструктора того же класса
    }
    
    // Конструктор 2
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Метод with this
    public void display() {
        System.out.println("Name: " + this.name + ", Age: " + this.age);
    }
}

public class ThisExample {
    public static void main(String[] args) {
        Student s1 = new Student();  // Вызовет конструктор 1, который вызовет конструктор 2
        s1.display();  // Name: Unknown, Age: 0
        
        Student s2 = new Student("Alice", 20);
        s2.display();  // Name: Alice, Age: 20
    }
}
                
Пример super():

class Animal {
    private String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    public void display() {
        System.out.println("Animal name: " + name);
    }
}

class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name);  // Вызывает конструктор родительского класса
        this.breed = breed;
    }
    
    @Override
    public void display() {
        super.display();  // Вызывает метод родительского класса
        System.out.println("Dog breed: " + breed);
    }
}

public class SuperExample {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy", "Labrador");
        dog.display();
        // Output:
        // Animal name: Buddy
        // Dog breed: Labrador
    }
}
                
Key Differences (Ключевые отличия):
  • this: Используется для обращения к членам текущего класса
  • super: Используется для обращения к членам родительского класса
  • this(): ВСЕГДА должен быть первой строкой конструктора (если используется)
  • super(): ВСЕГДА должен быть первой строкой конструктора (если используется)
  • Нельзя использовать одновременно this() и super() в одном конструкторе
Вопрос 169
Что такое multitasking?

Ответ: Multitasking — это способность операционной системы выполнять множество задач или процессов одновременно для улучшения использования CPU и эффективности.

Характеристики Multitasking:
  • В Java множество программ или процессов могут работать одновременно
  • Достигается через процессно-ориентированный multitasking (несколько программ) и потокно-ориентированный multitasking (несколько потоков в одной программе)
  • Потокно-ориентированный multitasking легче и эффективнее, чем процессно-ориентированный
Два типа Multitasking:
Тип Описание Пример
Process-based Multitasking Несколько независимых программ работают одновременно Одновременное выполнение браузера и текстового редактора
Thread-based Multitasking Несколько потоков внутри одной программы работают одновременно Загрузка музыки + отображение интерфейса в одном приложении
Пример Thread-based Multitasking:

// Java program for multitasking
public class MyThread extends Thread {
    public void run() {
        // Code to be executed in this thread
        for (int i = 0; i < 10; i++) {
            System.out.println(
                "Thread " + Thread.currentThread().getId()
                + ": " + i);
        }
    }
}

public class GFG {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        
        // Start the threads
        thread1.start();
        thread2.start();
    }
}
                
Преимущества Multitasking:
  • Улучшенное использование CPU
  • Быстрое выполнение программы
  • Меньше затрат памяти (thread-based vs process-based)
  • Лучший пользовательский интерфейс (отзывчивая программа)
Вопрос 170
Что вы понимаете под многопоточной программой?

Ответ: Многопоточная программа (multithreaded program) — это программа, которая запускает два или более потока одновременно (конкурентно) внутри одного процесса для выполнения множества задач одновременно.

Характеристики Multithreaded программы:
  • Улучшает использование CPU за счет выполнения множества задач в параллель
  • Потоки в многопоточной программе разделяют одно и то же адресное пространство памяти, но работают независимо
  • В Java многопоточность достигается с помощью класса Thread или интерфейса Runnable
Как создать многопоточную программу:

Способ 1: Расширение Thread класса


class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running");
    }
}

public class MultiThreadExample {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        
        t1.start();  // Запускает первый поток
        t2.start();  // Запускает второй поток
    }
}
                

Способ 2: Реализация Runnable интерфейса


class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable thread is running");
    }
}

public class MultiThreadExample {
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable());
        Thread t2 = new Thread(new MyRunnable());
        
        t1.start();  // Запускает первый поток
        t2.start();  // Запускает второй поток
    }
}
                
Жизненный цикл потока (Thread Lifecycle):
Состояние Описание
New Поток создан, но еще не запущен
Runnable Поток запущен (start()) и готов к выполнению
Running Поток активно выполняется (методу run() назначен CPU)
Waiting/Blocked Поток ждет ресурса или блокирован
Terminated Поток завершил выполнение (run() вернул управление)
Пример: Две задачи одновременно

class Task1 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Task1 - " + i);
        }
    }
}

class Task2 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Task2 - " + i);
        }
    }
}

public class MultiThreadingDemo {
    public static void main(String[] args) {
        Task1 t1 = new Task1();
        Task2 t2 = new Task2();
        
        t1.start();
        t2.start();
        
        // Оба потока работают одновременно!
    }
}
                
Преимущества Multithreaded программ:
  • Лучшее использование ресурсов: CPU может выполнять другие потоки, пока один ждет I/O операции
  • Отзывчивый интерфейс: UI остается отзывчивым даже если выполняется долгая операция
  • Параллельное выполнение: Несколько задач выполняются одновременно
  • Экономия памяти: Потоки разделяют память в отличие от отдельных процессов
Thread vs Runnable:
Аспект Extends Thread Implements Runnable
Наследование ✅ Класс может расширять только Thread ✅ Класс может реализовывать несколько интерфейсов
Гибкость ❌ Менее гибко ✅ Более гибко
Рекомендуется ❌ Устарело ✅ Современный подход