Java for Beginner
870 subscribers
1.01K photos
275 videos
14 files
1.68K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
[Совет по Java #034]

Тема: Ленивая инициализация синглтона через double-checked locking требует volatile.

Проблема: Паттерн double-checked locking (DCL) предназначен для ленивой инициализации синглтона с минимальной синхронизацией.

Классическая реализация без volatile содержит скрытую гонку данных из-за переупорядочивания инструкций (instruction reordering). Процесс создания объекта включает три этапа: выделение памяти, инициализация полей, присвоение ссылки переменной.

Компилятор и процессор могут переставить инициализацию и запись ссылки. В результате один поток может увидеть ненулевой, но еще не проинициализированный объект (partially constructed object), что приведет к непредсказуемому поведению, NullPointerException или чтению значений по умолчанию вместо заданных конструктором. Без volatile JVM не гарантирует happens-before связи между записью и последующим чтением.

Решение: Объявите поле синглтона как private static volatile. Модификатор volatile запрещает переупорядочивание операций с этим полем, обеспечивая, что запись ссылки произойдет только после полной инициализации объекта.

Начиная с Java 5 (и нового memory model), volatile обеспечивает правильный DCL.

Альтернативы: инициализация при загрузке класса (eager initialization) или использование enum-синглтона. Для современных проектов предпочтительнее подход с внутренним статическим классом (Initialization-on-demand holder idiom), который не требует ручной синхронизации.

public class Singleton {

//Антипаттерн: double-checked locking без volatile
private static Singleton instance; // отсутствует volatile!

public static Singleton getInstanceBad() {
if (instance == null) { // Первая проверка
synchronized (Singleton.class) {
if (instance == null) { // Вторая проверка
instance = new Singleton(); // Может быть переупорядочено!
}
}
}
return instance;
}

//Решение: volatile гарантирует корректность
private static volatile Singleton instance;

public static Singleton getInstanceGood() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(); // Теперь безопасно
}
}
}
return instance;
}

//Лучшее решение без синхронизации: Initialization-on-demand holder
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstanceHolder() {
return Holder.INSTANCE; // Инициализация при первом обращении
}

//enum-синглтон (сериализация безопасна)
public enum EnumSingleton {
INSTANCE;
public void doSomething() { }
}

private Singleton() { }
}


Объяснение: Проблема DCL без volatile связана с тем, что запись ссылки instance = new Singleton() неатомарна.

Без volatile возможен следующий сценарий: поток A выполняет выделение памяти, записывает ссылку в instance, но инициализация конструктора еще не завершена. Поток B входит в метод, видит instance != null и возвращает недосозданный объект. volatile создает барьер памяти (memory barrier), который запрещает переупорядочивание и гарантирует, что все записи до момента присвоения будут видны всем потокам после.

В Java 5+ спецификация memory model была усилена, и DCL с volatile работает корректно. Однако идиома holder-класса предпочтительнее: она использует механизм потокобезопасной инициализации классов JVM, не требует явной синхронизации и короче.


#Java #советы
👍6
Немаленькое обновление devforge.ru

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

Погнали тестить 💃
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Что выведет код?

public class Task070926 {
static int a = getB();
static int b = 5;
static int getB() { return b; }

public static void main(String[] args) {
System.out.println("a=" + a + ", b=" + b);
}
}


#Tasks
👍4
👍4
Что такое WeakHashMap? Где применяется? 🤓

Ответ:

WeakHashMap
— это реализация Map, в которой ключи хранятся через слабые ссылки (WeakReference).

Если на ключ нет сильных или мягких ссылок вне WeakHashMap, сборщик мусора может удалить этот ключ, а соответствующая запись будет удалена из карты при следующей операции.

Это полезно для реализации кэшей, чтобы избежать утечек памяти, когда объекты-ключи больше не используются в приложении. Например, хранение метаданных о загруженных классах.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологии сегодня — 08 мая

ℹ️ Кто родился в этот день

Кэйдзи Инафунэ (яп. 稲船 敬二 Инафунэ Кэйдзи, 8 мая 1965, Кисивада, Япония)японский игровой художник и продюсер компании Capcom, наиболее известный по созданию дизайна персонажей серии Mega Man, а также продюсированию игр Onimusha и Dead Rising.


🌐 Знаковые события

1886 — Впервые производится Coca-cola — напиток, созданный доктором Джоном Пембертоном.


#Biography #Birth_Date #Events #08мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Раздел 9. Исключения, логирование, отладка

Глава 2. Логирование (Logging)

Архитектура логирования: фасад и реализация. SLF4J, Logback, Log4j2

