Java for Beginner
870 subscribers
1.01K photos
275 videos
14 files
1.69K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Отсутствие барьеров в конвейере

Барьер (synchronization point) — операция, требующая видимости всех элементов или глобальной координации. Барьеры разрушают параллелизм, заставляя воркеров ждать друг друга.

sorted: полный барьер

Операция sorted() требует всех элементов для сортировки. В параллельном потоке каждый сегмент сортируется локально, затем результаты сливаются (merge) в глобально отсортированную последовательность. Слияние требует координации и дополнительной памяти.
// Барьер: локальная сортировка + глобальное слияние
List<Book> sorted = books.parallelStream()
.sorted(comparing(Book::year)) // Накладные расходы на merge
.collect(toList());


Если конвейер содержит sorted без последующих операций, параллелизм может быть оправдан для дорогих предшествующих операций. Но sorted + limit — особенно неэффективная комбинация: все элементы сортируются, хотя нужны только первые N.

limit и findFirst: частичные барьеры

limit(n) в параллельном потоке создаёт глобальный счётчик оставшихся элементов. Когда один воркер достигает лимита, другие должны быть уведомлены для остановки. Это требует синхронизации и снижает эффективность.
findFirst() требует упорядоченности. Если источник ORDERED, воркеры должны координироваться для определения, кто нашёл "первый" элемент.

Если источник неупорядочен или порядок не важен, findAny() предпочтительнее — он возвращает любой найденный элемент без координации.
// Плохо: упорядоченный источник + findFirst в parallel
Optional<Book> first = books.parallelStream()
.filter(b -> b.year() > 2000)
.findFirst(); // Требует проверки всех предшествующих сегментов

// Лучше: findAny для неупорядоченных задач
Optional<Book> any = books.parallelStream()
.filter(b -> b.year() > 2000)
.findAny(); // Первый найденный в любом сегменте


distinct: барьер с состоянием

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


Когда parallelStream применим

Суммируя критерии, эффективный сценарий для parallelStream:
Источник: ArrayList, массив, IntStream.range с большим размером (10 000+ элементов)
Операция: CPU-bound, дорогая (> 10 мкс), без блокировок
Конвейер: stateless операции, без sorted, limit, distinct или с ними в конце
Данные: иммутабельные, без shared mutable state
Цель: агрегация в коллектор с эффективным combiner
Пример подходящей задачи: анализ миллиона документов, извлечение признаков, подсчёт статистики.
Пример неподходящей задачи: фильтрация списка идентификаторов с простым предикатом, преобразование в строки, лимит первых десяти.


Измерение прежде оптимизации

Предположения о производительности часто ошибочны. Единственный надёжный метод — измерение с репрезентативными данными:
// JMH-бенчмарк для сравнения
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class StreamBenchmark {

@State(Scope.Thread)
public static class Data {
List<Book> books = generateBooks(100000);
}

@Benchmark
public List<Result> sequential(Data d) {
return d.books.stream()
.map(this::expensiveTransform)
.collect(toList());
}

@Benchmark
public List<Result> parallel(Data d) {
return d.books.parallelStream()
.map(this::expensiveTransform)
.collect(toList());
}
}


Микробенчмарки без JMH ненадёжны из-за JIT-оптимизаций, GC-пauses и прогрева кэша. Реальное приложение требует мониторинга в production: метрики latency, throughput, использование CPU, профилирование hot paths.


#Java #для_новичков #beginner #stream_api #ForkJoinPool #parallelStream
👍5
Что выведет код?

import java.util.*;

public class Task200326 {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));
List<Integer> list2 = new LinkedList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));

long count1 = list1.parallelStream()
.map(x -> {
try { Thread.sleep(10); } catch (InterruptedException e) {}
return x * 2;
})
.count();

long count2 = list2.parallelStream()
.map(x -> {
try { Thread.sleep(10); } catch (InterruptedException e) {}
return x * 2;
})
.count();

System.out.println(count1 == count2);
System.out.println(list1.parallelStream().isParallel());
System.out.println(list2.parallelStream().isParallel());
}
}


#Tasks
👍3
👍2
Что такое инициализационные блоки (initializer blocks)? 🤓

Ответ:

В Java есть два типа блоков инициализации.

Статические блоки (static { ... }) выполняются один раз при загрузке класса, до создания любых объектов, и используются для инициализации статических переменных.

Нестатические (instance) блоки { ... } выполняются при создании каждого нового объекта, перед вызовом конструктора. Они выполняются в порядке объявления. Instance-блоки удобны, когда у класса несколько конструкторов и нужно выполнить общий для всех код.


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

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

Барон (1809) Жан-Бати́ст Жозе́ф Фурье́ (фр. Jean-Baptiste Joseph Fourier; 21 марта 1768, Осер, Франция — 16 мая 1830, Париж) — французский математик и физик. Нашёл формулу представления функции с помощью интеграла, играющую важную роль в современной математике. Доказал, что всякую произвольно начерченную линию, составленную из отрезков дуг разных кривых, можно представить единым аналитическим выражением. В 1823 году независимо от Эрстеда открыл термоэлектрический эффект, показал, что он обладает свойством суперпозиции, создал термоэлектрический элемент.


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

1924 — 24-летний физик Вольфганг Паули в опубликованной статье сформулировал один из важнейших принципов современной теоретической физики, за который в 1945 году получил Нобелевскую премию.

1940 — Учёные Отто Фриш и Рудольф Пайерлс в Бирмингемском университете (Великобритания) сделали оценку критической массы урана-235.


#Biography #Birth_Date #Events #21марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
С 14.03 по 20.03
Предыдущий пост(с 07.03 по 13.03)

Воскресный мотивационный пост:
Не было мотивации, а вообще нужна?) (все равно это никто не читает)

Запись встреч/видео:
Видео в процессе подготовки... lvl2

Обучающие статьи:
Раздел 8. Stream API и функциональный стиль

Глава 5: Контракты. Почему equals, hashCode и иммутабельность — закон
(Практика): Саботаж и починка в «Библиотеке»

Глава 6: Parallel Stream
Механика ForkJoinPool.commonPool()
Условия эффективности параллельного stream

[Совет по Java #016]
Тема: Ленивая загрузка в Hibernate (FetchType.LAZY) не работает после закрытия сессии.

[Совет по Java #017]
Тема: ConcurrentModificationException при итерации и модификации коллекции


Полезные статьи и видео:
WebFlux, Virtual Threads и все-все-все

Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍4🔥1
🤣4
🤣4
Потратил 6! часов, чтобы собрать настройки ретраев и CircuitBreaker в resilience4j в полноценно работающую демонстрацию...

И все для вас)))🧑‍💻

Скоро будет видео 💃
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍3🍾11
2😱1
История технологий сегодня — 22 марта

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

Ро́берт Э́ндрюс Ми́лликен (англ. Robert Andrews Millikan; 22 марта 1868, Моррисон, Иллинойс, США — 19 декабря 1953, Сан-Марино, Калифорния, США) — американский физик. В 1923 году получил Нобелевскую премию по физике за работы в области фотоэлектрического эффекта и за измерения заряда электрона[4]. Впоследствии он занимался изучением космических лучей.

Бертон Ри́хтер (англ. Burton Richter; 22 марта 1931, Нью-Йорк, США — 18 июля 2018, Станфорд, штат Калифорния, США) американский физик, лауреат Нобелевской премии по физике в 1976 году, совместно с Самюэлем Тингом «за основополагающий вклад в работу по открытию тяжёлой элементарной частицы нового типа».


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

1895 — в Париже состоялась первая в истории публичная демонстрация кинофильма. Это был фильм братьев Люмьер «Выход рабочих с фабрики».

1902 — Британия и Персия заключили договор о соединении телеграфной линией Европы и Индии.


1904 — в лондонской газете «Иллюстрейтед Миррор» впервые в мире опубликована цветная фотография.


#Biography #Birth_Date #Events #22марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
9. Retry vs Circuit Breaker: кто спасёт ваши сервисы от каскадных падений?

В этом видео мы на реальном примере разберём, как правильно комбинировать Retry и Circuit Breaker с помощью Resilience4j, чтобы сделать систему устойчивой к сбоям внешних зависимостей.

Что вас ждёт:

🔵 Retry — когда он полезен, а когда опасен.
🔵 Circuit Breaker — как он работает, зачем нужны состояния CLOSED, OPEN, HALF-OPEN и как его настраивать.
🔵 Разбор настройки через application.yml: скользящие окна, пороги ошибок, медленные вызовы, экспоненциальный backoff.
🔵 Сравнение Spring Retry и Resilience4j: что выбрать для production?
🔵 Готовые фрагменты кода и конфигурации для внедрения в ваш проект.

Исходный код проекта на GitHub очень ждет Ваших звезд ☺️

Ссылка на Youtube
Ссылка на Рутьюб

Смотрите, ставьте лайки, подписывайтесь на каналы!✌️

