Java | Вопросы собесов
11.4K subscribers
42 photos
3 videos
1.13K links
Download Telegram
🤔 Чем обеспечена иммутабельность строк?

1. Использование final char[] (до Java 9) – строка после создания не может быть изменена.
2. String Pool – при повторном использовании одинаковых строк объект не создается заново.
3. Безопасность многопоточного доступа – строки могут использоваться в потоках без блокировок.
4. Кэширование хеш-кода – ускоряет работу с HashMap, Set.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥4
🤔 Расскажи про транзитивность

Транзитивность — это математическое и логическое свойство отношений, означающее, что если A связано с B, а B связано с C, то A связано с C.

🚩Транзитивность в отношении эквивалентности (`equals`)

Согласно контракту метода equals(), он должен быть транзитивным
class Person {
String name;

Person(String name) {
this.name = name;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name.equals(person.name);
}
}

public class Main {
public static void main(String[] args) {
Person p1 = new Person("Иван");
Person p2 = new Person("Иван");
Person p3 = new Person("Иван");

System.out.println(p1.equals(p2)); // true
System.out.println(p2.equals(p3)); // true
System.out.println(p1.equals(p3)); // true (транзитивность)
}
}


🚩Транзитивность в сравнении (`compareTo` из `Comparable`)

Метод compareTo() должен соблюдать транзитивность:
class Student implements Comparable<Student> {
int age;

Student(int age) {
this.age = age;
}

@Override
public int compareTo(Student other) {
return Integer.compare(this.age, other.age);
}
}

public class Main {
public static void main(String[] args) {
Student s1 = new Student(25);
Student s2 = new Student(20);
Student s3 = new Student(15);

System.out.println(s1.compareTo(s2)); // > 0 (s1 > s2)
System.out.println(s2.compareTo(s3)); // > 0 (s2 > s3)
System.out.println(s1.compareTo(s3)); // > 0 (s1 > s3) (транзитивность)
}
}


🚩Транзитивность в наследовании (`extends` / `implements`)

В Java классы могут наследоваться транзитивно
class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal {}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🤔 Какими характеристиками должен обладать метод, чтобы функциональный интерфейс был функциональным?

1. Единственный абстрактный метод (SAM - Single Abstract Method) – в интерфейсе должен быть ровно один абстрактный метод.
2. Допустимые default и static методы – могут присутствовать, но не считаются абстрактными.
3. Совместимость с лямбда-выражениями – позволяет использовать функциональный стиль.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍121🔥1
🤔 Назови основные свойства транзакции

В базах данных и многопоточных системах транзакция — это атомарная последовательность операций, которая должна выполняться корректно и полностью.

🚩Атомарность (Atomicity) — "всё или ничего"
Транзакция выполняется полностью или не выполняется вовсе.
Перевод 1000 рублей с одного счёта на другой:
- Списать 1000 рублей с А
- Зачислить 1000 рублей на B
Если вторая операция не удалась, первая должна быть отменена.
try {
connection.setAutoCommit(false); // Отключаем автокоммит
withdraw(accountA, 1000);
deposit(accountB, 1000);
connection.commit(); // Подтверждаем транзакцию
} catch (Exception e) {
connection.rollback(); // Откат в случае ошибки
}


🚩Согласованность (Consistency) — "данные остаются корректными"

После транзакции данные должны оставаться в логически правильном состоянии.

🚩Изолированность (Isolation) — "отдельно от других транзакций"

Одна транзакция не должна мешать выполнению другой.
Два клиента одновременно бронируют одно и то же место в самолёте.
Система должна обработать их по очереди, а не одновременно.
В Java изолированность регулируется уровнями транзакций (TRANSACTION_READ_COMMITTED, TRANSACTION_REPEATABLE_READ и т. д.), чтобы избежать проблем, таких как "грязное чтение" или "фантомные записи".
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);


🚩Долговечность (Durability) — "данные не теряются"

После успешного завершения транзакции данные не должны теряться даже при сбоях (например, отключении электричества).

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
🤔 Что нужно делать для того, чтобы метод принимал и возвращал значения?

Метод должен:
1. Принимать параметры – через сигнатуру метода.
2. Иметь return – если должен возвращать значение.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13😁11🤯5💊1
🤔 Что за исключение Interrupted Exception?

InterruptedException — это проверяемое исключение (checked exception) в Java, которое выбрасывается, когда поток (Thread) прерывается во время выполнения метода, который поддерживает прерывание (например, sleep(), wait(), join() и др.).

🚩Почему `InterruptedException` существует?

В многопоточной среде иногда требуется прервать выполнение потока, например, для завершения долгой задачи или для корректной остановки программы. Вместо грубого завершения потока (Thread.stop(), который устарел и считается небезопасным) Java предлагает мягкий способ прерывания через флаг прерывания и обработку InterruptedException.

