Java Guru 🤓
13.2K subscribers
898 photos
15 videos
772 links
Канал с вопросами и задачами с собеседований!

По сотрудничеству и рекламе: @NadikaKir

Канал в перечне РКН: https://vk.cc/cJrSQZ

Мы на бирже: telega.in/channels/javatasks/card?r=lcDuijdm
Download Telegram
Можно ли наследовать аннотацию?

Можно понять этот вопрос по-разному. Если имеется в виду, передается ли аннотация класса-родителя классу-наследнику, ответ – по умолчанию нет. Но наследование можно включить, если на объявлении аннотации поставить мета-аннотацию @Inherited. Это работает только для классов, переопределенные методы нужно аннотировать заново.

Другой возможный смысл вопроса – наследование самих типов-аннотаций. Аннотация, как класс или интерфейс представляется в системе ссылочным типом, она тоже компилируется в .class-файл. Вы можете создать переменную с типом, скажем, java.lang.Override.

Но в отличие от других ссылочных типов, объявление аннотации (
@interface) не может иметь секций extends или implements. Это ограничение добавлено просто чтобы не усложнять систему типов. В скомпилированном коде все типы-аннотации – это интерфейсы, унаследованные от Annotation.

Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥42
Чем CompletableFuture отличается от Future?

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

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

В Java 9 прогресс пошел дальше, и появилась библиотека Flow API. Это встроенная реализация реактивных стримов. Реактивный стрим, сильно упрощая, – это более общий случай, последовательность отложенных значений. Другая их реализация – популярная, но не входящая в стандарт библиотека
Reactive Extensions (RxJava).

Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥6
⌨️ DSL в Kotlin: от теории к практике

Приглашаем на открытый урок.

🗓 20 ноября в 19:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Kotlin Backend Developer. Professional».

Программа вебинара:


✔️ Что такое DSL и зачем он нужен в современной разработке

✔️ Основные элементы Kotlin для создания DSL: лямбды, infix-функции, расширения

✔️ Практические примеры использования DSL в Gradle, Ktor и TeamCity

Вебинар будет полезен:
Бэкенд-разработчикам на Kotlin, тимлидам и всем, кто хочет писать более чистый и поддерживаемый код.

В результате вебинара:
Научитесь создавать собственные DSL и применять их при разработке

🔗 Ссылка на регистрацию: https://vk.cc/cR9yeQ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Классы BigInteger и BigDecimal

BigInteger и BigDecimal – иммутабельные числа с заданной точностью. Эти классы – наследники Number, наряду с обертками примитивных чисел. В классах также реализованы базовые математические операции. Наибольший интерес представляет класс BigDecimal – дробное число.

Числа с плавающей точкой (float, double) хранят свои значения в памяти в экспоненциальном виде: знак-порядок-мантисса. Этот факт приводит к неочевидным с точки зрения десятичной системы округлениям при математических операциях.

BigDecimal хранит число в десятичном виде: немасштабированное значение (intVal), размерность (scale), точность (precision) и знак. Значение раскладывается на эти компоненты как intVal ÷ 10^scale. Точность – количество используемых знаков, без учета нулей в начале, но с учетом нулей в конце. Точность числа 0.0010 – 2.

Экземпляр BigDecimal можно создавать из числа с плавающей точкой, и из строки. В первом случае преобразование из экспоненциального в десятичный вид может привести к неожиданной точности, так что рекомендуется использовать строку.
У класса BigDecimal есть редкая особенность: у него не согласованы методы equals() и compareTo(). equals() сравнивает значения с точки зрения структуры объекта – компоненты точности, размерности и значения сравниваются по отдельности. Так equals на числах 0.1 и 0.10 вернет false – у них разная точность, 1 и 2. compareTo() сравнивает числа с математической точки зрения – на тех же 0.1 и 0.10 compareTo вернет 0.

Вместе с BigDecimal активно используется класс MathContext. Это точность, плюс план действий когда значение в нее не влазит – стратегия округления. MathContext можно передавать как в конструктор, так и в математические операции.

