Java Portal | Программирование
11.6K subscribers
1.59K photos
119 videos
45 files
1.65K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
План изучения Java за 6–12 месяцев в эпоху ИИ

Этап 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-собеседованиям.
• Основы алгоритмов и структур данных.
• Основы проектирования систем.
• Практики чистого кода.
• Умение объяснять, как вы используете ИИ в разработке.
• Привычка постоянно учиться.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
🚀 Spring Boot 4: EnvironmentPostProcessor сменил пакет

✅ Новый: org.springframework.boot.EnvironmentPostProcessor
✅ Старый пакет временно сохранён, но помечен как устаревший.
✅ Обновите импорты в коде и регистрацию в spring.factories.

👉 Java Portal
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
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+ хорошо подходят для задач, которые большую часть времени проводят в ожидании.

Общий Semaphore ограничивает число одновременных обращений к зависимому сервису: каждая задача получает собственный виртуальный поток, но одновременно выполнять вызов API могут не более 10 задач.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
💡 Spring Boot 4: DevTools больше не запускает сервер LiveReload по умолчанию

✅ Автоматический перезапуск приложения при изменениях в classpath работает как раньше.
✅ Для включения LiveReload задайте spring.devtools.livereload.enabled=true.
✅ Порт 35729 больше не занимается автоматически — удобно, когда на одной машине запущено несколько приложений.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1
Многопоточность в Java: volatile, Atomic и synchronized

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

Коротко:
• 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 — нужно согласованно выполнить несколько действий с общим состоянием

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Serializable, Externalizable и Protocol Buffers: в чём разница?

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

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 и отдельный формат обмена данными.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Connection Pool, Thread Pool и Object Pool: в чём разница?

Общая идея одна: повторно использовать дорогие ресурсы вместо постоянного создания новых. Но каждый пул управляет своим типом ресурсов.

• Connection Pool — пул соединений. Хранит соединения, например с базой данных. Приложение берёт свободное соединение, выполняет запросы и возвращает его в пул.

• Thread Pool — пул потоков. Повторно использует рабочие потоки для выполнения задач. Не нужно создавать отдельный поток под каждую новую задачу.

• Object Pool — пул объектов. Позволяет брать готовые объекты, использовать их, сбрасывать состояние и возвращать для следующего вызова.

Пример: Spring Boot с обычной блокирующей обработкой запросов. Рабочий поток обрабатывает HTTP-запрос и выполняет бизнес-логику. Когда требуется доступ к БД, приложение получает соединение из пула.

После завершения работы с БД соединение возвращается в пул. После обработки запроса рабочий поток освобождается для следующей задачи. Это два отдельных ресурса с разным временем использования.

А стоит ли переиспользовать обычные Java-объекты? Не всегда. JVM эффективно выделяет память под короткоживущие объекты и собирает их сборщиком мусора. Пул имеет смысл прежде всего для объектов с дорогим созданием или ресурсов с ограниченным количеством.

Больше ресурсов не означает быстрее:

• Слишком много соединений может перегрузить базу.
• Слишком много платформенных потоков увеличивает расход памяти и затраты на переключение контекста.
• Неудачный пул объектов удерживает память и создаёт конкуренцию за доступ.

Поэтому важен не только сам пул, но и его размер. Переиспользование полезно, когда оно действительно дешевле повторного создания.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
ForkJoinPool, ExecutorService и Virtual Threads: что выбирать в Java?

Всё зависит от нагрузки: задачи в основном вычисляют или ждут ответа базы и внешних сервисов? При этом сравниваются разные уровни: ExecutorService — интерфейс управления задачами, ForkJoinPool — одна из его реализаций, а виртуальные потоки — тип потоков. Их можно использовать вместе.

ForkJoinPool — для параллельных вычислений. Хорошо подходит для задач, которые можно разбить на независимые части: рекурсивных алгоритмов, обработки массивов и других CPU-intensive вычислений.

Использует work-stealing: свободный рабочий поток забирает задачи из очередей других потоков. Но не любая тяжёлая операция требует ForkJoinPool. Для независимых вычислительных задач может быть достаточно обычного фиксированного пула.

ExecutorService — для запуска и управления задачами. Позволяет отправлять задачи на выполнение, получать результаты через Future и управлять завершением исполнителя. Конкретная реализация определяет, как выполняются задачи.

ExecutorService executor =
Executors.newFixedThreadPool(10);


Здесь одновременно работают не более 10 потоков. Однако очередь задач у такого исполнителя не ограничена: при постоянной перегрузке она может расти. Для выполнения по расписанию используется ScheduledExecutorService.

Virtual Threads — для большого количества ожидающих задач. Виртуальные потоки стали стандартной возможностью в Java 21. Они особенно полезны, когда задачи много времени проводят в блокирующих вызовах к БД или HTTP-сервисам. Их тоже можно использовать через ExecutorService:

try (var executor =
Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> callExternalApi());
}


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

Что важно в продакшене:

• Виртуальные потоки не добавляют процессорных ядер и сами по себе не ускоряют вычисления.
• Тысячи виртуальных потоков не означают, что база выдержит тысячи одновременных запросов. Нужны отдельные ограничения, например пул соединений или Semaphore.
• Ограничение числа рабочих потоков не равно ограничению очереди задач.

ForkJoinPool помогает распараллеливать вычисления. ExecutorService управляет выполнением задач. Virtual Threads позволяют эффективно организовать множество задач, ожидающих I/O.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Откуда в Spring Boot берётся веб-сервер?

Запускаете приложение:

java -jar app.jar

И оно начинает принимать HTTP-запросы. Без отдельной установки Tomcat и развёртывания WAR-файла.

Секрет — во встроенном сервере. Для обычного Spring MVC-приложения зависимость веб-стартера по умолчанию подтягивает Tomcat. Его библиотеки входят в исполняемый JAR, а Spring Boot автоматически настраивает и запускает сервер вместе с приложением.

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

Embedded не означает, что сервера нет. Он работает внутри процесса вашего Java-приложения. Tomcat — не единственный вариант: например, приложения на Spring WebFlux по умолчанию используют Reactor Netty.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2