Java for Beginner
745 subscribers
733 photos
209 videos
12 files
1.2K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Flux в контроллере: для коллекций и стриминга

Flux — для нуля, одного или многих элементов, подходит для GET списков, пагинации или реального времени (стриминг событий). Возвращайте Flux<T>, и WebFlux отправит ответ как JSON-массив (для конечного) или text/event-stream для SSE (сервер-сент событий).


Простой пример: список элементов.

@GetMapping("/users")
public Flux<User> getAllUsers() {
return Flux.fromIterable(List.of(new User(1L, "Алиса"), new User(2L, "Боб")));
}


Фреймворк соберёт Flux в JSON-массив и отправит одним ответом.

Но если Flux асинхронный:
public Flux<User> findAllUsers() {
return Flux.range(1, 5)
.delayElements(Duration.ofSeconds(1)) // Симуляция задержки
.map(i -> new User((long) i, "Пользователь " + i));
}


Ответ будет стриминговым: клиенту придут данные по мере готовности (chunked transfer).

Для явного SSE добавьте produces = MediaType.TEXT_EVENT_STREAM_VALUE:
@GetMapping(value = "/stream-users", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<User> streamUsers() {
return findAllUsers();
}

Теперь ответ — SSE: каждый элемент как event: data: {"id":1,"name":"Пользователь 1"}\n\n. Клиент (браузер или WebClient) может реагировать на каждый по отдельности, без ожидания всего. Это решает боли callback-ада: вместо polling (опроса сервера), сервер толкает данные (push из поста 3).


Расширим: пагинация с @RequestParam.
@GetMapping("/users-paged")
public Flux<User> getPagedUsers(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
return userService.findPaged(page, size); // Сервис возвращает Flux<User>
}


Для POST с Flux телом (batch-операции):
@PostMapping("/batch-users")
public Flux<User> createBatch(@RequestBody Flux<UserRequest> requestsFlux) {
return requestsFlux.flatMap(req -> userService.createUser(req.getName()));
}

flatMap — для параллельной обработки, возвращает Flux сохранённых пользователей.


Обработка ошибок и валидация в контроллерах

Ошибки — часть жизни: в WebFlux используйте @ExceptionHandler в контроллере или глобально (@ControllerAdvice).

Пример:
@ExceptionHandler(UserNotFoundException.class)
public Mono<ResponseEntity<String>> handleNotFound(UserNotFoundException ex) {
return Mono.just(ResponseEntity.notFound().build());
}


Для валидации: @Validated на контроллере, @Valid на @RequestBody. Ошибки валидации — WebExchangeBindException, обработайте в handler.

Глобально:
@ControllerAdvice с @ExceptionHandler для централизованной обработки. Это интегрируется с onErrorResume/retry: в сервисе добавьте, и контроллер получит восстановленный поток.


Практические советы и подводные камни

- Тестирование: Используйте WebTestClient — webTestClient.get().uri("/greet/Name").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Привет, Name!");
- Schedulers: Если в сервисе blocking код, добавьте .publishOn(Schedulers.boundedElastic()) перед возвратом в контроллер.
- Проблема: Возврат Flux без produces = TEXT_EVENT_STREAM — соберётся в массив, но под большой нагрузкой рискуете буфером; для стриминга укажите media type.
- Оптимизация: Для больших ответов используйте Flux<DataBuffer> — стриминг байтов без сериализации в память.
- Интеграция: С Spring Security Reactive — фильтры асинхронны, не блокируют.



#Java #middle #Reactor #WebFlux #Mono #Flux
👍1
Что выведет код?

import java.util.Optional;

public class Task201025 {
public static void main(String[] args) {
Optional<String> optional = Optional.of("hello");
Optional<String> filtered = optional.filter(s -> s.length() > 10);
Optional<String> mapped = optional.map(s -> null);

System.out.println(filtered.isPresent());
System.out.println(mapped.isPresent());
System.out.println(optional.orElse("world"));
System.out.println(filtered.orElse("java"));
}
}


#Tasks
👍1
Вопрос с собеседований

Что такое method reference? 🤓

Ответ:

Ссылки на методы (::) позволяют использовать существующие методы как лямбды.

Например: System.out::println вместо (x) -> System.out.println(x).

Это делает код ещё короче и читаемее.



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
История IT-технологий сегодня — 21 октября


ℹ️ Кто родился в этот день

А́льфред Бе́рнхард Но́бель (швед. Alfred Bernhard Nobel МФА: [ˈǎlfrɛd nʊˈbɛlː]о файле; 21 октября 1833, Стокгольм, Шведско-норвежская уния — 10 декабря 1896, Сан-Ремо, Королевство Италия) — шведский химик, инженер, изобретатель, предприниматель и филантроп.


🌐 Знаковые события

1832 — российский учёный Павел Шиллинг в своей петербургской квартире продемонстрировал изобретённый им электромагнитный телеграф.

1879 — американский изобретатель Томас Алва Эдисон испытывает свою первую лампу накаливания с угольной нитью.

1944 — в Бермудском треугольнике загадочно исчез экипаж американского корабля «Рубикон». Корабль был найден без повреждений, а на его борту находилась только собака. Судно было в отличном состоянии, если не считать порванного буксирного троса, свисавшего с носа корабля.



#Biography #Birth_Date #Events #21Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Раздел 6. Коллекции в Java

Глава 4. Queue и Deque

Реализации: PriorityQueue, LinkedList как очередь. Применение: обработка задач, хранение заявок

Интерфейс Queue<E> имеет несколько реализаций в JCF, каждая оптимизирована под разные сценарии. Сегодня фокус на PriorityQueue и LinkedList (как Queue). Эти реализации демонстрируют разнообразие: от строгого FIFO до приоритетной обработки.

LinkedList<E> как Queue

LinkedList — это двусвязный список (doubly-linked list), который реализует Queue<E> (а также List<E> и Deque<E>). Как очередь, она идеальна для FIFO: добавление в конец, извлечение из начала.

Особенности:
FIFO: Строго соблюдается порядок добавления.
Уникальность: Нет, дубликаты разрешены.
Null: Разрешен (LinkedList позволяет null элементы).
Big O: O(1) для offer (добавление в конец), poll (извлечение из начала), peek (просмотр начала). Contains — O(n), так как перебор списка.


Внутренняя работа: Каждый элемент — узел (node) с ссылками на prev и next. Добавление — создание узла и обновление ссылок. Извлечение — удаление первого узла и сдвиг ссылок.

Нюансы:
Эффективна для частых вставок/удалений в концах (O(1)), но медленная для середины (O(n)).
Память: Выше, чем у ArrayDeque (из-за ссылок на prev/next).
Thread-safety: Нет — для многопоточности используйте BlockingQueue.
Дополнительно: Как Deque, поддерживает добавление/извлечение с обоих концов (об этом в следующем уроке).
Когда использовать: Для простых FIFO-очередей с небольшим размером, или когда нужна универсальность (Queue + List).


Пример кода для LinkedList как Queue:
javaimport java.util.LinkedList;
import java.util.Queue;

public class Main {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.offer("Задача 1"); // Добавление в конец
queue.offer("Задача 2");
queue.offer("Задача 3");
System.out.println(queue); // [Задача 1, Задача 2, Задача 3] — FIFO порядок

System.out.println(queue.peek()); // Задача 1 (просмотр)
System.out.println(queue.poll()); // Задача 1 (извлечение)
System.out.println(queue); // [Задача 2, Задача 3]

queue.offer(null); // Разрешен null
System.out.println(queue.poll()); // Задача 2
}
}

