Java Portal | Программирование
12.4K subscribers
1.1K photos
90 videos
36 files
963 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Терминальный интерфейс для Docker на Rust

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

Репозиторий на GitHub

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Вопросы по Java + Spring Boot на собеседованиях (сценарии из реальной практики)

Ниже приведены несколько типичных сценариев с короткими ответами (TL;DR — можно сохранить для повторения перед интервью):

🔸Типы Spring-бинов и стереотипы

Сценарий: Представь, что ты проектируешь сложную e-commerce платформу. Где ты используешь интерфейс с аннотацией
@Repository, а где — с аннотацией @Service? Приведи конкретный пример, какую роль каждая из этих аннотаций играет в процессе оформления заказа пользователем.


@Component — универсальный бин,
@Service — бизнес-логика,
@Repository — DAO + перевод исключений в DataAccessException,
@Controller — контроллер уровня MVC.

🔸Циклические зависимости

Сценарий: Коллега добавил новую фичу, и теперь твое Spring-приложение не стартует, выдавая BeanCurrentlyInCreationException из-за циклической зависимости между ServiceA и ServiceB.
Предположим, что быстро переработать бизнес-логику невозможно. Какое минимальное изменение кода ты бы предложил, чтобы приложение хотя бы запустилось, и почему это считается временным решением?


Spring по умолчанию может использовать проксирование и конструкторную/сеттерную инъекцию.
Лучшее решение — перепроектировать зависимости или использовать @Lazy.

🔸Распространение транзакций

Сценарий: У тебя есть OrderService с методом createOrder(), помеченным @Transactional.
Внутри он вызывает updateInventory() (тоже в OrderService и тоже с @Transactional).
Если updateInventory() выбрасывает runtime-исключение, что произойдет с транзакцией, начатой в createOrder()?
Как изменить дизайн, если нужно, чтобы оба метода выполнялись в отдельных, независимых транзакциях?


Транзакция не будет распространяться (прокси не сработает при внутреннем вызове).
Решение — self-injection (внедрение самого себя как зависимости) или использование AOP.

🔸Скоупы бинов

Сценарий: Нужно хранить товары пользователя в корзине и управлять временным списком поисковых фильтров, который очищается после каждого HTTP-запроса.
Какой скоуп ты выберешь для ShoppingCart и какой — для SearchFilter, и почему?


@SessionScope — для корзины (привязано к пользовательской сессии),
@RequestScope — для поискового фильтра (новый бин на каждый HTTP-запрос).

🔸Controller Advice

Сценарий: В приложении есть и традиционные веб-эндпоинты с Thymeleaf, и REST API.
Нужно централизовать обработку ошибок (например, перехват ResourceNotFoundException):

Как вернуть страницу 404 для обычных web-эндпоинтов?

Как вернуть JSON с ошибкой 404 для REST API?


@ControllerAdvice — используется с @Controller, возвращает view.
@RestControllerAdvice — сочетает @ControllerAdvice + @ResponseBody (для REST API).

🔸Автоконфигурация

Сценарий: Ты добавил в проект стороннюю библиотеку (например, кастомный логгер) и просто положил её JAR в classpath.
Без написания конфигурационных классов Spring автоматически подхватывает нужные бины.
Объясни, как Spring Boot определяет и подключает их при старте.


Использует SpringFactoriesLoader, который читает META-INF/spring.factories и конфигурирует бины в зависимости от содержимого classpath.

🔸Ограничение частоты запросов

Сценарий: Твой публичный API перегружен — один клиент шлет слишком много запросов, мешая остальным.
Какой практичный, независимый от технологий подход можно применить для ограничения, например, 100 запросов в минуту на клиента, и где обычно реализуется такая логика?


Bucket4j / Resilience4j, счетчики в Redis, лимитирование на уровне API Gateway.

🔸Распределённые транзакции

Сценарий: В микросервисной архитектуре оформление заказа включает два шага — списание товара в Inventory Service и списание денег через Payment Service.
Если списание товара прошло успешно, а оплата — нет, какой шаблон проектирования поможет откатить изменения в Inventory и обеспечить согласованность данных?


Шаблон Saga (хореография или оркестрация), либо двухфазный коммит (2PC, но редко используется на практике).

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍5
Как правильно обрабатывать ошибки в Spring Boot REST

Если ты делаешь REST-API на Spring Boot, важно не просто ловить исключения, а возвращать понятные ответы клиенту. Корректные HTTP-коды и осмысленные сообщения помогают быстрее понять, что пошло не так — будь то дубликаты записей, ошибки валидации или проблемы с аутентификацией.

В статье объясняется, как организовать централизованную обработку ошибок, какие статусы стоит использовать (400, 401, 404, 409, 500 и т.д.), и почему логирование играет ключевую роль в поддержке и быстром устранении проблем в проде.

Подробнее тут

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41🌚1💊1
Ты правильно используешь коллекции в Java?

Не все коллекции одинаково полезны, и неправильный выбор может увеличить нагрузку на CPU или память в 10 раз, даже не замечая этого. Если работаешь с большими коллекциями, это важно:

1. ArrayList

Идеально, когда:

Читаешь много, а пишешь мало.

Доступ к элементам по позиции (get(i)).

Почему? Внутри — массив. Чтение очень быстрое, но вставка или удаление в середине медленные, потому что нужно сдвигать элементы.

Используй для: каталогов, списков, которые почти не меняются, или результатов, которые создаются один раз и потом только читаются.

2. LinkedList

Идеально, когда:

Постоянно добавляешь или удаляешь элементы.

Не нужен прямой доступ к элементу по индексу.

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

Используй для: очередей, буферов или структур, где важен порядок, а не скорость доступа.

3. HashMap

Идеально, когда:

Нужно хранить пары ключ/значение.

Требуется быстрый доступ по ключу (как словарь).

Использует функцию хеширования для быстрого поиска. Если hashCode() реализован плохо, может работать медленно и потреблять больше памяти.

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

Перед оптимизацией спроси себя:

Много читаю и мало пишу? → ArrayList

Часто вставляю/удаляю? → LinkedList

Ищу по ключу? → HashMap

Нет универсально «лучшей» структуры. Есть та, которая подходит под твой способ доступа к данным.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍114
This media is not supported in your browser
VIEW IN TELEGRAM
Gitvizz превращает код в интерактивный граф

Терялся в собственном коде?

Встречай Gitvizz — инструмент, который мгновенно превращает кодовую базу в интерактивные графы, чтобы наглядно увидеть, как всё связано.

Посмотреть можно на gitvizz.com

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍4
Что такое String Pool

String Pool → это специальная область памяти внутри heap, где Java хранит строковые литералы.
Главная идея → повторное использование строк и экономия памяти.

Как это работает:

String s1 = "Java";
String s2 = "Java";
System.out.println(s1 == s2); // true


s1 и s2 указывают на один и тот же объект в String Pool → дубликаты не создаются.

Но если сделать так:

String s3 = new String("Java");
System.out.println(s1 == s3); // false


new String() обходит пул и создаёт новый объект в heap.

Зачем это нужно:
→ Экономит память за счёт переиспользования неизменяемых строк.
→ Повышает производительность при повторных строковых значениях.
→ Безопасно для потоков, потому что строки immutable.

Как заставить строку из heap использовать пул?

Ответ:

s3 = s3.intern();


Метод intern() → добавляет строку в пул и возвращает ссылку на объект из пула.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍95
Топ-20 вопросов по микросервисам для Java-разработчиков

На Java67 вышла подборка самых частых вопросов по микросервисной архитектуре — от отличий монолита до тем вроде Docker, Kubernetes, API Gateway, CQRS и Saga-паттернов.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2🤔1
Сценарный вопрос с реального интервью по Java/Spring Boot:

В контроллере вызывается метод сервиса, помеченный аннотацией @Transactional.
Этот метод не только сохраняет сущность, но и отправляет два письма: одно администратору, другое — пользователю, который сделал запрос.

