💡 Java: не создавайте ресурсоёмкие объекты, пока они действительно не понадобятся.
✅ Инициализация полей заранее тратит время и память впустую, если код, который их использует, так и не выполнится.
✅ Используйте ленивую инициализацию при первом обращении,
✅ Подходит для кэшей, клиентов и тяжёлых конфигураций.
👉 Java Portal
✅ Инициализация полей заранее тратит время и память впустую, если код, который их использует, так и не выполнится.
✅ Используйте ленивую инициализацию при первом обращении,
Supplier или паттерн Holder.✅ Подходит для кэшей, клиентов и тяжёлых конфигураций.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🤔1
Большинство Java-разработчиков используют эти термины каждый день. Удивительно, но многие до сих пор их путают. Вот простой способ запомнить разницу.
JDK (Java Development Kit)
• Всё необходимое для разработки Java-приложений:
• Компилятор
• Инструменты отладки
• Инструменты упаковки
• Среда выполнения JRE
JRE (Java Runtime Environment)
• Всё необходимое для запуска Java-приложений:
• Основные библиотеки
• Вспомогательные файлы
• Виртуальная машина JVM
JVM (Java Virtual Machine)
• Движок, который выполняет Java-байткод:
• Загружает классы
• Проверяет байткод
• JIT-компилирует часто выполняемый код
• Управляет памятью и сборкой мусора
Как запомнить:
JDK = JRE + инструменты разработки
JRE = JVM + библиотеки
JVM = выполнение байткода
Представьте приготовление кофе
• JDK — кофемашина, зёрна, кофемолка и всё необходимое для приготовления кофе.
• JRE — готовый к употреблению кофе.
• JVM — нагреватель, благодаря которому кофе заваривается.
Если вы пишете код, устанавливайте JDK. Если только запускаете Java-приложение, достаточно JRE, хотя современные дистрибутивы JDK обычно уже включают необходимую среду выполнения.
👉 Java Portal
JDK (Java Development Kit)
• Всё необходимое для разработки Java-приложений:
• Компилятор
javac• Инструменты отладки
• Инструменты упаковки
• Среда выполнения JRE
JRE (Java Runtime Environment)
• Всё необходимое для запуска Java-приложений:
• Основные библиотеки
• Вспомогательные файлы
• Виртуальная машина JVM
JVM (Java Virtual Machine)
• Движок, который выполняет Java-байткод:
• Загружает классы
• Проверяет байткод
• JIT-компилирует часто выполняемый код
• Управляет памятью и сборкой мусора
Как запомнить:
JDK = JRE + инструменты разработки
JRE = JVM + библиотеки
JVM = выполнение байткода
Представьте приготовление кофе
• JDK — кофемашина, зёрна, кофемолка и всё необходимое для приготовления кофе.
• JRE — готовый к употреблению кофе.
• JVM — нагреватель, благодаря которому кофе заваривается.
Если вы пишете код, устанавливайте JDK. Если только запускаете Java-приложение, достаточно JRE, хотя современные дистрибутивы JDK обычно уже включают необходимую среду выполнения.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Эволюция языков программирования
1940-е → Машинный код
⬇️
1950-е → Ассемблер
⬇️
1960-е → FORTRAN • COBOL • BASIC
⬇️
1970-е → C • Pascal
⬇️
1980-е → C++ • Objective-C
⬇️
1990-е → Java • JavaScript • PHP
⬇️
2000-е → C# • Ruby • Scala
⬇️
2010-е → Go • Rust • Kotlin • Swift
⬇️
2020-е → Программирование с помощью ИИ
Каждое поколение решало свои задачи:
• Машинный код → прямое управление оборудованием.
• Ассемблер → инструкции, понятные человеку.
• C и Pascal → переносимость программ и структурное программирование.
• Java и JavaScript → корпоративное ПО и современный веб.
• C#, Ruby и Scala → продуктивность разработчиков и масштабируемые приложения.
• Go, Rust, Kotlin и Swift → облачные системы, безопасность памяти и современные платформы.
• Программирование с помощью ИИ → ускорение разработки, при котором архитектурные решения по-прежнему принимают люди.
Что самое интересное?
Языки развивались не потому, что старые становились бесполезными. Каждое новое поколение ПО приносило новые задачи. И вот подтверждение:
• На C по-прежнему пишут операционные системы.
• На Java работают миллионы корпоративных приложений.
• JavaScript по-прежнему доминирует в вебе.
• Python остаётся ведущим языком в ИИ и анализе данных.
Новое не заменяет старое. Оно расширяет возможности. На каком языке вы написали свой первый Hello, World!?
👉 Java Portal
1940-е → Машинный код
1950-е → Ассемблер
1960-е → FORTRAN • COBOL • BASIC
1970-е → C • Pascal
1980-е → C++ • Objective-C
1990-е → Java • JavaScript • PHP
2000-е → C# • Ruby • Scala
2010-е → Go • Rust • Kotlin • Swift
2020-е → Программирование с помощью ИИ
Каждое поколение решало свои задачи:
• Машинный код → прямое управление оборудованием.
• Ассемблер → инструкции, понятные человеку.
• C и Pascal → переносимость программ и структурное программирование.
• Java и JavaScript → корпоративное ПО и современный веб.
• C#, Ruby и Scala → продуктивность разработчиков и масштабируемые приложения.
• Go, Rust, Kotlin и Swift → облачные системы, безопасность памяти и современные платформы.
• Программирование с помощью ИИ → ускорение разработки, при котором архитектурные решения по-прежнему принимают люди.
Что самое интересное?
Языки развивались не потому, что старые становились бесполезными. Каждое новое поколение ПО приносило новые задачи. И вот подтверждение:
• На C по-прежнему пишут операционные системы.
• На Java работают миллионы корпоративных приложений.
• JavaScript по-прежнему доминирует в вебе.
• Python остаётся ведущим языком в ИИ и анализе данных.
Новое не заменяет старое. Оно расширяет возможности. На каком языке вы написали свой первый Hello, World!?
Please open Telegram to view this post
VIEW IN TELEGRAM
🏆2😁1
Docker прост, пока всё работает.
Но что делать, если контейнер постоянно перезапускается, логи пропали, а приложение теряет данные после перезапуска? Тут уже недостаточно одного
Команды Docker, которые стоит знать каждому разработчику:
•
•
•
•
•
•
•
•
В продакшене не забывайте:
• Использовать небольшие базовые образы из доверенных источников.
• Запускать приложение от пользователя без прав root.
• Настраивать проверки работоспособности и ограничения ресурсов.
• Не хранить секреты в Docker-образах.
• Использовать тома для постоянного хранения данных.
Подготовили шпаргалку по Docker для продакшена: архитектура, команды, примеры, сети, тома, Compose и советы по диагностике проблем.
👉 Java Portal
Но что делать, если контейнер постоянно перезапускается, логи пропали, а приложение теряет данные после перезапуска? Тут уже недостаточно одного
docker run.Команды Docker, которые стоит знать каждому разработчику:
•
docker logs -f → следить за логами приложения.•
docker exec -it → выполнять команды внутри работающего контейнера для диагностики.•
docker inspect → изучать конфигурацию контейнера.•
docker stats → проверять потребление CPU и памяти.•
docker network → управлять сетями и разбираться с соединениями между сервисами.•
docker volume → управлять томами для хранения данных вне жизненного цикла контейнера.•
docker compose → запускать несколько сервисов вместе.•
docker system df → проверять, сколько места на диске занимает Docker.В продакшене не забывайте:
• Использовать небольшие базовые образы из доверенных источников.
• Запускать приложение от пользователя без прав root.
• Настраивать проверки работоспособности и ограничения ресурсов.
• Не хранить секреты в Docker-образах.
• Использовать тома для постоянного хранения данных.
Подготовили шпаргалку по Docker для продакшена: архитектура, команды, примеры, сети, тома, Compose и советы по диагностике проблем.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Почему один и тот же Java-файл
Секрет не в самом языке Java, а в JVM. Вот какой путь проходит программа:
Именно этот дополнительный уровень абстракции даёт Java её знаменитую возможность: «Написал один раз — запускай где угодно». Когда понимаешь эту цепочку, разобраться в JIT-компиляции, сборке мусора и настройке JVM становится гораздо проще.
Как думаете, почему Java использует промежуточный байткод, а не компилируется сразу в машинный код?
👉 Java Portal
.class запускается на Windows, Linux и macOS без перекомпиляции?Секрет не в самом языке Java, а в JVM. Вот какой путь проходит программа:
Hello.java → javac → Hello.class (байткод) → JVM → машинный код → выполнение программыИменно этот дополнительный уровень абстракции даёт Java её знаменитую возможность: «Написал один раз — запускай где угодно». Когда понимаешь эту цепочку, разобраться в JIT-компиляции, сборке мусора и настройке JVM становится гораздо проще.
Как думаете, почему Java использует промежуточный байткод, а не компилируется сразу в машинный код?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👀1
Spring Boot 4: приближение срока истечения SSL-сертификатов больше не меняет статус health-проверки на специальный.
✅ Статус
✅ Статус остаётся
✅ Порог предупреждения настраивается параметром:
👉 Java Portal
✅ Статус
WILL_EXPIRE_SOON удалён.✅ Статус остаётся
UP; проверяйте details.expiringChains.✅ Порог предупреждения настраивается параметром:
management.health.ssl.certificate-validity-warning-threshold
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👀1
Процесс ≠ Поток ≠ Виртуальный поток. Эти понятия часто путают, хотя они решают разные задачи.
Процесс — экземпляр запущенной программы с собственным адресным пространством.
Поток — единица выполнения внутри процесса. Потоки одного процесса разделяют память.
Виртуальный поток — легковесный поток под управлением JVM, который позволяет обрабатывать множество конкурентных задач с небольшими накладными расходами.
Когда что использовать?
Процесс:
• Нужна строгая изоляция.
• Требуется отдельное адресное пространство.
• Подходит для запуска независимых приложений.
Поток:
• Разделяет память с другими потоками процесса.
• Подходит для параллельной работы внутри приложения.
• Используется в традиционных многопоточных программах.
Виртуальный поток — Java 21+:
• Создаётся и управляется JVM.
• Требует мало ресурсов при создании.
• Хорошо подходит для задач с ожиданием ввода-вывода: запросов к БД, HTTP-вызовов и обработки сетевых соединений.
• Позволяет выполнять тысячи и даже миллионы конкурентных задач без отдельного потока ОС для каждой.
Примеры из практики
• Запущенные Chrome и VS Code → несколько процессов.
• Обработка запросов в Spring Boot → работа потоков внутри приложения.
• Java-сервис с большим количеством блокирующих обращений к БД или HTTP API → сценарий для виртуальных потоков.
Важно: виртуальные потоки полезны для задач с ожиданием ввода-вывода. Вычисления, интенсивно использующие CPU, сами по себе быстрее от них не станут.
👉 Java Portal
Процесс — экземпляр запущенной программы с собственным адресным пространством.
Поток — единица выполнения внутри процесса. Потоки одного процесса разделяют память.
Виртуальный поток — легковесный поток под управлением JVM, который позволяет обрабатывать множество конкурентных задач с небольшими накладными расходами.
Когда что использовать?
Процесс:
• Нужна строгая изоляция.
• Требуется отдельное адресное пространство.
• Подходит для запуска независимых приложений.
Поток:
• Разделяет память с другими потоками процесса.
• Подходит для параллельной работы внутри приложения.
• Используется в традиционных многопоточных программах.
Виртуальный поток — Java 21+:
• Создаётся и управляется JVM.
• Требует мало ресурсов при создании.
• Хорошо подходит для задач с ожиданием ввода-вывода: запросов к БД, HTTP-вызовов и обработки сетевых соединений.
• Позволяет выполнять тысячи и даже миллионы конкурентных задач без отдельного потока ОС для каждой.
Примеры из практики
• Запущенные Chrome и VS Code → несколько процессов.
• Обработка запросов в Spring Boot → работа потоков внутри приложения.
• Java-сервис с большим количеством блокирующих обращений к БД или HTTP API → сценарий для виртуальных потоков.
Важно: виртуальные потоки полезны для задач с ожиданием ввода-вывода. Вычисления, интенсивно использующие CPU, сами по себе быстрее от них не станут.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
🚀 Spring Boot 4: переименовано свойство преобразования исключений
✅ Было:
✅ Стало:
✅ Используйте
👉 Java Portal
✅ Было:
spring.dao.exceptiontranslation.enabled✅ Стало:
spring.persistence.exceptiontranslation.enabled✅ Используйте
spring-boot-properties-migrator, чтобы обнаружить устаревшее свойство при миграции.Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
💡 Предпочитайте делегирование наследованию: отношение «является» тесно связывает ваш класс с суперклассом.
✅ Подкласс наследует весь доступный API родителя, поэтому изменения в родительском классе могут сломать ваш код.
👉 Java Portal
✅ Подкласс наследует весь доступный API родителя, поэтому изменения в родительском классе могут сломать ваш код.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁10❤3🤯2
💡 Тестируйте крайние случаи: null, пустые значения и границы часто скрывают баги
✅ Проверки только успешного сценария могут пропустить
✅ Пустые списки и списки из одного элемента могут выявить ошибки, незаметные на обычных данных.
✅ Тесты крайних случаев также документируют ожидаемое поведение кода.
👉 Java Portal
✅ Проверки только успешного сценария могут пропустить
NullPointerException.✅ Пустые списки и списки из одного элемента могут выявить ошибки, незаметные на обычных данных.
✅ Тесты крайних случаев также документируют ожидаемое поведение кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
План изучения Java за 6–12 месяцев в эпоху ИИ
Этап 1. Java и основы программирования
• Что такое Java и где она применяется.
• Установка JDK и настройка IDE.
• Синтаксис и структура программы.
• Переменные, типы данных и операторы.
• Условия,
• Использование ИИ для объяснения концепций Java и ошибок.
Этап 2. Объектно-ориентированное программирование
• Классы и объекты.
• Инкапсуляция.
• Наследование.
• Полиморфизм.
• Абстракция.
• Интерфейсы.
• Визуализация связей между классами с помощью ИИ.
Этап 3. Основные возможности Java
• Массивы и коллекции:
• Дженерики.
• Обработка исключений.
• Работа с файлами и вводом-выводом.
• API даты и времени.
• Лямбда-выражения и Stream API.
• Рефакторинг с помощью ИИ.
Этап 4. Память и основы производительности
• Архитектура JVM.
• Heap и stack.
• Основы сборки мусора.
• Утечки памяти.
• Основы профилирования.
• Анализ проблем производительности с помощью ИИ.
Этап 5. Многопоточность и конкурентность
• Потоки и
• Executor Framework.
• Синхронизация.
• Блокировки и конкурентные коллекции.
•
• Предотвращение гонок данных и взаимных блокировок.
Этап 6. Базы данных и хранение данных
• Основы JDBC и SQL.
• Hibernate и JPA.
• Связи между сущностями.
• Транзакции.
• Основы кеширования.
• Оптимизация запросов с помощью ИИ.
Этап 7. Бэкенд-разработка на Java
• Основы Spring Boot.
• Разработка REST API.
• Контроллеры и сервисы.
• Внедрение зависимостей.
• Валидация.
• Управление конфигурацией.
• Документирование API: Swagger/OpenAPI.
• Генерация API с помощью ИИ.
Этап 8. Безопасность и аутентификация
• Основы Spring Security.
• Аутентификация с JWT.
• Концепции OAuth 2.0.
• Управление доступом на основе ролей.
• Хеширование паролей.
• Безопасная работа с конфигурацией.
Этап 9. Тестирование, DevOps и развёртывание
• Unit-тесты: JUnit и Mockito.
• Интеграционные тесты.
• Maven и Gradle.
• Контейнеризация Java-приложений с Docker.
• CI/CD.
• Основы развёртывания в облаке.
• Генерация тестов с помощью ИИ.
Этап 10. Продвинутая Java и архитектура
• Микросервисная архитектура.
• Взаимодействие сервисов.
• Кеширование с Redis.
• Брокеры сообщений: Kafka и RabbitMQ.
• Событийно-ориентированные системы.
• Мониторинг приложений.
• Настройка производительности.
Этап 11. Практические проекты
• Бэкенд с REST API.
• Система аутентификации.
• Бэкенд интернет-магазина.
• Система на микросервисах.
• Java-приложение, развёрнутое в облаке.
• Настройка логирования и мониторинга.
Этап 12. Подготовка к работе
• Подготовка к Java-собеседованиям.
• Основы алгоритмов и структур данных.
• Основы проектирования систем.
• Практики чистого кода.
• Умение объяснять, как вы используете ИИ в разработке.
• Привычка постоянно учиться.
👉 Java Portal
Этап 1. Java и основы программирования
• Что такое Java и где она применяется.
• Установка JDK и настройка IDE.
• Синтаксис и структура программы.
• Переменные, типы данных и операторы.
• Условия,
switch и циклы.• Использование ИИ для объяснения концепций Java и ошибок.
Этап 2. Объектно-ориентированное программирование
• Классы и объекты.
• Инкапсуляция.
• Наследование.
• Полиморфизм.
• Абстракция.
• Интерфейсы.
• Визуализация связей между классами с помощью ИИ.
Этап 3. Основные возможности Java
• Массивы и коллекции:
List, Set, Map.• Дженерики.
• Обработка исключений.
• Работа с файлами и вводом-выводом.
• API даты и времени.
• Лямбда-выражения и Stream API.
• Рефакторинг с помощью ИИ.
Этап 4. Память и основы производительности
• Архитектура JVM.
• Heap и stack.
• Основы сборки мусора.
• Утечки памяти.
• Основы профилирования.
• Анализ проблем производительности с помощью ИИ.
Этап 5. Многопоточность и конкурентность
• Потоки и
Runnable.• Executor Framework.
• Синхронизация.
• Блокировки и конкурентные коллекции.
•
CompletableFuture.• Предотвращение гонок данных и взаимных блокировок.
Этап 6. Базы данных и хранение данных
• Основы JDBC и SQL.
• Hibernate и JPA.
• Связи между сущностями.
• Транзакции.
• Основы кеширования.
• Оптимизация запросов с помощью ИИ.
Этап 7. Бэкенд-разработка на Java
• Основы Spring Boot.
• Разработка REST API.
• Контроллеры и сервисы.
• Внедрение зависимостей.
• Валидация.
• Управление конфигурацией.
• Документирование API: Swagger/OpenAPI.
• Генерация API с помощью ИИ.
Этап 8. Безопасность и аутентификация
• Основы Spring Security.
• Аутентификация с JWT.
• Концепции OAuth 2.0.
• Управление доступом на основе ролей.
• Хеширование паролей.
• Безопасная работа с конфигурацией.
Этап 9. Тестирование, DevOps и развёртывание
• Unit-тесты: JUnit и Mockito.
• Интеграционные тесты.
• Maven и Gradle.
• Контейнеризация Java-приложений с Docker.
• CI/CD.
• Основы развёртывания в облаке.
• Генерация тестов с помощью ИИ.
Этап 10. Продвинутая Java и архитектура
• Микросервисная архитектура.
• Взаимодействие сервисов.
• Кеширование с Redis.
• Брокеры сообщений: Kafka и RabbitMQ.
• Событийно-ориентированные системы.
• Мониторинг приложений.
• Настройка производительности.
Этап 11. Практические проекты
• Бэкенд с REST API.
• Система аутентификации.
• Бэкенд интернет-магазина.
• Система на микросервисах.
• Java-приложение, развёрнутое в облаке.
• Настройка логирования и мониторинга.
Этап 12. Подготовка к работе
• Подготовка к Java-собеседованиям.
• Основы алгоритмов и структур данных.
• Основы проектирования систем.
• Практики чистого кода.
• Умение объяснять, как вы используете ИИ в разработке.
• Привычка постоянно учиться.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
🚀 Spring Boot 4: EnvironmentPostProcessor сменил пакет
✅ Новый:
✅ Старый пакет временно сохранён, но помечен как устаревший.
✅ Обновите импорты в коде и регистрацию в
👉 Java Portal
✅ Новый:
org.springframework.boot.EnvironmentPostProcessor✅ Старый пакет временно сохранён, но помечен как устаревший.
✅ Обновите импорты в коде и регистрацию в
spring.factories.Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Prompt Engineering и Context Engineering
Prompt Engineering — проектирование инструкций для LLM, чтобы получать более качественные ответы. Главная задача — понять, как инструкции влияют на поведение модели.
1. Структура промпта:
Роль + Контекст + Ограничения + Формат ответа.
Пример:
«Ты опытный Java-архитектор. Объясни JWT-аутентификацию простым языком для начинающих. Оформи ответ списком».
2. Типы промптов:
• Zero-shot — задача без примеров.
• Few-shot — задача с примерами.
• Chain-of-thought — побуждение модели решать задачу пошагово.
• Structured prompting — запрос ответа в заданном формате, например JSON по определённой схеме.
3. Context Engineering:
Качество работы AI зависит не только от формулировки запроса, но и от того, какую информацию и возможности получает модель:
• Поиск и извлечение релевантных данных — retrieval.
• Память.
• Организация рабочего процесса — workflows.
• Инструменты.
• Системные инструкции.
Что важно для реальных проектов: Одних удачных промптов недостаточно для масштабирования AI-систем. В продакшене нужны продуманная архитектура, качественный retrieval, управление памятью и проверка результатов.
👉 Java Portal
Prompt Engineering — проектирование инструкций для LLM, чтобы получать более качественные ответы. Главная задача — понять, как инструкции влияют на поведение модели.
1. Структура промпта:
Роль + Контекст + Ограничения + Формат ответа.
Пример:
«Ты опытный Java-архитектор. Объясни JWT-аутентификацию простым языком для начинающих. Оформи ответ списком».
2. Типы промптов:
• Zero-shot — задача без примеров.
• Few-shot — задача с примерами.
• Chain-of-thought — побуждение модели решать задачу пошагово.
• Structured prompting — запрос ответа в заданном формате, например JSON по определённой схеме.
3. Context Engineering:
Качество работы AI зависит не только от формулировки запроса, но и от того, какую информацию и возможности получает модель:
• Поиск и извлечение релевантных данных — retrieval.
• Память.
• Организация рабочего процесса — workflows.
• Инструменты.
• Системные инструкции.
Что важно для реальных проектов: Одних удачных промптов недостаточно для масштабирования AI-систем. В продакшене нужны продуманная архитектура, качественный retrieval, управление памятью и проверка результатов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
💡 Измеряйте покрытие кода тестами, но не гонитесь за 100%.
✅ Покрытие показывает, какие строки выполнились, а не то, что они работают правильно.
✅ Даже при полном покрытии реальные баги могут остаться незамеченными.
✅ Содержательные проверки наиболее рискованных сценариев важнее идеального показателя.
👉 Java Portal
✅ Покрытие показывает, какие строки выполнились, а не то, что они работают правильно.
✅ Даже при полном покрытии реальные баги могут остаться незамеченными.
✅ Содержательные проверки наиболее рискованных сценариев важнее идеального показателя.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Виртуальные потоки в Java 21+ хорошо подходят для задач, которые большую часть времени проводят в ожидании.
Общий
👉 Java Portal
Общий
Semaphore ограничивает число одновременных обращений к зависимому сервису: каждая задача получает собственный виртуальный поток, но одновременно выполнять вызов API могут не более 10 задач.Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
💡 Spring Boot 4: DevTools больше не запускает сервер LiveReload по умолчанию
✅ Автоматический перезапуск приложения при изменениях в classpath работает как раньше.
✅ Для включения LiveReload задайте
✅ Порт
👉 Java Portal
✅ Автоматический перезапуск приложения при изменениях в classpath работает как раньше.
✅ Для включения LiveReload задайте
spring.devtools.livereload.enabled=true.✅ Порт
35729 больше не занимается автоматически — удобно, когда на одной машине запущено несколько приложений.Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1
Многопоточность в Java: volatile, Atomic и synchronized
Все три механизма применяются при работе с общими данными из нескольких потоков, но дают разные гарантии. Неправильный выбор может привести к багам, которые сложно воспроизвести.
Коротко:
•
•
•
volatile: когда важна видимость
Подходит, например, для флага остановки:
Изменение флага будет видно при последующих чтениях из другого потока. Но
Инкремент состоит из чтения, увеличения и записи. Между этими шагами другой поток может изменить значение — и одно из обновлений потеряется.
Atomic: когда нужна атомарная операция
В Java есть
Здесь увеличение счётчика выполняется атомарно, без явного блока
Типичные задачи: счётчики, последовательные номера, условное обновление флагов и ссылок. При этом несколько отдельных вызовов Atomic не становятся одной атомарной операцией автоматически.
synchronized: когда нужно защитить несколько действий
Только один поток может выполнять код, защищённый одним и тем же монитором, в конкретный момент. Для согласованности все обращения к защищаемому состоянию должны соблюдать ту же схему синхронизации.
Конкуренция за блокировку может приводить к ожиданию, а неправильный порядок захвата нескольких блокировок — к deadlock.
Вопрос с собеседования: достаточно ли volatile для count++? Нет. При конкурентном увеличении счётчика нужны
Atomic всегда быстрее synchronized? Тоже нет. При высокой конкуренции операции на основе CAS могут многократно повторять попытки обновления. Выбор зависит от нагрузки, размера критической секции и количества связанных переменных.
Выбирайте по нужной гарантии:
→
→
→
👉 Java Portal
Все три механизма применяются при работе с общими данными из нескольких потоков, но дают разные гарантии. Неправильный выбор может привести к багам, которые сложно воспроизвести.
Коротко:
•
volatile — видимость изменений и гарантии порядка.•
Atomic — атомарные операции над отдельной переменной.•
synchronized — взаимное исключение и видимость изменений.volatile: когда важна видимость
Подходит, например, для флага остановки:
private volatile boolean running = true;
// Один поток:
running = false;
// Другой поток:
while (running) {
// Работа
}
Изменение флага будет видно при последующих чтениях из другого потока. Но
volatile не делает составные операции атомарными:volatile int count;
count++;
Инкремент состоит из чтения, увеличения и записи. Между этими шагами другой поток может изменить значение — и одно из обновлений потеряется.
Atomic: когда нужна атомарная операция
В Java есть
AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference и другие классы:private final AtomicInteger counter =
new AtomicInteger();
counter.incrementAndGet();
Здесь увеличение счётчика выполняется атомарно, без явного блока
synchronized. Типичные задачи: счётчики, последовательные номера, условное обновление флагов и ссылок. При этом несколько отдельных вызовов Atomic не становятся одной атомарной операцией автоматически.
synchronized: когда нужно защитить несколько действий
public synchronized void updateState() {
checkState();
changeState();
updateCounter();
}Только один поток может выполнять код, защищённый одним и тем же монитором, в конкретный момент. Для согласованности все обращения к защищаемому состоянию должны соблюдать ту же схему синхронизации.
synchronized обеспечивает взаимное исключение и видимость изменений. При этом он не откатывает уже выполненные действия при исключении и не заменяет транзакцию базы данных.Конкуренция за блокировку может приводить к ожиданию, а неправильный порядок захвата нескольких блокировок — к deadlock.
Вопрос с собеседования: достаточно ли volatile для count++? Нет. При конкурентном увеличении счётчика нужны
AtomicInteger.incrementAndGet() или защита всей операции одной блокировкой.Atomic всегда быстрее synchronized? Тоже нет. При высокой конкуренции операции на основе CAS могут многократно повторять попытки обновления. Выбор зависит от нагрузки, размера критической секции и количества связанных переменных.
Выбирайте по нужной гарантии:
→
volatile — другие потоки должны видеть изменение.→
Atomic — нужна атомарная операция над переменной.→
synchronized — нужно согласованно выполнить несколько действий с общим состояниемPlease open Telegram to view this post
VIEW IN TELEGRAM
❤2
Serializable, Externalizable и Protocol Buffers: в чём разница?
Все три подхода позволяют представить данные в виде байтов, но отличаются управлением форматом и совместимостью.
Serializable — стандартная сериализация Java
Класс реализует
Это механизм Java, чувствительный к изменениям классов и не предназначенный для удобного обмена данными между разными языками.
Externalizable — явное управление записью и чтением
Класс реализует
Так можно сократить объём данных, но меньший размер и лучшая скорость не гарантированы. Совместимость версий и соответствие логики записи и чтения тоже придётся поддерживать самостоятельно.
Protocol Buffers — обмен данными по схеме
Структура сообщения описывается в
Из схемы генерируется код для Java, Go, Python, C# и других языков. Приложения обмениваются сообщениями в компактном бинарном формате.
Подходит для межсервисного взаимодействия, gRPC и систем, где важна совместимость между языками. При изменении схемы нужно соблюдать правила эволюции — например, не переиспользовать номера удалённых полей.
Как запомнить:
• Serializable: Java берёт на себя стандартную запись состояния объекта.
• Externalizable: разработчик управляет записью и восстановлением.
• Protobuf: приложения обмениваются данными по общей схеме.
Важное уточнение: сериализация — общее название процесса, и Protobuf тоже является способом сериализации. Здесь сравниваются именно механизмы Java и отдельный формат обмена данными.
👉 Java Portal
Все три подхода позволяют представить данные в виде байтов, но отличаются управлением форматом и совместимостью.
Serializable — стандартная сериализация Java
Класс реализует
Serializable, а ObjectOutputStream записывает объект и связанные с ним сериализуемые объекты. По умолчанию сохраняются нестатические поля, не помеченные transient; поведение можно настроить.Это механизм Java, чувствительный к изменениям классов и не предназначенный для удобного обмена данными между разными языками.
Externalizable — явное управление записью и чтением
Класс реализует
writeExternal() и readExternal(). Разработчик определяет, какие данные записать, в каком порядке и как восстановить объект.Так можно сократить объём данных, но меньший размер и лучшая скорость не гарантированы. Совместимость версий и соответствие логики записи и чтения тоже придётся поддерживать самостоятельно.
Protocol Buffers — обмен данными по схеме
Структура сообщения описывается в
.proto:message User {
int64 id = 1;
string name = 2;
}Из схемы генерируется код для Java, Go, Python, C# и других языков. Приложения обмениваются сообщениями в компактном бинарном формате.
Подходит для межсервисного взаимодействия, gRPC и систем, где важна совместимость между языками. При изменении схемы нужно соблюдать правила эволюции — например, не переиспользовать номера удалённых полей.
Как запомнить:
• Serializable: Java берёт на себя стандартную запись состояния объекта.
• Externalizable: разработчик управляет записью и восстановлением.
• Protobuf: приложения обмениваются данными по общей схеме.
Важное уточнение: сериализация — общее название процесса, и Protobuf тоже является способом сериализации. Здесь сравниваются именно механизмы Java и отдельный формат обмена данными.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4