Вывод: Показывает FIFO — элементы извлекаются в порядке добавления, null разрешен.



PriorityQueue<E>

PriorityQueue — это приоритетная очередь на основе кучи (binary heap, min-heap по умолчанию). Она не следует FIFO, а извлекает элементы по приоритету (минимальный первый для натуральных типов).

Особенности:
FIFO: Нет — приоритетный порядок (по Comparable или Comparator).
Уникальность: Нет, дубликаты разрешены.
Null: Не разрешен (NullPointerException).
Big O: O(log n) для offer (вставка в кучу), poll (извлечение минимума с перестройкой), peek — O(1). Contains — O(n), так как перебор.


Внутренняя работа: Хранит элементы в массиве как бинарную кучу. При добавлении/извлечении перестраивает кучу (heapify) для поддержания свойства: родитель <= дети. Приоритет определяется compareTo() или Comparator.

Нюансы:
Порядок итерации: Не гарантирован (куча не sorted list).
Comparator: Передайте при создании: new PriorityQueue<>((a, b) -> b - a) для max-heap.
Размер: Resizable, initial capacity 11.
Thread-safety: Нет — используйте PriorityBlockingQueue для потоков.
Custom объекты: Должны реализовывать Comparable<E> или предоставить Comparator, иначе ClassCastException.
Когда использовать: Для задач с приоритетами (например, планировщик задач, Dijkstra алгоритм).



#Java #для_новичков #beginner #Collections #PriorityQueue #LinkedList
👍1
Пример кода для PriorityQueue:
javaimport java.util.PriorityQueue;
import java.util.Queue;

public class Main {
public static void main(String[] args) {
Queue<Integer> queue = new PriorityQueue<>();
queue.offer(3);
queue.offer(1);
queue.offer(2);
System.out.println(queue); // [1, 3, 2] — min в начале, но итерация не sorted

System.out.println(queue.peek()); // 1 (минимальный)
System.out.println(queue.poll()); // 1
System.out.println(queue); // [2, 3]

// Max-heap с Comparator
Queue<Integer> maxQueue = new PriorityQueue<>((a, b) -> b - a);
maxQueue.offer(3);
maxQueue.offer(1);
maxQueue.offer(2);
System.out.println(maxQueue.poll()); // 3 (максимальный)

// queue.offer(null); // NPE
}
}

Вывод: Элементы извлекаются по приоритету, не по порядку добавления.


Применение очередей: Обработка задач, хранение заявок

Очереди идеальны для сценариев последовательной обработки.

Обработка задач (Task Processing):
Пример: Планировщик задач, где задачи добавляются в очередь и обрабатываются по порядку (FIFO с LinkedList) или по приоритету (PriorityQueue).
Нюанс: В многопоточных системах (например, Thread pool) используйте BlockingQueue для безопасного poll.


Пример кода (простой обработчик):
javaimport java.util.LinkedList;
import java.util.Queue;

public class TaskProcessor {
private Queue<String> tasks = new LinkedList<>();

public void addTask(String task) {
tasks.offer(task);
}

public void processTasks() {
while (!tasks.isEmpty()) {
String task = tasks.poll();
System.out.println("Обработка: " + task);
}
}
}

public class Main {
public static void main(String[] args) {
TaskProcessor processor = new TaskProcessor();
processor.addTask("Задача 1");
processor.addTask("Задача 2");
processor.processTasks(); // Обработка: Задача 1\nОбработка: Задача 2
}
}

Вывод: Задачи обрабатываются FIFO.


Хранение заявок (Request Storage):
Пример: Сервер хранит входящие заявки в очередь для последовательной обработки (например, HTTP requests).
С PriorityQueue: Заявки по срочности (high-priority first).
Нюанс: Для реальных систем используйте BlockingQueue (offer/poll с блокировкой при пустой/полной).


Пример кода (приоритетные заявки):
javaimport java.util.PriorityQueue;
import java.util.Queue;

class Request implements Comparable<Request> {
private String name;
private int priority; // 1 - высокий, 10 - низкий

public Request(String name, int priority) {
this.name = name;
this.priority = priority;
}

@Override
public int compareTo(Request other) {
return Integer.compare(this.priority, other.priority); // Min-heap по приоритету
}

public String getName() {
return name;
}
}

public class Main {
public static void main(String[] args) {
Queue<Request> requests = new PriorityQueue<>();
requests.offer(new Request("Заявка A", 5));
requests.offer(new Request("Заявка B", 1)); // Высокий приоритет
requests.offer(new Request("Заявка C", 3));

while (!requests.isEmpty()) {
System.out.println("Обработка: " + requests.poll().getName()); // Заявка B, Заявка C, Заявка A
}
}
}

Вывод: Заявки обрабатываются по приоритету.


Полезные советы для новичков

LinkedList для простоты: Универсальна для FIFO, легко добавить Deque-функции.
PriorityQueue для приоритетов: Передавайте Comparator для custom порядка (например, max-heap).
Custom классы: Реализуйте Comparable для PriorityQueue, или используйте Comparator.
Пустая очередь: Проверяйте isEmpty() перед poll, или используйте null от poll.
Итерация: For-each для просмотра, но не модифицируйте.



#Java #для_новичков #beginner #Collections #PriorityQueue #LinkedList
👍1
Что выведет код?

import java.util.PriorityQueue;

public class Task211025 {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(5);
pq.offer(2);
pq.offer(8);
pq.offer(1);

System.out.print(pq.poll() + " ");
System.out.print(pq.poll() + " ");

pq.offer(0);
pq.offer(3);

System.out.print(pq.poll() + " ");
System.out.print(pq.poll() + " ");
System.out.print(pq.poll());
}
}


#Tasks
👍1
Варианты ответа:
Anonymous Quiz
17%
1 2 3 0 5
17%
1 2 0 3 8
67%
1 2 0 3 5
0%
1 2 3 5 8
👍1
Вопрос с собеседований

Чем отличаются intermediate и terminal операции в Stream API? 🤓


Ответ:

Intermediate операции
(map, filter, sorted) возвращают новый Stream и выполняются лениво.

Terminal операции (collect, forEach, reduce) запускают обработку и возвращают результат.

Без terminal операций Stream не выполняется.



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
История IT-технологий сегодня — 22 октября


ℹ️ Кто родился в этот день

Александр Семёнович Кронрод (22 октября 1921 года, Москва — 6 октября 1986 года, там же) — советский математик и компьютерный учёный, внёс значимый вклад в вычислительные методы, численные решения физических задач, был одним из первых специалистов по прикладной информатике в СССР. Основоположник создания направления искусственного интеллекта. Лауреат Сталинской премии (1953).

Адольф Александр (Алекс или Ксандер) Веррейн Стюарт ( Роттердам , 22 октября 1923 г. – Харлем , 29 октября 2004 г.) — нидерландский учёный-информатик, первый профессор информатики в Нидерландах, оказал серьёзное влияние на развитие академической дисциплины “информатика”.


🌐 Знаковые события

1938 — американский изобретатель Честер Карлсон продемонстрировал свой аппарат для получения копий бумажных документов.

1966 — СССР запустил спутник «Луна-12».

1975 — советская космическая станция «Венера-9» совершила посадку на поверхность Венеры.



#Biography #Birth_Date #Events #22Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Сколько языков программирования вы знаете?
Anonymous Poll
50%
Пока ни одного) Java бы выучить!
15%
Java!
19%
2
15%
3 и больше
👍1
Реактивное программирование

R2DBC vs JDBC: реактивные базы данных


Исторический контекст: что такое JDBC и почему он доминировал десятилетиями

JDBC — это стандартный API Java для доступа к реляционным базам данных, появившийся ещё в JDK 1.1 (1997 год).

Он позволяет выполнять SQL-запросы, управлять соединениями и обрабатывать результаты через унифицированный интерфейс, независимо от конкретной БД (PostgreSQL, MySQL, Oracle и т.д.).


Ключевые компоненты JDBC:
DriverManager или DataSource: Для получения соединения (Connection).
Statement/PreparedStatement: Для выполнения SQL (executeQuery, executeUpdate).
ResultSet: Для чтения результатов (next(), getString() и т.д.).
Transaction management: commit(), rollback().


Пример простого JDBC-кода:
import java.sql.*;
public class JdbcExample {
public static void main(String[] args) {
try (Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/db", "user", "pass");
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?")) {
stmt.setLong(1, 1L);
ResultSet rs = stmt.executeQuery();

while (rs.next()) {
System.out.println("User: " + rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}


Это синхронно и блокирующе: executeQuery() "виснет" до ответа от БД, блокируя текущий поток.

В традиционных приложениях (как Spring MVC) это работало: каждый запрос — отдельный поток из пула (например, Tomcat с 200 потоками), и если БД отвечает быстро, проблем нет. Но под высокой нагрузкой или с медленными запросами (сетевые задержки, сложные джойны) пул исчерпывается: потоки "спят" в ожидании IO, CPU простаивает, а новые запросы ждут в очереди, вызывая таймауты и отказы. Это классическая проблема асинхронщины: JDBC не предназначен для non-blocking IO, он полагается на blocking calls операционной системы.

В реактивных приложениях (WebFlux) использование JDBC — антипаттерн: если контроллер возвращает Mono, но внутри — blocking JDBC, весь выигрыш теряется. Поток из event-loop (Netty) блокируется, снижая throughput (пропускную способность). Вот почему нужен новый подход.


Проблемы JDBC в реактивном контексте: почему старый стандарт не справляется

Давайте разберём проблемы JDBC подробно, чтобы понять мотивацию R2DBC:
Блокирующая природа: Все операции (connect, query, fetch) — синхронны. В асинхронном коде это требует обёрток вроде CompletableFuture или offload на отдельный пул (Schedulers.boundedElastic()), но это хак: теряется истинная реактивность, и под нагрузкой пулы переполняются.

Отсутствие backpressure: ResultSet — pull-модель (next() получает данные), но без контроля темпа. Если результат огромный (миллионы строк), буфер переполняется, рискуя OOM (OutOfMemoryError). В реактивном мире (push с backpressure) это несовместимо.

Управление соединениями: JDBC полагается на пулы (HikariCP), но они ориентированы на blocking: соединение "занято" весь запрос. В реактиве нужно multiplexing — одно соединение для многих операций асинхронно.

Транзакции:
@Transactional в Spring работает, но в реактиве требует специальной поддержки (reactive transactions), иначе — блокировки.

Масштабируемость: Под 10k+ RPS (requests per second) с БД-запросами JDBC требует огромных пулов потоков (тысячи), что жрёт память (каждый поток ~1MB стека) и контекст-свичинг.

Интеграция с Reactor: Нет native Publisher — результаты не "текут" как Flux, требуя ручной конвертации, что добавляет boilerplate и риски.


В итоге, JDBC — отличный для legacy или низконагруженных приложений, но в микросервисах с WebFlux он "ломает" реактивный стек, возвращая к болям callback-ада и ожиданий.


Введение в R2DBC: реактивный стандарт для реляционных БД

R2DBC — это спецификация (с 2019 года, под эгидой Spring и Pivotal), определяющая API для доступа к реляционным БД в реактивном стиле. Это не замена JDBC, а параллельный стандарт, ориентированный на non-blocking IO.

#Java #middle #Reactor #WebFlux #Mono #Flux #R2DBC
👍1
Ключевые идеи:
Publisher-based API: Все операции возвращают Publisher (Mono/Flux из Reactive Streams): Connection как Mono<Connection>, Statement.execute() как Flux<Row>.

Non-blocking от начала до конца: Использует асинхронные драйверы (для PostgreSQL, MySQL и т.д.), где соединения мультиплексируются — одно для многих запросов.

Backpressure встроено: Результаты (Flux<Row>) уважают request(n): если подписчик не готов, БД не шлёт данные, избегая перегрузки.

Транзакции реактивные: Поддержка
@Transactional с Mono/Flux.

Интеграция с экосистемой: Spring Data R2DBC — аналог Spring Data JPA, с репозиториями,
@Query и CRUD.

Драйверы: r2dbc-postgresql, r2dbc-mysql и т.д. — реализуют спецификацию, используя неблокирующие сокеты (Netty или аналог).

Пример базового R2DBC-кода (без Spring):
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import reactor.core.publisher.Flux;

public void createConnectionFactory () {

ConnectionFactory factory = ConnectionFactories.get("r2dbc:postgresql://localhost:5432/db?username=user&password=pass");

Flux<String> namesFlux = Flux.usingWhen(

factory.create(), // Асинхронно создать соединение

conn -> conn.createStatement("SELECT name FROM users").execute().flatMap(result -> result.map((row, metadata) -> row.get("name", String.class))),
conn -> conn.close() // Асинхронно закрыть
);

namesFlux.subscribe(System.out::println); // Строки приходят асинхронно
}


Здесь usingWhen — реактивный try-with-resources: создаёт соединение асинхронно, выполняет запрос как Flux<Result>, map извлекает данные. Нет блокировок: если БД медленная, поток свободен.


Spring Data R2DBC: упрощение с репозиториями и аннотациями

Spring Data R2DBC — модуль, который абстрагирует R2DBC, как Spring Data JPA для JDBC.

Добавьте зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId> <!-- Для PostgreSQL -->
</dependency>


Настройте в application.properties:
spring.r2dbc.url=r2dbc:postgresql://localhost:5432/db
spring.r2dbc.username=user
spring.r2dbc.password=pass


Репозитории:
ReactiveRepository extends ReactiveCrudRepository<Entity, ID>.


Сущность:
@Entity
public class User {
@Id
private Long id;
private String name;
// Getters/setters
}

public interface UserRepository extends ReactiveCrudRepository<User, Long> {
@Query("SELECT * FROM users WHERE name LIKE :name")
Flux<User> findByNameLike(String name);
}


В сервисе/контроллере:
@Service
public class UserService {
private final UserRepository repo;

public UserService(UserRepository repo) {
this.repo = repo;
}

public Flux<User> findAll() {
return repo.findAll(); // Flux асинхронно
}

public Mono<User> save(User user) {
return repo.save(user);
}
}


В контроллере:
@GetMapping("/users")
public Flux<User> getAllUsers() {
return userService.findAll();
}


Это декларативно: repo.findAll() — Flux, который "течёт" из БД без блокировок. Транзакции: @Transactional на методе — reactive, rollback асинхронно.

Расширенный пример: пагинация с ReactiveSortingRepository и Pageable.
public interface UserRepository extends ReactiveSortingRepository<User, Long> {}
Flux<User> paged = repo.findAll(Sort.by("name").ascending()).skip(10).take(20); // Простая пагинация
Для complex: используйте @Query с параметрами, или Criteria API.


Практические советы и подводные камни

Выбор БД: PostgreSQL — лучший для R2DBC (полная поддержка async).
Тестирование: Embedded H2 с r2dbc-h2, ReactiveTest для StepVerifier.
Камень: Нет full ORM (как JPA entities с relations) — используйте ручные joins или Spring Data Projections.
Камень: Транзакции не поддерживают propagation в nested методах fully — будьте осторожны.
Совет: Для hybrid (JDBC + R2DBC) — используйте разные DataSource, но избегайте в одном приложении.
Совет: Мониторьте с Micrometer: метрики на запросы, соединения.



#Java #middle #Reactor #WebFlux #Mono #Flux #R2DBC
👍1
Что выведет код?

import java.util.LinkedList;

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

list.remove(1);
list.remove(new Integer(2));

System.out.println(list.size());
System.out.println(list.get(0));
}
}


#Tasks
👍3
Варианты ответа:
Anonymous Quiz
20%
1 1
50%
1 3
10%
0
20%
2 1
👍1
Вопрос с собеседований

Что такое сериализация в Java? 🤓


Ответ:

Сериализация
— это преобразование объекта в поток байт для сохранения или передачи по сети.

Обратный процесс называется десериализацией. Реализуется через интерфейс Serializable.

Важно помнить о transient-полях и UID для совместимости.



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
История IT-технологий сегодня — 23 октября


ℹ️ Кто родился в этот день

Андрей Карпатый (или Андрей Карпаты, англ. Andrej Karpathy, родился 23 октября 1986 года) — словацко-канадский учёный в области машинного обучения, который занимал должность директора по искусственному интеллекту в компании Tesla. Он является сооснователем и бывшим сотрудником OpenAI, где он специализировался на глубоком обучении и компьютерном зрении.


🌐 Знаковые события

Не нашел
(


#Biography #Birth_Date #Events #23Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Раздел 6. Коллекции в Java

Глава 4. Queue и Deque

Интерфейс Deque. Двусторонняя очередь (FIFO и LIFO). Реализации: ArrayDeque, LinkedList

Интерфейс Deque<E> — это расширение Queue из пакета java.util, который представляет двустороннюю очередь (double-ended queue). Deque позволяет добавлять, удалять и просматривать элементы как с начала (head), так и с конца (tail) очереди. Это делает Deque универсальной структурой, способной моделировать как обычную очередь (FIFO), так и стек (LIFO), а также комбинированные сценарии.


Ключевые особенности Deque

Двусторонний доступ: Операции с first (начало) и last (конец).

FIFO и LIFO:
FIFO: Добавляйте в конец (addLast), извлекайте из начала (removeFirst) — как стандартная очередь.
LIFO: Добавляйте в начало (addFirst), извлекайте из начала (removeFirst) — как стек.


Уникальность элементов: Не гарантируется — дубликаты разрешены (зависит от реализации).
Null элементы: Зависит от реализации (ArrayDeque позволяет, но не рекомендуется; LinkedList позволяет).
Big O: Зависит от реализации, но обычно O(1) для операций на концах.
Итерация: Поддерживает Iterator для перебора от начала к концу, и descendingIterator() для обратного порядка.

Deque расширяет Queue, добавляя методы для работы с концом. Основные реализации: ArrayDeque (на массиве) и LinkedList (на связном списке). Deque можно использовать как Queue или Stack (вместо устаревшего Stack класса).

Когда использовать Deque:
Для стеков (LIFO, например, undo/redo).
Для очередей с доступом к концу (например, sliding window в алгоритмах).
Для двусторонних операций (например, палиндромы, где проверка с обоих концов).



FIFO и LIFO в Deque: Двусторонняя очередь

Deque поддерживает два основных режима:
FIFO (First-In-First-Out): "Первым вошел — первым вышел".

Добавление: addLast(E e) или offerLast(E e).
Извлечение: removeFirst() или pollFirst().
Просмотр: getFirst() или peekFirst().
Аналогия: Очередь в банке — первый пришел, первый ушел.


LIFO (Last-In-First-Out): "Последним вошел — первым вышел".

Добавление: addFirst(E e) или offerFirst(E e).
Извлечение: removeFirst() или pollFirst().
Просмотр: getFirst() или peekFirst().
Аналогия: Стопка тарелок — последняя сверху первой берется.



Методы Deque (основные, аналогично Queue, но с first/last)

Добавление:
addFirst(E e)/addLast(E e): Добавляет или кидает исключение, если переполнено.
offerFirst(E e)/offerLast(E e): Добавляет, возвращает boolean (false, если переполнено).


Извлечение:
removeFirst()/removeLast(): Извлекает или кидает NoSuchElementException, если пусто.
pollFirst()/pollLast(): Извлекает или возвращает null, если пусто.


Просмотр:
getFirst()/getLast(): Возвращает или кидает NoSuchElementException, если пусто.
peekFirst()/peekLast(): Возвращает или null, если пусто.


Другие: size(), isEmpty(), clear(), iterator(), descendingIterator().
Нюанс: Методы Queue (offer, poll, peek) в Deque эквивалентны offerLast, pollFirst, peekFirst (для FIFO).


#Java #для_новичков #beginner #Collections #Deque #ArrayDeque #LinkedList
👍3