🚩Когда выбрасывается `InterruptedException`?

Это исключение выбрасывается, если поток:
1. Ожидает (wait(), join())
2. Спит (sleep())
3. Блокируется на очереди (BlockingQueue.take(), LockSupport.park())
И при этом его прерывают с помощью метода interrupt().

Пример кода: обработка InterruptedException
class MyThread extends Thread {
public void run() {
try {
System.out.println("Поток засыпает...");
Thread.sleep(5000); // Поток засыпает на 5 секунд
} catch (InterruptedException e) {
System.out.println("Поток был прерван во время сна!");
}
System.out.println("Поток продолжает работу...");
}
}

public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();

try {
Thread.sleep(2000); // Даем потоку 2 секунды поработать
} catch (InterruptedException e) {
e.printStackTrace();
}

t.interrupt(); // Прерываем поток
}
}


Вывод программы
Поток засыпает...
Поток был прерван во время сна!
Поток продолжает работу...


🚩Что делать после `InterruptedException`?

1. Просто обработать исключение (как в примере выше).
2. Передать исключение дальше — например, если метод не может корректно обработать прерывание, он передает его вызывающему коду:
   void myMethod() throws InterruptedException {
Thread.sleep(1000); // Может выбросить исключение
}


🟠Восстановить флаг прерывания
если прерывание важно для логики программы:
   catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Восстанавливаем флаг прерывания
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Можно ли без JDK вести Java-разработку?

Нет. JDK (Java Development Kit) содержит компилятор (javac), отладчик и библиотеки, без которых невозможна разработка.
Однако можно запускать Java-программы без JDK, используя только JRE (Java Runtime Environment), но без возможности компиляции.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥3
🤔 Базовые отличия между List и Linked List?

В Java List — это интерфейс, а его самые популярные реализации — ArrayList и LinkedList. Они имеют разную структуру данных, что влияет на производительность и область применения.

🚩Структура данных

ArrayList использует динамический массив, который хранит элементы в непрерывной области памяти.
LinkedList — это двусвязный список, где каждый элемент (Node) содержит ссылку на предыдущий и следующий элементы.

🚩Использование памяти

ArrayList требует непрерывного блока памяти, что может быть проблемой при нехватке места.
LinkedList требует дополнительной памяти на хранение ссылок (prev и next), что увеличивает общий размер.

Пример кода: разница в скорости вставки в середину списка
import java.util.*;

public class ListComparison {
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();

int size = 100000;

// Заполнение списков
for (int i = 0; i < size; i++) {
arrayList.add(i);
linkedList.add(i);
}

// Вставка в середину
long start = System.nanoTime();
arrayList.add(size / 2, 999);
long end = System.nanoTime();
System.out.println("ArrayList вставка в середину: " + (end - start) + " нс");

start = System.nanoTime();
linkedList.add(size / 2, 999);
end = System.nanoTime();
System.out.println("LinkedList вставка в середину: " + (end - start) + " нс");
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
🤔 Чем обусловлено то, что int ограничен в размере?

1. Фиксированный размер – int занимает 4 байта (32 бита) в памяти.
2. Диапазон значений – от -2^31 до 2^31 - 1 (-2 147 483 648 до 2 147 483 647).
3. Архитектура процессоров – 32-битные процессоры используют 4-байтовые регистры, что соответствует int.
4. Эффективность вычислений – фиксированный размер позволяет оптимизировать работу с памятью и процессором.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥2🤔21
🤔 Каким образом можно получить синхронизированные объекты стандартных коллекций?

В Java стандартные коллекции из java.util (например, ArrayList, HashMap, HashSet) не потокобезопасны. Чтобы использовать их в многопоточной среде, можно применять синхронизированные обёртки** и **коллекции из java.util.concurrent.

🚩Синхронизация с `Collections.synchronizedXXX()`

Java предоставляет методы для создания потокобезопасных обёрток над обычными коллекциями:
import java.util.*;

public class SynchronizedCollectionsExample {
public static void main(String[] args) {
List<Integer> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());
Set<Integer> syncSet = Collections.synchronizedSet(new HashSet<>());

syncList.add(1);
syncMap.put("key", "value");
syncSet.add(10);
}
}


🚩Важный момент: Итерация через `synchronized` коллекции

Даже если коллекция синхронизирована, её итерация не потокобезопасна.
for (Integer num : syncList) { // Возможен ConcurrentModificationException!
System.out.println(num);
}


Чтобы избежать ошибок, итерацию нужно делать внутри synchronized блока
synchronized (syncList) {
for (Integer num : syncList) {
System.out.println(num);
}
}


