Java for Beginner
687 subscribers
589 photos
161 videos
12 files
913 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
StreamAPI JAVA.
Великолепие минимализма

Видео посвященное изучению Stream API в Java.

Что мы узнали:
Что такое Stream API и зачем оно вообще нужно.
Что такое Императивный и Декларативный подходы.
Рассмотрели функциональные интерфейсы и их основные виды.
Рассмотрели основные функциональные промежуточные и терминальные методы.
Посмотрели все это на примерах.

Если хотите посмотреть с более подробными примерами и описанием:
GitHub -
https://github.com/Oleborn/StreamAPI_Research
(понравилось - поставь звездочку)


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

Смотрите, ставьте лайки, подписывайтесь на каналы!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥91
Что такое Error в Java и чем он отличается от Exception? 🤓

Ответ:

Error и Exception — наследники Throwable.

Error обозначает серьезные системные ошибки, которые обычно нельзя обработать (например, OutOfMemoryError).

Exception — это ошибки, которые можно и нужно обрабатывать (например, IOException).

Программист редко обрабатывает Error, но должен учитывать Exception.

#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
📌 Факт дня:

А вы знали, что термин "флопс" для измерения вычислений появился в 1960-х?

Слово "FLOPS" (Floating Point Operations Per Second) начали использовать в 1960-х для оценки скорости компьютеров, таких как IBM 7030. Сегодня суперкомпьютеры измеряются в экзафлопсах!


Proof

#facts
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Best Practices и расширенные сценарии работы с Flyway

1. Организация миграций

1.1. Разделение миграций по окружениям

Проблема:
Разные БД для dev/test/prod могут требовать специфичных скриптов (например, тестовые данные только для dev).

Решение:
Структура папок:

db/
migration/
dev/
V1__Dev_only_data.sql
prod/
V1__Prod_indexes.sql
common/
V1__Base_schema.sql


Настройка application.yml для dev:
spring:
flyway:
locations: classpath:db/migration/common, classpath:db/migration/dev


1.2. Работа с существующей БД (baseline)

Проблема:
Flyway ожидает пустую БД или таблицу flyway_schema_history. Если БД уже используется, требуется инициализация.

Решение:
Включить baseline-on-migrate:

spring:
flyway:
baseline-on-migrate: true
baseline-version: 1.0 # Версия, с которой начнется контроль


Вручную через CLI:

flyway baseline -baselineVersion="1.0"


Важно:
После baseline миграции с версией ≤ baselineVersion игнорируются.


2. Тестирование миграций

2.1. Интеграция с Testcontainers + JUnit

Цель:
Проверить, что миграции применяются без ошибок в изолированной БД.

Пример теста (Java + JUnit 5):
import org.flywaydb.core.Flyway;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
public class FlywayMigrationTest {

@Container
private static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:15");

@Test
void testMigrations() {
Flyway flyway = Flyway.configure()
.dataSource(
postgres.getJdbcUrl(),
postgres.getUsername(),
postgres.getPassword()
)
.load();
flyway.migrate(); // Упадет, если есть ошибки
}
}


Что проверяем:
Применение всех миграций без исключений.
Соответствие схемы ожиданиям (можно добавить проверку через DataSource).



3. Работа в команде

3.1. Именование файлов

Правила:
Уникальность версий:
Используйте дату + порядковый номер: V20240315-1__Add_users_table.sql.

Описательные имена:
Плохо: V1__Changes.sql.
Хорошо: V20240315-2__Alter_users_add_email.sql.


3.2. Запрет изменения примененных скриптов

Проблема:
Изменение уже выполненного скрипта приводит к ошибке:

Validate failed: Migration checksum mismatch for V1__Create_table.sql


Решение:
Никогда не изменять содержимое V*-файлов после их применения.

Для исправлений:
Создать новую миграцию с корректировкой:
-- V20240315-3__Fix_users_table.sql
ALTER TABLE users ALTER COLUMN email SET NOT NULL;

Если критично, использовать flyway repair (пересчитывает контрольные суммы).

Исключение:
R__-миграции (повторяемые) можно изменять — они переприменяются при изменениях.


4. Расширенные сценарии

4.1. Миграции для нескольких схем БД

Настройка:
spring:
flyway:
schemas: public, audit
default-schema: public
В SQL-файлах укажите схему явно:

sql
-- V1__Create_audit_table.sql
CREATE TABLE audit.logs (
id SERIAL PRIMARY KEY,
message TEXT
);


4.2. Шаблонизация SQL