❗️❗️❗️ Огромная просьба - если Вам понравилась моя работа, распространите эту серию по всем доступным вам местам: телеграм, discord и прочим каналам. ❗️❗️❗️

Буду крайне благодарен
🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
История технологий сегодня — 23 марта

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

Джин Э. Саммет (23 марта 1928 — 20 мая 2017) — американская учёная в области информатики, разработавшая язык программирования FORMAC в 1962 году. Она также была одним из разработчиков влиятельного языка программирования COBOL.

Вернер Магнус Максимилиан фрайхерр фон Браун (нем. Wernher Magnus Maximilian Freiherr von Braun; 23 марта 1912, Вирзиц, провинция Позен, Пруссия, Германская империя — 16 июня 1977, Александрия, Виргиния, США)германский, а с 1955 года — американский конструктор ракетно-космической техники, один из основоположников современного ракетостроения, создатель первых баллистических ракет. Член НСДАП с 1937 года, штурмбаннфюрер СС (1943—1945). В США считается отцом американской космической программы.


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

1876 — русский инженер Павел Яблочков запатентовал электрическую лампочку.

1983 — запущен «Астрон», советский космический ультрафиолетовый телескоп.

2020 — компания Valve выпустила компьютерную игру для устройств виртуальной реальности «Half-Life: Alyx» (на Windows) *Кто не играл - рекомендую


#Biography #Birth_Date #Events #23марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Раздел 8. Stream API и функциональный стиль в Java

Глава 6: Parallel Stream

Гонка параллельных stream в «Библиотеке»

Подготовка: расширение модели Book

Добавьте поле для имитации дорогой операции:
public class Book {
private final String title;
private final String author;
private final int year;
private final List<String> genres;
private final int complexity; // «сложность» проверки, влияет на время фильтрации

public Book(String title, String author, int year,
List<String> genres, int complexity) {
this.title = title;
this.author = author;
this.year = year;
this.genres = genres;
this.complexity = complexity;
}

// геттеры...

public boolean isExpensiveFantasyCheck() {
// Имитация дорогой операции: чем выше complexity, тем дольше
try {
Thread.sleep(complexity); // миллисекунды
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return genres.contains("Фантастика");
}
}



Базовый эксперимент: поиск фантастики

Метод для измерения
public class ParallelStreamBenchmark {

public static List<String> findFantasyTitlesSequential(List<Book> books) {
return books.stream()
.filter(Book::isExpensiveFantasyCheck)
.map(Book::getTitle)
.collect(Collectors.toList());
}

public static List<String> findFantasyTitlesParallel(List<Book> books) {
return books.parallelStream()
.filter(Book::isExpensiveFantasyCheck)
.map(Book::getTitle)
.collect(Collectors.toList());
}

public static long measure(Runnable task) {
long start = System.nanoTime();
task.run();
long end = System.nanoTime();
return (end - start) / 1_000_000; // миллисекунды
}
}



Три сценария: малые, средние, большие данные

Сценарий А: 10 элементов, лёгкая операция (complexity = 0)

List<Book> tinyLibrary = IntStream.range(0, 10)
.mapToObj(i -> new Book("Книга " + i, "Автор " + i,
2000 + i, Arrays.asList(i % 2 == 0 ? "Фантастика" : "Роман"), 0))
.collect(Collectors.toList());

long seqTime = measure(() -> findFantasyTitlesSequential(tinyLibrary));
long parTime = measure(() -> findFantasyTitlesParallel(tinyLibrary));

System.out.println("10 элементов, лёгкая операция:");
System.out.println(" Последовательно: " + seqTime + " мс");
System.out.println(" Параллельно: " + parTime + " мс");
System.out.println(" Накладка: " + (parTime - seqTime) + " мс");


Ожидаемый результат: Параллельная версия медленнее в 2–10 раз.

Почему:
Разбиение потока на сегменты (splitting)
Передача задач в ForkJoinPool
Синхронизация при сборке результата (ConcurrentHashMap для toList)
Координация потоков дороже, чем сама работа

Сценарий Б: 10 000 элементов, лёгкая операция
List<Book> mediumLibrary = IntStream.range(0, 10_000)
.mapToObj(i -> new Book("Книга " + i, "Автор " + i,
2000 + i % 100,
Arrays.asList(i % 3 == 0 ? "Фантастика" : "Роман"), 0))
.collect(Collectors.toList());

// те же измерения


Ожидаемый результат: Примерно паритет или лёгкий проигрыш параллельной версии.

Почему:
Накладка на координацию амортизируется
Но операция всё ещё слишком лёгкая — переключение контекста не окупается

Сценарий В: 100 000 элементов, тяжёлая операция (complexity = 1 мс)
List<Book> largeLibrary = IntStream.range(0, 100_000)
.mapToObj(i -> new Book("Книга " + i, "Автор " + i,
2000 + i % 100,
Arrays.asList(i % 3 == 0 ? "Фантастика" : "Роман"), 1))
.collect(Collectors.toList());

// те же измерения


Ожидаемый результат: Параллельная версия быстрее в 2–4 раза (на многоядерной машине).

Почему:
Общая работа: 100 000 × 1 мс = 100 секунд последовательно
На 8 ядрах: теоретически ~12.5 секунд + накладка
Накладка амортизируется на большом объёме вычислений


#Java #для_новичков #beginner #stream_api #ForkJoinPool #parallelStream #практика
👍3🔥1
Проблема с неправильными источниками

Демонстрация: LinkedList vs ArrayList

List<Book> arrayList = new ArrayList<>(largeLibrary);
List<Book> linkedList = new LinkedList<>(largeLibrary);

// ArrayList — хорошее разбиение
long arrayListParallel = measure(() ->
arrayList.parallelStream().filter(...).collect(...));

// LinkedList — плохое разбиение
long linkedListParallel = measure(() ->
linkedList.parallelStream().filter(...).collect(...));

System.out.println("ArrayList parallel: " + arrayListParallel + " мс");
System.out.println("LinkedList parallel: " + linkedListParallel + " мс");


Ожидаемый результат: LinkedList в 3–10 раз медленнее из-за невозможности эффективного разбиения.


Интеграция в проект «Библиотеке»


Задача: параллельный анализ большой библиотеки

Добавьте в Library метод для статистики с тяжёлыми вычислениями:
public Map<String, Double> analyzeGenreComplexityParallel() {
return books.parallelStream()
.collect(Collectors.groupingByConcurrent(
book -> book.getGenres().get(0), // основной жанр
Collectors.averagingInt(Book::getComplexity)
));
}


Сравните с последовательной версией на 100 000 книгах.


Практические задания

Задача 1: неправильное использование

Напишите код, который демонстрирует проблемы:
parallelStream().forEach(System.out::println) — беспорядок в выводе
parallelStream().sorted() — избыточная синхронизация
parallelStream() для записи в общий StringBuilder — race condition
Объясните, почему каждый случай ломается.

Задача 2: правильный кастомный коллектор (звёздочка)

Реализуйте parallelStream-совместимый коллектор для Map<Author, List<Book>>, который:
Использует ConcurrentHashMap для аккумулятора
Корректно обрабатывает combiner для слияния частичных результатов
Сохраняет порядок книг внутри автора
Сравните производительность с groupingByConcurrent.

#Java #для_новичков #beginner #stream_api #ForkJoinPool #parallelStream #практика
👍4🔥1
Что выведет код?

import java.util.*;

public class Task230326 {
public static void main(String[] args) {
TreeSet<String> set = new TreeSet<>();
set.add("apple");
set.add("banana");
System.out.println(set.contains(null));
}
}


#Tasks
👍2
👍2
Что такое varargs (variable arguments)? 🤓

Ответ:

Varargs (синтаксис ...)
позволяет передавать в метод произвольное количество аргументов одного типа.

Объявляется как void method(String... args). Внутри метода аргументы обрабатываются как массив.

Varargs-параметр должен быть последним в списке параметров метода.

Это удобная альтернатива передаче массива — можно вызывать метод как method("a", "b", "c"), так и method() (с пустым массивом).


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологий сегодня — 24 марта

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

Серге́й Ива́нович Вави́лов (12 [24] марта 1891, Москва — 25 января 1951, там же) — советский физик, основатель научной школы физической оптики в СССР, общественный деятель и популяризатор науки; младший брат генетика Николая Вавилова. Президент Академии наук СССР (с 1945; действительный член с 1932), лауреат четырёх Сталинских премий. Соавтор (наряду со своими учеником Павлом Черенковым и коллегами Игорем Таммом и Ильёй Франком) открытия и истолкования эффекта Вавилова — Черенкова.


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

1802 — английский изобретатель Ричард Тревитик получил первый патент на паровоз.

1930 — карликовая планета Плутон получает своё нынешнее имя.

2001 — выход первого релиза Mac OS X (Гепард).


#Biography #Birth_Date #Events #24марта
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6