Класс, отвечающий за отправку почты, помечен аннотацией @Async, но Spring всё равно выполняет его синхронно.
В итоге API обрабатывает запрос целых 12 секунд — очевидно, это неприемлемо.

Вопрос: почему так происходит и как это исправить?

Реальная причина:

Когда используется @Transactional, Spring создаёт прокси для транзакции.
Если внутри этого же контекста вызывается @Async-метод, то Spring не создаёт новый поток — потому что вызов происходит внутри того же прокси.

Иными словами, асинхронный код оказывается «заперт» внутри транзакции.

В результате, коммит в базу ждёт, пока оба письма не будут отправлены.

Как исправить:

Заменить прямой вызов отправки писем на event-publisher подход.

После сохранения запроса просто опубликовать событие, например DemoRequestCreatedEvent.

Асинхронные слушатели (@EventListener + @Async) будут обрабатывать отправку писем вне основной транзакции.

Что получаем:

Транзакция завершается за ~100 мс вместо 12 секунд.

API реагирует почти мгновенно.

Письма всё так же надёжно уходят в фоне.

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

Дополнительный вопрос:
Кроме событий, какие подходы ты используешь, чтобы отделить транзакционную логику (например, коммит в БД) от побочных эффектов вроде отправки писем или уведомлений?

@Java_Iibrary
👍92
This media is not supported in your browser
VIEW IN TELEGRAM
Хочешь сделать крутой GitHub-профиль?

На этом сайте собраны десятки классных README от разработчиков со всего мира. Можно смотреть код, вдохновляться, подхватывать идеи и оформить свой профиль так, чтобы он реально выделялся.

github.com/zzetao/awesome-github-profile

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍3
В Java есть одно зарезервированное слово, которое многие не замечают — yield.

Оно появилось в Java 13 вместе с switch expressions.

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

Пример:

int day = 2;

String result = switch (day) {
case 1 -> "Понедельник";
case 2 -> {
System.out.println("Обработка...");
yield "Вторник"; // значение, которое возвращается
}
default -> "Другой день";
};


yield — не то же самое, что break:

break просто прерывает выполнение;

yield возвращает значение блока в switch, который используется как выражение.

🌟

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍136
🔍Тестовое собеседование с Java-разработчиком из Мегафон уже завтра

