Java Guru 🤓

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

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

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

Статистика

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

Java Guru 🤓
18 мая 2024 г. 8:03
Зачем выбирать ReentrantLock вместо synchronized?

Объект класса ReentrantLock решает те же задачи, что и блок synchronized. Поток висит на вызове метода lock() в ожидании своей очереди занять этот объект. Владеть локом, как и находиться внутри блока synchronized может только один поток одновременно. unlock(), подобно выходу из блока синхронизации, освобождает объект-монитор для других потоков.

В отличие от блока синхронизации, ReentrantLock дает расширенный интерфейс для получения информации о состоянии блокировки. Методы лока позволяют еще до блокировки узнать, занят ли он сейчас, сколько потоков ждут его в очереди, сколько раз подряд текущий поток завладел им.

Шире и возможные режимы блокировки. Кроме обычного ожидающего lock(), вариант tryLock() с параметром ожидает своей очереди только заданное время, а без параметра – вообще не ждет, а только захватывает свободный лок.

Еще одно отличие – свойство fair. Лок с этим свойством обеспечивает «справедливость» очереди: пришедший раньше поток захватывает объект раньше. Блок synchronized не дает никаких гарантий порядка.
Java Guru 🤓
17 мая 2024 г. 15:45
Стать бэкендером в Яндексе за выходные

8–9 июня устраиваем Weekend Offer Backend: всего за 2 дня можно пройти технические секции и попасть в Яндекс. Для этого нужно зарегистрироваться и решить несколько задач в Контесте.

Вы сможете выбрать одну из команд: Crowd, Ecom-сценарии, Поиск, Алиса, Автономные автомобили и Большие данные. Можно пообщаться с нанимающими менеджерами и выбрать самый интересный проект. Если всё пройдёт хорошо, сразу же получите офер.

Нанимаем в офисы России и Республики Беларусь.

Узнать подробности и зарегистрироваться можно здесь.
Java Guru 🤓
17 мая 2024 г. 14:20
Чем CompletableFuture отличается от Future?

Future – интерфейс, который представляет пока еще недовычисленный результат. Когда породившая его асинхронная операция заканчивается, он заполняется значением. Метод get блокирует выполнение до получения результата, isDone проверяет его наличие. К примеру результат выполнения задач в ExecutorService, ForkJoinTask, реализует интерфейс Future.

CompletableFuture появился в Java 8. Это класс-реализация старого интерфейса Future, а значит всё сказанное выше справедливо и для него. Вдобавок к этому, CompletableFuture реализует работу с отложенными результатами посредством коллбэков. Метод thenApply регистрирует код обработки значения, который будет автоматически вызван позже, когда это значение появится.

В Java 9 прогресс пошел дальше, и появилась библиотека Flow API. Это встроенная реализация реактивных стримов. Реактивный стрим, сильно упрощая, – это более общий случай, последовательность отложенных значений. Другая их реализация – популярная, но не входящая в стандарт библиотека
Reactive Extensions (RxJava).
Java Guru 🤓
17 мая 2024 г. 11:02
Москва, приглашаем 25 мая на One Day Offer для Java-разработчиков 😉

Сбер ищет опытных Java-разработчиков для создания нового продукта класса ERP для учёта и планирования хозяйственной деятельности, расчёта заработной платы. Проект полного цикла от подготовки требований до внедрения и сопровождения.

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

В работе мы используем:

✔️ Java 17, Spring Framework
✔️ Микросервисную архитектуру
✔️ Service Mesh, Kafka
✔️ WildFly, PostgreSQL, приложения с открытым исходным кодом
✔️ Сервисы Jenkins, Ansible, Git/BitBucket, Nexus, Jira, Confluence

Что будем делать?

✔️ Участвовать в полном цикле разработки компонентов и сервисов с нуля.
✔️ Проектировать и разрабатывать backend, API.
✔️ Внедрять масштабный продукт класса ERP для учёта и планирования хозяйственной деятельности.
✔️ Разрабатывать коммерческую версию ИТ-продуктов.
✔️ Оптимизировать производительность продуктов и сервисов.

Приглашаем в команду Java-разработчика для создания нового конкурентного продукта на современном технологическом стеке Platform V!

Регистрируйтесь по ссылке 👈
Java Guru 🤓
16 мая 2024 г. 19:31
Как работают параллельные стримы?

Основная цель, ради которой в Java 8 был добавлен Stream API – удобство многопоточной обработки.

Обычный стрим будет выполняться параллельно после вызова промежуточной операции parallel(). Некоторые стримы создаются уже многопоточными, например результат вызова Collection#parallelStream(). Для распараллеливания используется единый общий ForkJoinPool.

Внутри реализации потока его сплиттератор оборачивается в AbstractTask, который и отправляется на выполнение в пул. AbstractTask при выполнении считывает estimateSize сплиттератора и текущую степень параллелизма пула. На основе этих данных он принимает решение, распараллелить ли сплиттератор на два методом trySplit().

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

Если всё же требуется использовать отдельный пул потоков, сам стрим выполняется как задача этого отдельного пула.
Java Guru 🤓
16 мая 2024 г. 13:01
📘 С чего начать изучение Apache Kafka?

Apache KafkaApache Kafka — многогранный и непростой инструмент. Даже если вы уверены, что знаете его, наш курс докажет вам обратное!

💻 Начните работу с Kafka на открытом практическом уроке от OTUS, где вы:

— разберете особенности и устройство Kafka;
— познакомитесь с основными утилитами;
— рассмотрите базовое API для работы с Kafka.

Спикер — опытный разработчик и преподаватель.

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

👉 Регистрируйтесь прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cwQEYNhttps://vk.cc/cwQEYN

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ruwww.otus.ru
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. Этот класс «наследует» значение – изначально берет его для потока, являющегося родителем текущего.