🚩Коллекции из `java.util.concurrent` (рекомендуемый вариант)

Вместо Collections.synchronizedXXX() лучше использовать современные конкурентные коллекции из java.util.concurrent. Они спроектированы для многопоточности и работают быстрее.
import java.util.concurrent.*;

public class ConcurrentMapExample {
public static void main(String[] args) {
ConcurrentMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("one", 1);
concurrentMap.put("two", 2);

System.out.println(concurrentMap.get("one")); // 1
}
}


Пример CopyOnWriteArrayList (потокобезопасный список, работающий через копии)
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteExample {
public static void main(String[] args) {
CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();
list.add(1);
list.add(2);

for (Integer num : list) { // Без ConcurrentModificationException!
System.out.println(num);
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🤔 Где ссылочные типы данных хранятся?

Ссылочные типы данных (объекты, массивы, строки) хранятся в куче (Heap), а ссылки на них – в стеке (Stack).
Когда создается объект, JVM выделяет память в куче, а переменная содержит ссылку на эту область памяти.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2
🤔 Для чего нужен функциональный интерфейс BiConsumer<T,U>?

BiConsumer<T, U> — это функциональный интерфейс из пакета java.util.function, который принимает два входных аргумента и не возвращает результат.

Сигнатура BiConsumer<T, U>
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
}


🚩Вывод пар значений

Допустим, у нас есть Map<String, Integer>, и мы хотим вывести все ключи и значения:
import java.util.Map;
import java.util.function.BiConsumer;

public class BiConsumerExample {
public static void main(String[] args) {
Map<String, Integer> map = Map.of("Alice", 30, "Bob", 25, "Charlie", 35);

// Используем BiConsumer для вывода ключа и значения
BiConsumer<String, Integer> printEntry = (key, value) ->
System.out.println("Имя: " + key + ", возраст: " + value);

// Применяем BiConsumer к каждому элементу Map
map.forEach(printEntry);
}
}


Вывод
Имя: Alice, возраст: 30  
Имя: Bob, возраст: 25
Имя: Charlie, возраст: 35


🚩Использование `BiConsumer` в `Stream`

Допустим, у нас есть список продуктов и их цены. Мы хотим увеличить цену каждого товара и напечатать результат.
import java.util.*;
import java.util.function.BiConsumer;

public class BiConsumerStreamExample {
public static void main(String[] args) {
Map<String, Double> products = new HashMap<>();
products.put("Хлеб", 50.0);
products.put("Молоко", 80.0);
products.put("Яблоки", 120.0);

// BiConsumer, который увеличивает цену и выводит её
BiConsumer<String, Double> increaseAndPrint = (name, price) -> {
double newPrice = price * 1.1; // +10%
System.out.println(name + " теперь стоит " + newPrice);
};

products.forEach(increaseAndPrint);
}
}


Вывод
Хлеб теперь стоит 55.0  
Молоко теперь стоит 88.0
Яблоки теперь стоят 132.0


🚩Объединение `BiConsumer` с `andThen()`

Метод andThen(BiConsumer<T, U>) позволяет объединять несколько действий в цепочку.
import java.util.function.BiConsumer;

public class BiConsumerChaining {
public static void main(String[] args) {
BiConsumer<String, Integer> printUser = (name, age) ->
System.out.println("Пользователь: " + name + ", возраст: " + age);

BiConsumer<String, Integer> checkAdult = (name, age) ->
System.out.println(name + (age >= 18 ? " совершеннолетний" : " несовершеннолетний"));

// Объединяем два BiConsumer'а
BiConsumer<String, Integer> combined = printUser.andThen(checkAdult);

combined.accept("Алексей", 20);
combined.accept("Мария", 16);
}
}


Вывод:
Пользователь: Алексей, возраст: 20  
Алексей совершеннолетний
Пользователь: Мария, возраст: 16
Мария несовершеннолетний


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24
🤔 Можно ли использовать equals() в том виде, в котором он есть?

Да, но по умолчанию метод equals() в классе Object сравнивает ссылки, а не содержимое объектов.
Для корректного сравнения объектов необходимо переопределить equals(), если сравнение по значению (а не по ссылке) важно.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍162
🤔 Для чего предназначены теги <dl>, <dt>, <dd>?

В HTML теги <dl>, <dt>, <dd> используются для создания списка определений. Этот список обычно применяется для отображения терминов и их описаний.

🚩Разбор тегов

🟠`<dl>` (Description List, "список описаний")
это контейнер, в котором размещаются определения.
🟠`<dt>` (Definition Term, "термин")
обозначает термин, который нужно определить.
🟠`<dd>` (Definition Description, "описание")
содержит описание или расшифровку термина.

<dl>
<dt>HTML</dt>
<dd>Язык разметки для создания веб-страниц.</dd>

<dt>CSS</dt>
<dd>Язык стилей, используемый для оформления HTML-документов.</dd>

<dt>JavaScript</dt>
<dd>Язык программирования, который добавляет интерактивность на веб-страницы.</dd>
</dl>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊8👍4
🤔 В чем разница между абстрактным классом и абстрактным методом, и абстрактным методом и интерфейсом?

- Абстрактный класс – класс, который нельзя создать напрямую (new), может содержать как абстрактные методы, так и реализацию.
- Абстрактный метод – метод без реализации, который должен быть переопределен в наследнике.
- Интерфейс – чистая абстракция (до Java 8), содержит только абстрактные методы (начиная с Java 8, допускает default и static методы).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍182🔥2
🤔 Как остановить поток?

Остановить поток в Java можно несколькими способами, но важно помнить, что принудительная остановка потока – плохая практика. Java предлагает безопасные методы управления потоком, чтобы избежать неожиданных ошибок и некорректного поведения программы.

🚩Плохие способы (НЕ рекомендуется)

Раньше использовался метод Thread.stop(), но он был устаревшим и удалённым из-за того, что мог оставить программу в неконсистентном состоянии.
Thread thread = new Thread(() -> {
while (true) {
System.out.println("Работаю...");
}
});

thread.start();
thread.stop(); // ОПАСНО! Может привести к некорректному завершению работы.


🚩Флаг завершения работы (рекомендуемый способ)
Самый безопасный способ – это использование флага (volatile boolean).
class MyTask implements Runnable {
private volatile boolean running = true;

public void run() {
while (running) {
System.out.println("Работаю...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Важно восстанавливать флаг прерывания
}
}
System.out.println("Поток остановлен.");
}

public void stop() {
running = false;
}
}

public class Main {
public static void main(String[] args) throws InterruptedException {
MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();

Thread.sleep(2000);
task.stop(); // Корректно останавливаем поток
}
}


🚩Прерывание потока (`interrupt()`)

Этот способ удобен для потоков, которые ждут (sleep(), wait(), join()), потому что прерывание выбрасывает InterruptedException.
class MyTask implements Runnable {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Работаю...");
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Поток прерван.");
}
}
}