BigInteger можем рассматривать как частный случай BigDecimal. Он используется для целых чисел, больших чем Long.MAX_VALUE.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥65
Frontend VK Hub — как работают наши интерфейсы?

Что делает интерфейсы VK быстрыми, удобными и устойчивыми под нагрузкой миллионов пользователей?
Frontend VK Hub — это сообщество инженеров, которые создают и развивают пользовательские интерфейсы для ВКонтакте, VK Play, VK WorkSpace и других сервисов экосистемы. Мы делимся практическим опытом, рассказываем о подходах к производительности, внедрении современных фреймворков и всему, что связано с улучшением Developer Experience.

Здесь можно найти инсайты от ведущих фронтенд-разработчиков, разборы реальных задач, новости индустрии и приглашения на мероприятия VK. И конечно, вакансии!

Подписывайся!
2👍2🔥2🤣1
Назовите несколько примеров java.lang.Error

Как уже упоминалось ранее, исключения типа Error говорят о серьезных проблемах во время выполнения программы. Вот все ошибки стандартной библиотеки Java SE:

• AnnotationFormatError – AnnotationParser (Reflection) обнаружил дефект .class-файла аннотации;
• AssertionError – провалилась проверка утверждения (ключевое слово assert). Используется в тестах;
• CoderMalfunctionError – неисправность при кодировании/декодировании Unicode (в пакетах
java.io/java.nio);
• ServiceConfigurationError – проблема с загрузкой сервисов в ServiceLoader (Service Provider Interface);
• IOError – серьезная ошибка ввода-вывода;
• ThreadDeath – особенная ошибка: в отличие от остальных наследников Error, это – «нормальное явление», сигнал асинхронного завершения текущего потока;

• LinkageError – после перекомпиляции случилось непоправимое. Предок для 15 различных ошибок формата .class-файлов, загрузки классов, пропажи используемых членов, и прочего.

• VirtualMachineError – JVM сломалась. Абстрактный класс-предок для:
◦ StackOverflowError – переполнение стека вызовов, обычно встречается при бесконечной рекурсии;
◦ OutOfMemoryError – кончилась память, и GC уже не помогает;
◦ InternalError – внутренняя проблема JVM. Её единственный наследник ZipError не используется с Java 9;
◦ UnknownError – что-то другое.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥31
🎥 Открытый урок «Java Memory Model: как синхронизировать потоки».

🗓 20 ноября в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса
«Java Developer. Advanced».

JMM определяет, как JVM видит память: что наблюдают потоки и где нужна синхронизация — база корректного многопоточного кода.


Что будет на вебинаре:
✔️ Схематичное устройство памяти и взаимодействие с ядрами процессора.
✔️ Проблемы многопоточности: memory ordering, data race, race condition.
✔️ Правило happens-before и его практическое применение.
✔️ Какие гарантии дают synchronized и volatile.

В результате вебинара вы:
- Научитесь распознавать проблемный многопоточный код и понимать, где применять synchronized и volatile для корректной синхронизации.

Кому будет интересно:
Java-разработчикам и инженерам, работающим с многопоточностью и производительностью.

🔗 Ссылка на регистрацию: https://vk.cc/cRgKj0

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍2🔥2
Какие данные есть в исключении?

Разработчик может добавлять в исключение, как и в любой другой класс, произвольные поля и методы. Но у всех исключений есть общая часть, унаследованная от Throwable. В базовых Exception, RuntimeException и Error нет ничего кроме неё.

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

Message – сообщение ошибки. Устанавливается в конструкторе. Кроме обычного геттера есть getLocalizedMessage, который в наследниках может возвращать локализованный вариант сообщения.

Stack Trace – стек вызовов методов потока до того места, где сообщение было сконструировано (не выброшено!). JVM позволено терять часть, или даже все фреймы стека. Есть сеттер для фреймворков удаленного вызова (RPC). Сеттер можно отключить параметром конструктора writableStackTrace.

Suppressed – список исключений, которые были выброшены и подавлены, пока это исключение шло к обработчику. Сюда попадают подавленные исключения финализации ресурсов при использовании try-with-resource. Сеттер доступен и для пользовательского кода. Подавление можно отключить параметром конструктора enableSuppression.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥53
С выходом Java 25 LTS платформа снова изменилась: от синтаксиса и потоков до инструментов миграции.

На Podlodka Java Crew (17–21 ноября) обсудят, как новые фичи влияют на код, и как не потерять стабильность при обновлениях.

📌 В программе:

• как упрощённые исходники и «простые» методы меняют подход к разработке;

• где виртуальные потоки реально вредят производительности;

• что нового готовит Spring Boot 4 и как готовиться к переходу без боли;

• как автоматизировать апдейты и держать код в актуальном состоянии.

💡 Всё с реальными кейсами, метриками и инженерными решениями.

🔗Подробности и билеты: https://podlodka.io/javacrew
👍2🔥2
Какие значения возвращают мутаторы Map?

Давайте разберемся с этой путаницей раз и навсегда.

• Методы put (put, putIfAbsent) возвращают старое значение.

• Методы работы с множеством элементов (putAll, replaceAll, clear) не возвращают ничего.

• remove и replace с указанием не только ключа, но и старого значения, возвращают boolean; без указания – это самое старое значение.

• Методы с коллбэками (computeIfPresent, computeIfAbsent, compute, merge) возвращают актуальное значение после вызова, оставшееся или новое.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥32
Зачем выбирать ReentrantLock вместо synchronized?

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

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

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

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


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥6❤‍🔥3
Как используется метод Lock.newCondition()?

Если реализации интерфейса Lock представляют высокоуровневую альтернативу блока synchronized, то реализации его спутника, интерфейса Condition – альтернатива методам notify/wait. Оба этих интерфейса относятся к пакету java.util.concurrent.locks.

Как и ожидание на мониторе, Condition реализует примитив синхронизации «Условная переменная». Один или несколько потоков зависают на объекте-кондишне с помощью варианта метода await (ждут удовлетворения условия). Другой поток пробуждает их методами signal и signalAll (сигнализирует об удовлетворении условия).

Конкретные реализации Condition всегда решают те же задачи, что блокировка на мониторе, но в теории могут отличаться в нюансах поведения. Например, может не быть требования вызывать ожидание/сигнал только при захваченном локе (аналог требования, по которому notify/wait всегда вызываются в synchronized). Или может гарантироваться порядок получения сигнала ожидающими потоками.

Возвращаясь к поставленному вопросу, Condition всегда связан со своим объектом типа Lock, и метод Lock.newCondition() – единственный правильный способ создания кондишна.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥41
🏗 Курс “Software Architect” от OTUS — набор заканчивается! 🚨

Успейте занять место в группе курса «Software Architect»! Станьте экспертом в проектировании отказоустойчивых и масштабируемых систем. Пройдите вступительный тест и получите скидку, чтобы не пропустить старт обучения!

Почему стоит пойти:


- 100% практики на реальных проектах
- Проектирование гибких архитектур
- Микросервисы, интеграции, Big Data
- Современные паттерны: CQRS, Event Sourcing
- Карьерный рост: рекомендации партнёрам для лучших

Кому подойдёт:

- Разработчики, готовые к новому уровню
- Архитекторы, углубляющие экспертизу
- Тимлиды

Что освоите:

- Проектирование масштабируемых архитектур
- Оптимизация взаимодействия сервисов
- Повышение качества и устойчивости систем

📌 Пройдите тест и забронируйте место со скидкой. Не упустите шанс стать экспертом в архитектуре систем! Подробности уточняйте у менеджера

👉 Пройти тестирование https://vk.cc/cRn53d

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👍2🔥2
Чем отличается ReentrantLock от обычного Lock?

Lock – это интерфейс, ReentrantLock – его реализация. «Reentrant» говорит о том, что один и тот же поток может перезахватывать уже захваченный лок. Интерфейс не требует этого свойства. Обычный блок synchronized тоже является reentrant – вложенная синхронизация на том же мониторе отработает без проблем.

Примеры не-reentrant локов из стандартной библиотеки – представления класса StampedLock, возвращаемые его методами asReadLock() и asWriteLock().


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3
Исәнме! Встречайте новый VK JT Meetup: ML + Java!

4 декабря VK приглашает ML-инженеров и Java-разработчиков Казани на офлайн-встречу.

В программе:
— Практические доклады от экспертов VK: управление облаком One-cloud, запуск генеративного поиска в мессенджере и выкатка RAG в прод
— Два потока на выбор: нетворкинг с настольными играми или решение реальных кейсов от VK с призами

Общайтесь с экспертами, находите лучшие решения и оставайтесь на афтепати: фуршет, нетворкинг, настолки и свободное общение.

Только офлайн, в Big Twin Arena.
🎟 Участие бесплатное, регистрация на сайте.
4👍4🔥4
Как использовать ReadWriteLock?

Стандартный интерфейс ReadWriteLock предоставляет потокобезопасный разделенный доступ на чтение и на запись. Для этих целей в нём объявлены два метода: readLock() и writeLock(). Они возвращают объекты под интерфейсом Lock.

Оба типа блокировок одного экземпляра ReadWriteLock связаны. Пока какой-то поток не заберет блокировку на запись, сколько угодно потоков могут читать не мешая друг другу. Блокировкой readLock закрывается часть кода с семантикой «только чтения» некоторого условного «ресурса». В критической секции кода writeLock осуществляется модификация ресурса.

Свойства этих локов защищают программу от ситуаций конкурентной записи ресурса и чтения во время записи. Подобно copy-on-write коллекциям, этот подход становится выгодным, когда ресурс читают сильно чаще чем модифицируют.

Интерфейс реализуется классом ReentrantReadWriteLock, который во многом похож на обычный ReentrantLock.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥42👍1
This media is not supported in your browser
VIEW IN TELEGRAM
🚀 В микросервисной архитектуре всё держится на надёжных очередях задач. Без них — потери данных, дублирование событий и неожиданные сбои. А значит, пора разобраться, как это устроено в реальных продакшн-системах.

💎 На открытом уроке вы увидите, как с помощью Apache Kafka построить устойчивую систему обмена задачами между микросервисами. Развернём Kafka в Docker, создадим продюсера и консюмера, добавим сбой и проверим, как система гарантированно восстанавливает доставку.

📚 Вы поймёте, чем Kafka превосходит классические очереди (RabbitMQ, ActiveMQ), научитесь подключать её к микросервисам и отлаживать обмен задачами без потерь. После вебинара вы сможете применять эти знания в проектах любого масштаба.

Урок пройдёт 20 ноября в 18:00 (МСК) в преддверие старта курса «Apache Kafka». Зарегистрируйтесь и прокачайте архитектурное мышление! 🔗 https://vk.cc/cRsays

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
👍2🔥2
Когда используется StampedLock?

StampedLock – примитив синхронизации, добавленный в Java с версии 8. Общий принцип его работы точно такой же, как у ReadWriteLock: захват неэксклюзивной блокировки (на чтение), и эксклюзивной (на запись). Но есть у этих классов ряд различий в деталях.

Во-первых, если блокировка ReadWriteLock возвращает объекты типа Lock, то StampedLock возвращает числа типа long, которые и называется «штампами». Штамп служит идентификатором лока, он передается параметром в методы по работе с ранее захваченной блокировкой чтения или записи. Специальный штамп 0 означает неудавшийся захват.

StampedLock в отличие от ReentrantReadWriteLock – не реентрант. Это накладывает бóльшую ответственность на программиста: можно устроить дедлок на одном потоке.

В StampedLock расширена функциональность. Новые методы с префиксом try* не висят в ожидании. Методы tryOptimistic* реализуют оптимистичную блокировку. Методы tryConvert* дают возможность изменять «уровень» заблокированности: можно попытаться превратить readLock во writeLock, и наоборот.

Не смотря на похожесть, StampedLock не наследуется от ReadWriteLock. Но для совместимости в нём предусмотрены методы-адаптеры asReadWriteLock, asReadLock и asWriteLock.

Итого, блокировка на штампах решает те же задачи, что ReadWriteLock, но дает больше возможностей и лучшую производительность.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4
Неожиданное введение в Spring MVC

Spring MVC кажется сложным — пока не поймёшь, как он вырос из обычных сервлетов. На вебинаре шаг за шагом соберём свой первый фреймворк и разберёмся, зачем нужен MVC.

Приглашаем на открытый урок.
📅 Встречаемся 24 ноября в 20:00 мск.

Расскажет Александр Оруджев — Senior Software Engineer. Встречаемся на бесплатном практическом уроке от OTUS, где вы вместе с опытным экспертом разберете:
• как сервлеты превратились в контроллеры;
• что делает Spring под капотом;
• как построить собственный мини-MVC и понять принципы работы фреймворка.

После вебинара вы:
— поймёте архитектуру MVC без заучивания;
— перестанете бояться Spring MVC и начнёте использовать его осознанно;
— сделаете первый шаг к системному пониманию backend-разработки.

24 ноября в 20:00 открытый урок проходит в преддверие старта курса «Разработчик на Spring Framework». Все участники получат скидку на обучение.

👉 Регистрация бесплатная, но количество мест ограничено — успей занять своё место: https://vk.cc/cRtZCB

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
🔥32👍2
Чем отличается CountDownLatch от CyclicBarrier?

CountDownLatch, дословно «Запор с обратным отсчетом», – примитив синхронизации из стандартной библиотеки Java. Он останавливает пришедшие потоки, пока внутренний счетчик не достигнет нуля. Чтобы поставить поток на ожидание, нужно вызвать из него метод await().

Начальное значение счетчика задается параметром конструктора, затем уменьшается на 1 методом countDown(). Узнать текущее значение можно с помощью getCount(). Изменение значения счетчика никак не связано с потоками, его можно вызывать откуда и когда угодно.

CyclicBarrier – барьер для потоков, который ломается при достижении критической массы ожидающих. Это тоже класс из Java Concurrency Framework. Поток также встает на ожидание методом await(). Ожидающие потоки называются parties, их лимит также устанавливается в конструкторе.

Технически, parties барьера и count латча – одно и то же, await барьера – это await+countDown латча. В барьере тоже доступна информация о текущем состоянии барьера (методы isBroken, getParties и getNumberWaiting).

Помимо этого, CyclicBarrier дает две дополнительных возможности. Во-первых, в конструктор кроме parties можно передать коллбэк с действием, которое выполнится в момент прорыва барьера. Во-вторых, этот примитив переиспользуется: метод reset() насильно прорывает текущий барьер и устанавливает новый.

Оба этих примитива помогают решить задачу о гарантированных дедлоках. Противоположность латча и барьера – семафор. В нём потоки блокируются при достижении счетчиком нуля.


Подписывайся на наш канал в Max 🟪
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн

Но где их находить? Как узнавать о них раньше, чем когда все начнут выкладывать фотографии оттуда?

Переходите на канал IT-Мероприятия России. В нём каждый день анонсируются мероприятия со всех городов России

📆 в канале размещаются как онлайн, так и оффлайн мероприятия;
👩‍💻 можно найти ивенты по любому стеку: программирование, frontend-backend разработка, кибербезопасность, дата-аналитика, osint, devops и другие;
🎙 разнообразные форматы мероприятий: митапы с коллегами по цеху, конференции и вебинары с известными опытными специалистами, форумы и олимпиады от важных представителей индустрии и многое другое

А чтобы не искать по разным форумам и чатам новости о предстоящих ивентах:

🚀 IT-мероприятия Россииподписывайся и будь в курсе всех предстоящих мероприятий!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🔥1🥱1