Component → Controller → Service → Repository → База данных → Ответ
Так проходит поток данных в приложении Spring Boot — чисто и по слоям
👉 Java Portal
Так проходит поток данных в приложении Spring Boot — чисто и по слоям
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2🔥1
Многопоточность в Java
Есть основной метод, а вместе с ним — несколько потоков
Каждый поток выполняет свою задачу одновременно с другими
Это даёт прирост в скорости и производительности.
Полезно, когда нужно делать несколько вещей сразу — например, загружать файлы или обслуживать пользователей
👉 Java Portal
Есть основной метод, а вместе с ним — несколько потоков
Каждый поток выполняет свою задачу одновременно с другими
Это даёт прирост в скорости и производительности.
Полезно, когда нужно делать несколько вещей сразу — например, загружать файлы или обслуживать пользователей
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🤔1
Аннотации
Пример:
Пользователь может иметь много заказов →
Каждый заказ принадлежит одному пользователю →
👉 Java Portal
@OneToMany
и @ManyToOne
помогают определить связи между сущностями в базе данныхПример:
Пользователь может иметь много заказов →
@OneToMany(mappedBy = "user")
private List<Order> orders;
Каждый заказ принадлежит одному пользователю →
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2🔥2
Как синхронизировать двунаправленные ассоциации сущностей с помощью JPA и Hibernate
🔜 Читать: клик
👉 Java Portal | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
В Java тело лямбды прозрачно для
А если заменить лямбду на анонимный класс, результат будет вроде
То есть у лямбды нет собственного
Если хочешь разобраться глубже, смотри официальный гайд
👉 Java Portal
this
. Например, следующий код выведет Hello, World!
:private Runnable runnable = () -> {
System.out.println(this);
};
@Override
public String toString() {
return "Hello, World!";
}
void main() {
runnable.run();
}
А если заменить лямбду на анонимный класс, результат будет вроде
InnerClassThis$1@568bf312
:private Runnable runnable = new Runnable() {
@Override public void run() {
System.out.println(this);
}
};
@Override
public String toString() {
return "Hello, World!";
}
void main(String[] args) {
runnable.run();
}
То есть у лямбды нет собственного
this
— она использует this из внешнего контекста. Это чётко описано в спецификации Java:Значение this в теле лямбды — то же самое, что и this во внешнем контексте.
Если хочешь разобраться глубже, смотри официальный гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥1
В Java можно столкнуться с ситуацией, когда поле final кажется имеющим два разных значения. Рассмотрим такой пример:
Результат выполнения будет таким:
Это пример утечки
JEP 401 называет это larval object leakage — ситуация, когда объект, ещё не до конца инициализированный, "просачивается" из конструктора и используется раньше времени.
В JDK 24 в рамках JEP о гибких телах конструкторов (Flexible Constructor Bodies) эта проблема решается следующим образом:
Иначе говоря, в начальной части конструктора теперь нельзя "утечь" наружу с
👉 Java Portal
void main() {
var after = new Final(this::before);
IO.println("After value=" + after.value);
}
private void before(Final before){
IO.println("Before value=" + before.value);
}
class Final {
final int value;
Final(Consumer<? super Final> listener) {
listener.accept(this);
value = 123;
}
}
Результат выполнения будет таким:
Before value=0
After value=123
Это пример утечки
this
. JEP 401 называет это larval object leakage — ситуация, когда объект, ещё не до конца инициализированный, "просачивается" из конструктора и используется раньше времени.
В JDK 24 в рамках JEP о гибких телах конструкторов (Flexible Constructor Bodies) эта проблема решается следующим образом:
Код в начале конструктора не должен использовать this, кроме как для инициализации полей, у которых нет своих инициализаторов.
Иначе говоря, в начальной части конструктора теперь нельзя "утечь" наружу с
this
, пока объект не готовPlease open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥1
Хотите получить строковое представление объекта так, как если бы методы
При выполнении на моей машине выводится:
Метод был введён в JDK 19. Документация Javadoc не говорит много о возможных вариантах использования. В баге JDK-8280184 Стюарт Маркс пишет:
👉 Java Portal
toString
и hashCode
не были переопределены? Тогда метод Objects::toIdentityString
— это то, что вам нужно:void main() {
IO.println(this);
IO.println(Objects.toIdentityString(this));
}
@Override
public String toString() {
return "Hello, World!";
}
При выполнении на моей машине выводится:
Hello, World!
HelloWorld@275710fc
Метод был введён в JDK 19. Документация Javadoc не говорит много о возможных вариантах использования. В баге JDK-8280184 Стюарт Маркс пишет:
Это может быть полезно в логировании, например, когда нужно отслеживать операции, выполненные над каким-то конкретным объектом, например, перед сбоем. Идентичный хэшкод — полезный способ сделать это
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
Хочешь, чтобы Swagger UI был доступен без авторизации в Spring Boot?
Просто добавь его в белый список:
Так разработчики смогут спокойно тестировать и изучать API без входа в систему
👉 Java Portal
Просто добавь его в белый список:
.antMatchers("/swagger-ui/", "/v3/api-docs/").permitAll()
Так разработчики смогут спокойно тестировать и изучать API без входа в систему
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥1
Шпаргалка по Map-реализациям
Если путаешься в
> HashMap — быстрая, но не потокобезопасная. Подходит для общего использования
> LinkedHashMap — сохраняет порядок вставки
> TreeMap — сортирует по ключам.
> Hashtable — потокобезопасна, но старая и медленная
> ConcurrentHashMap — оптимальна для многопоточности
> EnumMap — супербыстрая для enum-ключей
> IdentityHashMap — использует
> WeakHashMap — ключи могут быть удалены GC. Полезно для кэшей
Не забывай про null-ключи, производительность, порядок —> всё это влияет на выбор структуры данных💖
👉 Java Portal
Если путаешься в
HashMap, TreeMap, ConcurrentHashMap
— лови таблицу сравнения> HashMap — быстрая, но не потокобезопасная. Подходит для общего использования
> LinkedHashMap — сохраняет порядок вставки
> TreeMap — сортирует по ключам.
> Hashtable — потокобезопасна, но старая и медленная
> ConcurrentHashMap — оптимальна для многопоточности
> EnumMap — супербыстрая для enum-ключей
> IdentityHashMap — использует
==
вместо .equals()
> WeakHashMap — ключи могут быть удалены GC. Полезно для кэшей
Не забывай про null-ключи, производительность, порядок —> всё это влияет на выбор структуры данных
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2🔥1
Strategy Pattern без занудства
Ситуация: вы пишете платёжную систему
У вас есть
Вы пишете:
Потом добавляют PayPal, UPI, крипту, Apple Pay, кошельки, NetBanking и тд..😢
Теперь ваш метод выглядит вот так:
Вы тонете в аду
> Вы трогаете старый код
> Рискуете сломать существующую логику
> Нельзя нормально протестировать стратегии
> Нарушается принцип OCP (Open/Closed)
В чём настоящая проблема?
1. Ваш код слишком жёстко связан с конкретными реализациями оплат
2. Добавление новых стратегий требует изменения существующего кода
3. Тестировать/переиспользовать отдельные стратегии — сложно
4.
Как Strategy Pattern вас спасает
1. Создаёшь интерфейс PaymentStrategy
2. Для каждой оплаты — свой класс:
3.
☑ Добавить новый способ? Просто пишешь новый класс
☑ Никаких
☑ Стратегии изолированы и легко тестируются
👉 Java Portal
Ситуация: вы пишете платёжную систему
У вас есть
PaymentService
, поддерживающий оплату кредитной картой.Вы пишете:
public void pay(String method) {
if (method.equals("creditcard")) {
// логика оплаты кредиткой
}
}
Потом добавляют PayPal, UPI, крипту, Apple Pay, кошельки, NetBanking и тд..
Теперь ваш метод выглядит вот так:
if (method.equals("creditcard")) {
// логика кредитки
} else if (method.equals("paypal")) {
// логика PayPal
} else if ...
Вы тонете в аду
if-else
. Каждый раз при добавлении нового способа оплаты:> Вы трогаете старый код
> Рискуете сломать существующую логику
> Нельзя нормально протестировать стратегии
> Нарушается принцип OCP (Open/Closed)
В чём настоящая проблема?
1. Ваш код слишком жёстко связан с конкретными реализациями оплат
2. Добавление новых стратегий требует изменения существующего кода
3. Тестировать/переиспользовать отдельные стратегии — сложно
4.
PaymentService
теперь отвечает за слишком многоеКак Strategy Pattern вас спасает
1. Создаёшь интерфейс PaymentStrategy
2. Для каждой оплаты — свой класс:
CreditCardPayment, PayPalPayment, UPIPayment
3.
PaymentService
просто вызывает .pay()
на нужной стратегииif-else
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Плачу " + amount + " с помощью кредитки");
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Плачу " + amount + " через PayPal");
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤3
This media is not supported in your browser
VIEW IN TELEGRAM
Имбовая библиотека цветов для Kotlin Multiplatform
Если ты пилишь на Kotlin и хочешь красивые цвета под любую платформу — зацени compose-pipette
Поддерживает:
> JVM
> Android (от API 21)
> Kotlin/JS
> Kotlin/WASM
> macOS (пока не тестили)
> iOS (тоже не тестили)
Поддержи пост лайком❤️
👉 Java Portal
Если ты пилишь на Kotlin и хочешь красивые цвета под любую платформу — зацени compose-pipette
Поддерживает:
> JVM
> Android (от API 21)
> Kotlin/JS
> Kotlin/WASM
> macOS (пока не тестили)
> iOS (тоже не тестили)
Поддержи пост лайком
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🌭3😁1🤣1
В Java лямбда-выражение создаёт экземпляр функционального интерфейса. Во время выполнения этот экземпляр создаётся с помощью класса
Следующий код на Java создаёт объект
Во время выполнения объект создаётся с помощью кода, аналогичного следующему:
При выполнении этот код выведет в консоль❤️
👉 Java Portal
LambdaMetaFactory
Следующий код на Java создаёт объект
Function<String, String>
Function<String, String> f = s -> s.toUpperCase();
Во время выполнения объект создаётся с помощью кода, аналогичного следующему:
@SuppressWarnings("unchecked")
void main() throws Throwable {
MethodHandles.Lookup lookup;
lookup = MethodHandles.lookup();
CallSite callSite;
callSite = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(Function.class),
MethodType.methodType(Object.class, Object.class),
lookup.findStatic(
getClass(),
"lambda",
MethodType.methodType(String.class, String.class)
),
MethodType.methodType(String.class, String.class)
);
MethodHandle target;
target = callSite.getTarget();
Function<String, String> f;
f = (Function<String, String>) target.invokeExact();
String msg;
msg = f.apply("Hello, World!");
IO.println(msg);
}
private static String lambda(String s) {
return s.toUpperCase();
}
При выполнении этот код выведет в консоль
HELLO, WORLD!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4
Курс по конкурентному программированию от Ильи Сергеева
Если хочешь разобраться в параллельности, потоках, акторной модели и распределёнке — лови топовый курс от препода Yale-NUS
— Scala для конкурентного кода
— Мьютексы, блокировки, атомики
— Futures и async
— Акторы и обмен сообщениями
— Распределённый консенсус (в т.ч. BFT)
Можешь поблагодарить лукасом😍
👉 Java Portal
Если хочешь разобраться в параллельности, потоках, акторной модели и распределёнке — лови топовый курс от препода Yale-NUS
— Scala для конкурентного кода
— Мьютексы, блокировки, атомики
— Futures и async
— Акторы и обмен сообщениями
— Распределённый консенсус (в т.ч. BFT)
Можешь поблагодарить лукасом
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍6
Начиная с JDK 12, появилась новая фича —
Пример:
Вывод:
Также доступен стиль LONG:
Результат:
Идеально для UI, отчетов и всего, где важна краткость💖
👉 Java Portal
java.text.CompactNumberFormat
. Она позволяет компактно отображать большие числаПример:
Locale.setDefault(Locale.US);
NumberFormat compact = NumberFormat.getCompactNumberInstance();
System.out.println(compact.format(1));
System.out.println(compact.format(999));
System.out.println(compact.format(2_000));
System.out.println(compact.format(55_555));
System.out.println(compact.format(3_777_999));
System.out.println(compact.format(Integer.MAX_VALUE));
Вывод:
1
999
2K
56K
4M
2B
Также доступен стиль LONG:
NumberFormat compact;
compact = NumberFormat.getCompactNumberInstance(Locale.US, Style.LONG);
Результат:
1
999
2 thousand
56 thousand
4 million
2 billion
Идеально для UI, отчетов и всего, где важна краткость
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤3🤔1
Разработчики, вот вам шпаргалка по техникам синхронизации потоков в Java 🧑💻
synchronized блок/метод -> использует встроенную блокировку объекта для обеспечения взаимного исключения.
ReentrantLock -> явная блокировка с более гибкими возможностями по сравнению с synchronized.
volatile- > гарантирует видимость изменений переменной между потоками.
Атомарные переменные (AtomicInteger и др.) -> обеспечивают атомарные операции без блокировок.
Semaphore -> управляет доступом к ресурсу с ограниченным числом разрешений.
CountDownLatch -> позволяет одному или нескольким потокам ожидать завершения операций в других потоках.
CyclicBarrier -> позволяет группе потоков дождаться друг друга до продолжения выполнения.
ReadWriteLock -> разрешает множественные параллельные чтения, но только одну запись.
👉 Java Portal
synchronized блок/метод -> использует встроенную блокировку объекта для обеспечения взаимного исключения.
ReentrantLock -> явная блокировка с более гибкими возможностями по сравнению с synchronized.
volatile- > гарантирует видимость изменений переменной между потоками.
Атомарные переменные (AtomicInteger и др.) -> обеспечивают атомарные операции без блокировок.
Semaphore -> управляет доступом к ресурсу с ограниченным числом разрешений.
CountDownLatch -> позволяет одному или нескольким потокам ожидать завершения операций в других потоках.
CyclicBarrier -> позволяет группе потоков дождаться друг друга до продолжения выполнения.
ReadWriteLock -> разрешает множественные параллельные чтения, но только одну запись.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
Вот хороший пример очень плохого использования метки в Java:
Компилируется без ошибок. При выполнении выводит:
Это приводит к бесконечному циклу🙂
👉 Java Portal
void main() {
do onlyOnce: {
IO.println("Один раз?");
break onlyOnce;
} while (true);
}
Компилируется без ошибок. При выполнении выводит:
Один раз?
Один раз?
Один раз?
Один раз?
Один раз?
...
Это приводит к бесконечному циклу
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7😁4🤣1
Вопросы для собеседования по микросервисам с ответами
👉 Java Portal
1. Каковы ключевые характеристики микросервисов?
Ответ:
> Децентрализованное управление данными
> Сервисы развёртываются независимо друг от друга
> Проектирование на основе предметной области (DDD)
> Лёгкое взаимодействие (например, REST, gRPC)
> Изоляция сбоев
> Удобны для непрерывной доставки
2. Чем микросервисы отличаются от монолитной архитектуры?
Ответ:
> Монолит: единая кодовая база, жёстко связанные компоненты, сложно масштабировать.
> Микросервисы: множество сервисов, слабо связанные, развёртываются и масштабируются независимо.
3. Каковы основные преимущества использования микросервисов?
Ответ:
> Лучшая масштабируемость
> Более быстрое выведение продукта на рынок
> Независимые развёртывания
> Лучшая устойчивость к сбоям
> Возможность использовать разные языки и технологии
4. Какие есть сложности при работе с микросервисами?
Ответ:
> Сложность управления распределёнными системами
> Задержки в сети и накладные расходы на коммуникацию
> Согласованность данных
> Отладка и мониторинг
> Развёртывание и оркестрация
5. Как микросервисы обмениваются данными?
Ответ:
> Синхронно: через REST, gRPC
> Асинхронно: через очереди сообщений (RabbitMQ, Kafka)
6. Что такое service discovery в микросервисах?
Ответ:
> Это механизм, с помощью которого сервисы находят друг друга в сети.
> Применяются инструменты вроде Consul, Eureka, DNS Kubernetes.
7. Что такое API Gateway и зачем он нужен?
Ответ:
> API Gateway — это единая точка входа в систему. Он отвечает за маршрутизацию, безопасность, ограничение частоты запросов и агрегацию ответов от разных сервисов.
> Примеры: Kong, Zuul, NGINX, Spring Cloud Gateway.
8. Как в микросервисах управляют данными?
Ответ:
> Каждый сервис использует свою отдельную базу данных (подход “одна база на сервис”).
> Для согласованности применяются событийная архитектура или паттерн саги.
9. Что такое паттерн Saga?
Ответ:
> Saga — это последовательность локальных транзакций.
> Если одна из них завершается с ошибкой, запускаются компенсирующие действия для отката изменений.
10. Какие инструменты используют для разработки микросервисов?
Ответ:
> Языки: Java (Spring Boot), Node.js, Go, Python
> Сборка: Maven, Gradle
> Контейнеризация: Docker
> Оркестрация: Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14