💡 Редкий совет Java: используйте `ClassValue` для кэша, привязанного к классу
Обычно метаданные кэшируют так:
Map<Class<?>, Metadata> cache = new ConcurrentHashMap<>();
Но такой кэш способен удерживать классы и их
Для подобных случаев в Java есть
private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return inspect(type);
}
};
Metadata metadata = CACHE.get(User.class);
Значение вычисляется отдельно для каждого класса и может быть очищено после его выгрузки.
Редкий инструмент JVM, который часто безопаснее, чем
#Java #JVM #Backend #Performance
Обычно метаданные кэшируют так:
Map<Class<?>, Metadata> cache = new ConcurrentHashMap<>();
Но такой кэш способен удерживать классы и их
ClassLoader, создавая утечки памяти в плагинах, серверах приложений и системах с динамической загрузкой.Для подобных случаев в Java есть
ClassValue:private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return inspect(type);
}
};
Metadata metadata = CACHE.get(User.class);
Значение вычисляется отдельно для каждого класса и может быть очищено после его выгрузки.
ClassValue особенно полезен для reflection-кэшей, сериализаторов, ORM, прокси и плагинных архитектур.Редкий инструмент JVM, который часто безопаснее, чем
ConcurrentHashMap<Class<?>, ...>.#Java #JVM #Backend #Performance
👍4🔥2🥰1
💡 Java cj:
Эти два варианта выглядят похоже, но работают по-разному:
Используйте:
-
-
Так внешний код не сможет изменить внутреннюю коллекцию, а последующие изменения
#Java #JavaTips #Backend
unmodifiableList() не делает настоящую копиюЭти два варианта выглядят похоже, но работают по-разному:
List<String> source = new ArrayList<>();
source.add("Java");
List<String> view = Collections.unmodifiableList(source);
List<String> copy = List.copyOf(source);
source.add("Spring");
System.out.println(view); // [Java, Spring]
System.out.println(copy); // [Java]
Collections.unmodifiableList() создаёт только неизменяемое представление исходного списка. Если source изменится, изменения появятся и в view.List.copyOf() создаёт отдельный неизменяемый снимок данных.Используйте:
-
unmodifiableList() — когда нужен read-only view актуального списка;-
List.copyOf() — когда нужно зафиксировать состояние и безопасно вернуть его наружу.
public List<String> getUsers() {
return List.copyOf(users);
}
Так внешний код не сможет изменить внутреннюю коллекцию, а последующие изменения
users не повлияют на уже возвращённый результат.List.copyOf() доступен начиная с Java 10.#Java #JavaTips #Backend
👍3👏1
💡 Java совет: два пути могут указывать на один и тот же файл
Хотя оба пути могут вести к одному файлу.
Для проверки используйте:
- относительные пути;
- символические ссылки;
- реальное расположение файла.
Полезно при поиске дубликатов, проверке пользовательских путей и защите от повторной обработки одного файла.
Учтите: метод может обращаться к диску и выбрасывать
Доступно начиная с Java 7.
#Java #JavaTips #Files
Path.equals() сравнивает только представление пути:
Path a = Path.of("data.txt");
Path b = Path.of("./data.txt");
System.out.println(a.equals(b)); // false
Хотя оба пути могут вести к одному файлу.
Для проверки используйте:
boolean same = Files.isSameFile(a, b);
Files.isSameFile() обращается к файловой системе и учитывает:- относительные пути;
- символические ссылки;
- реальное расположение файла.
Path file = Path.of("data.txt");
Path link = Path.of("data-link.txt");
Files.isSameFile(file, link); // true, если link ведёт к data.txt
Полезно при поиске дубликатов, проверке пользовательских путей и защите от повторной обработки одного файла.
Учтите: метод может обращаться к диску и выбрасывать
IOException, поэтому это не просто строковое сравнение.Доступно начиная с Java 7.
#Java #JavaTips #Files
❤3👍2
☕️ Java-совет: не запускайте блокирующий I/O через `CompletableFuture` без собственного пула
Такой код выглядит асинхронным:
Но без явного
Если
Лучше выделить отдельный пул для блокирующего I/O:
И не забыть корректно его закрыть:
Для цепочки тоже важно явно выбирать executor:
Почему это полезно:
- медленный внешний сервис не блокирует общий пул;
- нагрузку можно ограничить размером executor;
- проще наблюдать очередь и время выполнения;
- разные типы задач не мешают друг другу.
Асинхронность без контроля executor - это просто блокировка в менее заметном месте.
Такой код выглядит асинхронным:
CompletableFuture<User> future =
CompletableFuture.supplyAsync(() -> userClient.loadUser(id));
Но без явного
Executor задача обычно попадёт в общий ForkJoinPool.commonPool().Если
loadUser() ждёт HTTP, базу данных или файловую систему, поток блокируется. Несколько медленных вызовов могут занять весь общий пул и затормозить совершенно несвязанные операции приложения.Лучше выделить отдельный пул для блокирующего I/O:
private static final ExecutorService IO_POOL =
Executors.newFixedThreadPool(32);
CompletableFuture<User> future =
CompletableFuture.supplyAsync(
() -> userClient.loadUser(id),
IO_POOL
);
И не забыть корректно его закрыть:
IO_POOL.shutdown();
Для цепочки тоже важно явно выбирать executor:
future.thenApplyAsync(
user -> enrichUser(user),
IO_POOL
);
Почему это полезно:
- медленный внешний сервис не блокирует общий пул;
- нагрузку можно ограничить размером executor;
- проще наблюдать очередь и время выполнения;
- разные типы задач не мешают друг другу.
CompletableFuture не делает блокирующий код неблокирующим. Он лишь переносит ожидание в другой поток.Асинхронность без контроля executor - это просто блокировка в менее заметном месте.
❤5👍4🔥2
⚡️ Java-приём: не храни метаданные классов в `static Map<Class<?>, ...>` — используй `ClassValue`.
Допустим, библиотека кеширует информацию о каждом классе:
На первый взгляд всё нормально.
Но в приложениях с динамической загрузкой классов — plugins, application servers, hot reload — такой кеш может удерживать
И получить неприятную утечку памяти.
В Java для этого есть малоизвестный
Использование:
Что даёт
- ленивое вычисление значения для каждого класса;
- thread-safe доступ;
- не нужен собственный
- кеш лучше согласован с жизненным циклом загруженных классов.
Особенно полезно для reflection, serializers, ORM, DI-контейнеров и framework-кода, где постоянно кешируются данные по
🔥 Если видишь в библиотеке:
стоит хотя бы задать вопрос:
а почему здесь не `ClassValue`?
#Java #JVM #Backend #Programming
Допустим, библиотека кеширует информацию о каждом классе:
private static final Map<Class<?>, Metadata> CACHE =
new ConcurrentHashMap<>();
На первый взгляд всё нормально.
Но в приложениях с динамической загрузкой классов — plugins, application servers, hot reload — такой кеш может удерживать
Class, а вместе с ним и его ClassLoader.И получить неприятную утечку памяти.
В Java для этого есть малоизвестный
ClassValue<T>:
private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return buildMetadata(type);
}
};
Использование:
Metadata metadata = CACHE.get(MyClass.class);
Что даёт
ClassValue:- ленивое вычисление значения для каждого класса;
- thread-safe доступ;
- не нужен собственный
ConcurrentHashMap;- кеш лучше согласован с жизненным циклом загруженных классов.
Особенно полезно для reflection, serializers, ORM, DI-контейнеров и framework-кода, где постоянно кешируются данные по
Class<?>.🔥 Если видишь в библиотеке:
static ConcurrentHashMap<Class<?>, ...>
стоит хотя бы задать вопрос:
а почему здесь не `ClassValue`?
#Java #JVM #Backend #Programming
❤3👍2
Полезный Java-совет:
Не вызывай parallelStream() просто потому, что данных много.
Для коротких операций он легко оказывается медленнее обычного stream(), потому что платишь за разбиение задачи, синхронизацию и работу ForkJoinPool.
Особенно неприятно то, что по умолчанию parallelStream() использует общий ForkJoinPool.commonPool(). Если приложение уже нагружает его другими задачами, производительность может внезапно просесть вообще в другом месте.
Если параллелизм реально нужен, лучше контролировать executor явно, а не прятать его внутри parallelStream().
Не вызывай parallelStream() просто потому, что данных много.
Для коротких операций он легко оказывается медленнее обычного stream(), потому что платишь за разбиение задачи, синхронизацию и работу ForkJoinPool.
Особенно неприятно то, что по умолчанию parallelStream() использует общий ForkJoinPool.commonPool(). Если приложение уже нагружает его другими задачами, производительность может внезапно просесть вообще в другом месте.
Если параллелизм реально нужен, лучше контролировать executor явно, а не прятать его внутри parallelStream().
❤5👍4
Java-ловушка: почему `parallelStream()` может замедлить приложение
Многие думают:
«Есть
Но не всегда.
Если внутри идут HTTP-запросы, SQL или ожидание внешнего сервиса, можно получить обратный эффект:
забить общий пул потоков
увеличить задержки
замедлить другие части приложения
parallelStream() хорошо подходит для:
✅ сложных CPU-вычислений
✅ обработки больших коллекций
✅ математических операций
Но плохо подходит для:
❌ HTTP
❌ базы данных
❌ файлового I/O
❌ ожидания внешних сервисов
Для таких задач лучше использовать отдельный пул:
и контролировать количество параллельных операций.
Главное правило:
parallelStream() — для вычислений.
ExecutorService — для бизнес-логики и внешних вызовов.
Код может идеально работать на тестах, но в production внезапно получить проблемы из-за одного parallelStream().
Многие думают:
«Есть
stream(), добавлю parallelStream() — станет быстрее».Но не всегда.
parallelStream() использует общий ForkJoinPool Java:
users.parallelStream()
.map(this::callExternalApi)
.toList();
Если внутри идут HTTP-запросы, SQL или ожидание внешнего сервиса, можно получить обратный эффект:
забить общий пул потоков
увеличить задержки
замедлить другие части приложения
parallelStream() хорошо подходит для:
✅ сложных CPU-вычислений
✅ обработки больших коллекций
✅ математических операций
Но плохо подходит для:
❌ HTTP
❌ базы данных
❌ файлового I/O
❌ ожидания внешних сервисов
Для таких задач лучше использовать отдельный пул:
ExecutorService executor =
Executors.newFixedThreadPool(20);
и контролировать количество параллельных операций.
Главное правило:
parallelStream() — для вычислений.
ExecutorService — для бизнес-логики и внешних вызовов.
Код может идеально работать на тестах, но в production внезапно получить проблемы из-за одного parallelStream().
❤2👍1
🔥 Java:
Кажется, что:
оставит только 10 элементов.
Но subList() обычно создаёт представление исходного списка, а не независимую копию. Пока жив small, исходный ArrayList и его внутренний массив тоже могут оставаться в памяти.
Если нужна отдельная маленькая коллекция:
Особенно неприятный баг в кэшах и долгоживущих объектах: сохраняешь 10 элементов — а в памяти остаются сотни тысяч.
subList() может неожиданно удерживать огромный список в памятиКажется, что:
List<Item> small = hugeList.subList(0, 10);
hugeList = null;
оставит только 10 элементов.
Но subList() обычно создаёт представление исходного списка, а не независимую копию. Пока жив small, исходный ArrayList и его внутренний массив тоже могут оставаться в памяти.
Если нужна отдельная маленькая коллекция:
List<Item> small = new ArrayList<>(hugeList.subList(0, 10));
Особенно неприятный баг в кэшах и долгоживущих объектах: сохраняешь 10 элементов — а в памяти остаются сотни тысяч.
🤔6❤2👍2
Обычно контейнер объясняют так:
> контейнер = обычный Linux-процесс + namespaces + cgroups
Для первого знакомства этого хватает. Но OCI Runtime Spec определяет контейнер шире: это изолированная среда для запуска процессов, а не сам процесс.
И Linux-механизмы, только один из вариантов реализации.
OCI охватывает не только Linux, но и:
- Windows
- FreeBSD
- Solaris
- z/OS
- VM-based containers
То есть контейнер не обязан быть «процессом в Linux». Важнее то, что среда соответствует контейнерной модели: изоляция, файловая система, ресурсы, lifecycle и правила запуска.
Хороший разбор того, что контейнер представляет собой на самом деле:
https://labs.iximiuz.com/tutorials/oci-containers-explained
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3
Autobase
Это инструмент, разработанный для автоматизации развёртывания и управления PostgreSQL-кластерами с использованием Ansible. Он поддерживает широкий набор функций, включая настройку репликации, автоматизацию резервного копирования с помощью инструментов, таких как pgBackRest и WAL-G, мониторинг состояния кластеров, а также настройку высокодоступной инфраструктуры (HA).
Проект упрощает настройку PostgreSQL и снижает вероятность ошибок, обеспечивая удобные плейбуки для типичных задач. Его можно использовать как для новых установок, так и для работы с существующими конфигурациями.
https://github.com/autobase-tech/autobase
Это инструмент, разработанный для автоматизации развёртывания и управления PostgreSQL-кластерами с использованием Ansible. Он поддерживает широкий набор функций, включая настройку репликации, автоматизацию резервного копирования с помощью инструментов, таких как pgBackRest и WAL-G, мониторинг состояния кластеров, а также настройку высокодоступной инфраструктуры (HA).
Проект упрощает настройку PostgreSQL и снижает вероятность ошибок, обеспечивая удобные плейбуки для типичных задач. Его можно использовать как для новых установок, так и для работы с существующими конфигурациями.
https://github.com/autobase-tech/autobase
👍2❤1🤯1
Apache Kafka 4.x - продвинутый бесплатный практический курс 2026 года
https://github.com/justxor/KAFKAFREECOURSR/tree/main
https://github.com/justxor/KAFKAFREECOURSR/tree/main
❤4👍2
☕️ Java получил практический MCP-сервер для медицинского AI-триажа
На JavaOne показали систему, где жалоба пациента превращается в тикет, а AI определяет его срочность. Теперь Oracle подробно разобрала MCP-сервер, который принимает текст и возвращает оценку от 0 до 10.
Сервер построен на Helidon и публикует один инструмент через
Доступны два режима:
* локальный MiniLM через DJL - 384-мерные эмбеддинги, без API и сети;
* OpenAI
Финальную оценку в обоих случаях вычисляет локальная нейросеть DeepNetts.
Важный нюанс: для каждого типа эмбеддингов нужна отдельно обученная модель оценки. Нельзя взять модель, обученную на векторах MiniLM, и передать ей векторы OpenAI, даже если привести их к одинаковому размеру.
MCP-интерфейс при этом остаётся неизменным:
Локальный режим подходит для разработки и интеграционных тестов, внешний - для проверки качества на более мощной модели.
https://inside.java/2026/07/25/design-java-mcp-tool/
На JavaOne показали систему, где жалоба пациента превращается в тикет, а AI определяет его срочность. Теперь Oracle подробно разобрала MCP-сервер, который принимает текст и возвращает оценку от 0 до 10.
Сервер построен на Helidon и публикует один инструмент через
@Mcp.Tool. Клиенту не нужно знать, какая модель работает внутри.Доступны два режима:
* локальный MiniLM через DJL - 384-мерные эмбеддинги, без API и сети;
* OpenAI
text-embedding-3-small - 1536-мерные эмбеддинги.Финальную оценку в обоих случаях вычисляет локальная нейросеть DeepNetts.
Важный нюанс: для каждого типа эмбеддингов нужна отдельно обученная модель оценки. Нельзя взять модель, обученную на векторах MiniLM, и передать ей векторы OpenAI, даже если привести их к одинаковому размеру.
MCP-интерфейс при этом остаётся неизменным:
жалоба → эмбеддинг → DeepNetts → срочность 0–10
Локальный режим подходит для разработки и интеграционных тестов, внешний - для проверки качества на более мощной модели.
https://inside.java/2026/07/25/design-java-mcp-tool/
Inside.java
Pairing In-Process and Hosted Embeddings for Java MCP Tool Development - Inside.java
Discover why a Java MCP tool can benefit from both in-process and hosted embeddings: in-process embeddings keep development, testing, and conformance fast and reliable, while external provider-backed embeddings offer production-quality semantic scoring behind…
❤3👍1
☕ Java: в HashSet всего 10 элементов, а обход всё равно тормозит
Редкий нюанс: время обхода
После добавления элементов внутри выделена огромная таблица. Итератор проходит по её ячейкам, включая пустые, хотя
Сложность обхода - O(size + capacity). Поэтому большая ёмкость «про запас» может замедлить регулярный перебор.
Если коллекция уже сильно разрослась, а затем почти опустела, можно пересобрать её:
Новый набор подберёт ёмкость под оставшиеся элементы. Пересборка требует времени и дополнительной памяти, поэтому имеет смысл перед многократными обходами, а не внутри каждого цикла.
Документация - https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/HashSet.html
Редкий нюанс: время обхода
HashSet зависит от количества элементов и размера внутренней таблицы.
var ids = new HashSet<Integer>(1_000_000);
for (int i = 0; i < 10; i++) {
ids.add(i);
}
for (int id : ids) {
process(id);
}
После добавления элементов внутри выделена огромная таблица. Итератор проходит по её ячейкам, включая пустые, хотя
size() возвращает всего 10.Сложность обхода - O(size + capacity). Поэтому большая ёмкость «про запас» может замедлить регулярный перебор.
Если коллекция уже сильно разрослась, а затем почти опустела, можно пересобрать её:
ids = new HashSet<>(ids);
Новый набор подберёт ёмкость под оставшиеся элементы. Пересборка требует времени и дополнительной памяти, поэтому имеет смысл перед многократными обходами, а не внутри каждого цикла.
Документация - https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/HashSet.html
🔥5👍1
https://uproger.com/java-v-2026-godu-25-luchshih-prakticheskih-primerov-koda-ot-osnov-do-mnogopotochnosti/
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Apache Kafka курс 2026: бесплатный курс по Kafka с нуля до профи на русском
Kafka обучение без воды: каждый модуль состоит из понятной теории, схем, команд, которые можно запустить у себя, типичных ошибок и вопросов для самопроверки. Курс подходит, чтобы выучить Kafka с нуля, подготовиться к собеседованию на backend, data engineer или DevOps-позицию и спроектировать надёжную систему на Kafka в продакшене.
https://github.com/justxor/KAFKAFREECOURSR
Kafka обучение без воды: каждый модуль состоит из понятной теории, схем, команд, которые можно запустить у себя, типичных ошибок и вопросов для самопроверки. Курс подходит, чтобы выучить Kafka с нуля, подготовиться к собеседованию на backend, data engineer или DevOps-позицию и спроектировать надёжную систему на Kafka в продакшене.
https://github.com/justxor/KAFKAFREECOURSR
❤9👍3🔥1
💡 Предпочитайте делегирование наследованию
Связь
Но есть цена.
✅ Подкласс получает весь API родителя.
✅ Он зависит от деталей реализации суперкласса.
✅ Изменение родительского класса может неожиданно сломать потомка.
И чем глубже иерархия, тем сложнее понять, откуда вообще взялось конкретное поведение.
Часто безопаснее композиция:
Вместо наследования:
Композиция связывает объекты. Наследование связывает их судьбы.
Если объекту просто нужна чужая функциональность, чаще лучше её делегировать, а не наследовать.
Связь
is-a выглядит удобно: создаём подкласс, наследуем поведение и пишем меньше кода.Но есть цена.
✅ Подкласс получает весь API родителя.
✅ Он зависит от деталей реализации суперкласса.
✅ Изменение родительского класса может неожиданно сломать потомка.
И чем глубже иерархия, тем сложнее понять, откуда вообще взялось конкретное поведение.
Часто безопаснее композиция:
class OrderService {
private final PaymentService paymentService;
}
Вместо наследования:
class OrderService extends PaymentService {
}
Композиция связывает объекты. Наследование связывает их судьбы.
Если объекту просто нужна чужая функциональность, чаще лучше её делегировать, а не наследовать.
👍7❤2
Forwarded from Java
🧠 Spring AI показал, как сделать RAG заметно умнее обычного vector search.
Проблема классического RAG: похожий документ ещё не значит полезный.
Новый пайплайн делает так:
Jev проверяет каждый найденный chunk: есть ли там реальный ответ, противоречие или prompt injection.
В демо vector search нашёл 6 фрагментов, но до модели дошли только 2 действительно полезных.
Меньше мусора в контексте → точнее ответы и меньше шансов на prompt injection.
Код и разбор:
https://spring.io/blog/2026/10/02/spring-ai-modular-rag-typesafe-jev/
Проблема классического RAG: похожий документ ещё не значит полезный.
Новый пайплайн делает так:
Question → Rewrite → MultiQuery → Vector Search → Jev Filter → Rerank → LLMJev проверяет каждый найденный chunk: есть ли там реальный ответ, противоречие или prompt injection.
В демо vector search нашёл 6 фрагментов, но до модели дошли только 2 действительно полезных.
Меньше мусора в контексте → точнее ответы и меньше шансов на prompt injection.
Код и разбор:
https://spring.io/blog/2026/10/02/spring-ai-modular-rag-typesafe-jev/
❤1
💡 Одинаковый ввод? Не вычисляйте результат заново.
Сохраняйте результаты затратных вычислений в кэше:
✅ Используйте входные данные как ключ в
✅ Если кэш общий для нескольких потоков, выбирайте
✅
Нюанс: если функция вернула
Сам по себе
Сохраняйте результаты затратных вычислений в кэше:
✅ Используйте входные данные как ключ в
Map.✅ Если кэш общий для нескольких потоков, выбирайте
ConcurrentHashMap.✅
computeIfAbsent() вычислит и сохранит значение, если ключа ещё нет. Следующие вызовы вернут готовый результат.Нюанс: если функция вернула
null или выбросила исключение, результат не сохранится и вычисление может повториться.Сам по себе
ConcurrentHashMap не ограничивает размер кэша и не удаляет устаревшие записи.❤1👍1
🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку
Окружение решает больше, чем кажется.
Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.
AI: t.iss.one/ai_machinelearning_big_data
Python: t.iss.one/pythonl
Linux: t.iss.one/linuxacademiya
Хакинг: t.iss.one/linuxkalii
DevOps: t.iss.one/DevOPSitsec
Docker: https://t.iss.one/+90Z5TAyfuNU5YmRi
Golang: t.iss.one/Golang_google
Rust: t.iss.one/rust_code
C++: t.iss.one/cpluspluc
C#: t.iss.one/csharp_ci
Java: t.iss.one/javatg
JavaScript: t.iss.one/javascriptv
React: t.iss.one/react_tg
Frontend: t.iss.one/front
PHP: t.iss.one/phpshka
Android: t.iss.one/android_its
Мобильная разработка: t.iss.one/mobdevelop
Базы данных: t.iss.one/sqlhub
Data Science: t.iss.one/data_analysis_ml
Big Data: t.iss.one/bigdatai
Математика: t.iss.one/data_math
Физика: t.iss.one/fizmat
Kubernetes: t.iss.one/kubernetc
GameDev: https://t.iss.one/gamedev
Haskell: t.iss.one/haskell_tg
Собеседования и карьера:
DS собеседования: t.iss.one/machinelearning_interview
Python собеседования: t.iss.one/python_job_interview
Папка с вакансиями: t.iss.one/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.iss.one/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.iss.one/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.iss.one/addlist/2Ls-snqEeytkMDgy
Папка Frontend: https://t.iss.one/addlist/mzMMG3RPZhY2M2Iy
Полезное сверху:
ИТ-мемы: t.iss.one/memes_prog
Английский для программистов: t.iss.one/english_forprogrammers
ИИ и технологии: t.iss.one/vistehno
954 ГБ open-source курсов: https://t.iss.one/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: https://t.iss.one/addlist/BkskQciUW_FhNjEy
Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg
Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.
Окружение решает больше, чем кажется.
Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.
AI: t.iss.one/ai_machinelearning_big_data
Python: t.iss.one/pythonl
Linux: t.iss.one/linuxacademiya
Хакинг: t.iss.one/linuxkalii
DevOps: t.iss.one/DevOPSitsec
Docker: https://t.iss.one/+90Z5TAyfuNU5YmRi
Golang: t.iss.one/Golang_google
Rust: t.iss.one/rust_code
C++: t.iss.one/cpluspluc
C#: t.iss.one/csharp_ci
Java: t.iss.one/javatg
JavaScript: t.iss.one/javascriptv
React: t.iss.one/react_tg
Frontend: t.iss.one/front
PHP: t.iss.one/phpshka
Android: t.iss.one/android_its
Мобильная разработка: t.iss.one/mobdevelop
Базы данных: t.iss.one/sqlhub
Data Science: t.iss.one/data_analysis_ml
Big Data: t.iss.one/bigdatai
Математика: t.iss.one/data_math
Физика: t.iss.one/fizmat
Kubernetes: t.iss.one/kubernetc
GameDev: https://t.iss.one/gamedev
Haskell: t.iss.one/haskell_tg
Собеседования и карьера:
DS собеседования: t.iss.one/machinelearning_interview
Python собеседования: t.iss.one/python_job_interview
Папка с вакансиями: t.iss.one/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.iss.one/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.iss.one/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.iss.one/addlist/2Ls-snqEeytkMDgy
Папка Frontend: https://t.iss.one/addlist/mzMMG3RPZhY2M2Iy
Полезное сверху:
ИТ-мемы: t.iss.one/memes_prog
Английский для программистов: t.iss.one/english_forprogrammers
ИИ и технологии: t.iss.one/vistehno
954 ГБ open-source курсов: https://t.iss.one/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: https://t.iss.one/addlist/BkskQciUW_FhNjEy
Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg
Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.
💡 Миллион потоков в Java? С virtual threads это реально
Виртуальные потоки, ставшие стабильной возможностью в Java 21, позволяют обслуживать множество задач, которые большую часть времени ждут ответа от сети или базы данных.
Каждому такому потоку не нужен отдельный поток ОС. При многих блокирующих I/O-операциях JVM освобождает системный поток для другой работы, пока виртуальный ждёт.
Код остаётся привычным и последовательным, без обязательного перехода на цепочки колбэков.
Особенно полезно для множества одновременных HTTP-запросов и обращений к БД. Но тяжёлые вычисления быстрее не станут: виртуальные потоки помогают увеличить число обслуживаемых задач, а не скорость процессора.
И да: миллион потоков не означает миллион соединений с БД. Пулы соединений и ограничения нагрузки по-прежнему нужны.
Виртуальные потоки, ставшие стабильной возможностью в Java 21, позволяют обслуживать множество задач, которые большую часть времени ждут ответа от сети или базы данных.
Каждому такому потоку не нужен отдельный поток ОС. При многих блокирующих I/O-операциях JVM освобождает системный поток для другой работы, пока виртуальный ждёт.
Код остаётся привычным и последовательным, без обязательного перехода на цепочки колбэков.
Особенно полезно для множества одновременных HTTP-запросов и обращений к БД. Но тяжёлые вычисления быстрее не станут: виртуальные потоки помогают увеличить число обслуживаемых задач, а не скорость процессора.
И да: миллион потоков не означает миллион соединений с БД. Пулы соединений и ограничения нагрузки по-прежнему нужны.
❤4👍2