Java Guru 🤓

channel icon
Канал с вопросами и задачами с собеседований!

Условия размещения

Цена за 48 часов в ленте 3500,00
Цена за 1 час закрепления N/A
Взаимопиар Нет
Дополнительные условия рекламы Отсутствуют
-5
12 322
подписчиков
-45
~2.2k
охват 1 публикации
0
~2
постов / день
-0,4%
17,9%
ERR % ?

Статистика

Последние публикации

Java Guru 🤓
16 мая 2024 г. 11:30
Чем ForkJoinPool отличается от ExecutorService?

ForkJoinPool сам по себе является наследником ExecutorService. Вопрос подразумевает его отличия от обычного пула потоков – ThreadPoolExecutor.

Преимущества, которые дает work stealing по сравнению с обычным пулом:
• Сокращение расходов на переключение контекста;
• Защита от проблемы голодания потоков (thread starvation);
• Защита от дедлока для рекурсивных задач.

Как положено любому представителю ExecutorService, ForkJoinPool тоже умеет выполнять Runnable и Callable, но помимо этого работает и со специальными задачами ForkJoinTask, о которых также говорилось ранее.

Интерфейс настройки и мониторинга остается тем же, что и в классических тред-пулах.

Каждый обычный пул использует собственный набор потоков. ForkJoinPool по умолчанию использует общий пул-синглтон commonPool. Альтернативный отдельный пул всё еще можно задать в конструкторе.

ForkJoinPool сам регулирует количество запущенных потоков, достигая максимальной эффективности при заданном уровне параллелизма.
Java Guru 🤓
16 мая 2024 г. 10:15
Хотите узнать о технологиях в Яндексе? Слушайте I like techno 🔥

I like techno — подкаст про технологии от Яндекс Еды, Лавки, Такси, Маркета, Доставки и Техплатформы Екома и Райдтеха. В выпусках эксперты рассказывают, что стоит за простыми приложениями в гаджетах, и говорят о бизнесе, продукте и людях, которые создают технологии.

В первых двух эпизодах обсудили технологии в Яндекс Еде и Лавке и продуктовую разработку в Такси и Самокатах.

Узнайте подробнее на сайте подкаста и переходите слушать на YouTube и Яндекс Музыку! 🎧
Java Guru 🤓
16 мая 2024 г. 9:08
Что такое ForkJoinPool?

ForkJoinPool – специальный вид ExecutorService (пулла потоков), который появился в Java с версии 7. Предназначен для выполнения рекурсивных задач.

Задача для сервиса представляется экземпляром класса ForkJoinTask. В основном используются подклассы RecursiveTask и RecursiveAction, для задач с результатом и без соответственно. Аналогично интерфейсам Callable и Runnable обычного ExecutorService.

Тело рекурсивной операции задается в реализации метода compute() задачи ForkJoinTask. Здесь же создаются новые подзадачи, и запускаются параллельно методом fork(). Чтобы дождаться завершения выполнения задачи, на каждой форкнутой подзадаче вызывается блокирующий метод join(), результат выполнения при необходимости агрегируется.

С точки зрения использования метод ForkJoinTask.join() похож на аналогичный метод класса Thread. Но в случае fork-join поток может на самом деле не заснуть, а переключиться на выполнение другой задачи. Такая стратегия называется work stealing, и позволяет эффективнее использовать ограниченное количество потоков. Это похоже на переиспользование потоков
корутинах Kotlinкорутинах Kotlin (green threadsgreen threads).

Примеры практического использования ForkJoinPool.Примеры практического использования ForkJoinPool.
Java Guru 🤓
15 мая 2024 г. 13:20
👩‍💻 Как и зачем Java-разработчику сочетать DTO, MapStruct и Spring?

Расскажем на открытом практическом уроке от OTUS.
Спикер занятия — Senior Software Engineer.

На вебинаре мы:

- разберем паттерн DTO (Data Transfer Object);
- обсудим проблемы, которые решает паттерн и его основные сценарии использования на примере небольшого приложения на Spring Boot;
- изучим инструмент MapStruct, чтобы сделать данное сочетание удобным и сократить количество boilerplate кода.

Встречаемся 23 мая в 20:00 мск в преддверии старта курса «Разработчик на Spring Framework».
Все участники вебинара получат специальную цену на обучение и персональную консультацию от менеджеров OTUS!

➡️ Регистрация на урок: https://vk.cc/cwP6FZ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Java Guru 🤓
15 мая 2024 г. 10:50
Из чего состоит пакет java.nio?

Этому вопросу посвящена отдельная страница документациидокументации. Если вы никогда раньше не сталкивались с Java NIO – это хорошее место для начала знакомства. Отвечая на этот вопрос, нужно перечислить и объяснить основные понятия NIO:

Буфферы. Временные хранилища фиксированного размера для транспортируемых данных. Именно буферизация – основное отличие неблокирующего чтения от
NIO:

Буфферы. Временные хранилища фиксированного размера для транспортируемых данных. Именно буферизация – основное отличие неблокирующего чтения от java.iojava.io.

Каналы. Реализации интерфейса Channel – сущности, представляющие соединения между разными участниками ввода-вывода (файлы, сокеты, консоль).

Селекторы. Наследники класса Selector. «Мультиплексоры» каналов – комбинируют несколько каналов в один. Регистрация канала в селекторе возвращает SelectionKey, который содержит ссылку на сам канал, и ряд его атрибутов. Селектор позволяет выбрать из набора зарегистрированных каналов подмножество готовых к работе, при необходимости блокируя выполнение на время ожидания. Каналы и селекторы располагаются в пакете java.nio.channels. Полный пример использования селекторов можно найти в
Каналы. Реализации интерфейса Channel – сущности, представляющие соединения между разными участниками ввода-вывода (файлы, сокеты, консоль).

Селекторы. Наследники класса Selector. «Мультиплексоры» каналов – комбинируют несколько каналов в один. Регистрация канала в селекторе возвращает SelectionKey, который содержит ссылку на сам канал, и ряд его атрибутов. Селектор позволяет выбрать из набора зарегистрированных каналов подмножество готовых к работе, при необходимости блокируя выполнение на время ожидания. Каналы и селекторы располагаются в пакете java.nio.channels. Полный пример использования селекторов можно найти в статье на baeldung.

Кодировки. Charset – то, как бинарные данные будут конвертироваться в родные для Java символы UTF-16 и обратно. Классы для работы с кодировками хранятся в пакете java.nio.charset.
Кодировки. Charset – то, как бинарные данные будут конвертироваться в родные для Java символы UTF-16 и обратно. Классы для работы с кодировками хранятся в пакете java.nio.charset.
Java Guru 🤓
15 мая 2024 г. 9:01
🧠 Хотите упростить создание тестовой отчетности? 
Ждём вас на открытом практическом уроке «Организовываем отчетность по автотестам на Allure» от OTUS.

💪 На вебинаре разберем:
- интеграцию Allure с Groovy pipeline на Jenkins;
- разницу между TestResult и TestResultContainer;
- интеграцию allure артефактов с Allure TestOps. 

☝️Все это позволит вам оптимизировать работу и сэкономить время на рутинных задачах. 

👉 Зарегистрируйтесь, чтобы посетить бесплатный урок: https://otus.pw/RbCM/?erid=LjN8K9MZw

⏰ Встречаемся 15 мая в 20:00 мск в преддверии старта курса «Java QA Engineer. Professional». Все участники вебинара получат специальную цену на обучение и персональную консультацию от менеджеров OTUS! 

Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
Java Guru 🤓
14 мая 2024 г. 22:47
Что происходит если не обработать исключение?

Если не было предпринято дополнительных действий, в этой ситуации нет никаких хитростей. Всё приложение, и даже метод main(), выполняется в потоках. Поток, в котором было выброшено и не обработано исключение, остановится, и распечатает стектрейс в вывод System.err. Если это был последний пользовательский поток, приложение начнет завершение работы.

Для изменения логики обработки непойманных исключений в Java существует функциональный интерфейс Thread.UncaughtExceptionHandler.

Обработчик упущенных исключений может быть установлен (в порядке возрастания приоритета):
• глобально на всё приложение, статическим методом Thread.setDefaultUncaughtExceptionHandler();
• для группы потоков, переопределением метода uncaughtException() в реализации объекта подкласса ThreadGroup (т.к. ThreadGroup сам является наследником UncaughtExceptionHandler);
• для отдельного потока, методом setUncaughtExceptionHandler().

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

Хорошей практикой считается обрабатывать исключение настолько близко к месту его выброса, насколько возможно. Следовательно, использование глобальных обработчиков – самый плохой вариант.

Так же как в случае различных финализаций, несмотря на все её недостатки, глобальная обработка иногда лучше, чем ничего. Она может, например, дать последний шанс освободить внешние ресурсы, или уведомить о некорректной работе программы более эффективно, чем через логи.
Когда код с исключением выполняет ExecutorService, мы не имеем прямого доступа к объектам потока. Но в этом случае результатом выполнения будет объект типа Future. Такой отложенный объект при попытке прочитать значение перевыбросит полученное исключение, завернув его в ExecutionException. Новое исключение-обертка уже пойдет по обычному пути обработки текущего потока. Исключение как бы перекочует из внутреннего потока пулла во внешний, который использует этот пулл.

Если же пользовательский код не станет дожидаться результатов, исключение будет потеряно, не оставив даже стектрейса в потоке вывода. Для предотвращения такой ситуации стоит снабдить поток обработчиком сразу после создания, определив для сервиса собственную ThreadFactory.

Обычно, если фреймворк скрывает от пользователя детали работы с потоками, он также скрывает и детали работы с исключениями, оставляя свой специальный способ назначить обработчик. И этот специальный обработчик – более специфичный, а значит более правильный подход, чем стандартная глобальная обработка исключений Java. Так, например, в Spring MVC применяется аннотация
@ExceptionHandler@ExceptionHandler.
Java Guru 🤓
14 мая 2024 г. 16:00
30 мая встречаемся на бесплатном онлайн-митапе от Naumen для java-разработчиков. В программе четыре доклада. Делимся анонсами некоторых из них:

🔸 Обновление Java с 17 на 21: через тернии к звездам — Денис Абрамов из Naumen.
Расскажем о непростом пути миграции систем на Java 21, с какими неожиданными препятствиями можно столкнуться и как их преодолеть. Поделимся, какие результаты мы получили после обновления и почему вообще стоит обновляться.

🔸 Лучше день потерять, потом за 5 минут долететь — Анатолий Саблин из «Сибур».
Представим несколько кейсов из тринадцатилетнего опыта java-разработчика. Расскажем, как лень обработать исключение вылилась в плавающую ошибку в промышленной эксплуатации на несколько месяцев. И как нехватка опыта спрогнозировать возможное поведение системы, а также непонимание работы инфраструктуры и компонентов привели к финансовым убыткам компании. На примере продемонстрируем, почему паттерны проектирования придумали не ради каверзных вопросов на собеседовании.
→ Зарегистрироваться.

Встречаемся онлайн 30 мая в 16:00 мск.
Если вы из Екатеринбурга — ждём на афтепати 🍕

erid: 2Vtzqwru93f
Реклама, АО «Нау-сервис», ИНН 6671116364,
https://www.naumen.ru/
Java Guru 🤓
14 мая 2024 г. 14:45
Как реализовать паттерн producer/consumer?

Шаблон producer/consumer (производитель/потребитель) – простая и базовая реализация обмена данными между несколькими потоками. Поток-производитель отправляет объекты на условную обработку, потоки-потребители асинхронно принимают и обрабатывают их.

Общий вид решения выглядит так. Продюсер отправляет объекты в специальную коллекцию – буфер. Когда потребитель освобождается, он отправляет запрос на извлечение одного объекта из буфера. Если буфер пуст, потребитель блокируется и ждет, если буфер переполнен – ждет производитель.

На практике реализовать этот паттерн можно множеством способов. Самый правильный способ для применения в бою – использовать готовую реализацию из стандартной библиотеки, объект типа BlockingQueue.

На собеседовании обычно просят реализовать паттерн с нуля. Реализация представлена на изображении. Модификатор synchronized делает так, чтобы в каждый момент времени мог выполняться только один из методов, и только одним потоком. Этого достаточно для корректной работы пока буфер не пуст и не полон. При пустом или полном буфере управление явно перебрасывается на производителя или потребителя соответственно, с помощью методов notify() и wait().

Шаблону producer/consumer посвящена глава 5.3 книги Java Concurrency in Practice.

Сильно упрощая, на основе этого паттерна работают сервисы-брокеры сообщений: Rabbit MQ, Apache ActiveMQ и другие.
Java Guru 🤓
14 мая 2024 г. 11:30
Как прошла самая яркая конференция весны от Яндекс Go🔥

20 апреля прошла Яндекс Go Dev Day&Night — конференция для мобильных и бэкенд-разработчиков, которая уходит в ночь. Формат нестандартный: днем доклады, а после заката — тусовка и неформальные дискуссии.

На конференции эксперты Яндекс Такси, Еды, Лавки, Доставки, Маркета и Техплатформы выступали с докладами о перформансе в мобильной разработке, опенсорс-проектах, математике надежности и других темах

➡️Смотрите записи на YouTube и делитесь с друзьями!

Реклама. ООО «Яндекс»
ИНН 7736207543
Java Guru 🤓
14 мая 2024 г. 9:27
Как выполнить две задачи параллельно?

Простейший, путь – явно создать два объекта типа Thread, передать им инстансы Runnable, с нужными задачами в реализации их методов run, и запустить вызвав thread.start(). Если в основном потоке нужно дождаться завершения задач – после start() вызывается метод thread.join(). Исполнение зависнет на вызове этого метода до тех пор, пока тред не закончит свою задачу и не умрет. Вся работа задач с внешними данными должна быть синхронизирована.

Такое ручное создание тредов полезно в учебных целях, но считается плохой практикой в промышленном коде: само создание – дорогостоящая операция, а большое количество случайно созданных потоков может приводить к проблеме голодания (starvation) потоков.

В качестве продвинутой альтернативы используются пуллы потоков – реализации интерфейса ExecutorService. Такие сервисы создаются статическими фабричными методами класса Executors. Они умеют принимать задачи в виде Runnable- или Callable-объектов на заранее созданном наборе потоков (собственно, пулле).

Кроме самого пулла, экземпляры ExecutorService содержат фабрику потоков («инструкцию» как создать тред при необходимости), и коллекцию-очередь задач на исполнение.

В ответ на передачу на исполнение Runnable или Callable, сервис возвращает связанный с ним объект типа Future – хранилище, которое будет заполнено результатом выполнения задачи в будущем. Даже если никакого результата не ожидается, Future поможет дождаться момента завершения обработки задачи.

В Android для асинхронного выполнения используется похожая сущность – Looper.
Java Guru 🤓
13 мая 2024 г. 18:30
16–17 мая ВСК проводит One Day Offer.

Если ты разработчик или системный аналитик уровня middle и выше, регистрируйся https://onedayoffer.vsk.ru до 15:00 15 мая.

Пройди онлайн-собеседование в компании из золотого рейтинга Forbes и получи офер в тот же день. Выбирай сам формат будущей работы и пользуйся ДМС с первого дня.

Создавай лучшие InsurTech-продукты страны в одной из наших Agile-команд.
Java Guru 🤓
8 мая 2024 г. 16:00
Как прошла самая яркая конференция весны от Яндекс Go🔥

20 апреля прошла Яндекс Go Dev Day&Night — конференция для мобильных и бэкенд-разработчиков, которая уходит в ночь. Формат нестандартный: днем доклады, а после заката — тусовка и неформальные дискуссии.

На конференции эксперты Яндекс Такси, Еды, Лавки, Доставки, Маркета и Техплатформы выступали с докладами о перформансе в мобильной разработке, опенсорс-проектах, математике надежности и других темах

➡️Смотрите записи на YouTube и делитесь с друзьями!

Реклама. ООО «Яндекс»
ИНН 7736207543
Java Guru 🤓
8 мая 2024 г. 14:45
Зачем используются thread local переменные?

Класс ThreadLocal представляет хранилище тред-локальных переменных. По способу использования он похож на обычную обертку над значением, с методами get(), set() и remove() для доступа к нему, и дополнительным фабричным методом ThreadLocal.withInitial(), устанавливающим значение по-умолчанию.

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

Проще говоря, объект класса ThreadLocal хранит внутри не одно значение, а как бы хэш-таблицу поток➝значение, и при использовании обращается к значению для текущего потока.

Первый, самый очевидный вариант использования – данные, относящиеся непосредственно к треду, определенный пользователем «контекст потока». На скриншоте ниже пример такого использования: ThreadId.get() вернет порядковый номер текущего треда.

Другой случай, с которым локальная переменная потока может помочь – кэширование read-only данных в многопоточной среде без дорогостоящей синхронизации.

Помимо обычного ThreadLocal, в стандартной библиотеке присутствует его расширение InheritableThreadLocal. Этот класс «наследует» значение – изначально берет его для потока, являющегося родителем текущего.
Java Guru 🤓
8 мая 2024 г. 11:40
🎯 Исключения в разработке — что это и как с ними работать?

Узнайте на открытом практическом уроке «Исключения. От Java до Spring, от шестнадцати и старше» от OTUS.

На вебинаре опытный эксперт разберет:

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

И, конечно, мы не забудем про Spring!

Спикер — Senior Software Engineer.

Встречаемся 15 мая в 20:00 мск в преддверии старта курса «Разработчик на Spring Framework».
Все участники вебинара получат специальную цену на обучение и персональную консультацию от менеджеров OTUS!

👉 Пройдите короткий тест прямо сейчас, чтобы посетить бесплатный урок: https://otus.pw/dWE9/

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Java Guru 🤓
8 мая 2024 г. 9:20
Что такое и как создать daemon thread?

Демон в широком значении – фоновая программа. В Java потоки-демоны имеют схожий смысл: это потоки для фоновых действий по обслуживанию основных потоков. Потоки не-демоны называются пользовательскими (user thread).

Тред создается демоном, если его родитель демон. Свойство Java-треда isDaemon можно переключать в любой момент до старта потока.

По сравнению с пользовательскими потоками демоны имеют меньший приоритет выполнения.

Когда все пользовательские треды завершились, JVM завершает работу. Демоны не выполняют самостоятельных задач, поэтому не препятствуют остановке, программа завершается не дожидаясь окончания их работы.

Daemon thread может быть полезен для таких действий, как инвалидация кэша, периодическая актуализация значений из внешних источников, освобождение неиспользуемых пользовательских ресурсов.
Java Guru 🤓
6 мая 2024 г. 13:40
Java — один из трёх самых популярных языков программирования в мире. С его помощью сайты, интернет-магазины, мобильные приложения и даже telegram-боты подключаются к платёжным системам вроде Robokassa или Yandex Pay, отправляют уведомления, сохраняют клиентские данные и многое другое. Вы сталкиваетесь с результатами кода на Java каждый день. 

Научиться программировать на Java может каждый. Главное — искренний интерес к работе с кодом и стремление к постоянному развитию. На бесплатном курсе «Основы разработки на Java» вы изучите основы синтаксиса языка Java, а в качестве практики разработаете приложение для публикации фото из NASA и перепишете его под Telegram API. Для участия в курсе вам не обязательно уметь программировать. 

Попробуйте себя в Java-разработке

