С помощью картинок и коротких видео даже новички начнут применять продвинутые инструменты разработки и использовать Docker.
Стоит подписаться: www.tg-me.com/DevopsDocker
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🤬3🔥2🥰1😁1
☕ Java: задача
Что выведет программа, пишите в комментариях?
A) YesNo
B) YESNO
C) Ошибка компиляции
D) null
✅ Правильный ответ:A
➡️ Вызов и однозначно указывает на метод , оба возвращают строки.
Результат: . Метод не используется.
@javatg
public class Mystery {
public static void main(String[] args) {
System.out.println(method(true) + method(false));
}
static String method(boolean flag) {
return flag ? "Yes" : "No";
}
static String method(String val) {
return val.toUpperCase();
}
}
Что выведет программа, пишите в комментариях?
A) YesNo
B) YESNO
C) Ошибка компиляции
D) null
✅ Правильный ответ:
➡️ Вызов
method(true)method(false)method(boolean)Результат:
"YesNo"method(String)@javatg
👍28❤3🔥2😁2🤯1
📊 Kotlin DataFrame — библиотека для типизированной обработки данных от JetBrains, вдохновленная Pandas.
Проект позволяет загружать данные из CSV/JSON/SQL, фильтровать и агрегировать их через цепочки вызовов в Kotlin-стиле. Интересно, что инструмент поддержи очень быструю генерацию type-safe API: при работе в Jupyter Notebook или с Gradle-плагином система автоматически создаёт extension-свойства для колонок.
🤖 Github
@javatg
Проект позволяет загружать данные из CSV/JSON/SQL, фильтровать и агрегировать их через цепочки вызовов в Kotlin-стиле. Интересно, что инструмент поддержи очень быструю генерацию type-safe API: при работе в Jupyter Notebook или с Gradle-плагином система автоматически создаёт extension-свойства для колонок.
🤖 Github
@javatg
👍8🔥3🎉1
❓ Что выведет этот код на Java?
🔢 Варианты ответа:
A)
B)
C)
D)
✅ Правильный ответ:B
💡 Почему?
- Строки в Java — immutable и используют string pool.
- → , потому что конкатенируется на этапе компиляции.
- — создаёт новый объект во время выполнения.
- → , но → , потому что сравнивает содержимое строк.
@javatg
public class Main {
public static void main(String[] args) {
String a = "hello";
String b = "he" + "llo";
String c = "he";
String d = c + "llo";
System.out.println(a == b); // #1
System.out.println(a == d); // #2
System.out.println(a.equals(d)); // #3
}
}
🔢 Варианты ответа:
A)
true
true
B)
false
true
C)
false
true
D)
false
false
✅ Правильный ответ:
💡 Почему?
- Строки в Java — immutable и используют string pool.
-
a == btrue"he" + "llo"-
c + "llo"-
a == dfalsea.equals(d)true.equals()@javatg
👍32❤8🔥3
🔐 Bouncy Castle — криптографическая библиотека для Java с открытым кодом. Это решение поддерживает широкий спектр алгоритмов — от базовых шифровальных схем до сложных протоколов вроде S/MIME и OpenPGP.
Проект имеет модульную структуру с разделением на core, JCE-провайдер и специализированные модули для работы с сертификатами X.509 и TLS. Библиотека совместима даже с устаревшими версиями Java, включая J2ME, а сборка теперь поддерживает JDK 21.
🤖 GitHub
@javatg
Проект имеет модульную структуру с разделением на core, JCE-провайдер и специализированные модули для работы с сертификатами X.509 и TLS. Библиотека совместима даже с устаревшими версиями Java, включая J2ME, а сборка теперь поддерживает JDK 21.
🤖 GitHub
@javatg
👍6🔥4❤3
Это высокопроизводительный распределённый движок SQL для анализа больших объёмов данных в реальном времени. Основные характеристики:
Распределённая архитектура
Состоит из координатора и множества воркеров, которые параллельно выполняют фрагменты запросов, обеспечивая низкую задержку даже при обработке петабайтовых данных
GitHub
Поддержка ANSI SQL и UDF
Полноценная поддержка стандартного SQL с возможностью расширения набором пользовательских функций (UDF), агрегатов и аналитических функций.
Плагинные коннекторы
Из коробки доступны коннекторы к Hive (HDFS/S3), Cassandra, Kafka, MongoDB, MySQL, PostgreSQL, Elasticsearch и многим другим системам хранения. При желании можно написать собственный плагин
GitHub
.
Масштабируемость и отказоустойчивость
Горизонтальное масштабирование за счёт добавления воркеров, автоматическое перераспределение задач при выходе узлов из строя.
Удобство развёртывания
Можно собрать из исходников через Maven (./mvnw clean install), развернуть через Docker (официальный образ есть в папке docker/), или сразу использовать готовые пакеты на prestodb.io.
Клиенты и интеграции
Имеется CLI (presto-cli), JDBC/ODBC‑драйверы, REST API. Лёгко встраивается в BI‑инструменты и платформы визуализации.
Сферы применения
Ad‑hoc‑аналитика, интерактивные дашборды, federated query (объединение данных из разных источников), подготовка данных для машинного обучения.
https://github.com/prestodb/presto
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤2👍2
🧪 Зачем Java-разработчику тестировать логику в SQL?
Привет! Сегодня покажу вам полезный трюк для тех, кто пишет сложные запросы в PostgreSQL (или любом другом SQL-движке) и хочет их тестировать ещё до интеграции в Java-приложение.
Если у тебя в проекте сложная логика в
🔹 Создаём функцию в PostgreSQL:
🔹 Проверяем прямо в базе:
✅ Это удобно, когда:
- Ты хочешь протестировать ветки логики без запуска всего приложения;
- У тебя CI/CD запускает SQL-тесты отдельно (через
- Ты хочешь быстро показать запрос аналитику или тимлиду без Java-контекста.
💡 Лайфхак: если ты используешь Liquibase/Flyway — можно держать такие функции прямо в changelog'ах как test-only objects, не влияя на runtime-приложение.
Попробуй — экономит массу времени на ревью и отладке запросов!
@javatg
Привет! Сегодня покажу вам полезный трюк для тех, кто пишет сложные запросы в PostgreSQL (или любом другом SQL-движке) и хочет их тестировать ещё до интеграции в Java-приложение.
Если у тебя в проекте сложная логика в
JOIN, CASE, оконных функциях или CTE — протестируй это на стороне базы, как обычную функцию.🔹 Создаём функцию в PostgreSQL:
CREATE OR REPLACE FUNCTION test_discount(user_id INT)
RETURNS NUMERIC AS $$
BEGIN
RETURN (
SELECT
CASE
WHEN u.vip = true THEN 0.2
ELSE 0.05
END
FROM users u WHERE u.id = user_id
);
END;
$$ LANGUAGE plpgsql;
🔹 Проверяем прямо в базе:
SELECT test_discount(101); -- вернёт 0.2 или 0.05
✅ Это удобно, когда:
- Ты хочешь протестировать ветки логики без запуска всего приложения;
- У тебя CI/CD запускает SQL-тесты отдельно (через
pgTAP, например);- Ты хочешь быстро показать запрос аналитику или тимлиду без Java-контекста.
💡 Лайфхак: если ты используешь Liquibase/Flyway — можно держать такие функции прямо в changelog'ах как test-only objects, не влияя на runtime-приложение.
Попробуй — экономит массу времени на ревью и отладке запросов!
@javatg
👍12❤4🔥4🥰3
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4
⚡️ xManager — проект позиционируется как легковесная альтернатива с открытым исходным кодом, где нет рекламы и трекеров.
Приложение изначально разрабатывалось в Sketchware Pro для Android, а затем конвертировалось в Android Studio-совместимый формат. Несмотря на некоторые технические ограничения такого подхода, xManager предлагает базовый функционал: установку разных версий, очистку кеша и быстрый доступ к настройкам.
Сейчас проект поддерживается международной командой волонтеров, включая переводчиков на 30+ языков. Разработчики подчеркивают, что xManager полностью бесплатен, а вознаграждения за рекламу идут лишь на поддержку инфраструктуры.
🤖 GitHub
@javatg
Приложение изначально разрабатывалось в Sketchware Pro для Android, а затем конвертировалось в Android Studio-совместимый формат. Несмотря на некоторые технические ограничения такого подхода, xManager предлагает базовый функционал: установку разных версий, очистку кеша и быстрый доступ к настройкам.
Сейчас проект поддерживается международной командой волонтеров, включая переводчиков на 30+ языков. Разработчики подчеркивают, что xManager полностью бесплатен, а вознаграждения за рекламу идут лишь на поддержку инфраструктуры.
🤖 GitHub
@javatg
🔥3❤2👍2🥰1
⚡️Легкий способ получать свежие обновления и следить за трендами в разработке на вашем языке. Находите свой стек и подписывайтесь:
Python: www.tg-me.com/pythonl
Linux: www.tg-me.com/linuxacademiya
Собеседования DS: www.tg-me.com/machinelearning_interview
Нерйросети www.tg-me.com/ai_machinelearning_big_data
C++ www.tg-me.com/cpluspluc
Docker: www.tg-me.com/DevopsDocker
Хакинг: www.tg-me.com/linuxkalii
Devops: www.tg-me.com/DevOPSitsec
Data Science: www.tg-me.com/data_analysis_ml
Javascript: www.tg-me.com/javascriptv
C#: www.tg-me.com/csharp_ci
Java: www.tg-me.com/javatg
Базы данных: www.tg-me.com/sqlhub
Python собеседования: www.tg-me.com/python_job_interview
Мобильная разработка: www.tg-me.com/mobdevelop
Golang: www.tg-me.com/Golang_google
React: www.tg-me.com/react_tg
Rust: www.tg-me.com/rust_code
ИИ: www.tg-me.com/vistehno
PHP: www.tg-me.com/phpshka
Android: www.tg-me.com/android_its
Frontend: www.tg-me.com/front
Big Data: www.tg-me.com/bigdatai
МАТЕМАТИКА: www.tg-me.com/data_math
Kubernets: www.tg-me.com/kubernetc
Разработка игр: https://www.tg-me.com/gamedev
Haskell: www.tg-me.com/haskell_tg
Физика: www.tg-me.com/fizmat
💼 Папка с вакансиями: www.tg-me.com/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: www.tg-me.com/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: www.tg-me.com/addlist/eEPya-HF6mkxMGIy
Папка ML: https://www.tg-me.com/addlist/2Ls-snqEeytkMDgy
Папка FRONTEND: https://www.tg-me.com/addlist/mzMMG3RPZhY2M2Iy
😆ИТ-Мемы: www.tg-me.com/memes_prog
🇬🇧Английский: www.tg-me.com/english_forprogrammers
🧠ИИ: www.tg-me.com/vistehno
🎓954ГБ ОПЕНСОРС КУРСОВ: @courses
📕Ит-книги бесплатно: https://www.tg-me.com/addlist/BkskQciUW_FhNjEy
Python: www.tg-me.com/pythonl
Linux: www.tg-me.com/linuxacademiya
Собеседования DS: www.tg-me.com/machinelearning_interview
Нерйросети www.tg-me.com/ai_machinelearning_big_data
C++ www.tg-me.com/cpluspluc
Docker: www.tg-me.com/DevopsDocker
Хакинг: www.tg-me.com/linuxkalii
Devops: www.tg-me.com/DevOPSitsec
Data Science: www.tg-me.com/data_analysis_ml
Javascript: www.tg-me.com/javascriptv
C#: www.tg-me.com/csharp_ci
Java: www.tg-me.com/javatg
Базы данных: www.tg-me.com/sqlhub
Python собеседования: www.tg-me.com/python_job_interview
Мобильная разработка: www.tg-me.com/mobdevelop
Golang: www.tg-me.com/Golang_google
React: www.tg-me.com/react_tg
Rust: www.tg-me.com/rust_code
ИИ: www.tg-me.com/vistehno
PHP: www.tg-me.com/phpshka
Android: www.tg-me.com/android_its
Frontend: www.tg-me.com/front
Big Data: www.tg-me.com/bigdatai
МАТЕМАТИКА: www.tg-me.com/data_math
Kubernets: www.tg-me.com/kubernetc
Разработка игр: https://www.tg-me.com/gamedev
Haskell: www.tg-me.com/haskell_tg
Физика: www.tg-me.com/fizmat
💼 Папка с вакансиями: www.tg-me.com/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: www.tg-me.com/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: www.tg-me.com/addlist/eEPya-HF6mkxMGIy
Папка ML: https://www.tg-me.com/addlist/2Ls-snqEeytkMDgy
Папка FRONTEND: https://www.tg-me.com/addlist/mzMMG3RPZhY2M2Iy
😆ИТ-Мемы: www.tg-me.com/memes_prog
🇬🇧Английский: www.tg-me.com/english_forprogrammers
🧠ИИ: www.tg-me.com/vistehno
🎓954ГБ ОПЕНСОРС КУРСОВ: @courses
📕Ит-книги бесплатно: https://www.tg-me.com/addlist/BkskQciUW_FhNjEy
👍1🔥1
## Условие задачи:
Вам нужно спроектировать и реализовать на Java следующую систему:
1. Система подключается к непрерывному потоку событий (`EventStream`).
2. Каждое событие (`Event`) имеет структуру:
class Event {
String entityId;
Instant timestamp;
String eventType;
Map<String, Object> payload;
}
3. В реальном времени нужно собирать и поддерживать текущее состояние каждой сущности (`Entity`), применяя полученные события.
4. Система должна поддерживать откат состояния:
- Пользователь может запросить состояние любой сущности на любую произвольную временную точку (`Instant timestamp`).
- После отката система должна продолжать обрабатывать новые события без остановки и потери данных.
## Дополнительные требования:
- Потокобезопасность обработки событий и запросов на откат.
- Высокая производительность: обработка миллионов событий в минуту.
- Быстрый откат состояния (target: **< 100 мс**).
- Только стандартные библиотеки Java (`java.util.concurrent`,
java.time, коллекции и т.д.).- Архитектура должна позволять добавлять новые типы событий без модификации существующего кода.
## Бонус:
- Реализация механизма снимков (`snapshot`) состояний для оптимизации откатов.
- Автоматическое создание snapshot'ов каждые N событий для каждой сущности.
- Поддержка нескольких стратегий отката (например, быстрый откат по ближайшему snapshot + события, или чистая перемотка всех событий).
---
📌 Что оценивается:
Архитектура: Четкая декомпозиция слоёв, масштабируемость и возможность расширения системы без существенных изменений базового кода.
Работа с многопоточностью: Гарантия безопасности доступа к общим структурам данных в условиях параллельной обработки событий.
Производительность: Минимизация блокировок, эффективная работа с большими объёмами данных, оптимизация по времени отклика и использованию ресурсов.
Чистота кода: Понятные и логичные интерфейсы, чистая реализация без "грязных хака", хорошая читаемость и поддерживаемость кода.
Способность предвидеть риски: Умение анализировать потенциальные угрозы системе, например, рост очередей при перегрузке событий или замедление обработки данных.
Стратегии оптимизации: Эффективное использование snapshot'ов состояния, продуманная организация хранения и восстановления событий.
Обработка ошибок и отказоустойчивость: Умение проектировать систему так, чтобы она корректно вела себя при сбоях, сетевых ошибках и высоких нагрузках.
---
# Подводные камни:
- Проблема гонки состояний: если одновременно приходит событие и запрашивается откат — что происходит?
- Рост памяти: если хранить все события, как не "убить" память?
- Перепутанные таймстемпы: что делать, если события приходят с задержкой или не по порядку?
- Обновление типов событий: как легко добавить новый
eventType без переписывания всей логики?- Производительность при откате: как не делать полный перебор событий за годы работы?
---
# Рекомендация к решению:
- Используйте copy-on-write подход для состояний сущностей.
- Используйте параллельные структуры данных (`ConcurrentHashMap`,
ConcurrentSkipListMap и т.д.).- Реализуйте инкапсуляцию логики обработки событий через паттерн "Event Handler" или "Command Handler".
- Внедрите отдельный менеджер snapshot'ов и менеджер событий.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥8❤5🤬1
Есть фича. Есть дедлайн. Есть понимание, что тесты надо писать… но они отъедают время, которого итак впритык.
Один наш знакомый девелопер сказал: «С тех пор как поставил Explyt Test — начал писать меньше тестов… но покрытие стало лучше. Как это вообще возможно?!»
Попробуйте сами. Плагин сам предлагает тесты для вашего кода — прямо в IDE.
👉 explyt.ai — сэкономь себе пару часов уже сегодня.
Один наш знакомый девелопер сказал: «С тех пор как поставил Explyt Test — начал писать меньше тестов… но покрытие стало лучше. Как это вообще возможно?!»
Попробуйте сами. Плагин сам предлагает тесты для вашего кода — прямо в IDE.
👉 explyt.ai — сэкономь себе пару часов уже сегодня.
❤6👍1🔥1
☕️ TeaVM — компилятор Java в JavaScript и WebAssembly. Необычный инструмент, который превращает байт-код Java в компактный и эффективный JavaScript-код.
В отличие от GWT, TeaVM не требует исходников и работает прямо с .class-файлами, предлагая свою реализацию стандартной библиотеки Java. Инструмент также позволяет переносить бизнес-логику с бэкенда на фронтенд без полного переписывания. Поддерживает даже многопоточность через Web Workers.
🤖 GitHub
@java_tg
В отличие от GWT, TeaVM не требует исходников и работает прямо с .class-файлами, предлагая свою реализацию стандартной библиотеки Java. Инструмент также позволяет переносить бизнес-логику с бэкенда на фронтенд без полного переписывания. Поддерживает даже многопоточность через Web Workers.
🤖 GitHub
@java_tg
👍5🔥4❤3
💡 Базовые команды Linux, которые должен знать каждый! 🐧
📁 Работа с файлами и директориями:
📂 Просмотр и редактирование файлов:
🔐 Свойства файлов:
📝 Манипуляции с текстом:
👥 Управление пользователями и группами:
🖥 Мониторинг и управление системой:
🌐 Сетевые команды:
🔥 Сохрани себе, чтобы не забыть и делись с друзьями!
@javatg
📁 Работа с файлами и директориями:
ls — просмотр содержимого папки
cp — копирование файлов/папок
mv — перемещение или переименование
cd — переход между папками
mkdir — создание директории
rm — удаление файлов/папок
📂 Просмотр и редактирование файлов:
cat — вывод содержимого файла
less — постраничный просмотр
head — первые строки файла
tail — последние строки
more — аналог less
nano — простой текстовый редактор
vim — мощный редактор в терминале
🔐 Свойства файлов:
file — тип файла
touch — создать пустой файл или обновить дату
chmod — изменение прав доступа
chgrp — смена группы
wc — подсчёт строк, слов, символов
du — объём занимаемого дискового пространства
📝 Манипуляции с текстом:
grep — поиск по шаблону
cut/paste — извлечение/вставка колонок
tr — замена символов
sort — сортировка
tee — вывод в файл и на экран
expand — замена табуляции пробелами
👥 Управление пользователями и группами:
useradd — добавление пользователя
usermod — изменение пользователя
userdel — удаление пользователя
groupadd — добавление группы
groupdel — удаление группы
groupmod — изменение группы
chgrp — смена группы файла
🖥 Мониторинг и управление системой:
df — свободное место на дисках
uname — информация о системе
free — использование оперативной памяти
shutdown — выключение/перезагрузка
lsof — открытые файлы
rsync — синхронизация данных
ps — активные процессы
🌐 Сетевые команды:
dig/nslookup — DNS-запросы
ping — проверка доступности
curl — запрос к URL
scp — копирование по SSH
ifconfig — настройки сети
traceroute — путь до хоста
🔥 Сохрани себе, чтобы не забыть и делись с друзьями!
@javatg
🔥17👍8❤4
Столкнулись с падением производительности базы данных?
Не делайте резких движений: вы можете ухудшить ситуацию.
Сначала нужно верно диагностировать причину проблемы.
Возможно вы неправильно выбрали индексы, а быть может дело вообще в самой архитектуре БД – вариантов масса!
На открытом вебинаре «Как ускорить работу и повысить надёжность PostgreSQL»
вы узнаете:
🎯как обеспечить высокую производительность и отказоустойчивость базы данных
🎯как вовремя выявить деградацию производительности с помощью диагностики
Вебинар проведёт Дмитрий Золотов, Kotlin-разработчик в «Яндексе».
Приглашаем технических руководителей, админов БД, девопсов и разработчиков.
Все участники получат в подарок видеоурок «Безопасность в PostgreSQL: защита данных, управление доступом и аудит» и скидку 7% на любой курс OTUS.
6 мая, 19:00 МСК
Бесплатно
Записаться - https://otus.pw/RBkj/
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963. erid: 2W5zFG5y1f6
Не делайте резких движений: вы можете ухудшить ситуацию.
Сначала нужно верно диагностировать причину проблемы.
Возможно вы неправильно выбрали индексы, а быть может дело вообще в самой архитектуре БД – вариантов масса!
На открытом вебинаре «Как ускорить работу и повысить надёжность PostgreSQL»
вы узнаете:
🎯как обеспечить высокую производительность и отказоустойчивость базы данных
🎯как вовремя выявить деградацию производительности с помощью диагностики
Вебинар проведёт Дмитрий Золотов, Kotlin-разработчик в «Яндексе».
Приглашаем технических руководителей, админов БД, девопсов и разработчиков.
Все участники получат в подарок видеоурок «Безопасность в PostgreSQL: защита данных, управление доступом и аудит» и скидку 7% на любой курс OTUS.
6 мая, 19:00 МСК
Бесплатно
Записаться - https://otus.pw/RBkj/
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963. erid: 2W5zFG5y1f6
👍2🤯1
🧪 Pocket Science Lab — карманная лаборатория для экспериментов. Это компактное устройство с открытым исходным кодом, превращающее смартфон или ПК в полноценную лабораторию для физических и инженерных экспериментов.
Проект предлагает приложение с впечатляющим функционалом: осциллограф, генератор сигналов, люксметр, датчики давления и даже управление сервоприводами для робототехники. Интересно реализована работа с реальными данными, например, можно анализировать звуковые волны через микрофон или строить графики на основе показаний акселерометра.
🤖 GitHub
@javatg
Проект предлагает приложение с впечатляющим функционалом: осциллограф, генератор сигналов, люксметр, датчики давления и даже управление сервоприводами для робототехники. Интересно реализована работа с реальными данными, например, можно анализировать звуковые волны через микрофон или строить графики на основе показаний акселерометра.
🤖 GitHub
@javatg
👍7❤3🔥3
🦉 Apache ZooKeeper — координация распределенных систем без лишней сложности
В эпоху Kubernetes и сервис-мешей скромный ZooKeeper продолжает оставаться фундаментальным инструментом для управления конфигурацией и синхронизации распределенных систем. Последние версии проекта (3.5.5+) сохраняют минималистичный подход — чистые Java-бинарники, документация в Markdown и прозрачный процесс сборки через Maven.
Несмотря на появление альтернатив вроде etcd, ZooKeeper по-прежнему широко используется в Hadoop-экосистеме и как бэкенд для Apache Kafka.
🤖 GitHub
@javatg
В эпоху Kubernetes и сервис-мешей скромный ZooKeeper продолжает оставаться фундаментальным инструментом для управления конфигурацией и синхронизации распределенных систем. Последние версии проекта (3.5.5+) сохраняют минималистичный подход — чистые Java-бинарники, документация в Markdown и прозрачный процесс сборки через Maven.
Несмотря на появление альтернатив вроде etcd, ZooKeeper по-прежнему широко используется в Hadoop-экосистеме и как бэкенд для Apache Kafka.
🤖 GitHub
@javatg
👍5❤3🔥3
🧩 Задача «Три счётчика» (с подвохом)
Условие
Дан класс
Нужно запустить три параллельных потока, каждый увеличивает счётчик ровно 1 000 000 раз.
В финале программа должна вывести
Допустимы любые потоки (обычные или виртуальные) и любая коллекция из стандартной библиотеки Java 19+.
Тип поля менять нельзя — только
⚡️ В чем здесь подвох?
Операция value++ не атомарна: «прочитать → увеличить → записать».
Без привычных примитивов придётся найти альтернативный путь синхронизации.
💡 Решение через message queue (Actor‑подход)
Создаём очередь команд BlockingQueue<Runnable>.
Поднимаем один служебный поток servo, который единственный обращается к Counter.value.
Три рабочих потока кладут в очередь лямбду counter::increment.
```java
import java.util.concurrent.*;
final class Counter {
int value;
void increment() { value++; }
}
public class ThreeCountersDemo {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
BlockingQueue<Runnable> q = new LinkedBlockingQueue<>();
// 1️⃣ Сервисный поток: изменяет value
Thread servo = Thread.startVirtualThread(() -> {
try { while (true) q.take().run(); }
catch (InterruptedException ignored) {}
});
// 2️⃣ Три рабочих потока — по миллиону инкрементов
Runnable worker = () -> {
for (int i = 0; i < 1_000_000; i++)
q.add(counter::increment);
};
Thread.ofVirtual().start(worker);
Thread.ofVirtual().start(worker);
Thread.ofVirtual().start(worker);
// 3️⃣ Ждём опустошения очереди и выключаем сервис
while (!q.isEmpty()) Thread.sleep(10);
servo.interrupt();
servo.join();
System.out.println("Counter value = " + counter.value);
}
}```
✅ Почему это работает
- Value модифицирует только поток servo.
- Очереди java.util.concurrent не были запрещены.
- Параллельность: виртуальные потоки лёгкие (~2 КБ стек), можно масштабировать.
@javatg
Условие
Дан класс
Counter с полем int value и методом increment().Нужно запустить три параллельных потока, каждый увеличивает счётчик ровно 1 000 000 раз.
В финале программа должна вывести
Counter value = 3000000
Нельзя использовать synchronized, ReentrantLock, Atomic*, LongAdder, VarHandle.
Допустимы любые потоки (обычные или виртуальные) и любая коллекция из стандартной библиотеки Java 19+.
Тип поля менять нельзя — только
int.⚡️ В чем здесь подвох?
Операция value++ не атомарна: «прочитать → увеличить → записать».
Без привычных примитивов придётся найти альтернативный путь синхронизации.
💡 Решение
Создаём очередь команд BlockingQueue<Runnable>.
Поднимаем один служебный поток servo, который единственный обращается к Counter.value.
Три рабочих потока кладут в очередь лямбду counter::increment.
```java
import java.util.concurrent.*;
final class Counter {
int value;
void increment() { value++; }
}
public class ThreeCountersDemo {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
BlockingQueue<Runnable> q = new LinkedBlockingQueue<>();
// 1️⃣ Сервисный поток: изменяет value
Thread servo = Thread.startVirtualThread(() -> {
try { while (true) q.take().run(); }
catch (InterruptedException ignored) {}
});
// 2️⃣ Три рабочих потока — по миллиону инкрементов
Runnable worker = () -> {
for (int i = 0; i < 1_000_000; i++)
q.add(counter::increment);
};
Thread.ofVirtual().start(worker);
Thread.ofVirtual().start(worker);
Thread.ofVirtual().start(worker);
// 3️⃣ Ждём опустошения очереди и выключаем сервис
while (!q.isEmpty()) Thread.sleep(10);
servo.interrupt();
servo.join();
System.out.println("Counter value = " + counter.value);
}
}```
✅ Почему это работает
- Value модифицирует только поток servo.
- Очереди java.util.concurrent не были запрещены.
- Параллельность: виртуальные потоки лёгкие (~2 КБ стек), можно масштабировать.
@javatg
👍15🤯6❤4🔥4
