Connection Pool, Thread Pool и Object Pool: в чём разница?
Общая идея одна: повторно использовать дорогие ресурсы вместо постоянного создания новых. Но каждый пул управляет своим типом ресурсов.
• Connection Pool — пул соединений. Хранит соединения, например с базой данных. Приложение берёт свободное соединение, выполняет запросы и возвращает его в пул.
• Thread Pool — пул потоков. Повторно использует рабочие потоки для выполнения задач. Не нужно создавать отдельный поток под каждую новую задачу.
• Object Pool — пул объектов. Позволяет брать готовые объекты, использовать их, сбрасывать состояние и возвращать для следующего вызова.
Пример: Spring Boot с обычной блокирующей обработкой запросов. Рабочий поток обрабатывает HTTP-запрос и выполняет бизнес-логику. Когда требуется доступ к БД, приложение получает соединение из пула.
После завершения работы с БД соединение возвращается в пул. После обработки запроса рабочий поток освобождается для следующей задачи. Это два отдельных ресурса с разным временем использования.
А стоит ли переиспользовать обычные Java-объекты? Не всегда. JVM эффективно выделяет память под короткоживущие объекты и собирает их сборщиком мусора. Пул имеет смысл прежде всего для объектов с дорогим созданием или ресурсов с ограниченным количеством.
Больше ресурсов не означает быстрее:
• Слишком много соединений может перегрузить базу.
• Слишком много платформенных потоков увеличивает расход памяти и затраты на переключение контекста.
• Неудачный пул объектов удерживает память и создаёт конкуренцию за доступ.
Поэтому важен не только сам пул, но и его размер. Переиспользование полезно, когда оно действительно дешевле повторного создания.
👉 Java Portal
Общая идея одна: повторно использовать дорогие ресурсы вместо постоянного создания новых. Но каждый пул управляет своим типом ресурсов.
• Connection Pool — пул соединений. Хранит соединения, например с базой данных. Приложение берёт свободное соединение, выполняет запросы и возвращает его в пул.
• Thread Pool — пул потоков. Повторно использует рабочие потоки для выполнения задач. Не нужно создавать отдельный поток под каждую новую задачу.
• Object Pool — пул объектов. Позволяет брать готовые объекты, использовать их, сбрасывать состояние и возвращать для следующего вызова.
Пример: Spring Boot с обычной блокирующей обработкой запросов. Рабочий поток обрабатывает HTTP-запрос и выполняет бизнес-логику. Когда требуется доступ к БД, приложение получает соединение из пула.
После завершения работы с БД соединение возвращается в пул. После обработки запроса рабочий поток освобождается для следующей задачи. Это два отдельных ресурса с разным временем использования.
А стоит ли переиспользовать обычные Java-объекты? Не всегда. JVM эффективно выделяет память под короткоживущие объекты и собирает их сборщиком мусора. Пул имеет смысл прежде всего для объектов с дорогим созданием или ресурсов с ограниченным количеством.
Больше ресурсов не означает быстрее:
• Слишком много соединений может перегрузить базу.
• Слишком много платформенных потоков увеличивает расход памяти и затраты на переключение контекста.
• Неудачный пул объектов удерживает память и создаёт конкуренцию за доступ.
Поэтому важен не только сам пул, но и его размер. Переиспользование полезно, когда оно действительно дешевле повторного создания.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
ForkJoinPool, ExecutorService и Virtual Threads: что выбирать в Java?
Всё зависит от нагрузки: задачи в основном вычисляют или ждут ответа базы и внешних сервисов? При этом сравниваются разные уровни: ExecutorService — интерфейс управления задачами, ForkJoinPool — одна из его реализаций, а виртуальные потоки — тип потоков. Их можно использовать вместе.
ForkJoinPool — для параллельных вычислений. Хорошо подходит для задач, которые можно разбить на независимые части: рекурсивных алгоритмов, обработки массивов и других CPU-intensive вычислений.
Использует work-stealing: свободный рабочий поток забирает задачи из очередей других потоков. Но не любая тяжёлая операция требует ForkJoinPool. Для независимых вычислительных задач может быть достаточно обычного фиксированного пула.
ExecutorService — для запуска и управления задачами. Позволяет отправлять задачи на выполнение, получать результаты через
Здесь одновременно работают не более 10 потоков. Однако очередь задач у такого исполнителя не ограничена: при постоянной перегрузке она может расти. Для выполнения по расписанию используется
Virtual Threads — для большого количества ожидающих задач. Виртуальные потоки стали стандартной возможностью в Java 21. Они особенно полезны, когда задачи много времени проводят в блокирующих вызовах к БД или HTTP-сервисам. Их тоже можно использовать через
Каждая задача получает отдельный виртуальный поток. Создавать пул для переиспользования виртуальных потоков не нужно.
Что важно в продакшене:
• Виртуальные потоки не добавляют процессорных ядер и сами по себе не ускоряют вычисления.
• Тысячи виртуальных потоков не означают, что база выдержит тысячи одновременных запросов. Нужны отдельные ограничения, например пул соединений или
• Ограничение числа рабочих потоков не равно ограничению очереди задач.
ForkJoinPool помогает распараллеливать вычисления. ExecutorService управляет выполнением задач. Virtual Threads позволяют эффективно организовать множество задач, ожидающих I/O.
👉 Java Portal
Всё зависит от нагрузки: задачи в основном вычисляют или ждут ответа базы и внешних сервисов? При этом сравниваются разные уровни: ExecutorService — интерфейс управления задачами, ForkJoinPool — одна из его реализаций, а виртуальные потоки — тип потоков. Их можно использовать вместе.
ForkJoinPool — для параллельных вычислений. Хорошо подходит для задач, которые можно разбить на независимые части: рекурсивных алгоритмов, обработки массивов и других CPU-intensive вычислений.
Использует work-stealing: свободный рабочий поток забирает задачи из очередей других потоков. Но не любая тяжёлая операция требует ForkJoinPool. Для независимых вычислительных задач может быть достаточно обычного фиксированного пула.
ExecutorService — для запуска и управления задачами. Позволяет отправлять задачи на выполнение, получать результаты через
Future и управлять завершением исполнителя. Конкретная реализация определяет, как выполняются задачи.ExecutorService executor =
Executors.newFixedThreadPool(10);
Здесь одновременно работают не более 10 потоков. Однако очередь задач у такого исполнителя не ограничена: при постоянной перегрузке она может расти. Для выполнения по расписанию используется
ScheduledExecutorService.Virtual Threads — для большого количества ожидающих задач. Виртуальные потоки стали стандартной возможностью в Java 21. Они особенно полезны, когда задачи много времени проводят в блокирующих вызовах к БД или HTTP-сервисам. Их тоже можно использовать через
ExecutorService:try (var executor =
Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> callExternalApi());
}
Каждая задача получает отдельный виртуальный поток. Создавать пул для переиспользования виртуальных потоков не нужно.
Что важно в продакшене:
• Виртуальные потоки не добавляют процессорных ядер и сами по себе не ускоряют вычисления.
• Тысячи виртуальных потоков не означают, что база выдержит тысячи одновременных запросов. Нужны отдельные ограничения, например пул соединений или
Semaphore.• Ограничение числа рабочих потоков не равно ограничению очереди задач.
ForkJoinPool помогает распараллеливать вычисления. ExecutorService управляет выполнением задач. Virtual Threads позволяют эффективно организовать множество задач, ожидающих I/O.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Откуда в Spring Boot берётся веб-сервер?
Запускаете приложение:
И оно начинает принимать HTTP-запросы. Без отдельной установки Tomcat и развёртывания WAR-файла.
Секрет — во встроенном сервере. Для обычного Spring MVC-приложения зависимость веб-стартера по умолчанию подтягивает Tomcat. Его библиотеки входят в исполняемый JAR, а Spring Boot автоматически настраивает и запускает сервер вместе с приложением.
Это упрощает запуск и развёртывание: приложение и сервер поставляются как единое целое, с согласованными версиями и настройками. Такой JAR удобно запускать локально, на сервере или в контейнере.
Embedded не означает, что сервера нет. Он работает внутри процесса вашего Java-приложения. Tomcat — не единственный вариант: например, приложения на Spring WebFlux по умолчанию используют Reactor Netty.
👉 Java Portal
Запускаете приложение:
java -jar app.jar
И оно начинает принимать HTTP-запросы. Без отдельной установки Tomcat и развёртывания WAR-файла.
Секрет — во встроенном сервере. Для обычного Spring MVC-приложения зависимость веб-стартера по умолчанию подтягивает Tomcat. Его библиотеки входят в исполняемый JAR, а Spring Boot автоматически настраивает и запускает сервер вместе с приложением.
Это упрощает запуск и развёртывание: приложение и сервер поставляются как единое целое, с согласованными версиями и настройками. Такой JAR удобно запускать локально, на сервере или в контейнере.
Embedded не означает, что сервера нет. Он работает внутри процесса вашего Java-приложения. Tomcat — не единственный вариант: например, приложения на Spring WebFlux по умолчанию используют Reactor Netty.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3
Как менялись языки программирования
Каждое поколение языков помогало решать новые задачи: от управления железом до разработки веб-приложений и распределённых систем.
История по десятилетиям появления:
• 1940-е: машинный код и первые ассемблеры.
• 1950-е: FORTRAN, Lisp, COBOL.
• 1960-е: BASIC.
• 1970-е: C, Pascal.
• 1980-е: C++, Objective-C.
• 1990-е: Python, Ruby, Java, JavaScript, PHP.
• 2000-е: C#, Scala, Go.
• 2010-е: Rust, Kotlin, Swift.
2020-е — распространение разработки с AI-помощниками. Это уже изменение способа работы с кодом, а не отдельное поколение языков.
Новые инструменты не делают старые языки ненужными. C остаётся важным для операционных систем, Java — для корпоративных приложений, JavaScript — для веба, Python — для анализа данных и машинного обучения.
А на каком языке вы написали свой первый Hello, World?
👉 Java Portal
Каждое поколение языков помогало решать новые задачи: от управления железом до разработки веб-приложений и распределённых систем.
История по десятилетиям появления:
• 1940-е: машинный код и первые ассемблеры.
• 1950-е: FORTRAN, Lisp, COBOL.
• 1960-е: BASIC.
• 1970-е: C, Pascal.
• 1980-е: C++, Objective-C.
• 1990-е: Python, Ruby, Java, JavaScript, PHP.
• 2000-е: C#, Scala, Go.
• 2010-е: Rust, Kotlin, Swift.
2020-е — распространение разработки с AI-помощниками. Это уже изменение способа работы с кодом, а не отдельное поколение языков.
Новые инструменты не делают старые языки ненужными. C остаётся важным для операционных систем, Java — для корпоративных приложений, JavaScript — для веба, Python — для анализа данных и машинного обучения.
А на каком языке вы написали свой первый Hello, World?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣5
Как HashMap устроен внутри
• Вычисляет хеш ключа.
• Определяет индекс корзины во внутреннем массиве.
• Сохраняет запись в узле с хешем, ключом и значением.
• При коллизиях использует связный список, а начиная с Java 8 при определённых условиях преобразует его в красно-чёрное дерево.
Если такой ключ уже существует,
👉 Java Portal
• Вычисляет хеш ключа.
• Определяет индекс корзины во внутреннем массиве.
• Сохраняет запись в узле с хешем, ключом и значением.
• При коллизиях использует связный список, а начиная с Java 8 при определённых условиях преобразует его в красно-чёрное дерево.
Если такой ключ уже существует,
put() заменяет его значение.Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Java, Spring Boot, React, микросервисы… А чем веб-сервер отличается от сервера приложений?
У кандидата в резюме несколько full-stack проектов и внушительный стек. Но простой вопрос на собеседовании поставил его в тупик.
• Веб-сервер принимает HTTP-запросы, отдаёт статические файлы и может перенаправлять запросы приложению как reverse proxy. Примеры: Nginx, Apache HTTP Server.
• Сервер приложений предоставляет среду для выполнения приложения и его бизнес-логики. В экосистеме Java примеры — WildFly и Payara.
При этом граница не строгая: сервер приложений может сам принимать HTTP-запросы. Например, Spring Boot со встроенным Tomcat способен обслуживать их без отдельного Nginx, хотя Tomcat точнее называть контейнером сервлетов.
Собрать проект из десяти технологий полезно. Понимать, за что отвечает каждая, — не менее важно.
👉 Java Portal
У кандидата в резюме несколько full-stack проектов и внушительный стек. Но простой вопрос на собеседовании поставил его в тупик.
• Веб-сервер принимает HTTP-запросы, отдаёт статические файлы и может перенаправлять запросы приложению как reverse proxy. Примеры: Nginx, Apache HTTP Server.
• Сервер приложений предоставляет среду для выполнения приложения и его бизнес-логики. В экосистеме Java примеры — WildFly и Payara.
При этом граница не строгая: сервер приложений может сам принимать HTTP-запросы. Например, Spring Boot со встроенным Tomcat способен обслуживать их без отдельного Nginx, хотя Tomcat точнее называть контейнером сервлетов.
Собрать проект из десяти технологий полезно. Понимать, за что отвечает каждая, — не менее важно.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1