Java | Фишки и трюки
Ir al canal en Telegram
Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg
Mostrar más6 819
Suscriptores
Sin datos24 horas
-127 días
-6130 días
Archivo de publicaciones
6 819
Решать технические задачи — самая простая часть работы в IT.
Сложности начинаются там, где нужно договариваться со смежниками, выстраивать процессы в хаосе и осознанно управлять карьерой.
В канале @ulshinblog Никита (руководитель разработки в Highload, 10+ лет в IT) разбирает эти темы через понятную логику и личный опыт:
📍 Как пройти секцию System Design? Пошаговый чек-лист от интервьюера;
📍 Как находить внутренние сайд-проекты, которые принесут пользу и бизнесу, и вашему карьерному росту;
📍 Защита от плохой обратной связи: как вежливо поставить на место коллегу с неконструктивным фидбеком;
📍 Инженерный конвейер самообучения: как перестать читать книги для галочки и внедрять знания в жизнь и карьеру;
📚 База 50+ авторских обзоров IT-литературы для сильного инженера: разработка, управление, архитектура, мышление.
👉 Присоединяйтесь
6 819
Java-приложение в Docker
В современном мире разработки программного обеспечения Docker становится важным инструментом, помогающим разрабатывать, тестировать и развертывать приложения в изолированной среде. Использование Docker с Java-приложениями позволяет значительно упростить процесс развертывания, гарантируя, что ваше приложение будет работать одинаково на всех средах.
Docker — это платформа для создания, развертывания и управления контейнерами. Контейнеры изолируют приложения и все их зависимости, что делает возможным запуск кода в любом окружении без конфликта с другими приложениями.
Шаг 1: Установка Docker
Перед тем как начать, убедитесь, что Docker установлен на вашем компьютере. Вы можете следовать [официальной документации](https://docs.docker.com/get-docker/) для установки на вашу операционную систему.
Шаг 2: Создание Java-приложения
Для примера создадим простое приложение. Предположим, у вас есть простая программа, которая выводит "Hello, World!".
Создайте файл
HelloWorld.java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Скомпилируйте её с помощью:
javac HelloWorld.java
Шаг 3: Создание Dockerfile
Dockerfile — это текстовый файл, позволяющий автоматически собирать образ Docker. Создайте файл с именем Dockerfile в каталоге вашего проекта:
# Используем официальный образ OpenJDK
FROM openjdk:17-jdk-slim
# Устанавливаем рабочий каталог
WORKDIR /app
# Копируем скомпилированный класс в контейнер
COPY HelloWorld.class ./
# Определяем команду запуска
CMD ["java", "HelloWorld"]
Шаг 4: Сборка Docker-образа
Теперь создайте Docker-образ, используя следующую команду в каталоге вашего проекта:
docker build -t helloworld .
Эта команда соберет образ и назовет его helloworld.
Шаг 5: Запуск контейнера
Чтобы запустить контейнер, выполните команду:
docker run --rm helloworld
Вы должны увидеть вывод:
Hello, World!Флаг
--rm автоматически удаляет контейнер после его остановки.
#java #docker6 819
🔴 Завтра тестовое собеседование с Java-разработчиком
10 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Виктору
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
6 819
☕️Text Blocks в Java: читаемые строки без \n и слёз
До Java 13 работа с многострочными строками была болью. JSON? HTML? SQL? Только через
"\n" + и кучу экранирования.
Но с Text Blocks всё стало проще, понятнее и читаемо.
Сравни:
❌ До:
String html = "<html>\n" +
" <body>Hello</body>\n" +
"</html>";
✅ После (Text Block):
String html = """
<html>
<body>Hello</body>
</html>
""";
➡️ Стало чище, короче и как в оригинале. Это обычная String, просто оформленная красиво.
✔️ Преимущества Text Blocks:
1. 👍 Читаемость на уровне "как есть"
Код больше не превращается в кашу. Особенно полезно для:
SQL-запросов:
String query = """
SELECT id, name
FROM users
WHERE active = true
ORDER BY created_at DESC
""";
HTML/JSON шаблонов:
String json = """
{
"name": "Alice",
"role": "admin"
}
""";
2. 👍 Меньше экранирования
Забудь про \", \\n, \\t — теперь можно писать почти как в блокноте.
3. 👍 Автоматическое выравнивание
Java сама уберёт начальные отступы на основе самой "узкой" строки.
Пример:
String msg = """
Line 1
Line 2
Line 3
""";
➡️ Результат будет:
Line 1 Line 2 Line 34. 👍 Интеграция с
.formatted()
Нельзя вставить переменные прямо в Text Block?
Используем .formatted() — коротко и читабельно:
String user = "Bob";
String template = """
{
"user": "%s",
"access": "granted"
}
""".formatted(user);
````
```java
String s = """
Hello""";
System.out.println(s.length()); // 6, а не 5 (есть \n)
3. 🟢 Нет интерполяции переменных
Нельзя писать так:
String name = "Eve";
String wrong = """
Hello, $name!
"""; // ❌ не сработает
Вместо этого:
String right = """
Hello, %s!
""".formatted(name);
🗣️ Запомни: Text Blocks делают строки в Java человечными. Это не просто сахар — это инструмент, чтобы твой код говорил с тобой на одном языке. Используй их для всего, что требует форматирования — и забудь про + "\n".6 819
⌨️ Java Concurrency API: Основные классы
Современные приложения все чаще требуют выполнения нескольких задач одновременно, и для этого Java предоставляет мощный инструмент — Concurrency API (набор классов и интерфейсов). Этот API позволяет разработчикам легко реализовывать многопоточность, управлять потоками и синхронизировать действия между ними, что значительно увеличивает производительность и отзывчивость приложений.
Основные классы:
1. Thread
- Класс для создания и управления потоками. Вы можете создать новый поток, реализовав интерфейс
Runnable или расширив класс Thread.
2. Executor
- Интерфейс для управления потоками и выполнения задач. Позволяет абстрагироваться от управления потоками, сосредоточившись на логике приложения.
- ExecutorService: расширение Executor, управляющее жизненным циклом потоков.
3. Future
- Позволяет получать результаты из асинхронных задач. Используется в связке с ExecutorService для выполнения задач в фоновом режиме.
4. CountDownLatch
- Синхронизирует потоки, позволяя одному или нескольким потокам ждать завершения других потоков перед продолжением работы.
5. CyclicBarrier
- Используется для синхронизации группы потоков. Позволяет потоку ждать, пока все другие не достигнут определенной точки.
6. Semaphore
- Контролирует доступ к ресурсу, предоставляя определенное количество разрешений для потоков.
7. BlockingQueue
- Интерфейс, предоставляющий безопасный способ обмена данными между потоками при помощи очередей. Реализации включают ArrayBlockingQueue, LinkedBlockingQueue и другие.
#java #ConcurrencyAPI #Thread6 819
Собрали подборку IT-каналов для тех, кто интересуется тестированием, разработкой, автотестами и карьерой в IT.
Внутри:
QA и AQA - практика, собеседования, рабочие заметки и разборы
Java и Python - задачи, тесты, полезные фишки и материалы для разработчиков
SQL и аналитика данных - запросы, работа с данными и прикладные разборы
Программирование и IT-карьера - каналы для тех, кто развивается в профессии и хочет лучше понимать рынок
Можно подписаться на всю подборку сразу или выбрать только те каналы, которые подходят под ваши цели.
Забрать папку
6 819
⌨️ Desktop
Класс
Desktop используется для взаимодействия с приложениями операционной системы, такими как веб-браузер, почтовый клиент, просмотрщик изображений и т.д. Этот класс входит в пакет java.awt и позволяет, например, открыть веб-ссылку в браузере или отправить письмо через почтовый клиент.
Основные возможности класса Desktop:
✔️ browse(URI uri) – открывает URI (например, веб-страницу) в браузере.
✔️ open(File file) – открывает файл в приложении, ассоциированном с его типом (например, текстовый файл в текстовом редакторе).
✔️ edit(File file) – открывает файл в режиме редактирования (если доступно).
✔️ mail(URI mailtoURI) – открывает почтовое приложение с указанным URI.
✔️ print(File file) – отправляет файл на печать.
Пример:
import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class DesktopExample {
public static void main(String[] args) throws IOException, URISyntaxException {
// Проверяем, поддерживает ли система класс Desktop
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
// Пример: Открытие веб-страницы
URI uri = new URI("http://www.google.com");
desktop.browse(uri);
} else {
System.out.println("Класс Desktop не поддерживается на этой системе.");
}
}
}
Проверка Desktop.isDesktopSupported() обязательна, так как класс может не поддерживаться на некоторых системах.
#java #Desktop6 819
⌨️ Почему Stream.parallel() может сделать код медленнее
Когда разработчики впервые видят:
list.parallelStream()
возникает мысль: О, бесплатная многопоточность 🚀
Но на практике parallelStream() очень часто:
❗ НЕ ускоряет код
❗ делает его медленнее
❗ а иногда ещё и ломает логику
📦 Как это работает
list.parallelStream()
.map(this::process)
.toList();
Java разбивает задачи между потоками через ForkJoinPool.commonPool().
🔥 Когда это реально помогает
✔️ CPU-heavy вычисления
✔️ большие объёмы данных
✔️ независимые операции
Например:
✅ обработка миллионов чисел
✅ сложные математические вычисления
✅ image processing
⚠️ Когда будет хуже
❌ Маленькие коллекции
List.of(1, 2, 3)
.parallelStream()
👉 накладные расходы на потоки будут больше пользы
❌ I/O операции
users.parallelStream()
.map(this::callApi)
👉 потоки начинают ждать сеть/БД
👉 ForkJoinPool забивается
❌ Общие mutable-данные
List<String> result = new ArrayList<>();
list.parallelStream()
.forEach(result::add);
💣 Race condition detected 🙂
❌ Неочевидный порядок
parallelStream().forEach(System.out::println);
Порядок вывода будет случайным.
🧠 Самая скрытая проблема
parallelStream() использует ОБЩИЙ pool потоков.
То есть:
▸ твой код
▸ библиотека
▸ другой модуль приложения
могут конкурировать за одни и те же потоки.
👉 Особенно весело в backend-приложениях.
🚀 Иногда обычный stream быстрее
Почему?
Потому что parallel:
▸ делит задачи
▸ синхронизирует результаты
▸ координирует потоки
Это тоже стоит времени.
✅ Хорошее правило
Используй parallelStream() только если:
▸ операция тяжёлая
▸ данных много
▸ нет shared mutable state
▸ ты реально измерил performance6 819
⌨️ EnumMap — это реализация Map, которая использует в качестве ключей исключительно
Enum.
Внутренне EnumMap использует массив для хранения значений, где индекс массива соответствует порядковому номеру (ordinal()) элемента перечисления. Это делает его быстрее, чем хэш-таблицы (HashMap) и более экономным по памяти.
EnumMap хранит ключи в порядке их объявления в перечислении, что отличает его от большинства других Map (кроме LinkedHashMap).
Так как ключи строго ограничены перечислением, это снижает вероятность ошибок при разработке.
🔍 Пример:
import java.util.EnumMap;
enum Action {
START, STOP, PAUSE
}
public class EnumMapExample {
public static void main(String[] args) {
EnumMap<Action, Runnable> actionMap = new EnumMap<>(Action.class);
// Определяем поведение для каждого значения Enum
actionMap.put(Action.START, () -> System.out.println("Starting the process..."));
actionMap.put(Action.STOP, () -> System.out.println("Stopping the process..."));
actionMap.put(Action.PAUSE, () -> System.out.println("Pausing the process..."));
// Пример вызова
Action currentAction = Action.START;
actionMap.get(currentAction).run();
}
}
#Java #EnumMap6 819
👨👨👨👨👨👨👨👨👨👨
Каналы с Junior IT вакансиями
и стажировками
Подписывайся и забирай свой оффер 🤘
1. Стажировки и вакансии по России и миру
2. IT вакансии по СНГ
3. IT стажировки по СНГ
4. ИИ-ассистент для автооткликов
5. IT стажировки и волонтерства
6. IT стажировки в топовых компаниях мира
7. Удалённые IT вакансии и стажировки
8. Python вакансии и стажировки
9. БИГТЕХ вакансии и стажировки
10. Design вакансии и стажировки
11. QA вакансии и стажировки
12. Junior вакансии и стажировки
13. Frontend вакансии и вопросы собесов
14. Вакансии и стажировки для аналитиков
15. Вакансии в русских стартапах за границей
16. Вакансии и стажировки для DevOps
17. Вакансии, которых нет на ХХ.РУ
6 819
⌨️ ThreadLocal - удобство, которое легко превращается в утечку памяти
ThreadLocal выглядит как магия:
У каждого потока будет своё собственное значение
И это правда. Но именно из-за этого он часто становится источником очень неприятных багов в production.
📦 Как работает ThreadLocal
ThreadLocal<String> currentUser = new ThreadLocal<>();
currentUser.set("Alex");
Теперь в каждом потоке хранится своё значение:
System.out.println(currentUser.get());
🔥 Где это используют
* Spring Security
* Hibernate
* логирование (`traceId`)
* транзакции
* хранение request context
🤔 Кажется идеально. В чём проблема?
Проблема начинается с thread pool.
⚠️ Главная ловушка
ThreadLocal<String> local = new ThreadLocal<>();
executor.submit(() -> {
local.set("DATA");
});
Поток из пула НЕ уничтожается после задачи.
👉 Значение остаётся висеть внутри потока.
💣 Что это вызывает
* утечки памяти
* неожиданные данные между запросами
* "рандомные" баги в серверных приложениях
😨 Самое неприятное
Даже если сам ThreadLocal удалён GC,
значение внутри потока может продолжать жить.
Почему?
Потому что внутри Thread:
* ключ (`ThreadLocal`) хранится как weak reference
* а значение - как strong reference
👉 Ключ умер
👉 Значение осталось
Классическая hidden memory leak.
✅ Правильный подход
ВСЕГДА чистить ThreadLocal:
try {
local.set("DATA");
// работа
} finally {
local.remove();
}
🚀 Почему это критично в Spring / Tomcat
Сервер использует thread pool:
* один поток обслуживает тысячи запросов
* забытый ThreadLocal живёт очень долго
Отсюда:
* рост памяти
* странное поведение пользователей
* “невоспроизводимые” баги
🧠 Интересный факт
ThreadLocal не хранит данные “в себе”.
Наоборот:
👉 каждый Thread хранит ThreadLocalMap
То есть данные лежат внутри потока, а не объекта ThreadLocal.6 819
👨👨👨👨👨👨👨👨👨👨
Каналы с IT мероприятиями
Подписывайся,
чтобы не пропустить 🤘
1. IT мероприятия для стажеров и студентов
2. IT мероприятия по РФ
3. IT мероприятия и хакатоны
4. Бесплатные IT мероприятия
5. IT мероприятия онлайн
6. IT мероприятия Москва
7. IT мероприятия Санкт-Петербург
6 819
⌨️ Сравнение объектов с помощью
Comparator и Comparable
В Java для сортировки объектов используются два ключевых интерфейса: Comparable и Comparator. Понимание их отличий и применения поможет вам эффективно управлять сортировкой данных в коллекциях.
📚 Краткие определения:
- Comparable:
- Используется, когда класс должен иметь естественный порядок. Например, мы можем сортировать людей по возрасту.
- Сигнатура метода: int compareTo(T o).
Пример:
class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age); // Сравнение по возрасту
}
}
- Comparator:
- Используется для создания внешних стратегий сравнения, позволяя определять несколько способов сортировки. Подходит для сортировки объектов разных классов.
- Сигнатура метода: int compare(T o1, T o2).
Пример:
import java.util.Comparator;
class NameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name); // Сравнение по имени
}
}
⚖️ Когда использовать:
- Comparable:
- Используйте, если у класса есть естественный порядок. Например, чтобы сортировать людей по возрасту.
- Сортировка с помощью Collections.sort() или Arrays.sort() будет проще.
Пример использования:
List<Person> people = Arrays.asList(new Person("Alice", 30), new Person("Bob", 25));
Collections.sort(people); // Сортировка по возрасту с использованием Comparable
- Comparator:
- Идеален для ситуаций, когда необходимо изменить порядок сортировки или сравнивать объекты разных классов.
Пример использования:
List<Person> people = Arrays.asList(new Person("Alice", 30), new Person("Bob", 25));
Collections.sort(people, new NameComparator()); // Сортировка по имени с использованием Comparator
#java #Comparator #Comparable6 819
⌨️ Чем абстрактный класс отличается от интерфейса? В каких случаях следует использовать абстрактный класс, а в каких интерфейс?
✔️ В Java класс может одновременно реализовать несколько интерфейсов, но наследоваться только от одного класса.
✔️ Абстрактные классы используются только тогда, когда присутствует тип отношений «is a» (является). Интерфейсы могут реализоваться классами, которые не связаны друг с другом.
✔️ Абстрактный класс - средство, позволяющее избежать написания повторяющегося кода, инструмент для частичной реализации поведения. Интерфейс - это средство выражения семантики класса, контракт, описывающий возможности. Все методы интерфейса неявно объявляются как
public abstract или (начиная с Java 8) default - методами с реализацией по-умолчанию, а поля - public static final.
✔️ Интерфейсы позволяют создавать структуры типов без иерархии.
✔️ Наследуясь от абстрактного, класс «растворяет» собственную индивидуальность. Реализуя интерфейс, он расширяет собственную функциональность.
Абстрактные классы содержат частичную реализацию, которая дополняется или расширяется в подклассах. При этом все подклассы схожи между собой в части реализации, унаследованной от абстрактного класса, и отличаются лишь в части собственной реализации абстрактных методов родителя. Поэтому абстрактные классы применяются в случае построения иерархии однотипных, очень похожих друг на друга классов. В этом случае наследование от абстрактного класса, реализующего поведение объекта по умолчанию может быть полезно, так как позволяет избежать написания повторяющегося кода. Во всех остальных случаях лучше использовать интерфейсы.
#java #interface #abstract6 819
🔴 Завтра тестовое собеседование с Java-разработчиком
13 мая(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Виктору
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
6 819
🛠 Разница между
StringBuilder и StringBuffer
И StringBuilder, и StringBuffer используются для работы со строками, но между ними есть важные отличия.
➡️ Основные различия:
✔️ StringBuilder быстрее, но не потокобезопасен.
✔️ StringBuffer потокобезопасен, но медленнее из-за синхронизации.
✔️ Пример использования StringBuilder:
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb); // Hello World
✔️ Пример использования StringBuffer:
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
System.out.println(sb); // Hello World
💡 Совет: Если ваш код выполняется в одном потоке, используйте StringBuilder для лучшей производительности.
#java #stringbuilder #stringbuffer6 819
⚠️ Внимание: Опубликована слитая недавно База из 1000+ топовых курсов и материалов для айтишников
Отсортировали их для вашего удобства и выложили в телеграм-каналы по категориям:
🤖 Нейросети – 855+ материалов
🖥 Python — 1558+ материалов
👩💻 Frontend — 1241+ материалов
👩💻 Backend — 1095+ материалов
⚙️ Программы — 978+ материалов
📚 Книги по IT — 779+ материалов
⌛️ Ссылки будут активны 48 часов, сохрани себе, чтобы не потерять!
6 819
⌨️ Arrays.deepToString()
Метод
deepToString из класса Arrays используется для создания строкового представления многомерных массивов (например, массивов массивов). Он обходит каждый уровень вложенности массива и выводит его элементы в виде строки. Это удобно для работы с многомерными массивами, так как стандартный метод toString не раскрывает их структуру.
Пример использования:
int[][] array = {{1, 2, 3}, {4, 5, 6}};
System.out.println(Arrays.deepToString(array));
// [[1, 2, 3], [4, 5, 6]]
Этот метод работает рекурсивно, обеспечивая полное отображение структуры массива любой вложенности.
#java #Arrays #deepToString6 819
📌 Что такое
volatile и как оно работает?
Ключевое слово volatile в Java используется для переменных, к которым обращаются несколько потоков. Оно гарантирует, что изменения переменной одним потоком будут видны другим.
✔️ Основные особенности:
1️⃣ Обеспечивает чтение переменной из основной памяти, а не из кэша потока.
2️⃣ Гарантирует видимость изменений между потоками.
Пример:
class SharedObject {
volatile int count = 0;
}
💡 Ограничение: volatile не гарантирует атомарность операций. Для этого используйте synchronized или классы из java.util.concurrent.
#java #volatile #multithreading6 819
Изучаете программирование, или хотите стать классным айтишником с высокой ЗП?
Пока многие паникуют из-за бума ИИ, вы можете стремительно войти в сферу IT при помощи сборки "IT в деле" которую мы составили. Специально для вас разбили нашу сборку мини папки по конкретным тематикам:)
Что внутри сборки:
- Каналы о программировании и разработке: Python, CSS, HTML, Java и Swift
- GameDev и каналы о QA тестироварии, создание игр, помощь для ваших проектов и реальный опыт от тестировщиков 💍
- Авторские каналы и вайбкодинг: IT & AI, простые заметки с проектов, работа с нейросетями, и как они реально влияют на индустрию 🔤
- Информационная безопасность: многое узнаете о работе хакеров и о том, как защитить себя в этом интернет-хаосе. 🔫
Для каждого здесь что-то найдётся! Выберите интересные вам каналы или подпишитесь на всю сборку, и найдите то, что нужно вам для следующего шага в IT.
