Java Portal | Программирование
12K subscribers
1.43K photos
110 videos
43 files
1.45K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
image_2026-06-14_11-48-52.png
1.4 MB
Сегодняшняя концепция: Consistent Hashing (согласованное хеширование)

Обычное хеширование:
Добавили 1 сервер

Почти все ключи перераспределяются

Согласованное хеширование:
Добавили 1 сервер

Перемещаются только ключи, находящиеся рядом с ним

Эта простая идея лежит в основе таких систем, как:
• Redis Cluster
• Apache Cassandra
• Amazon DynamoDB
• Memcached

Одна из самых важных концепций, на которых строятся масштабируемые распределённые системы.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
💡 Java: Ловите ошибки ещё на этапе компиляции, помечая переопределённые методы аннотацией @Override. #Java #Annotations

//  Опечатка в имени метода — код компилируется,
// но вы НЕ переопределили toString()

public class User {
private final String name;

public User(String name) {
this.name = name;
}

public String toStrng() { // хотели toString()
return name;
}
}

// Баг остаётся незамеченным — println(user)
// не будет использовать ваш метод



// @Override превращает опечатку в ошибку компиляции

public class User {
private final String name;

public User(String name) {
this.name = name;
}

@Override
public String toString() {
return "User(" + name + ")";
}
}

// @Override
// public String toStrng() { ... }
//
// Ошибка компиляции:
// method does not override or implement a method from a supertype


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Circuit Breaker — это паттерн отказоустойчивости, который предотвращает постоянные попытки выполнить операцию, если она с высокой вероятностью завершится ошибкой.

В этом подробном руководстве Джессика показывает, как реализовать собственный Circuit Breaker в Spring Boot.

Из статьи ты узнаешь:

- зачем нужны Circuit Breaker;
- как обеспечиваются гарантии конкурентного доступа и переходов между состояниями;
- как отслеживать и учитывать ошибки;
- как устроена логика срабатывания Circuit Breaker;
- и многое другое.

Источник: https://freecodecamp.org/news/how-to-build-your-own-circuit-breaker-in-spring-boot-and-really-understand-resilience4j/

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
До сих пор вручную собираешь шаблон проекта каждый раз, когда начинаешь что-то новое?

Я недавно наткнулся на Better-Fullstack — генератор, который помогает быстро поднять основу приложения и не тратить время на однотипную настройку.

Что умеет:

1️⃣ Поддерживает четыре основных экосистемы: TypeScript, Rust, Python и Go.

2️⃣ Более 270 комбинаций технологий, которые можно свободно комбинировать.

3️⃣ Позволяет выбрать фронтенд, бэкенд, базу данных, аутентификацию, платежи, AI-интеграции и DevOps-компоненты в одном месте.

4️⃣ Автоматически генерирует готовый каркас проекта, который можно использовать сразу после создания.

Главная польза не столько в экономии времени, сколько в том, что тебе не приходится снова и снова заниматься настройкой окружения. Вместо этого можно сосредоточиться на бизнес-логике и функциональности продукта.

Подойдёт для соло-разработчиков, команд с типовыми стек-требованиями и проектов с жёсткими сроками.

GitHub: https://github.com/Marve10s/Better-Fullstack

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
💊41
💡 Совет по Java: всегда закрывайте ресурсы вроде BufferedReader, InputStream и OutputStream через try-with-resources, чтобы избежать утечек памяти и ресурсов. #Java #BestPractices

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
В чем разница между балансировщиками нагрузки, обратными прокси и API-шлюзами?

🍩Балансировщик нагрузки распределяет клиентские запросы между серверами, выбирая их по алгоритму, чтобы равномерно распределять нагрузку, избегать перегрузок и обеспечивать стабильную работу системы.

Он получает запрос, перенаправляет его на сервер, принимает ответ и отправляет его обратно клиенту.

Это увеличивает пропускную способность, снижает задержки и оптимизирует использование ресурсов.

🍩Обратные прокси работают как посредники между клиентами и серверами, обрабатывая запросы и передавая данные, скрывая серверы и повышая их безопасность.

Они обеспечивают контроль за сетевым трафиком, снижая риски атак и угроз.

Дополнительно, они могут кэшировать контент для уменьшения нагрузки на сервер, сжимать данные для ускорения передачи и управлять SSL/TLS-шифрованием, разгружая веб-серверы.

🍩API-шлюзы работают как единая точка входа для всех API-запросов, направляя их к нужным микросервисам и собирая результаты.

Они упрощают взаимодействие клиентов с разными сервисами, добавляют защиту, применяют правила, переводят между веб-протоколами и агрегируют данные.

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍3
gRPC в Java раньше означал proto-файлы, codegen, build-плагины, настройку сервера и client channels. Куча возни ещё до первого hello world.

Spring Boot 4.1 закрывает большую часть этой рутины.
Если ты умеешь писать REST-приложение, базовые шаги уже знакомы:
→ описать контракт
→ добавить bean с @GrpcService
→ заинжектить stub на клиенте

Полный сервер, клиент и in-memory тест с нуля 👇

https://github.com/danvega/hello-grpc

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
7
Совет по Java: не ловите Exception на всякий случай

Плохая практика:
catch (Exception e)


Такой код скрывает реальные проблемы. Для приложения одинаково начинают выглядеть ошибки бизнес-логики, NullPointerException, проблемы с памятью и другие сбои.
Ловите только те исключения, которые действительно можете обработать:

catch (IOException e) { ... }
catch (JsonProcessingException e) { ... }
catch (DuplicateKeyException e) { ... }


Тогда становится понятно:
что именно пошло не так;
какие ошибки ожидаемы;
какие нужно логировать;
какие должны прерывать выполнение.

И ещё одно правило:
catch (Throwable t)


Почти никогда не используйте. Так можно перехватить OutOfMemoryError, StackOverflowError и другие критические ошибки, после которых приложение зачастую уже не способно нормально продолжать работу.

Лови только то, что умеешь исправить. Остальное пусть поднимается выше по стеку вызовов.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Совет по Spring: ставь circuit breaker на удалённые вызовы

Если сервис ходит в другой сервис через Feign, этот вызов может зависнуть, упасть или начать возвращать ошибки.

@CircuitBreaker(name = "CircuitBreakerService")
String getInstance();


Circuit breaker временно «размыкает цепь», когда ошибок слишком много. Вместо бесконечных ретраев и просадки всего приложения ты отдаёшь fallback:
public String getAuthorServiceInstanceFallback(Exception ex) {
return "Fallback content";
}


В application.yml можно задать порог ошибок и время ожидания:
failure-rate-threshold: 50
wait-duration-in-open-state: 5s


Идея простая: внешний сервис упал — твоё приложение деградирует контролируемо, а не валится следом.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
6
This media is not supported in your browser
VIEW IN TELEGRAM
DBeaver уже 15 лет остаётся де-факто стандартом среди SQL-клиентов.

Инструмент мощный, но это ещё и тяжёлый Java-монолит, который может запускаться по 20 секунд.

Кто-то решил переписать его с нуля на Rust и добавить возможности, которых в DBeaver никогда не было.

Проект называется Tabularis. 2.5 тыс. звёзд. Лицензия Apache 2.0. Последняя активность — 17 часов назад.

Самое интересное:

Tabularis создал один разработчик — Debba — как эксперимент по AI-assisted разработке.

Цель была простой: проверить, насколько далеко AI-агенты способны зайти при создании реального продукта.

В итоге получилось 55 релизов, 1192 коммита и SQL-клиент, который уже конкурирует с продуктами компаний, где над подобными инструментами работают десятки инженеров.

Что есть в Tabularis, а в DBeaver нет:

Встроенный MCP-сервер — Claude, Cursor и Windsurf могут читать схему БД и выполнять запросы прямо из чата
SQL Notebooks с графиками внутри ячеек и общими переменными между ними
Визуальный EXPLAIN с AI-анализом плана выполнения
Визуальный конструктор запросов с drag-and-drop JOIN'ами
Автоматическая генерация ER-диаграмм
Поддержка PostgreSQL, MySQL/MariaDB, SQLite и ClickHouse через плагины
Редактор на базе Monaco с интеллектуальным автодополнением
Без телеметрии, аккаунтов и подписок

Чего пока нет в Tabularis, но есть в DBeaver:

SQL Server
Oracle

Если работаешь с ними, DBeaver пока остаётся более очевидным выбором.

Во всех остальных случаях Tabularis запускается примерно за 2 секунды, занимает меньше ресурсов и позволяет AI-агентам работать с базой напрямую.

https://github.com/TabularisDB/tabularis

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
😁7🔥1
Java: используйте полиморфизм вместо цепочек instanceof.
Проверки типов часто приводят к разрастающимся if/else, нарушают принцип Open/Closed и заставляют изменять существующий код при добавлении новых сущностей.

До:

public String describe(Animal animal) {
if (animal instanceof Dog) {
return "Woof";
} else if (animal instanceof Cat) {
return "Meow";
} else if (animal instanceof Cow) {
return "Moo";
}

throw new IllegalArgumentException("Unknown animal");
}


Каждый новый тип требует правки метода.

После:

public interface Animal {
String sound();
}

public final class Dog implements Animal {
public String sound() {
return "Woof";
}
}

public final class Cat implements Animal {
public String sound() {
return "Meow";
}
}

public final class Cow implements Animal {
public String sound() {
return "Moo";
}
}

public String describe(Animal animal) {
return animal.sound();
}


Преимущества:
→ нет цепочек instanceof и приведения типов
→ меньше условной логики
→ проще расширять систему новыми типами
→ соблюдается принцип Open/Closed
→ поведение находится внутри самого объекта, а не размазано по коду

Добавить новое животное теперь можно без изменения существующей логики:
public final class Sheep implements Animal {
public String sound() {
return "Baa";
}
}


Клиентский код останется прежним:
describe(new Sheep());


Пусть объекты сами решают, как себя вести. Именно для этого и существует полиморфизм. #Java #OOP

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Java: отдавай предпочтение неизменяемым объектам (immutable), чтобы упростить потокобезопасность.

Изменяемое состояние, разделяемое между потоками
public class Balance {
private BigDecimal amount = BigDecimal.ZERO;

public void deposit(BigDecimal v) {
amount = amount.add(v);
}

public BigDecimal get() {
return amount;
}
}


Если два потока одновременно вызовут deposit(), возможны потерянные обновления (lost updates), гонки данных (race conditions) и чтение неконсистентного состояния.

Неизменяемый объект — обновление через создание нового экземпляра
public record Balance(BigDecimal amount) {

public Balance deposit(BigDecimal v) {
return new Balance(amount.add(v));
}
}


Вместо изменения существующего объекта создаётся новый.
Потоки могут безопасно работать со своими снимками состояния (snapshot), а каждый вызов deposit() возвращает новый объект.

Неизменяемые коллекции
List<String> roles = List.of("READ", "WRITE");

Map<String, Integer> limits =
Map.of("free", 10, "pro", 100);


Такие коллекции можно безопасно передавать между потоками без дополнительной синхронизации.

Защитная копия (defensive copy)
Если исходная коллекция всё ещё изменяемая:
List<String> snapshot = List.copyOf(mutableRoles);


Создай неизменяемую копию перед публикацией другим частям приложения.

На практике immutable-подход позволяет существенно сократить количество synchronized, блокировок и ошибок многопоточности. Поэтому современные API Java (record, List.of(), Map.of(), Optional, LocalDateTime) активно используют неизменяемые объекты по умолчанию.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
Spring Boot 4.1 добавляет всего одно свойство:

spring.datasource.connection-fetch=lazy


По умолчанию методы с @Transactional получают соединение с БД сразу при открытии транзакции, даже если запрос в итоге так и не выполняется.

Попадание в кэш, ранний return, долгий вызов внешнего API перед сохранением данных — во всех этих случаях соединение просто простаивает без дела.

Режим lazy откладывает получение соединения до момента, когда действительно выполняется SQL-запрос.

Dan Vega собрал демо, которое показывает это на метриках HikariCP.
Количество захватов соединений (acquire count) падает примерно со 100 до почти 0.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Java-паттерны: Builder

Паттерн Builder помогает создавать сложные объекты более гибким и понятным способом.
На примере выше хорошо видно проблему длинных конструкторов:

new Order("Mario", "Laptop", 2, true, "Leave at door");


Через несколько месяцев уже сложно понять, что означает true, а при добавлении новых параметров конструктор быстро становится неудобным.
Builder решает эту проблему:

Order order = Order.builder()
.customer("Mario")
.product("Laptop")
.quantity(2)
.express(true)
.note("Leave at door")
.build();


Преимущества:
Именованные параметры делают код читаемее
Можно задавать значения в любом порядке
Удобно работать с необязательными полями
Значения по умолчанию задаются в Builder
Валидацию можно выполнять один раз в build()
Нет путаницы с конструкторами из 5–10 аргументов

Builder особенно полезен для DTO, конфигураций, запросов к API и объектов с большим количеством параметров.
Поэтому его часто можно встретить в Java-проектах и библиотеках вроде Lombok, где достаточно добавить аннотацию @Builder.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥65
SQLBolt - изучайте SQL с помощью простых интерактивных упражнений.

https://sqlbolt.com/

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Как создаются продукты, которыми пользуются миллионы?

Покажут на «Сезоне кода» в Казани — летнем ИТ-фесте, где объединяют разработку, аналитику и продукт в одном пространстве.

В программе:

— прикладные доклады команд Т-Банка и других компаний;
— демо-зоны с продуктами и платформами: можно посмотреть, как все работает изнутри и пообщаться с разработчиками;
— новая секция «Продуктовая кухня»: поговорим о развитии продуктов через инсайты, data-driven-подход и продуманный дизайн.

И конечно, живое общение, интерактивы и афтепати с диджеем в конце дня.

Количество мест ограничено — успейте зарегистрироваться
🔥2
💡 Java tip: Use the Stream API для работы с коллекциями в декларативном стиле.

List<String> names = users.stream()
.filter(User::isActive)
.map(User::getName)
.sorted()
.toList();


Пиши, что тебе нужно получить из данных. Не расписывай цикл вручную. Stream сделает это короче и чище.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Spring Boot 4.1 приносит с собой много новых фич, включая автоконфигурацию job repository для Spring Batch на базе MongoDB.

\ Читай об этом здесь

👉 Java Portal !
Please open Telegram to view this post
VIEW IN TELEGRAM
Docker-ошибка, которую я вижу почти в каждом junior Dockerfile:
COPY . .
RUN npm install


должно быть:
COPY package*.json ./
RUN npm install
COPY . .


почему это важно?

docker кэширует каждую инструкцию как отдельный слой
исходный код меняется с каждым коммитом
поэтому COPY . . ломает кэш, и всё после него (включая npm install) пересобирается с нуля при каждой сборке
если поменять порядок, слой с установкой зависимостей остаётся в кэше даже при изменении кода, потому что он зависит только от package.json
одна перестановка строк. экономит 40+ секунд на каждой пересборке. кэшируй зависимости, а не код.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72
Java Tip: Не перегружайте методы параметрами

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

Плохо:
createUser(firstName, lastName, street, city, zip, country);


Лучше сгруппировать связанные данные в отдельный объект:
createUser(firstName, lastName,
new Address(street, city, zip, country));


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

Если несколько параметров всегда используются вместе — вероятно, им нужен собственный класс или record.
#Java #Refactoring #CleanCode

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