Реклама. ООО "Нетология". Erid 2VSb5yjwDw6
Java Guru 🤓
6 мая 2024 г. 10:29
Как устроены атомики?

Начнем с того, что такое атомики и зачем нужны. Atomic* – семейство классов из java.util.concurrent. Они предоставляют набор атомарных операций для соответствующих типов. Например с помощью методов getAndIncrement/incrementAndGet класса AtomicInteger можно делать неатомарный в обычных условиях инкремент (i++).

Условно можно разделить подходы реализации большинства atomic-методов на две группы: compare-and-set и set-and-get.

Методы категории compare-and-set принимают старое значение и новое. Если переданное старое значение совпало с текущим, устанавливается новое. Обычно делегируют вызов в методы класса Unsafe, которые заменяются нативными реализациями виртуальной машины. Виртуальная машина в большинстве случаев использует атомарную операцию процессора compare-and-swap (CAS). Поэтому атомики обычно более эффективны чем стандартная дорогостоящая блокировка.

В случае set-and-get старое значение неизвестно. Поэтому нужен небольшой трюк: программа сначала считывает текущее значение, а затем записывает новое, тоже с помощью CAS, потому что запись могла успеть поменяться даже за этот шаг. Эта попытка чтения+записи повторяется в цикле, пока старое значение не совпадет и переменная не будет успешно записана.

Этот трюк называется double-checked или optimistic locking, и может быть использован и в пользовательском коде с любым способом синхронизации. Оптимистичность заключается в том, что мы надеемся что состояния гонки нет, прибегая к синхронизации только если гонка всё же случилась. Реализация оптимистичной блокировки может быть дана как отдельная задача.
Java Guru 🤓
4 мая 2024 г. 14:30
🧠 Улучши ИИ на хакатоне X5 Tech AI Hack! У тебя будет 10 дней, чтобы избавить нейросеть от галлюцинаций и научить ее работать с конфиденциальными данными. Призовой фонд от X5 Tech – 2 000 000 рублей.

Старт ML-соревнования – 17 мая. Не жди дедлайна, регистрируйся прямо сейчас: https://cnrlink.com/x5techaihackjavaguru

На выбор – один из двух треков:
1️⃣ Маскирование. Предстоит разработать алгоритм, который будет заменять чувствительные данные в датасете без потери смысла.
2️⃣ Детекция галлюцинаций. Задача конкурсантов – создать систему, которая сможет эффективно выявлять аномалии в тексте, сгенерированном нейросетью.

28-29 мая 5 лучших команд в каждом треке получат приглашение на финал в Москве. Церемония награждения пройдет на X5 Future Night.

Участвуй в X5 Tech AI Hack и внеси свой вклад в развитие ML-технологий: https://cnrlink.com/x5techaihackjavaguru

Реклама. ООО «ИТ ИКС 5 Технологии». ИНН 1615014289. erid: LjN8JtteF
Java Guru 🤓
4 мая 2024 г. 11:15
Как получить гарантированный дедлок?

Сначала поговорим о том, что это такое. Deadlock – это взаимная блокировка, ситуация, когда два или более потока «наступают друг-другу на хвост» – зависают в вечном ожидании ресурсов, захваченных друг другом.

Livelock – похожая проблема, с тем лишь отличием, что потоки не останавливаются, а вместо этого зацикливаются, выполняя одни и те же бесполезные действия, ходят по кругу.

Стандартный подход к обеспечению гарантии защиты от дедлока – установка строгого порядка взятия блокировок. Если для мониторов A и B соблюдается всеобщий порядок захвата AB (и соответственно отпускания BA), то ни с одним потоком не случится попасть на ожидание B, успешно при этом захватив A.

Из этого можно догадаться, простой способ гарантировать возможность дедлока – явно нарушить это условие.

Нарушение условия даст дедлок «скорее всего когда-нибудь». Чтобы получить его точно и с первого раза, нужно гарантировать, что оба потока окажутся на этапе между захватами одного и другого ресурса в одно время. Это можно сделать множеством способов, в примере ниже использован CyclicBarrier.