public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyTask());
thread.start();

Thread.sleep(2000);
thread.interrupt(); // Прерывание потока
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6💊2
🤔 Что такое динамический полиморфизм?

Динамический полиморфизм – это возможность вызывать переопределенные методы во время выполнения.
Реализуется через переопределение методов (
@Override).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥4
🤔 Какая самая минимальная единица для работы с потоками?

В Java потоки управляются объектами класса Thread, и каждый поток выполняет одну последовательность инструкций. Минимальная рабочая единица – это один поток выполнения, который работает независимо от других.

🚩Создание минимального потока

🟠Через `Thread` (анонимный класс)
Самый простой способ создать поток – использовать класс Thread:
Thread thread = new Thread(() -> System.out.println("Привет из потока!"));
thread.start();


🟠Через `Runnable`
Можно создать поток, передав задачу в Runnable:
Runnable task = () -> System.out.println("Работает поток!");
Thread thread = new Thread(task);
thread.start();


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 В чем заключается идея перегрузки конструкторов?

Перегрузка конструкторов позволяет создавать объекты с разными входными параметрами, улучшая гибкость.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥1
🤔 Является ли коллекция HashMap потоком безопасной?

Коллекция HashMap не является потокобезопасной. Это означает, что при одновременном доступе к нему из нескольких потоков без должной синхронизации могут возникнуть проблемы, такие как потеря данных, гонки за данные и другие виды состояний гонки. Если один поток изменяет ее структуру (например, добавляя или удаляя элементы), в то время как другой поток итерирует по ней или также пытается внести изменения, результаты могут быть непредсказуемыми.

🟠Collections.synchronizedMap(Map)
Оборачивает ее (или любую другую карту) в потокобезопасную обёртку, гарантируя безопасность при доступе из разных потоков. Однако при использовании этого метода важно помнить, что если итерация по коллекции происходит в многопоточной среде, необходимо синхронизировать весь блок итерации на возвращённой карте для предотвращения конкурентных модификаций.
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());    


🟠ConcurrentHashMap
Предоставляет потокобезопасную реализацию карты без блокировки всей карты. ConcurrentHashMap разработан для высокой конкуренции и эффективности при доступе из множества потоков, обеспечивая лучшую производительность по сравнению с synchronizedMap. ConcurrentHashMap позволяет одновременно читать данные из карты несколькими потоками без блокировки и записывать данные при минимальной блокировке.
Map<String, String> concurrentMap = new ConcurrentHashMap<>();    


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2😁1