IT Academy
Справочник курса

Java и промышленный backend

Все объяснения, задачи и лабораторная в одном месте.

Можно сохранить страницу в PDF через печать браузера. Для печати разборы ответов раскрываются автоматически.

1. Java type system, records и exceptions

Объяснение

Ссылочный тип может иметь null, примитив — непосредственное значение. Record сокращает описание носителя данных, но не делает вложенные изменяемые объекты неизменяемыми. Исключения передают ошибку отдельно от обычного результата.

Задача для самостоятельного решения

Неизменяем ли record с полем List?

Показать разбор ответа

Ссылка поля фиксирована, но список может изменяться. Для снимка используйте защитную копию, например List.copyOf, и учитывайте изменяемость самих элементов.

2. Collections, generics и Stream API

Объяснение

HashMap ищет по hashCode и equals. Если ключ изменил поля, участвующие в хеше, запись может стать недоступной через обычный lookup. Stream описывает цепочку операций и выполняется терминальной операцией.

Задача для самостоятельного решения

Почему mutable объект — опасный ключ map?

Показать разбор ответа

После изменения hashCode поиск идёт в другую корзину. Ключ должен сохранять равенство и хеш, пока находится в map; удобны неизменяемые идентификаторы.

3. JVM, память, GC и диагностика

Объяснение

JVM управляет heap и сборкой мусора. GC освобождает недостижимые объекты, а не просто старые. Утечка Java обычно означает ненужную, но достижимую цепочку ссылок.

Задача для самостоятельного решения

Кеш растёт после каждого запроса. Что искать в heap dump?

Показать разбор ответа

Dominator и путь к GC root, удерживающий записи. Исправление — политика вытеснения или удаление ссылок; увеличение heap только откладывает проблему.

4. Concurrency и structured async

Объяснение

Потоки разделяют память, поэтому публикация данных требует правил happens-before. Executor управляет задачами, а не бизнес-транзакциями. Отмена и timeout должны доходить до сетевых и БД-операций.

Задача для самостоятельного решения

Почему timeout HTTP-ответа не гарантирует прекращение SQL-запроса?

Показать разбор ответа

Завершение ожидания клиента не обязательно отменяет работу сервера. Нужны отдельный timeout запроса, отмена и освобождение соединения; иначе нагрузка продолжает расти.

5. Spring Boot, DI и конфигурация

Объяснение

Dependency injection передаёт зависимости извне. Singleton bean должен безопасно обслуживать параллельные запросы. Конфигурацию окружения отделяют от кода; секреты не хранят в репозитории.

Задача для самостоятельного решения

Можно ли хранить текущего пользователя в поле singleton controller?

Показать разбор ответа

Нет: параллельные запросы перезапишут поле. Передавайте пользователя параметром или используйте предназначенный request context.

6. Persistence, тесты и эксплуатация сервиса

Объяснение

Транзакция объединяет изменения, а ORM не устраняет стоимость запросов. N+1 появляется, когда обход N сущностей вызывает отдельную загрузку каждой связи. Интеграционный тест должен проверять реальную границу БД.

Задача для самостоятельного решения

Список из 50 заказов вызывает 51 запрос. Как диагностировать?

Показать разбор ответа

Один запрос загружает заказы, ещё 50 — связанные данные. Проверьте SQL-лог, используйте fetch join или batch fetching с учётом пагинации и объёма результата.

Практика

Лабораторная работа

Подготовка

JDK с поддержкой records. Сохраните Main.java, выполните javac Main.java и java Main.

Учебный пример

import java.util.List;
public class Main {
    record Item(String name, int price) {}
    public static void main(String[] args) {
        var items = List.of(new Item("A",100), new Item("B",200));
        int total = items.stream().mapToInt(Item::price).sum();
        if (total != 300) throw new IllegalStateException();
        System.out.println(total);
    }
}

Как работает пример и что ожидать

Вывод 300. Record описывает пару значений, stream преобразует items в цены и суммирует их. Целые цены здесь условно выражены в минимальных денежных единицах; для реального контракта нужно назвать валюту и правило округления.

Итоговая работа

Постройте REST-сервис заказов с разделением controller/service/repository, транзакцией и интеграционным тестом. Добавьте валидацию цены, проверку владельца заказа, ограничение времени БД и тест повторного запроса.

Проверка результата

1. Опишите исходные данные и условия запуска, чтобы другой человек мог повторить работу.
2. Приложите результат обычного сценария и сравните его с ожидаемым.
3. Проверьте неверный вход, граничный случай и отказ зависимости, если она есть.
4. Объясните выбранное решение и известное ограничение.
5. Сохраните исправления после самопроверки вместе с примером, который раньше не работал.

Как оценить работу

По каждому пункту поставьте 0 (не выполнено), 1 (выполнено с пробелами) или 2 (результат воспроизводим и объяснён). Если обязательный сценарий не работает, вернитесь к нему независимо от общей суммы. Это рубрика самопроверки: сайт не исполняет присланный код и не выдаёт автоматическую оценку проекта.