15 октября(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Мария Пивоварова, старший разработчик в Мегафон, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Мария будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Марии

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Шаг за шагом проектируем сокращатель ссылок

В статье разбираем System Design на реальном примере = создаем свой сервис сокращения ссылок. Это классическая задача, которую часто дают на собеседованиях, и при этом отличная возможность понять, как устроен процесс проектирования систем: от постановки задачи до расчёта нагрузки и продумывания архитектуры.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
4
В Spring Boot можно включить «мягкое» завершение приложения, добавив в конфиг строку: "server.shutdown=graceful"

server:
shutdown: graceful

spring:
lifecycle:
timeout-per-shutdown-phase: 20s

# Сервер будет завершать работу корректно
# Он даст до 20 секунд на завершение всех запросов и бинов.


Это помогает избежать типичных проблем при остановке сервиса:

- Активные HTTP-запросы обрываются посреди выполнения
- Транзакции в базе откатываются неожиданно
- Потоки прерываются до завершения работы

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11👀4
6.851 MIT: Продвинутые структуры данных (весна'21)

Этот курс давно был у меня в списке рекомендаций. Разбор темы иерархии памяти там отлично подан в контексте cache-oblivious алгоритмов.

https://courses.csail.mit.edu/6.851/spring21/

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
Сборщик мусора (Garbage Collector, GC) сильно эволюционировал со временем. Сегодня есть несколько вариантов, и ты можешь выбрать тот, что подходит под твои нужды. Смотри:

- Serial GC (олдскул)

Самый простой и древний.
Один поток, останавливает всё приложение на время очистки памяти.
Подходит для мелких приложений, CLI-инструментов или систем с маленьким heap (пара десятков мегабайт).

- Parallel GC

По сути, тот же Serial, но работает в несколько потоков.
Паузы всё ещё есть, но они короче.
Хорош для batch-задач или сервисов, где короткая остановка не критична.

- G1 GC (Garbage First)

С Java 9 — сборщик по умолчанию.
Делит heap на регионы и чистит только самые “грязные”.
Даёт меньше пауз и предсказуемее поведение.
Оптимальный выбор для большинства продакшен-приложений: Spring, микросервисы и т. д.

- ZGC (Z Garbage Collector)

Паузы меньше 1 мс даже при heap в сотни гигабайт.
Работает почти полностью конкурентно, фактически в реальном времени.
Подходит для систем, которые не могут останавливаться: трейдинг, онлайн-игры, API с высокой доступностью.

- Shenandoah GC

Похож на ZGC, но реализован по-другому (Red Hat).
Тоже стремится к минимальным паузам, отлично чувствует себя на Linux.
Менее популярный, но стабильный вариант.

Что выбрать?

Небольшие приложения → Serial

Batch-процессы → Parallel

Веб-сервисы, микросервисы → G1

Реальное время, критичная задержка → ZGC или Shenandoah

GC уже давно не “та самая штука, что стопит Java”, а гибкий инструмент, который можно подобрать под задачу.
И от этого выбора реально зависит будет твое приложение тормозить… или летать

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍104
Transactions_and_Concurrency_Control.pdf
6.3 MB
Если ты работаешь с Java, очень советую почитать последнее издание “Troubleshooting Java”

В книге куча практических вещей: от лучших практик отладки до логирования, трейсинга, телеметрии, модели памяти Java, предотвращения дедлоков, профайлинга и сэмплинга.

Отличное чтиво, если хочешь реально понимать, что происходит под капотом JVM и как быстро находить проблемы в проде.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
Может ли статический блок выбросить исключение?


У тебя есть класс, который инициализирует какой-то критически важный статический ресурс внутри статического блока. В процессе инициализации может произойти ошибка, и выбросится исключение. Что произойдет, если исключение будет выброшено из статического инициализатора? Какую ошибку в итоге выбросит JVM, и в каком состоянии останется класс после этого?
Подсказка → Если из статического блока выбрасывается исключение, инициализация класса завершается с ошибкой.

Есть ли в Java концепция выбрасывания исключений конструктором?


Ты создаешь класс DatabaseConnection. В конструкторе происходит попытка установить соединение с базой данных, и если это не удается, выбрасывается SQLException. Что произойдет с памятью, выделенной под объект DatabaseConnection, если конструктор выбросит исключение? Можно ли использовать объект после того, как исключение было выброшено?
Подсказка → Конструкторы могут (и часто должны) выбрасывать исключения, если объект невозможно создать в корректном состоянии.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
Хочешь учить и практиковать SQL без установки ничего на компьютер?

Есть классный ресурс и всё работает прямо в браузере.
Можно создавать базы MySQL и PostgreSQL, писать запросы и сразу видеть результат.

Бесплатно → http://sqlplayground.app

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82
Почему важно давать хорошие имена в коде?

Потому что большую часть времени мы не пишем код, а читаем его. И одно удачное имя способно объяснить то, что комментарий бы растянул на три строки.

Что решает хорошее имя:

Намерение: expireSession() говорит больше, чем process().
Контекст: calculatePriceWithTax() понятнее, чем просто calculate().
Контракт: isEmpty() (логический результат) и getSize() (число) — разное поведение, и имя это чётко показывает.

Простые, но работающие правила:

Глагол + объект для действий: sendInvoiceEmail().
Ясное существительное для данных: PaymentRequest, CustomerId.
Без тайнописи вроде cfg, mgr, tmp2.
Если логика нетривиальна, пусть имя объясняет “почему”: retryOnRateLimit().

А комментарии не нужны? 🤔

Нужны, но точечно. Пиши их там, где код сам не может выразить мысль:

когда решение неочевидное;
когда нужна историческая справка или ссылка на ADR.

Главное не использовать комментарии, чтобы объяснять то, что код и так должен рассказывать сам.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍132