#builder #lombok
Как реализовать builder паттерн если аннотация вешается на конструктор родительского класса и на конструктор наследника?
На скриншоте явно определена проблема - компилятор ругается на метод builder по возвращаемому типу.
Решение заключается в том, что в аннотацию надо добавить свое имя билдер метода для наследника:
@Builder(builderMethodName = "sunnyBuilder")
Еще один пример для решения этой проблемы можно прочитать по ссылке в пункте "2.3. Сосуществование нескольких Builders".
https://javascopes.com/lombok-builder-inheritance-bce31ecd/
Как реализовать builder паттерн если аннотация вешается на конструктор родительского класса и на конструктор наследника?
На скриншоте явно определена проблема - компилятор ругается на метод builder по возвращаемому типу.
Решение заключается в том, что в аннотацию надо добавить свое имя билдер метода для наследника:
@Builder(builderMethodName = "sunnyBuilder")
Еще один пример для решения этой проблемы можно прочитать по ссылке в пункте "2.3. Сосуществование нескольких Builders".
https://javascopes.com/lombok-builder-inheritance-bce31ecd/
👍1
#mutable #immutable #cuncurrency
https://youtu.be/f8nEQ5zDsOQ
На мой взгляд настоящее понимание мутабельности, а особенно в контексте многопоточки - это фундаментальная тема.
В этом видео автор кратко раскрывает вопрос почему иммутабельность - это выгодно!
https://youtu.be/f8nEQ5zDsOQ
На мой взгляд настоящее понимание мутабельности, а особенно в контексте многопоточки - это фундаментальная тема.
В этом видео автор кратко раскрывает вопрос почему иммутабельность - это выгодно!
YouTube
25 3 Иммутабельные и Мутабельные объекты в Java
Меня много раз просили выложить курс по основам Java. Я понимаю что таких курсов уже много, но некоторые говорят что им понятней когда объясняю именно я.
Данный курс основан на книге OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam…
Данный курс основан на книге OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam…
🤔1
#threadlocal
Столкнулся с проблемой - завел ThreadLocal поле, выполнил .set(), а это поле хоть ты тресни, при запуска сервиса в многопоточном режиме - null и все!
Оказывается, чтобы ThreadLocal поле получило значение внутри параллельной зоны кода - нужно задавать через .set() внутри этой многопоточной зоны кода (в рамках ThreadPool, в котором поле должно иметь определенное состояние).
А от того, что до попадания в параллельную зону делал .set() - ThreadLocal полю на это "фиолетово", оно как было "null" (по инициализации при создании класса), так "null" и зашло в зону работы ThreadPool.
Хоть 100 раз делай .set() до многопоточного режима - ThreadLocal поле окажется в параллельной зоне в таком состоянии, в которым оно было создано.
Мораль басни такова - задать значение ThreadLocal для работы в параллельности можно 2 вариантами:
1) При создании экземпляра класса.
2) С помощью .set() но только внутри многопоточной зоны.
Классные примеры "thread-safety":
https://javascopes.com/java-thread-safety-11db95ab/
Столкнулся с проблемой - завел ThreadLocal поле, выполнил .set(), а это поле хоть ты тресни, при запуска сервиса в многопоточном режиме - null и все!
Оказывается, чтобы ThreadLocal поле получило значение внутри параллельной зоны кода - нужно задавать через .set() внутри этой многопоточной зоны кода (в рамках ThreadPool, в котором поле должно иметь определенное состояние).
А от того, что до попадания в параллельную зону делал .set() - ThreadLocal полю на это "фиолетово", оно как было "null" (по инициализации при создании класса), так "null" и зашло в зону работы ThreadPool.
Хоть 100 раз делай .set() до многопоточного режима - ThreadLocal поле окажется в параллельной зоне в таком состоянии, в которым оно было создано.
Мораль басни такова - задать значение ThreadLocal для работы в параллельности можно 2 вариантами:
1) При создании экземпляра класса.
2) С помощью .set() но только внутри многопоточной зоны.
Классные примеры "thread-safety":
https://javascopes.com/java-thread-safety-11db95ab/
🔥4👍1
#atomicreference
Почему когда пишешь Stream то IDEA предлагает конвертацию в AtomicReference?
Вообще для чего нужен этот тип полей?
Атомики - это классы, которые выполняют операции изменения своего значения атомарно, т.о. они поддерживают lock-free thread-safe использование переменных. Достигается это с помощью алгоритма compare-and-swap (CAS) и работает быстрее, чем аналогичные реализации с блокировками. На уровне инструкций большинства процессоров имеется поддержка CAS.
Например, на скриншоте метод addMissedColToDf может работать в многопоточке и потоки сильно захотят зайти в переменную resultDf и добавить колонку к набору данных, но она (resultDf) даст поработать с ней только по очереди во избежание разбитого состояния каждым из потоков одновременно!
То есть операция либо выполняется полностью либо это поле посылает java действие лесом и не дает ничего сделать.
Классное описание атомиков:
https://github.com/jmorozov/awesome-java-backend-interview-rus/blob/main/java/concurrency.md#как-работают-атомики
Почему когда пишешь Stream то IDEA предлагает конвертацию в AtomicReference?
Вообще для чего нужен этот тип полей?
Атомики - это классы, которые выполняют операции изменения своего значения атомарно, т.о. они поддерживают lock-free thread-safe использование переменных. Достигается это с помощью алгоритма compare-and-swap (CAS) и работает быстрее, чем аналогичные реализации с блокировками. На уровне инструкций большинства процессоров имеется поддержка CAS.
Например, на скриншоте метод addMissedColToDf может работать в многопоточке и потоки сильно захотят зайти в переменную resultDf и добавить колонку к набору данных, но она (resultDf) даст поработать с ней только по очереди во избежание разбитого состояния каждым из потоков одновременно!
То есть операция либо выполняется полностью либо это поле посылает java действие лесом и не дает ничего сделать.
Классное описание атомиков:
https://github.com/jmorozov/awesome-java-backend-interview-rus/blob/main/java/concurrency.md#как-работают-атомики
👏2
#idea #replace #refact
Сегодня делал много замен в коде ввиду разделения классов модуля на несколько модулей по логическому функционалу.
Стимулирующая к работе картина, когда ссылки на объекты краснеют, проект не собирается...
И тут на помощью приходит IDEA!
Горячее сочетание клавиш "Ctrl+Shift+R" и меню замены спасает это покраснение.
Особенно мне понравилась опция замены на базе выделенной зоны. Для этого в "Scope" надо выбрать "Selection".
Подробнее о замене есть в статье на сайте JetBrains: https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-project.html#replace_search_string_in_project
Сегодня делал много замен в коде ввиду разделения классов модуля на несколько модулей по логическому функционалу.
Стимулирующая к работе картина, когда ссылки на объекты краснеют, проект не собирается...
И тут на помощью приходит IDEA!
Горячее сочетание клавиш "Ctrl+Shift+R" и меню замены спасает это покраснение.
Особенно мне понравилась опция замены на базе выделенной зоны. Для этого в "Scope" надо выбрать "Selection".
Подробнее о замене есть в статье на сайте JetBrains: https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-project.html#replace_search_string_in_project
IntelliJ IDEA Help
Search and replace a target within a project | IntelliJ IDEA
Learn how to search for text strings in IntelliJ IDEA: filter results, find usages, replace, and configure
automatic highlighting.
automatic highlighting.
👍3
#forkjoinpool
Конкретно в текущем проекте, где я работаю, этот вид threadpool используется для параллельной обработки порций данных.
Надо сказать, что справляется со своей задачей хорошо. Были сделаны сравнения с классическим fixedThreadPool. В результате тестов под настоящей нагрузкой forkjoin подход первым прорвал линию фронта и отработал без ошибок.
В чем сила??
В нем воровская технология отбирания задач у соседа!
Простыми словами можно сказать, что ядра-потоки помогают друг другу в беде, если кого-то из них заваливают.
На самом деле в литературе эта технология так и называется "work stealing".
Классная статья на тему:
https://www.google.com/amp/s/nuancesprog.ru/p/11996/%3famp
Конкретно в текущем проекте, где я работаю, этот вид threadpool используется для параллельной обработки порций данных.
Надо сказать, что справляется со своей задачей хорошо. Были сделаны сравнения с классическим fixedThreadPool. В результате тестов под настоящей нагрузкой forkjoin подход первым прорвал линию фронта и отработал без ошибок.
В чем сила??
В нем воровская технология отбирания задач у соседа!
Простыми словами можно сказать, что ядра-потоки помогают друг другу в беде, если кого-то из них заваливают.
На самом деле в литературе эта технология так и называется "work stealing".
Классная статья на тему:
https://www.google.com/amp/s/nuancesprog.ru/p/11996/%3famp
🤔2
#functionalinterface
Допустим надо получить длину строки.
Пишем в коментах - какой вариант вам нравиться и почему?
1. s -> s.length()
2. String::length
Мне нравится, когда в коде используется method reference с двойным двоеточием :: лаконично и красиво. О рекомендации по method reference кстати пишет и Джошуа Блох в книге "Effective Java".
Есть такой вид интерфейсов - "функциональный интерфейс" – содержит только 1 абстрактный метод, и позволяют получить возможность делать method reference :: и пользоваться лямбда выражениями ->.
На такие интерфейсы обычно вешается аннотация @FunctionalInterface - обеспечивает наличие только одного абстрактного метода.
ВАЖНО - default и static методы не в счёт.
https://javarush.ru/groups/posts/592-java-functional-interfaces
Допустим надо получить длину строки.
Пишем в коментах - какой вариант вам нравиться и почему?
1. s -> s.length()
2. String::length
Мне нравится, когда в коде используется method reference с двойным двоеточием :: лаконично и красиво. О рекомендации по method reference кстати пишет и Джошуа Блох в книге "Effective Java".
Есть такой вид интерфейсов - "функциональный интерфейс" – содержит только 1 абстрактный метод, и позволяют получить возможность делать method reference :: и пользоваться лямбда выражениями ->.
На такие интерфейсы обычно вешается аннотация @FunctionalInterface - обеспечивает наличие только одного абстрактного метода.
ВАЖНО - default и static методы не в счёт.
https://javarush.ru/groups/posts/592-java-functional-interfaces
👍2
#spring #enabletransactionmanagement #transaction
С версии 3.1 Spring ввел аннотацию @EnableTransactionManagement, которая используется с аннотацией @Configuration над конфигурационными классами и включает поддержку бесшовной транзакций через аннотацию @Transactional.
И че за аннотация @Transactional и почему бесшовные??
Метод помечен как @Transactional - это означает откат всех записей, если любая из операций вставки в этом методе завершится неудачей, а также Spring бросит оригинальное исключение.
ВАЖНО: если в методе с аннотацией @Transactional будут действия с БД в виде цикла и будет ошибка хотя бы в одном - то ни один элемент из списка не запишется.
Пример записи в виде цикла:
@Transactional
public void book(String... persons) {
for (String person : persons) {
log.info("Booking " + person + " in a seat...");
jdbcTemplate.update("insert into BOOKINGS(FIRST_NAME) values (?)", person);
}
};
https://spring-projects.ru/guides/managing-transactions/
С версии 3.1 Spring ввел аннотацию @EnableTransactionManagement, которая используется с аннотацией @Configuration над конфигурационными классами и включает поддержку бесшовной транзакций через аннотацию @Transactional.
И че за аннотация @Transactional и почему бесшовные??
Метод помечен как @Transactional - это означает откат всех записей, если любая из операций вставки в этом методе завершится неудачей, а также Spring бросит оригинальное исключение.
ВАЖНО: если в методе с аннотацией @Transactional будут действия с БД в виде цикла и будет ошибка хотя бы в одном - то ни один элемент из списка не запишется.
Пример записи в виде цикла:
@Transactional
public void book(String... persons) {
for (String person : persons) {
log.info("Booking " + person + " in a seat...");
jdbcTemplate.update("insert into BOOKINGS(FIRST_NAME) values (?)", person);
}
};
https://spring-projects.ru/guides/managing-transactions/
👍3
#springscopes
Например, с помощью аннотаций
@Component
@Scope("prototype")
над классом, мы укажем, что бин создается каждый раз, когда бин необходим в качестве зависимости.
Ниже список областей видимостей, описанных в документации на момент написания:
singleton - По умолчанию. Создаётся единственный экземпляр. Для бинов без состояния(stateless).
prototype - создается каждый раз, когда бин необходим в качестве зависимости. Для бинов с сохранением состояния(stateful).
request - ограничен единственным HTTP запросом. (web компонент)
session - жизненный цикл экземпляра ограничен в пределах одной и той же HTTP сессии. (web-компонент)
global session - жизненный цикл экземпляра ограничен в пределах глобальной HTTP сессии. (web компонент)
application - жизненный цикл экземпляра ограничен в пределах ServletContext. (web компонент)
Пример:
@Component
@Scope("prototype")
public class GreetingServiceImpl implements GreetingService {
//вкусная начинка
}
https://spring-projects.ru/guides/lessons/lesson-2/
Например, с помощью аннотаций
@Component
@Scope("prototype")
над классом, мы укажем, что бин создается каждый раз, когда бин необходим в качестве зависимости.
Ниже список областей видимостей, описанных в документации на момент написания:
singleton - По умолчанию. Создаётся единственный экземпляр. Для бинов без состояния(stateless).
prototype - создается каждый раз, когда бин необходим в качестве зависимости. Для бинов с сохранением состояния(stateful).
request - ограничен единственным HTTP запросом. (web компонент)
session - жизненный цикл экземпляра ограничен в пределах одной и той же HTTP сессии. (web-компонент)
global session - жизненный цикл экземпляра ограничен в пределах глобальной HTTP сессии. (web компонент)
application - жизненный цикл экземпляра ограничен в пределах ServletContext. (web компонент)
Пример:
@Component
@Scope("prototype")
public class GreetingServiceImpl implements GreetingService {
//вкусная начинка
}
https://spring-projects.ru/guides/lessons/lesson-2/
👍3
#springprofiles
Профиль в спринге - это именованная группа определений бинов.
Например, у вас есть два стенда, testing для тестов и production, где работает приложение. При этом у вас будут различаться параметры в окружениях.
Чтобы каждый раз не пересобирать приложение с разными конфигурациями, изпользуем профили:
@Configuration
public class AppConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
// test options
}
@Bean
@Profile("production")
public DataSource productionDataSource() throws Exception {
// real options
}
}
Важно!
Если класс конфигурации аннатирован @Profile({"p1", "p2"}), то она будет действовать, если профили "р1" и/или "р2" будут активны. При @Profile({"p1", "!p2"}) конфигурация действует, если профиль "р1" активен или профиль "р2" не активен.
https://spring-projects.ru/guides/lessons/lesson-2/
Профиль в спринге - это именованная группа определений бинов.
Например, у вас есть два стенда, testing для тестов и production, где работает приложение. При этом у вас будут различаться параметры в окружениях.
Чтобы каждый раз не пересобирать приложение с разными конфигурациями, изпользуем профили:
@Configuration
public class AppConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
// test options
}
@Bean
@Profile("production")
public DataSource productionDataSource() throws Exception {
// real options
}
}
Важно!
Если класс конфигурации аннатирован @Profile({"p1", "p2"}), то она будет действовать, если профили "р1" и/или "р2" будут активны. При @Profile({"p1", "!p2"}) конфигурация действует, если профиль "р1" активен или профиль "р2" не активен.
https://spring-projects.ru/guides/lessons/lesson-2/
#nonnull #npe
Чтобы сделать поле или параметр не null, добавь аннотацию @NonNull.
И не парься.
Ломбок сам сгенерит проверку на NullPointerException.
Разбор аннотации здесь:
https://projectlombok.org/features/NonNull
Чтобы сделать поле или параметр не null, добавь аннотацию @NonNull.
И не парься.
Ломбок сам сгенерит проверку на NullPointerException.
Разбор аннотации здесь:
https://projectlombok.org/features/NonNull
👍4
#мусор #unused
Если код в проекте не используется, то нечего его хранить. И поддерживать пакеты понятнее, если класс стоит на месте, то значит работает.
При необходимости через Git можно восстановить нужный класс из истории репозитория.
В IDEA есть инструменты инспекции и анализа кода.
Можно пойти таким путем:
Code > Analyze Code > Run Inspection by Name > Unused declaration.
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360010821479-How-to-use-IntelliJ-IDEA-to-find-all-unused-code-
Если код в проекте не используется, то нечего его хранить. И поддерживать пакеты понятнее, если класс стоит на месте, то значит работает.
При необходимости через Git можно восстановить нужный класс из истории репозитория.
В IDEA есть инструменты инспекции и анализа кода.
Можно пойти таким путем:
Code > Analyze Code > Run Inspection by Name > Unused declaration.
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360010821479-How-to-use-IntelliJ-IDEA-to-find-all-unused-code-
IDEs Support (IntelliJ Platform) | JetBrains
How to use IntelliJ IDEA to find all unused code?
When I am in a .java file the unused code is ordinarily grayed out or features a green underline saying this code will likely (likely since of a few peculiar JNI/Reflection corner cases) be unused....
👍2
#todo
Пиши //TODO комментарии прям на месте "не отходя от кассы" пока помнишь что хотел сделать с классом или методом.
В IDEA есть отдельная вкладка снизу для отображения TODO и этим очень удобно пользоваться.
В отличии от записок из блокнотов, TODO не надо искать по проекту как иголку в стоге сена, он уже написан в том месте, где требуется лечение.
Пиши //TODO комментарии прям на месте "не отходя от кассы" пока помнишь что хотел сделать с классом или методом.
В IDEA есть отдельная вкладка снизу для отображения TODO и этим очень удобно пользоваться.
В отличии от записок из блокнотов, TODO не надо искать по проекту как иголку в стоге сена, он уже написан в том месте, где требуется лечение.
👍3🏆3
#forkjointask #completablefuture
Чтобы запустить ForkJoinTask в ForkJoinPool со своими настройками, мне удалось найти такое решение:
CompletableFuture<?> cf = CompletableFuture.runAsync(forJoinTask::invoke, customForkJoinPool);
В такой конструкции получаем классные плюсы:
1. Результаты объеденных CompletableFuture с отловом InterruptedException и ExecutionException исключений через CompletableFuture.allOf(cf1, cf2).get(), чего нет при вызовах через ForkJoinPool::invokeAll и ForkJoinTask::invokeAll.
2. Возможность управления поведением каждого из потоков с помощью богатого контракта CompletableFuture.
3. Использование настроек своего customForkJoinPool. Я как минимум делаю спец. имена ForkJoinWorkerThread потоков для каждого из сервисов в проекте.
Пример создания сustomForkJoinPool:
protected СustomForkJoinPool(int logicTasksCount) {
int availableProcessors = Runtime.getRuntime().availableProcessors();
ForkJoinPool.ForkJoinWorkerThreadFactory workerFactory = this::initWorkerFactory;
if (logicTasksCount < availableProcessors) {
this.threadPool = new ForkJoinPool(logicTasksCount, workerFactory, null, false);
} else {
this.threadPool = new ForkJoinPool(availableProcessors, workerFactory, null, false);
}
log.info("Thread pool parallelism level - {}.", threadPool.getParallelism());
}
private ForkJoinWorkerThread initWorkerFactory(ForkJoinPool pool) {
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setName("MyService-" + thread.getPoolIndex());
return thread;
}
https://www.baeldung.com/java-completablefuture
https://www.baeldung.com/java-work-stealing
Чтобы запустить ForkJoinTask в ForkJoinPool со своими настройками, мне удалось найти такое решение:
CompletableFuture<?> cf = CompletableFuture.runAsync(forJoinTask::invoke, customForkJoinPool);
В такой конструкции получаем классные плюсы:
1. Результаты объеденных CompletableFuture с отловом InterruptedException и ExecutionException исключений через CompletableFuture.allOf(cf1, cf2).get(), чего нет при вызовах через ForkJoinPool::invokeAll и ForkJoinTask::invokeAll.
2. Возможность управления поведением каждого из потоков с помощью богатого контракта CompletableFuture.
3. Использование настроек своего customForkJoinPool. Я как минимум делаю спец. имена ForkJoinWorkerThread потоков для каждого из сервисов в проекте.
Пример создания сustomForkJoinPool:
protected СustomForkJoinPool(int logicTasksCount) {
int availableProcessors = Runtime.getRuntime().availableProcessors();
ForkJoinPool.ForkJoinWorkerThreadFactory workerFactory = this::initWorkerFactory;
if (logicTasksCount < availableProcessors) {
this.threadPool = new ForkJoinPool(logicTasksCount, workerFactory, null, false);
} else {
this.threadPool = new ForkJoinPool(availableProcessors, workerFactory, null, false);
}
log.info("Thread pool parallelism level - {}.", threadPool.getParallelism());
}
private ForkJoinWorkerThread initWorkerFactory(ForkJoinPool pool) {
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setName("MyService-" + thread.getPoolIndex());
return thread;
}
https://www.baeldung.com/java-completablefuture
https://www.baeldung.com/java-work-stealing
Baeldung on Kotlin
Guide To CompletableFuture | Baeldung
Quick and practical guide to Java 8's CompletableFuture.
🤔1
#jokerconf
Скоро состоится одна из самых крупных площадок по Java разработке!
Вот список докладов по разделам:
https://jokerconf.com/talks/
Есть возможность попасть на кусочек пирога и бесплатно, подробнее здесь:
https://jokerconf.com/registration/personal/
Скоро состоится одна из самых крупных площадок по Java разработке!
Вот список докладов по разделам:
https://jokerconf.com/talks/
Есть возможность попасть на кусочек пирога и бесплатно, подробнее здесь:
https://jokerconf.com/registration/personal/
#immutablemap
ImmutableMap на самом деле полезная вещь и порой недооценена там где она должна быть.
Уверен, что значения в мапе будут меняться? На самом деле?
Может достаточно сделать вот так:
ImmutableMap<String, String> immutableMap = ImmutableMap.<String, String>builder()
.putAll(someMutableMap)
.put("Costa Rica", "North America")
.build();
В таком виде получается безопасная мапа с которой не страшно работать при отсутствии необходимости модификации, особенно если ее надо отдать наружу из класса.
Подробнее здесь:
https://www.baeldung.com/java-immutable-maps
ImmutableMap на самом деле полезная вещь и порой недооценена там где она должна быть.
Уверен, что значения в мапе будут меняться? На самом деле?
Может достаточно сделать вот так:
ImmutableMap<String, String> immutableMap = ImmutableMap.<String, String>builder()
.putAll(someMutableMap)
.put("Costa Rica", "North America")
.build();
В таком виде получается безопасная мапа с которой не страшно работать при отсутствии необходимости модификации, особенно если ее надо отдать наружу из класса.
Подробнее здесь:
https://www.baeldung.com/java-immutable-maps
Baeldung on Kotlin
Immutable Map Implementations in Java | Baeldung
Explore the differences between an Unmodifiable Map and Immutable Map in Java.
👍5
#cpu #ram
Для меня всегда было некоторой загадкой - как же написанный код превращается в сигналы на платах и компьютер понимает что надо делать?
Это видео позволяет приоткрыть завесу вопроса работы памяти.
https://youtu.be/Wh22_O8jXVQ
Для меня всегда было некоторой загадкой - как же написанный код превращается в сигналы на платах и компьютер понимает что надо делать?
Это видео позволяет приоткрыть завесу вопроса работы памяти.
https://youtu.be/Wh22_O8jXVQ
YouTube
КАК РАБОТАЕТ ПАМЯТЬ КОМПЬЮТЕРА | ОСНОВЫ ПРОГРАММИРОВАНИЯ
Чтобы понять, что из себя представляет программа на самом деле, нужно разобраться с тем, кто и как ее выполняет в конечном итоге.
Этим занимается процессор, но без понимания того, как организована оперативная память компьютера, как в ней хранятся данные и…
Этим занимается процессор, но без понимания того, как организована оперативная память компьютера, как в ней хранятся данные и…
🔥2🤔1
#singular
Удобно пользоваться аннотацией @Singular от Lombok в билдерах @Builder.
Аннотация автоматически генерирует возможность подавать элементы коллекции в билдере в виде:
.table(sourceTable)
.table(targetTable)
Вместо оборачивания всех подаваемых полей через конструкцию из древних веков - Arrays.asList(sourceTable, targetTable).
https://www.baeldung.com/lombok-builder-singular
Удобно пользоваться аннотацией @Singular от Lombok в билдерах @Builder.
Аннотация автоматически генерирует возможность подавать элементы коллекции в билдере в виде:
.table(sourceTable)
.table(targetTable)
Вместо оборачивания всех подаваемых полей через конструкцию из древних веков - Arrays.asList(sourceTable, targetTable).
https://www.baeldung.com/lombok-builder-singular
🤓1
#lombokvar
Когда ты знаешь контекст и тебе быстро нужно определённое поле под рукой, то Lombok var - то что надо.
Достаточно написать вот так как на картинке (указано стрелкой) и стринги готовы к работе.
ВАЖНО!
С этими var надо быть внимательным:
- при множестве таких полей не перепутать при работе
- не стоит давать малопонятные имена var полям
- это lazy тип, который получает себя от начинки.
https://www.baeldung.com/java-lombok-val-var
Когда ты знаешь контекст и тебе быстро нужно определённое поле под рукой, то Lombok var - то что надо.
Достаточно написать вот так как на картинке (указано стрелкой) и стринги готовы к работе.
ВАЖНО!
С этими var надо быть внимательным:
- при множестве таких полей не перепутать при работе
- не стоит давать малопонятные имена var полям
- это lazy тип, который получает себя от начинки.
https://www.baeldung.com/java-lombok-val-var
👌1
#cachedthreadpool
Важно контролировать кол-во потоков (thread) и задач (task) в работающем пуле (thread pool), в противном случае многопоточка может только навредить работе приложения.
Это связано с тем, что потоки и задачи в очереди кушают ресурсы (память и процессор).
Особенно это касается Cached Thread Pool.
В этом типе пула очередь не может хранить задачи и создаёт новый поток если все заняты.
Так же этот тип пула не ⛔ рекомендуется для I/O задач ВВОДА-ВЫВОДА.
Он подходит для ограниченного кол-ва задач и маленьких по времени выполнения.
👉 Почитать здесь:
https://www.baeldung.com/java-executors-cached-fixed-threadpool
https://javarush.com/quests/lectures/jru.module2.lecture23
Важно контролировать кол-во потоков (thread) и задач (task) в работающем пуле (thread pool), в противном случае многопоточка может только навредить работе приложения.
Это связано с тем, что потоки и задачи в очереди кушают ресурсы (память и процессор).
Особенно это касается Cached Thread Pool.
В этом типе пула очередь не может хранить задачи и создаёт новый поток если все заняты.
Так же этот тип пула не ⛔ рекомендуется для I/O задач ВВОДА-ВЫВОДА.
Он подходит для ограниченного кол-ва задач и маленьких по времени выполнения.
👉 Почитать здесь:
https://www.baeldung.com/java-executors-cached-fixed-threadpool
https://javarush.com/quests/lectures/jru.module2.lecture23
Baeldung on Kotlin
Executors newCachedThreadPool() vs newFixedThreadPool() | Baeldung
Compare the newCachedThreadPool() and newFixedThreadPool() implementations and their use-cases
👍1