До появления SLF4J Java-приложения напрямую зависели от конкретной библиотеки логирования — Log4j 1.x, java.util.logging (JUL), Jakarta Commons Logging.

Это создавало фундаментальную проблему: библиотека, использующая Log4j, несовместима с приложением, использующим JUL. При подключении сторонней библиотеки разработчик получал транзитивную зависимость от её логгера, что приводило к конфликтам classpath, дублированию конфигураций и невозможности централизованного управления.

Прямая зависимость от реализации нарушает принцип инверсии зависимостей из SOLID. Модуль высокого уровня (бизнес-логика) зависит от модуля низкого уровня (конкретный логгер). При смене реализации требуется модификация кода, а не только конфигурации.


Фасадный паттерн в логировании


Решением стало применение фасадного паттерна (Facade pattern) — создание абстрактного API, не зависящего от конкретной реализации. Фасад определяет контракт операций логирования: получение логгера, запись сообщений разных уровней, передача параметров, работа с маркерами и MDC. Реализация предоставляет конкретные механизмы: форматирование, запись в файл, ротацию, сетевую передачу.

Это разделение аналогично JDBC: приложение работает с интерфейсами Connection, Statement, ResultSet, не завися от конкретного драйвера базы данных. Смена базы данных требует только замены драйвера в classpath, без модификации кода.


SLF4J: Simple Logging Facade for Java

SLF4J, созданный Ceki Gülcü (также автор Log4j 1.x и Logback), стал де-факто стандартом фасада логирования в Java-экосистеме. Архитектура SLF4J состоит из трех компонентов:
- API (slf4j-api) — интерфейсы Logger, LoggerFactory, Marker, MDC. Это единственная зависимость, которую должна объявлять библиотека. API не содержит кода записи логов, только контракт.
- Binding (slf4j-logback, log4j-slf4j-impl) — адаптер, связывающий API с конкретной реализацией. Binding реализует интерфейс org.slf4j.spi.SLF4JServiceProvider и регистрирует фабрику логгеров для конкретной backend-системы.
- Bridge (jcl-over-slf4j, log4j-over-slf4j, jul-to-slf4j) — адаптеры для перенаправления вызовов из legacy-API в SLF4J. Это позволяет мигрировать постепенно: старый код, использующий Commons Logging, прозрачно направляется через SLF4J в актуальную реализацию.

Ключевое правило classpath: должен присутствовать ровно один binding. Наличие нескольких bindings приводит к предупреждению и непредсказуемому выбору реализации.


Получение логгера: LoggerFactory

Центральная точка входа в SLF4J — класс org.slf4j.LoggerFactory. Метод getLogger(Class<?>) возвращает именованный логгер, обычно с именем класса для точной идентификации источника сообщения.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OrderService {
// Конвенция: private static final, имя CLASS_NAME или просто logger
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

public void processOrder(String orderId) {
logger.info("Processing order: {}", orderId);
}
}


Имя логгера формирует иерархию, используемую для конфигурации уровней. Логгер com.example.service.OrderService наследует уровень от com.example.service, который наследует от com.example, и так до корневого логгера. Это позволяет управлять детализацией на уровне пакета или класса без перекомпиляции.


#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍5
Logback: нативная реализация SLF4J

Logback, также созданный Ceki Gülcü, разработан как преемник Log4j 1.x и нативная реализация SLF4J.

Он состоит из трех модулей:
logback-core — базовые классы для appenders, layouts, фильтров. Независим от SLF4J, может использоваться для других целей.
logback-classic — реализация SLF4J API. Содержит LoggerContext — реестр логгеров, и систему конфигурации.
logback-access — специализированный модуль для логирования HTTP-запросов в сервлет-контейнерах.

Архитектура Logback построена на компонентах: Logger формирует событие LoggingEvent, которое передается через фильтры к Appender. Appender записывает событие через Layout в целевой ресурс — консоль, файл, сокет, базу данных. Appenders комбинируются: один логгер может иметь несколько appenders для дублирования вывода.
Конфигурация выполняется через XML (logback.xml, logback-test.xml), Groovy или программно. Logback поддерживает автоматическую перезагрузку конфигурации при изменении файла без перезапуска приложения.


Log4j2: следующее поколение

Apache Log4j2 — полная перепись Log4j 1.x, разработанная с учетом требований современных высоконагруженных систем.