Проблема:
Разные SQL-синтаксисы для PostgreSQL/Oracle.

Решение (через Maven/Gradle):
Используйте placeholders в pom.xml:
<configuration>
<placeholders>
<table.prefix>${env}</table.prefix>
</placeholders>
</configuration>


В SQL:
CREATE TABLE ${table.prefix}_users (...);


4.3. Откаты (безопасная альтернатива)


Тактика:
Для деструктивных изменений (DROP, DELETE) создавать "обратные" миграции:
-- V5__Drop_users.sql
DROP TABLE users;

-- V6__Restore_users.sql (если нужно откатить)
CREATE TABLE users (...); -- Повторяем структуру из V1
INSERT INTO users (...) SELECT ... FROM backup_users;
Использовать резервные копии перед рискованными операциями.


#Java #middle #Flyway
👍3
Что выведет код?

import java.util.function.Supplier;

public class Task200625 {
public static void main(String[] args) {
Supplier<Integer> supplier = () -> {
System.out.print("A");
return 1;
};

System.out.print("B");
supplier.get();
System.out.print("C");
}
}


#Tasks
👍2
Варианты ответа:
Anonymous Quiz
10%
"ABC"
48%
"BAC"
29%
"A"
14%
Exception
👍1
Продолжаем выбирать темы для разбора и голосовать за рассмотрение предложенных! 🤓

Голосуем за тему к рассмотрению в эти выходные!

Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)

Не стесняемся! ✌️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Что такое Thread.sleep() и чем он отличается от Thread.yield()? 🤓

Ответ:

Thread.sleep(long millis) приостанавливает выполнение текущего потока на указанное время (в миллисекундах), не освобождая монитор. Может выбросить InterruptedException.


Thread.yield() дает возможность другим потокам с таким же приоритетом выполниться, но не гарантирует переключение.

Пример:
Thread.sleep(1000); // Пауза на 1 секунду
Thread.yield(); // Уступить процессор другим потокам

#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
После проведенного голосования, определилась тема для рассмотрения в выходные - Optional

Несмотря на то, что на канале уже публиковались ранее подобные статьи, я подготовил для вас еще одну, для расширения темы 🤫

Ну читаем'с статейку


Optional в Java: Глубокое погружение

Optional — это класс, введенный в Java 8, представляющий собой контейнер для значений, который может содержать значение или быть пустым. Его основная цель — минимизировать вероятность возникновения NullPointerException (NPE), обеспечивая явное указание на возможность отсутствия значения. Optional побуждает разработчиков к более безопасной и выразительной обработке потенциально отсутствующих данных.


Основы Optional

Optional — это обертка, которая может содержать либо одно значение, либо быть пустой. Вместо возврата null, методы могут возвращать экземпляр Optional, что сигнализирует о возможном отсутствии результата. Это позволяет явно обрабатывать случаи отсутствия значения, избегая NPE.

Пример базового использования
import java.util.Optional;

public class OptionalExample {
public static void main(String[] args) {
Optional<String> possibleValue = Optional.of("Hello, World!");
possibleValue.ifPresent(System.out::println); // Выведет "Hello, World!"

Optional<String> emptyValue = Optional.empty();
System.out.println(emptyValue.isPresent()); // Выведет "false"
}
}

В этом примере possibleValue содержит строку, которая выводится на консоль, если значение присутствует. emptyValue является пустым, и метод isPresent() возвращает false.



Внутреннее устройство Optional

Optional реализован как финальный класс с двумя основными полями:
value — содержит значение, если оно присутствует (может быть null только в случае пустого Optional).
EMPTY — статическое поле, представляющее пустой Optional, реализованное как синглтон.


Конструктор Optional приватный, и создание экземпляров осуществляется через статические фабричные методы:
of(T value): Создает Optional, содержащий переданное значение. Если значение null, выбрасывается NullPointerException.
ofNullable(T value): Создает Optional, который может быть пустым, если переданное значение null.
empty(): Возвращает пустой Optional.


Пример внутренней структуры
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();

private final T value;

private Optional() {
this.value = null;
}

private Optional(T value) {
this.value = Objects.requireNonNull(value);
}

public static <T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}

public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}

public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}

// Другие методы...
}

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


#Java #Training #Medium #Optional
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ключевые методы Optional

Optional предоставляет множество методов для работы с данными:

isPresent(): Возвращает true, если значение присутствует.
isEmpty() (добавлен в Java 11): Возвращает true, если значение отсутствует.
ifPresent(Consumer<? super T> consumer): Выполняет действие, если значение присутствует.
orElse(T other): Возвращает значение, если оно присутствует, или other, если отсутствует.
orElseGet(Supplier<? extends T> supplier): Возвращает значение или результат выполнения Supplier, если значение отсутствует.
orElseThrow(Supplier<? extends X> exceptionSupplier): Возвращает значение или выбрасывает исключение, если значение отсутствует.
map(Function<? super T, ? extends U> mapper): Преобразует значение, если оно присутствует, возвращая новый Optional.
flatMap(Function<? super T, Optional<U>> mapper): Преобразует значение, возвращая Optional, результат которого не оборачивается в дополнительный Optional.
filter(Predicate<? super T> predicate): Возвращает Optional, содержащий значение, если оно удовлетворяет предикату, или пустой Optional.
or(Supplier<? extends Optional<? extends T>> supplier) (добавлен в Java 9): Возвращает текущий Optional, если значение присутствует, или результат Supplier.


Пример использования методов
Optional<String> name = Optional.ofNullable(getName()); // Может вернуть null
String result = name
.map(String::toUpperCase)
.filter(s -> s.length() > 3)
.orElse("DEFAULT");
System.out.println(result); // Выведет преобразованное значение или "DEFAULT"

Этот пример демонстрирует цепочку вызовов, характерную для функционального программирования, где Optional используется для обработки значения с возможностью отсутствия.



Преимущества Optional
Безопасность от NPE: Optional явно указывает на возможность отсутствия значения, заставляя разработчика обрабатывать этот случай.
Читаемость кода: Код с Optional более выразителен, так как сигнализирует о потенциальном отсутствии значения.
Избежание явного null: Уменьшает использование проверок if (value != null), делая код чище.
Интеграция с функциональным программированием: Методы map, flatMap и filter позволяют использовать Optional в цепочках обработки данных, интегрируясь с Stream API.



Практическое использование Optional

Интеграция со Stream API
Optional часто используется в связке со Stream API для обработки данных, которые могут отсутствовать. Например:
Optional<User> user = findUserById(123);
Stream<User> userStream = user.stream(); // Преобразует Optional в Stream
userStream.forEach(System.out::println);

Метод stream() (добавлен в Java 9) позволяет преобразовать Optional в Stream, содержащий либо одно значение, либо пустой.


Обработка вложенных объектов
Optional особенно полезен при работе с цепочками объектов, где каждое звено может быть null. Без Optional код выглядел бы так:
String city = null;
if (user != null && user.getAddress() != null && user.getAddress().getCity() != null) {
city = user.getAddress().getCity();
}


С использованием Optional код становится более компактным:
String city = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("Unknown");


Метод flatMap полезен, если методы возвращают Optional:
Optional<String> city = Optional.ofNullable(user)
.flatMap(u -> Optional.ofNullable(u.getAddress()))
.flatMap(a -> Optional.ofNullable(a.getCity()));


Использование в API
Optional часто применяется в публичных API для возврата значений, которые могут отсутствовать. Например, метод Map.getOrDefault может быть заменен на Optional:
Map<String, String> map = new HashMap<>();
Optional<String> value = Optional.ofNullable(map.get("key"));


#Java #Training #Medium #Optional
👍2
Антипаттерны и ограничения

Использование Optional для полей класса: Optional не предназначен для хранения состояния в полях класса, так как он не сериализуем (Optional не реализует Serializable). Вместо этого используйте null для полей или коллекции.
// Антипаттерн
public class User {
private Optional<String> name; // Не рекомендуется
}


Чрезмерное использование isPresent():
Проверки isPresent() с последующим вызовом get() сводят на нет преимущества Optional:

// Антипаттерн
if (optional.isPresent()) {
return optional.get();
}


Вместо этого используйте orElse, orElseGet или map
:
return optional.orElse(defaultValue);


Передача Optional в методы: Передача Optional в качестве аргумента метода может усложнить API. Лучше передавать значение или null:
// Антипаттерн
void process(Optional<String> value) { ... }

// Лучше
void process(String value) { ... }


Производительность: Создание объектов Optional в циклах или в высокопроизводительных системах может привести к накладным расходам. В таких случаях рассмотрите использование null или оптимизируйте код.
Сериализация: Optional не реализует Serializable, что делает его непригодным для использования в сериализуемых классах. Если сериализация необходима, преобразуйте Optional в null или значение перед сохранением.
Потокобезопасность: Optional не является потокобезопасным, так как он не предназначен для конкурентного доступа. Если значение внутри Optional изменяется в многопоточной среде, используйте синхронизацию или потокобезопасные альтернативы.


Производительность и оптимизация
Создание объектов: Каждый вызов Optional.of или ofNullable создает новый объект (кроме empty(), который использует синглтон). В критически важных участках кода минимизируйте создание Optional.
Кэширование: Если Optional возвращается часто используемым методом, рассмотрите кэширование результата, чтобы избежать повторного создания объектов.
Ленивые вычисления: Используйте orElseGet вместо orElse, если альтернативное значение требует вычислений:

// Менее эффективно
String result = optional.orElse(computeExpensiveDefault());

// Более эффективно
String result = optional.orElseGet(() -> computeExpensiveDefault());



Рекомендации

- Используйте Optional только там, где это имеет смысл: Применяйте Optional для возвращаемых значений методов, где отсутствие значения — это ожидаемый сценарий. Не используйте его для всех случаев, чтобы избежать ненужной сложности.
- Интеграция с функциональными API: Максимально используйте методы map, flatMap и filter для обработки данных в функциональном стиле. Это улучшает читаемость и поддерживаемость кода.
- Проверка на обратную совместимость: Если вы разрабатываете публичное API, учитывайте, что клиенты на Java 7 и ниже не смогут использовать Optional. В таких случаях предоставляйте альтернативные методы, возвращающие null.
- Тестирование: Убедитесь, что тесты покрывают оба случая — присутствие и отсутствие значения в Optional. Это гарантирует корректную обработку всех сценариев.
- Рефакторинг старого кода: При рефакторинге кода, использующего null, заменяйте проверки на Optional, но только если это улучшает читаемость и безопасность. Не заменяйте null на Optional механически.



Пример реального сценария

Предположим, у нас есть сервис, который возвращает информацию о пользователе:
public class UserService {
public Optional<User> findUserById(long id) {
// Имитация поиска в базе данных
return id == 123 ? Optional.of(new User("Alice")) : Optional.empty();
}

public Optional<String> getUserCity(long id) {
return findUserById(id)
.flatMap(user -> Optional.ofNullable(user.getAddress()))
.flatMap(address -> Optional.ofNullable(address.getCity()));
}
}

Этот код демонстрирует, как Optional используется для безопасной обработки цепочки объектов, где каждое звено может быть отсутствующим.


#Java #Training #Medium #Optional
👍2
Есть предложение встретиться завтра в 16:00 по МСК на лайвкодинг!

Тема будет: MailSender - или как отправить email из Spring
Anonymous Poll
42%
Да, интересно, я приду!🥳
11%
Блиин, хочу но не могу 🤷‍♀️
42%
Посмотрю в записи 😋
5%
Не приду, фигню рассматриваете 👎
👍1
Всем привет! 👋

Приглашаю всех желающих сегодня собраться в Яндекс.Телемост в 16:00 по МСК!

В этот раз мы рассмотрим один из модулей Spring - MailSender

И даже если раньше вы все это знали, лишним повторить не будет.

Приходите, это хороший шанс позадавать вопросы 🧑‍💻

Как всегда жду всех! 🫡
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Наш "Темный попутчик"

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

“О, уведомление в телефоне, хм...”
“Пойду налью кофе/чай/вискарика, а то не сосредоточусь”
“Так, а может завтра тоже есть время?”


И вот он уже рядом. Сел поудобнее рядом и улыбается.

Тёмный попутчик - ПРОКРАСТИНАЦИЯ🏝


Но на самом деле, все не так страшно ☺️

Давай разбираться
😉

Прокрастинация — это не лень ❗️

Серьёзно.
Если бы это была просто лень — ты бы не испытывал вину за бездействие.
Ты бы не планировал, не страдал, не искал решения.


С научной точки зрения, прокрастинация — это иррациональное откладывание дел, сопровождающееся стрессом, тревожностью, и часто — сниженной самооценкой.

"Прокрастинация — это не проблема управления временем. Это проблема управления эмоциями."
— Тимоти Пихл, профессор психологии, автор исследований по теме.

То есть ты откладываешь не потому что «плохо спланировал день», а потому что в моменте задача вызывает дискомфорт, страх, перфекционизм или даже неосознанную тревогу провала.
(И мозг такой: “А может не надо испытывать всё это прямо сейчас?.. Давай YouTube-чик?..”)


Ты можешь спросить: Это как «Синдром самозванца» из предыдущей статьи?

Да.
И они очень часто идут рука об руку. 🤝

Синдром самозванца шепчет тебе: "Ты не справишься. Ты недостаточно хорош. Это не для тебя".
А прокрастинация отвечает: "Окей! Давай немного отложим! На потом! А пока посмотрим видосы про котиков".
🆘

Сочетание этих двух — вражеский тандем внутри твоей головы. Один пугает, другой уводит от страха. В итоге ты вроде и не бездельничаешь (ну, ты же чем-то занят!), но никуда не продвигаешься.



Откуда приходит прокрастинация?

Психологи выделяют несколько корней прокрастинации:
Эмоциональное избегание – когда ты еще не начал задачу, но уже стрессуешь, что она сложная и ты не справишься. И вместо поиска решения, залипаешь в тик-ток.
Перфекционизм – когда задача кажется слишком важной, и хочется сделать ее «идеально». Но идеал недостижим → страшно, что не получится → откладываем.
Низкая саморегуляция – отсутствие способности справляться с своими внутренними импульсами. Ты просто не можешь заставить себя сесть за задачу.



И что делать-то?

1. Принять, что это НОРМАЛЬНО.
Если ты осознал, что прокрастинируешь — не страшно. Я, ты, даже суперуспешные программисты — все откладывают. Просто надо научиться держать этот хаос под контролем.🧑‍💻

2. Обманывать мозг.
Сказать себе: “Сделаю 10 минут, и всё, можно будет отдыхать”. И, о чудо — через 30 минут ты уже глубоко в дебрях кода.
Это называется “техника маленьких шагов” — не грузить себя “большой задачей”, а начинать с малого. Упростить задачу, выбрав, что полегче и начать.
Работает почти всегда.


3. Выбери что-то одно.
Когда у тебя открыто множество обучающих вкладок: “Выучить Spring”, “Новое по Hibernate” или новая статья на канале “ Java for Beginner” — угадай, чем всё закончится? Правильно: YouTube, котики и стирка носков.
Выбери ОДНО и делай. Остальное — в «позже» (а может и в "нафиг"...
☺️).

4. Используй "tecnica del pomodoro"
25 минут работаешь, 5 отдыхаешь. Простой трюк, но мозгу легче "терпеть" неприятное, если знает, что скоро — пауза.
Это методика из когнитивно-поведенческой психологии — дробление задач снижает тревожность.



Но главное: не жди, что мотивация заняться задачей появится. 🤫

Если честно — мотивация в 90% случаев НЕ приходит.
Если прокрастинация в разгаре, то можно провалиться в окончательную лень и перестать бороться.
Начинать нужно без неё. Начинать нужно через "нехочу".

А вот когда пошел процесс, когда что-то получилось — появляется и мотивация.

Старт → действие → результат → мотивация.



Прокрастинация — не отсутствие силы воли. Это просто неправильный диалог с собой.

Мозг не против работать. Он просто не хочет страдать.
Договорись с темным попутчиком, обмани, разбей задачу, убери лишние эмоции — и действуй.



А теперь — иди и начни делать то, что откладывал, прокрастинируя и залипая в эту статью! 💪

😎

#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3
Предлагаем темы для разбора и публикации! 📖

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

Голосование будет проводиться всю неделю, а статья или видео - выходить по выходным.

Примерные правила:
🟢 темы, не выше уровня middle, чтоб был интерес общим.
🟢Один человек - одна тема.
🟢Тема должна быть отдельным теоретически-практическим вопросом. Готовый проект - это не тема!

Жду Ваших предложений! 👏
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Выбираем темы для рассмотрения в следующие выходные! 🤨
Anonymous Poll
31%
Object Mapper
28%
Mockito
22%
IO/NIO
19%
AOP
👍1
Встреча создана - https://telemost.yandex.ru/j/57583303935425

Залетаем! ✈️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
MailSender - как отправить mail из Spring.

Встреча от 22.06.2025

На сегодняшней встрече мы рассмотрели:
🔵 Что такое MailSender и зачем он вообще нужен.
🔵 Прошлись по основным свойствам и настройкам, посмотрели как запустить отправку писем через Mail.ru
🔵 Написали код в котором научились отправлять как просто письма, так и делать рассылку с вложениями, картинками и html-кодом для красивого оформления писем.
🔵 Все это протестировали через Postman.

Более подробное описание всего, что рассмотрели в видео и пример реализации, который можно скачать:
GitHub -
https://github.com/Oleborn/MailSender_Research
(понравилось - поставь звездочку ❤️)

Всем кто пришел и участвовал - моя признательность 🙂

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

Смотрите, ставьте лайки, подписывайтесь на каналы!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥91