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
Что выведет код?

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
[Совет по Java #018]

Тема: Анонимные классы и лямбды захватывают переменные. Если переменная используется внутри, она должна быть effectively final. Нельзя менять ее значение внутри лямбды.

Проблема: Лямбда-выражения и анонимные классы захватывают (capture) переменные из объемлющего контекста.

Для обеспечения согласованности и предотвращения проблем с многопоточностью Java требует, чтобы такие переменные были effectively final — то есть не изменялись после инициализации. Попытка изменить захваченную переменную внутри лямбды или передать в лямбду переменную, которая изменяется где-то еще, приводит к ошибке компиляции.

Это ограничение связано с тем, что лямбда может выполняться в другом потоке, и изменение внешней переменной создало бы состояние гонки (race condition).

Решение: Используйте обертку (массив, AtomicReference, или поле класса) для "модифицируемых" переменных, если модификация необходима.

Однако лучше пересмотреть дизайн: для накопления результатов используйте Stream API (reduce, collect) или вынесите логику в отдельный метод. Для счетчиков внутри лямбды применяйте AtomicInteger или объекты-контейнеры.

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.*;

public class LambdaCaptureExample {

public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

//Ошибка: переменная не effectively final
int count = 0;
// names.forEach(name -> count++); // Compilation error!

//Ошибка: передача изменяемой переменной
int threshold = 5;
// threshold = 10;
// names.stream().filter(name -> name.length() > threshold); // Ошибка! threshold изменился

//Решение 1: AtomicInteger для счетчика
AtomicInteger counter = new AtomicInteger(0);
names.forEach(name -> {
if (name.length() > 3) {
counter.incrementAndGet(); // Безопасно
}
});
System.out.println("Count > 3: " + counter.get());

//Решение 2: Использование Stream API вместо накопления
long streamCount = names.stream()
.filter(name -> name.length() > 3)
.count(); // Никаких захваченных переменных
System.out.println("Stream count: " + streamCount);

//Решение 3: Массив как контейнер
int[] arrayCount = {0};
names.forEach(name -> {
if (name.length() > 3) {
arrayCount[0]++; // Работает, но менее элегантно
}
});
System.out.println("Array count: " + arrayCount[0]);

//Антипаттерн: сложный захват
for (int i = 0; i < 3; i++) {
// i меняется, нельзя использовать в лямбде
// new Thread(() -> System.out.println(i)).start(); // Ошибка!

//Правильно: копия значения
int index = i;
new Thread(() -> System.out.println("Index: " + index)).start();
}

// Пример с effectively final
String prefix = "User: "; // effectively final
names.stream()
.map(name -> prefix + name) // Работает
.forEach(System.out::println);

// prefix = "Person: "; // Раскомментируй — ошибка!
}
}


Объяснение: Понятие "effectively final" было введено в Java 8. Переменная считается effectively final, если ее значение не изменяется после инициализации.

Лямбды и анонимные классы не могут изменять локальные переменные, так как они хранятся на стеке, а лямбда может быть выполнена после выхода из метода (например, в другом потоке). Использование оберток (AtomicInteger, массивы) работает, потому что ссылка на объект-контейнер effectively final, а изменяется внутреннее состояние объекта. Однако это неидиоматично.

#Java #советы
👍6
Что выведет код?

import java.util.function.Consumer;

public class Task240326 {
public static void main(String[] args) {
int[] counter = {0};

Consumer<String> processor = s -> {
counter[0]++;
System.out.print(s + counter[0] + " ");
};

for (int i = 0; i < 3; i++) {
processor.accept("A");
}

System.out.println(counter[0]);
}
}


#Tasks
👍4