Ключевые архитектурные отличия от Logback:
Асинхронные Loggers на базе LMAX Disruptor — lock-free RingBuffer, обеспечивающий пропускную способность в миллионы сообщений в секунду с минимальной латентностью. В Logback асинхронность реализована через AsyncAppender с LinkedBlockingQueue, что менее эффективно при экстремальных нагрузках.
Lazy initialization — Log4j2 не создает appenders до первого лог-сообщения, что ускоряет старт приложения. Logback инициализирует всю конфигурацию при загрузке.
Garbage-free logging — при определенных конфигурациях Log4j2 избегает аллокаций объектов при логировании, что критично для low-latency систем с чувствительным GC.
Plugin architecture — расширяемость через аннотации @Plugin, что упрощает создание кастомных appenders, layouts и фильтров.

Log4j2 может работать как самостоятельный фреймворк или через SLF4J API (log4j-slf4j-impl binding). Для приложений, уже использующих SLF4J, переход на Log4j2 требует только замены binding и конфигурации, без модификации кода.


Сравнение и выбор реализации

Выбор между Logback и Log4j2 зависит от требований проекта:
Logback предпочтителен для стандартных Spring Boot-приложений, где он является дефолтной реализацией. Конфигурация через logback-spring.xml интегрирована с профилями Spring. Logback проще в настройке, имеет меньше зависимостей, широко документирован.
Log4j2 выбирают для высоконагруженных систем, где критична пропускная способность логирования. Асинхронные логгеры на Disruptor обеспечивают порядок магнитуды лучшую производительность при пиковых нагрузках. Garbage-free режим важен для систем с жесткими требованиями к паузам GC.

Оба фреймворка поддерживают структурированное логирование в JSON, интеграцию с MDC, маркеры, фильтрацию и ротацию. Различия в производительности заметны только при экстремальных нагрузках — для большинства enterprise-приложений оба варианта адекватны.

#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍4
Что выведет код?

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Task080526 {
public static void main(String[] args) {
Logger logger1 = LoggerFactory.getLogger(Task080526.class);
Logger logger2 = LoggerFactory.getLogger("test.logger");

System.out.println(logger1.getName());
System.out.println(logger2.getName());

Logger logger3 = LoggerFactory.getLogger(Task080526.class);
System.out.println(logger1 == logger3);
}
}


#Tasks
🗿3👍1
Что такое LinkedHashMap? Чем отличается от HashMap? 🤓

Ответ:

LinkedHashMap
— это наследник HashMap, который дополнительно поддерживает двусвязный список всех записей в порядке их добавления (insertion order) или порядке доступа (access order).

Благодаря этому итерация по LinkedHashMap происходит в предсказуемом порядке, в отличие от HashMap (порядок не гарантирован).

LinkedHashMap немного медленнее из-за поддержки списка. При использовании access order можно создать LRU-кэш (Least Recently Used), переопределив removeEldestEntry().


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Всем привет 😊

Сегодня не будет обучающих постов или постов с мемами.

В этот день мы, как и все адекватные жители планеты, чтим память миллионов человек отдавших свою жизнь в борьбе с фашистской Германией.

Чтим тех, кто сегодня как и тогда, воюет за свободу и независимость нашей Родины.

На фоне современной геополитической борьбы, попыток принизить и уничтожить память о героизме народов СССР, просто непозволительно игнорировать такой день.

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

С Днем Победы! ⭐️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3
История технологии сегодня — 09 мая

Россия,  Беларусь,  Молдова,  Армения,  Азербайджан,  Грузия,  Республика Абхазия,  Южная Осетия,  Казахстан,  Узбекистан (День памяти и почестей),  Туркменистан,  Кыргызстан,  Таджикистан,  Босния и Герцеговина ( Республика Сербская),  Северная Македония,  Сербия,  Черногория,  Израиль (с 2017 года) —День Побе́ды — праздник победы Красной армии и советского народа над нацистской Германией в Великой Отечественной войне 19411945 годов.

Установлен Указом 
Президиума Верховного Совета СССР от 8 мая 1945 года и ежегодно отмечается 9 мая

ℹ️ Кто родился в этот день

А́дам О́пель (нем. Adam Opel; 9 мая 1837, Рюссельсхайм — 8 сентября 1895, Рюссельсхайм) — основатель компании Adam Opel GmbH. Через 25 лет с момента основания Опель стал успешным международным изготовителем, экспортирующим швейные машины в Европу, США, Россию и Индию. В 1887 году Опель запустил в производство другую исключительно высоко оцененную машину — велосипед. За эти годы Опель стал самым большим в мире изготовителем велосипедов. В 1899 году Опель произвел первый автомобиль, потратив 37 лет на разработку и наработку производственного опыта. Хотя сам Адам Опель умер прежде, чем было начато автомобильное производство, семья Опель продолжила его видение, делая автомобиль доступным для как можно большего числа людей.

🌐 Знаковые события

1996 — официальным талисманом Linux стал Tux.


#Biography #Birth_Date #Events #09мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🎖 Анатолий Китов — фронтовик, который мечтал соединить страну через компьютеры

В День Победы стоит вспомнить не только тех, кто сражался с оружием в руках, но и тех, кто, пройдя войну, посвятил жизнь будущему — науке и технологиям. Один из таких людей — Анатолий Иванович Китов (1920–2005).

Китов — участник Великой Отечественной, артиллерист, позже — доктор технических наук, генерал-майор, основоположник советской кибернетики и один из первых, кто мечтал о "государственной вычислительной сети" задолго до появления интернета.



🪖 Военная биография

В 1940 году окончил артиллерийское училище.
Прошёл всю войну — от Брянского фронта до Восточной Пруссии.
Был тяжело ранен, но вернулся в строй.
Уже тогда проявлял интерес к вычислениям: составлял таблицы стрельбы, занимался баллистикой.


«Война научила меня одной важной вещи: точность и скорость расчетов — вопрос жизни и смерти».



💻 После войны: путь к вычислительной технике

После демобилизации поступает в Военную артиллерийскую академию им. Дзержинского.
Защищает диссертацию по автоматизации военных расчетов.
В 1950-е — начинает работу с первыми ЭВМ (МЭСМ, БЭСМ).
Предлагает использовать компьютеры не только в военной, но и в народнохозяйственной сфере.


«Если бы все министерства были объединены в одну вычислительную сеть — экономика стала бы прозрачной и эффективной».
(из письма Хрущёву, 1959)


🌐 Первая идея "советского интернета"

В 1959 году Китов отправляет в ЦК КПСС письмо под названием «Красная книга» — манифест о создании национальной автоматизированной системы управления экономикой (АСУ).

Он предлагает:

Централизованную сеть ЭВМ по всей стране;
Автоматизацию планирования и снабжения;
Снижение бюрократии через программирование.


Это предложение опередило ARPANET и идеи интернета на 10 лет, но в СССР кибернетика тогда ещё считалась "буржуазной лженаукой".

«Меня не поняли. Или не захотели понять. Мечта осталась в ящике».


⚙️ Вклад в науку

Один из авторов первого учебника по программированию в СССР.
Участвовал в создании первых языков программирования в СССР (в т.ч. АЛГЭМ).
Продвигал идеи автоматизации в оборонной промышленности.


📘 Наследие

Китов не только изобрёл термины, схемы и алгоритмы. Он пытался изменить мышление эпохи — чтобы компьютеры служили людям, а не только военной машине.
Сегодня, когда мы сидим в IDE и запускаем CI/CD пайплайны, можно вспомнить, что в 1950-е в СССР жил человек, который хотел сделать единую цифровую систему управления всей страной.


https://kitov.rea.ru/polnaa-biografia
👍9
🎖 Александр Ляпунов — фронтовик, который научил СССР программировать

В День Победы важно помнить не только тех, кто сражался с оружием в руках, но и тех, кто после войны строил новое мирное будущее — с помощью разума, логики и вычислительной техники. Один из таких людей — Александр Андреевич Ляпунов (1911–2003).

Ляпунов - это:
Математик, логик, кибернетик.
Один из основоположников теории алгоритмов и программирования в СССР.
Ветеран Великой Отечественной войны.
Один из авторов первого отечественного языка программирования («Альфа»).
Участвовал в создании первой советской ЭВМ — БЭСМ.


🪖 Военные годы


В начале войны — сотрудник Академии наук СССР.
Служил в рядах Красной Армии, занимался военными расчётами и криптоанализом.
После войны продолжил научную работу в сфере автоматизации и математики.


🧮 После войны — математика, логика, ЭВМ

Работал в Институте точной механики и вычислительной техники АН СССР.
Один из первых, кто преподавал программирование в СССР.
В 1954 году стал соавтором учебника «Основы программирования» — первого в стране.
Создавал языки программирования и системы автоматического перевода с математического языка на машинный код.

«Язык программирования — это мост между идеей и железом».


💻 Язык «Альфа» — шаг в сторону системного программирования

Совместно с Андреем Ершовым и Сергеем Масловым, Ляпунов разработал в конце 1950-х язык "Альфа" — предшественник более развитых систем программирования.
Основан на математической логике и языках типа АЛГОЛ.
Предназначался для научных расчётов.
Был использован на первых отечественных ЭВМ (в т.ч. БЭСМ-2).


🔬 Исследователь искусственного интеллекта

С 1960-х годов Ляпунов активно интересовался темами:
Машинного перевода;
Искусственного интеллекта;
Теории автоматов.
Он был одним из тех, кто помогал вносить термин «кибернетика» в научный обиход СССР, когда её ещё воспринимали с подозрением.


📘 Учитель поколений

Занимался научной педагогикой;
Подготовил целую плеяду учёных-программистов;
Один из основателей советской школы автоматического программирования.


https://www.computer-museum.ru/galglory/lypunov2.htm
википедия
👍10🔥1
🎖 Сергей Лебедев — человек, который построил первый советский компьютер

9 мая мы говорим не только о прошлом, но и о людях, которые после войны проложили путь к будущему. Один из них — Сергей Алексеевич Лебедев (1902–1974) — инженер, создатель первой советской ЭВМ, основатель советской школы вычислительной техники.

Лебедев - это:
Электротехник, математик, академик.
Автор первой в СССР цифровой электронной вычислительной машины — МЭСМ (1951).
Руководитель проекта БЭСМ — самой мощной машины в Европе на тот момент.

Практически в одиночку заложил основы того, что позже стало IT-отраслью в СССР.

🪖 Война: расчёты для Победы

Во время Великой Отечественной Лебедев:
Руководил отделом в Энергетическом институте АН СССР;
Занимался молниезащитой авиации и боевой техники;
Курировал расчёты для систем ПВО и баллистики;
Его методы позволили существенно ускорить проектирование систем вооружения.


💻 МЭСМ — первый советский «компьютер»

В 1948 году Лебедев переезжает в Киев, где в здании бывшего монастыря начинает работу над машиной МЭСМ — Малой электронной счётной машиной.
Команда: около 20 инженеров и студентов;
Первый запуск — декабрь 1951 года;
Производительность: ~50 операций в секунду (на то время — прорыв);
Машина полностью отечественная, собрана без западной помощи.


"Примечательно то, что проектирование, монтаж и отладка машины были выполнены в течении трех лет. При этом в разработке участвовали лишь 11 инженеров и 15 технических сотрудников. Тогда как на разработку первого в мире электронного компьютера ЭНИАК (США) ушло пять лет и было задействовано 13 разработчиков и более 200 техников."


⚙️ БЭСМ — Большая ЭВМ

Следующим шагом стала БЭСМ — более мощная машина, которая:
Вошла в тройку самых мощных компьютеров мира в 1950-х;
Использовалась для расчётов в атомной промышленности, космосе, аэродинамике;
Применялась при проектировании спутников и баллистических ракет.


🌐 Без него не было бы советского программирования

Лебедев не только создавал «железо», он:
Разрабатывал архитектуру команд;
Поддерживал развитие языков программирования (в том числе автокод и "Адресный язык");
Сформировал первое поколение инженеров-программистов в СССР;
Поддерживал развитие автоматизированных систем управления (АСУ).


🧬 Наследие

Основал Институт точной механики и вычислительной техники (ИТМиВТ);
Его ученики — ключевые фигуры в истории вычислительной техники СССР;
Его имя носит одна из крупнейших лабораторий в России.



https://habr.com/ru/companies/ua-hosting/articles/388169/
Вики
👍7🔥2
История технологии сегодня — 10 мая

ℹ️ Кто родился в этот день

Лео́н Эрнест Гомо́н (фр. Léon Ernest Gaumont, 10 мая 1864 года, Париж — 10 августа 1946 года, Сент-Максим, департамент Вар) — французский продюсер, предприниматель, один из основоположников мирового кинематографа.


🌐 Знаковые события

1975 — Sony представила видеомагнитофон формата Betamax.


#Biography #Birth_Date #Events #10мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
С 02.05 по 08.05
Предыдущий пост(с 25.04 по 01.05)

Запись встреч/видео:
В процессе создания

Обучающие статьи:
Раздел 9. Исключения, логирование, отладка

Глава 1. Иерархия исключений (Exceptions)
Практика: Защитное программирование в «Библиотеке»

Глава 2. Логирование (Logging)
Почему System.out.println — антипаттерн для production-приложений
Архитектура логирования: фасад и реализация. SLF4J, Logback, Log4j2

[Совет по Java #033]
Тема: Collections.emptyList() и List.of() возвращают иммутабельные списки.

[Совет по Java #034]
Тема: Ленивая инициализация синглтона через double-checked locking требует volatile.

Полезные статьи и видео:
https://habr.com/ru/articles/1031336/

Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍4