Для Java-приложений в Docker лучше всего использовать многоступенчатую сборку с
jlink или jpackage, чтобы собрать кастомный JRE только с нужными модулями.
# Этап сборки jar
FROM maven:3.9.8-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests
# Этап с оптимизированным JRE
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY --from=builder /app/target/myapp.jar myapp.jar
# Оптимизация: ограничим потребление памяти JVM в контейнере
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75", "-jar", "myapp.jar"]
💡 Такой подход:
- уменьшает размер образа,
- использует только нужные зависимости,
- и корректно учитывает ограничения памяти/CPU контейнера.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍10🔥5
Хотите быстро замерить время выполнения кода без тяжёлых библиотек?
Используйте
System.nanoTime() - он точнее, чем currentTimeMillis(), и подходит для измерения производительности:
long start = System.nanoTime();
// код, который нужно замерить
Thread.sleep(500);
long end = System.nanoTime();
System.out.println("Время выполнения: " + (end - start) / 1_000_000 + " ms");
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍7🔥3
Работаете с классом на 500 строк? Теряетесь в методах и полях? Structure Tool Window помогает быстро сориентироваться в любом файле.
— Показывает структуру текущего файла: методы, поля, вложенные классы
— Подсвечивает override-методы, конструкторы, аннотации
— Поддерживает навигацию и поиск по элементам
— Работает для Java, Kotlin, XML, и даже .properties
— Быстро находите нужный метод без скроллинга
— Помогает понять, как устроен чужой код
— Ускоряет навигацию по большим классам и конфигурациям
— Alt+7 (или Cmd+7 на macOS) — откроет Structure
— Можно настроить сортировку, группировку и фильтры
— Клик — и вы уже в нужном месте кода
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥6❤4
🦙 Jlama — LLM-движок для Java-разработчиков. Проект поддерживает популярные модели вроде Llama 3, Mistral и Gemma 2, предлагая инструменты для их загрузки, квантования и запуска. Он работает с Java 20+ и поддерживает распределенные вычисления.
Разработчики могут использовать Jlama как через CLI-интерфейс для локального тестирования моделей, так и встраивать его в свои проекты через Maven-зависимости. Проект будет полезен для интеграции LLM в enterprise-решения без перехода на Python-стек.
🖥 GitHub
✅ Java библиотека #java
Разработчики могут использовать Jlama как через CLI-интерфейс для локального тестирования моделей, так и встраивать его в свои проекты через Maven-зависимости. Проект будет полезен для интеграции LLM в enterprise-решения без перехода на Python-стек.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍9❤4
S3-совместимое хранилище (AWS S3, MinIO, Yandex Object Storage и т.п.) — удобный способ хранить файлы вне приложения. Подключим его к Spring Boot и реализуем минимальный upload/download.
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.60</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
ИЛИ
implementation 'software.amazon.awssdk:s3:2.25.60'
implementation 'org.springframework.boot:spring-boot-starter-web'
s3:
region: eu-central-1
accessKey: minioadmin
secretKey: minioadmin
bucket: demo-bucket
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 20MB
@Configuration
public class S3Config {
@Bean
public S3Client s3Client(S3Props props) {
var builder = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(props.accessKey(), props.secretKey())))
.region(Region.of(props.region()))
.httpClientBuilder(UrlConnectionHttpClient.builder());
if (props.endpoint() != null && !props.endpoint().isBlank()) {
builder = builder
.endpointOverride(java.net.URI.create(props.endpoint()))
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(props.pathStyleAccess())
.build());
}
return builder.build();
}
@Bean
public S3Props s3Props(org.springframework.core.env.Environment env) {
return new S3Props(
env.getProperty("s3.endpoint"),
env.getProperty("s3.region", "eu-central-1"),
env.getProperty("s3.accessKey"),
env.getProperty("s3.secretKey"),
env.getProperty("s3.bucket", "demo-bucket"),
Boolean.parseBoolean(env.getProperty("s3.pathStyleAccess", "true"))
);
}
public record S3Props(String endpoint, String region, String accessKey,
String secretKey, String bucket, boolean pathStyleAccess) {}
}
@Service
@RequiredArgsConstructor
public class S3StorageService {
private final S3Client s3;
private final S3Config.S3Props props;
public String upload(String originalName, String contentType, byte[] bytes) {
String key = UUID.randomUUID() + "_" + originalName;
s3.putObject(PutObjectRequest.builder()
.bucket(props.bucket())
.key(key)
.contentType(contentType)
.build(),
RequestBody.fromBytes(bytes));
return key;
}
public byte[] download(String key) {
GetObjectResponse[] meta = new GetObjectResponse[1];
try (var resp = s3.getObject(GetObjectRequest.builder()
.bucket(props.bucket()).key(key).build())) {
meta[0] = resp.response();
return resp.readAllBytes();
} catch (Exception e) {
throw NoSuchKeyException.builder().message("Object not found: " + key).build();
}
}
public void createBucketIfMissing() {
var bucket = props.bucket();
var exists = s3.listBuckets().buckets().stream().anyMatch(b -> b.name().equals(bucket));
if (!exists) s3.createBucket(CreateBucketRequest.builder().bucket(bucket).build());
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15🔥8👍3⚡1
В Java часто нужно работать с датами и временем. Вместо устаревших Date и Calendar лучше использовать современное API java.time, появившееся в Java 8. Оно более удобное, безопасное и читаемое.
Например, если нужно добавить дни к текущей дате:
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusDays(7);
System.out.println("Сегодня: " + today);
System.out.println("Через неделю: " + nextWeek);
}
}
✅ Код становится проще и понятнее.
📌 Совет: всегда отдавайте предпочтение java.time вместо старых классов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤21💯7🔥3
В свежем релизе — важные улучшения, о которых стоит знать каждому Java-разработчику:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4🎉4❤1
Интеграция системы оповещений через почтовую рассылку
Нужна быстрая интеграция с системой оповещений для отправки уведомлений по электронной почте? Используйте AI, чтобы автоматизировать подключение почтового сервиса и эффективно управлять рассылками.
📝 Промпт:
💡 Расширения:
— Добавьте
— Добавьте
✅ Java библиотека #java
Нужна быстрая интеграция с системой оповещений для отправки уведомлений по электронной почте? Используйте AI, чтобы автоматизировать подключение почтового сервиса и эффективно управлять рассылками.
📝 Промпт:
Generate an email notification system integration for a Spring Boot 3 application.
— Set up SMTP configuration in application.properties with email provider details (e.g., Gmail, SendGrid).
— Implement EmailService to send notifications using JavaMailSender and MimeMessage.
— Create a method to send transactional emails (e.g., order confirmation, password reset).
— Integrate email templates using Thymeleaf or FreeMarker for dynamic content generation.
— Set up email queues using Spring’s @Async to process notifications asynchronously.
— Handle email failures gracefully with retry mechanisms and user feedback.
— Добавьте
Send welcome emails with a personalized subject and content for new user registrations для приветственных писем.— Добавьте
Implement email subscription management for users to opt-in/opt-out from specific notifications для управления подписками пользователей.Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4❤2😁1
При работе с коллекциями часто нужно проверить элемент на наличие в списке.
Если использовать
List.contains(), то поиск будет O(n) — медленно на больших данных. Лучше сразу применять
Set (например, HashSet) для поиска за O(1). Пример
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "orange", "grape");
// Медленно — O(n)
boolean slowCheck = list.contains("orange");
// Быстро — O(1)
Set<String> set = new HashSet<>(list);
boolean fastCheck = set.contains("orange");
System.out.println("List check: " + slowCheck);
System.out.println("Set check: " + fastCheck);
}
}
📌 Итог:
- Для поиска в коллекции всегда используйте Set, если не нужен порядок.
- HashSet → быстрый доступ за O(1).
- TreeSet → доступ за O(log n), но с сортировкой элементов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18😁6🔥4❤3
🚀 Индексы в PostgreSQL
Когда сервис начинает работать с десятками миллионов строк, простое findById уже не выглядит «мгновенным». Тут в игру вступают индексы.
🔍 Что такое индекс
Индекс в PostgreSQL — это отдельная структура данных, которая позволяет находить строки намного быстрее, чем полный перебор таблицы.
⚡️ Типы индексов и когда применять
— B-Tree (по умолчанию)
Отлично работает для операций =, <, >, ORDER BY.
Частый кейс: поиск по id, created_at, username.
— GIN (Generalized Inverted Index)
Для jsonb, массивов и полнотекстового поиска.
Например, поиск по тегам или WHERE metadata @> '{"os":"android"}'.
— GiST (Generalized Search Tree)
Для геоданных, поиска по диапазонам (tsrange, daterange).
— Hash Index
Для очень быстрого поиска по точному совпадению, но реже нужен (B-Tree почти всегда быстрее).
⚠️ На что обратить внимание
— Индекс ускоряет SELECT, но замедляет INSERT/UPDATE/DELETE (нужно обновлять и таблицу, и индекс).
— Слишком много индексов = «смерть от оптимизации». Держите баланс.
— Никогда не делайте индексы «на всё подряд». Индекс должен соответствовать реальным запросам.
❓ А вы чаще оптимизируете запросы через индексы или через переписывание логики?
✅ Java библиотека #java
Когда сервис начинает работать с десятками миллионов строк, простое findById уже не выглядит «мгновенным». Тут в игру вступают индексы.
🔍 Что такое индекс
Индекс в PostgreSQL — это отдельная структура данных, которая позволяет находить строки намного быстрее, чем полный перебор таблицы.
⚡️ Типы индексов и когда применять
— B-Tree (по умолчанию)
Отлично работает для операций =, <, >, ORDER BY.
Частый кейс: поиск по id, created_at, username.
CREATE INDEX idx_user_email ON users(email);
— GIN (Generalized Inverted Index)
Для jsonb, массивов и полнотекстового поиска.
Например, поиск по тегам или WHERE metadata @> '{"os":"android"}'.
CREATE INDEX idx_logs_metadata ON logs USING gin (metadata jsonb_path_ops);
— GiST (Generalized Search Tree)
Для геоданных, поиска по диапазонам (tsrange, daterange).
CREATE INDEX idx_places_geom ON places USING gist (geom);
— Hash Index
Для очень быстрого поиска по точному совпадению, но реже нужен (B-Tree почти всегда быстрее).
CREATE INDEX idx_sessions_sid ON sessions USING hash (session_id);
⚠️ На что обратить внимание
— Индекс ускоряет SELECT, но замедляет INSERT/UPDATE/DELETE (нужно обновлять и таблицу, и индекс).
— Слишком много индексов = «смерть от оптимизации». Держите баланс.
— Никогда не делайте индексы «на всё подряд». Индекс должен соответствовать реальным запросам.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18👍8🔥5🍾2
Media is too big
VIEW IN TELEGRAM
В Java нет двумерных массивов?
Есть ли разница между двумерным массивом и массивом массивов?
🌐 🗣 СМОТРЕТЬ VKVIDEO
📺 🗣 СМОТРЕТЬ RUTUBE
✅ Java библиотека #java
Есть ли разница между двумерным массивом и массивом массивов?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤4🔥4
Используй ApplicationPidFileWriter, чтобы при старте приложения записывать его PID в файл.
Это удобно для ops-скриптов, health-checks в контейнерах и мониторинга процессов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤7🔥7🎅1
⚙️ Async Profiler
Async Profiler — это современный профайлер для JVM, который показывает, где именно «горит» CPU и где происходят утечки памяти. В отличие от классических профайлеров, он использует низкоуровневые возможности ОС (perf, JVMTI) и практически не влияет на производительность.
📌 Что умеет:
— Делает CPU и allocation flame graph'ы
— Минимальный overhead
— Поддерживает анализ Java и нативного кода вместе
— Умеет снимать снапшоты и строить красивые SVG-отчёты
🧠 Особенно полезен, если у вас микросервисы или приложения с нагрузкой 24/7 — можно ловить узкие места без остановки сервиса.
🔗 Async Profiler на GitHub
✅ Java библиотека #java
Async Profiler — это современный профайлер для JVM, который показывает, где именно «горит» CPU и где происходят утечки памяти. В отличие от классических профайлеров, он использует низкоуровневые возможности ОС (perf, JVMTI) и практически не влияет на производительность.
📌 Что умеет:
— Делает CPU и allocation flame graph'ы
— Минимальный overhead
— Поддерживает анализ Java и нативного кода вместе
— Умеет снимать снапшоты и строить красивые SVG-отчёты
🧠 Особенно полезен, если у вас микросервисы или приложения с нагрузкой 24/7 — можно ловить узкие места без остановки сервиса.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4
Задачи с собеседований: Поиск первого уникального символа в строке (jun+)
— Как найти первый уникальный символ в строке?
🔘 Ключевые моменты:
- Используйте доп. структуру данных для хранения количества вхождений каждого символа
- Предложите в комментарии другие варианты решения.
Реализация через Map на картинке👆
✅ Java библиотека #java
— Как найти первый уникальный символ в строке?
- Используйте доп. структуру данных для хранения количества вхождений каждого символа
- Предложите в комментарии другие варианты решения.
Реализация через Map на картинке
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥5❤4
@javalib #java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍5❤3
С помощью
sealed можно чётко ограничить набор допустимых типов, а record делает код компактным и иммутабельным. Пример 👇
sealed interface Payment permits CardPayment, CashPayment, CryptoPayment {}
record CardPayment(String cardNumber, double amount) implements Payment {}
record CashPayment(double amount) implements Payment {}
record CryptoPayment(String wallet, double amount) implements Payment {}
Теперь можно использовать switch с исчерпывающей проверкой:
static String process(Payment p) {
return switch (p) {
case CardPayment c -> "Оплата картой: " + c.amount();
case CashPayment c -> "Оплата наличными: " + c.amount();
case CryptoPayment c -> "Крипта из кошелька: " + c.wallet();
};
}
✅ Преимущества:
- меньше if/instanceof;
- компилятор гарантирует, что рассмотрены все варианты;
- код становится выразительным и легко расширяемым.
🔥 Такой подход отлично подходит для бизнес-логики: платежи, статусы заказов, события системы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤14🔥4☃2
В JUnit 5 появилась интересная аннотация @ClassTemplate. Она полезна, когда один и тот же набор тестов нужно выполнить в разных контекстах. Например: проверить класс с разными локалями, флагами или окружениями.
Обычно в таких случаях мы либо дублируем тестовые классы, либо городим параметризованные тесты. Но @ClassTemplate позволяет описать тест один раз, а запускать его несколько раз — каждый раз в новом окружении.
— Помечаем тестовый класс @ClassTemplate.
— Регистрируем ClassTemplateInvocationContextProvider, который возвращает список «контекстов» (например, en/it).
— JUnit прогоняет один и тот же класс для каждого контекста.
— Есть Greeter, который должен возвращать приветствие по-английски и по-русски.
— Мы пишем один тест → JUnit запускает его дважды: для en и для ru.
— В отчёте два результата, код теста при этом один.
— Работает начиная с JUnit 5.13.
— Для читаемых логов удобнее запускать через JUnit Console Launcher.
— Отличается от @TestTemplate тем, что переиспользует весь класс, а не отдельные методы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤8🔥3
— Statement используется для
— PreparedStatement
Поэтому в реальных проектах почти всегда используют
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥15👍6❤5🎄1