Java for Beginner
871 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
Варианты ответа:
Anonymous Quiz
38%
10
25%
20
19%
30
19%
Исключение
👍2
Как работает finally с return?🤓

Ответ:

Если в блоках try или catch есть оператор return, то блок finally всё равно выполнится перед фактическим возвратом значения.

Если finally также содержит return, то он переопределит возвращаемое значение из try/catch.

Исключение, выброшенное в finally, будет иметь приоритет над исключением из try/catch. Поэтому в finally не рекомендуется использовать return или бросать исключения — это может скрыть важную информацию.

Лучше использовать finally только для освобождения ресурсов.


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

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

Оле́г Бори́сович Лупа́нов (2 июня 1932 — 3 мая 2006) — советский и российский математикакадемик Российской академии наук, декан механико-математического факультета МГУ (1980—2006), главный научный сотрудник Института прикладной математики им. М. В. Келдыша (1993—2006), специалист по дискретной математикематематической кибернетикематематической логике. В 1958 году под руководством А. А. Ляпунова защитил кандидатскую диссертацию «О синтезе контактных схем». Докторская диссертация — «Об aсимптотических закономерностях синтезa схем из функциональных элементов» (1963). Разработал асимптотически наилучший метод синтеза схем из функциональных элементов — так называемый метод Лупанова (англ. Lupanov representation).


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

1857 — Джеймс Гиббс из Вирджинии запатентовал однониточную стежковую швейную машинку.


#Biography #Birth_Date #Events #02июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
This media is not supported in your browser
VIEW IN TELEGRAM
Напоминаю ребят, что набираю желающих изучить Java 🤓

Возьму еще буквально пару человек.🤫

Пишите @oleborn 😎
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
[Совет по Java #045]

Тема: volatile не гарантирует атомарность.

Проблема: Ключевое слово volatile обеспечивает видимость изменений между потоками (запись в volatile переменную происходит в main memory, чтение — также из main memory) и запрещает переупорядочивание инструкций.

Однако оно не делает операции атомарными. Операция инкремента (count++) состоит из трех действий: чтение значения, увеличение на 1, запись нового значения. Два потока могут одновременно прочитать одно и то же значение, увеличить его и записать обратно. В результате один инкремент будет потерян, и финальное значение будет меньше ожидаемого.

Решение: Для атомарных счетчиков используйте классы из пакета java.util.concurrent.atomicAtomicIntegerAtomicLong.

Их методы incrementAndGet()getAndIncrement() и другие гарантируют атомарность без блокировок (через низкоуровневые CAS-операции). Если нужна более сложная логика (условное обновление), используйте compareAndSet(). Для примитивов long и double volatile обеспечивает атомарность записи/чтения на 64-битных платформах согласно спецификации Java (начиная с Java 5), но инкремент все равно не атомарен.

Для простых флагов (boolean, ссылки) volatile подходит.
public class VolatileNotAtomic {

//Антипаттерн: volatile без атомарности
private static volatile int volatileCounter = 0;

//Решение: AtomicInteger
private static final AtomicInteger atomicCounter = new AtomicInteger(0);

public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(10);

// Неправильный счетчик
for (int i = 0; i < 1000; i++) {
executor.submit(() -> volatileCounter++);
}

// Правильный счетчик
for (int i = 0; i < 1000; i++) {
executor.submit(() -> atomicCounter.incrementAndGet());
}

executor.shutdown();
executor.awaitTermination(1, TimeUnit.SECONDS);

System.out.println("volatile count: " + volatileCounter); // почти всегда < 1000
System.out.println("Atomic count: " + atomicCounter.get()); // всегда 1000

// Другие методы AtomicInteger
AtomicInteger ai = new AtomicInteger(0);
int old = ai.getAndSet(10); // old = 0, new = 10
int updated = ai.incrementAndGet(); // 11
boolean set = ai.compareAndSet(11, 20); // true, меняет 11 на 20

// Для long: AtomicLong
// Для boolean: AtomicBoolean
// Для ссылок: AtomicReference<V>
}
}


Объяснение:
 volatile гарантирует, что чтение и запись переменной происходят непосредственно из основной памяти (стека основного потока), но не делает составные операции атомарными.

Инкремент — это read-modify-write. Даже если переменная volatile, два потока могут одновременно считать одно значение, каждый увеличит его до n+1, и оба запишут n+1, потеряв одно приращение. AtomicInteger использует инструкцию CAS (Compare-And-Swap), аппаратно поддерживаемую процессором, которая выполняет сравнение и обмен за одну атомарную операцию. CAS не требует блокировок и обычно быстрее synchronized.

#Java #советы
👍5
Начал работу над новым видео... 🧑‍💻

Через пару дней - ждите))
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9
Что выведет код?

public class Task020626 {
private static volatile int counter = 0;

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter++;
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter++;
}
});

t1.start();
t2.start();
t1.join();
t2.join();

System.out.println(counter);
}
}



#Tasks
👍4
Варианты ответа:
Anonymous Quiz
19%
20000
76%
Меньше или равно 20000
0%
10000
5%
0
👍2
🤣🤣🤣 по-моему это знак
🤣5🤓4
Что такое NavigableMap и NavigableSet?🤓

Ответ:

NavigableMap (реализация — TreeMap)
и NavigableSet (TreeSet) расширяют SortedMap/SortedSet, добавляя методы для навигации, близкие к запросам "ближайший меньший/больший элемент".

Полезные методы: 
lowerKey() / lowerEntry() (строго меньше), 
floorKey() (меньше или равно), 
ceilingKey() (больше или равно), 
higherKey() (строго больше), 
descendingMap() (обратный порядок), 
subMap(from, to) (диапазон с опциями включения границ).

Удобно для поиска интервалов, например, в системах бронирования.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Всем доброго летнего утра! 👋

Вот вывел своего конька погулять, впервые в этом году 🚲

Че нам безработным🤣🤣🤣

А как ваше утро проходит?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2
История технологии сегодня — 3 июня

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

И́горь Ростисла́вович Шафаре́вич (3 июня 1923, Житомир — 19 февраля 2017, Москва) — советский и российский математик, доктор физико-математических наук, профессор, академик Российской академии наук (1991; член-корреспондент Академии наук СССР с 1958). Основные труды посвящены алгебретеории чисел и алгебраической геометрии.

Дьёрдь фон Бе́кеши (Джордж) (венг. Békésy György; нем. Georg von Békésy; 3 июня 1899, Будапешт — 13 июня 1972, Гонолулу, Гавайи, США) — венгерско-американский физик, биофизик и физиолог, лауреат Нобелевской премии в области медицины 1961 года. Основные труды по биофизике и физиологии слуха. Открыл закономерности колебаний базилярной мембраны улитки внутреннего уха при действии звука и сформулировал теорию первичного амплитудно-частотного анализа звуков в органе слуха. Изучал передачу звука в среднем ухе. Предложил метод и прибор оценки слуха человека, порога различения слуха (аудиометр Бекеши). Исследования по костной проводимости звука, пространственному слуху и контрасту восприятия в сенсорных системах.


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

1980 — вследствие сбоя компьютера, сообщившего о советском ядерном нападении, в США объявлена ядерная тревога. В течение десяти минут мир находился на краю ядерной войны.


#Biography #Birth_Date #Events #03июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)

Глава 1. Классический Java I/O (java.io)

FileInputStream – чтение байтов из файла. Путь данных в памяти JVM

FileInputStream — конкретная реализация InputStream, предназначенная для чтения байтов из файловой системы. Она представляет собой низкоуровневый мост между Java-кодом и операционной системой: каждый вызов read() транслируется в системный вызов read() ядра ОС, который взаимодействует с файловой системой и блочным устройством хранения.

В отличие от BufferedInputStream, FileInputStream не выполняет внутреннюю буферизацию. Каждый вызов read() напрямую обращается к ОС, что делает посимвольное чтение через FileInputStream крайне неэффективным для больших файлов. Однако именно эта прямота делает FileInputStream полезным для сценариев, где требуется точный контроль над каждым системным вызовом: чтение с устройств с поблочным доступом, работа с pipe-файлами, или как underlying поток для буферизующих оберток.


Конструкторы и жизненный цикл файлового дескриптора


FileInputStream предоставляет два основных конструктора:
// Конструктор по строковому пути
public FileInputStream(String name) throws FileNotFoundException

// Конструктор по объекту File
public FileInputStream(File file) throws FileNotFoundException


Оба конструктора выполняют одну и ту же последовательность операций на уровне JVM и ОС:
Валидация параметра. Проверка на null, проверка существования файла через системный вызов stat() или аналог.
Открытие файла. Системный вызов open() создает файловый дескриптор (file descriptor) — целочисленный идентификатор, представляющий открытый файл в контексте процесса.
Создание объекта FileInputStream. Выделение объекта в heap JVM, инициализация полей, включая нативное поле fd типа FileDescriptor, которое хранит целочисленный дескриптор ОС.

Файловый дескриптор — это ограниченный ресурс операционной системы. Каждый процесс имеет лимит на количество открытых дескрипторов (обычно 1024 по умолчанию, расширяемый до миллионов через ulimit). Незакрытый FileInputStream удерживает дескриптор до вызова close() или финализации объекта GC, что создает риск исчерпания лимита при интенсивном открытии файлов без закрытия.


FileNotFoundException: семантика и обработка


Конструкторы FileInputStream объявляют throws FileNotFoundException — checked-исключение, которое компилятор обязывает обрабатывать.

Это исключение возникает в трех основных сценариях:
Файл не существует по указанному пути
Файл существует, но является директорией, а не обычным файлом
Файл существует, но приложение не имеет прав на чтение
public byte[] readFileContent(String path) {
try (FileInputStream fis = new FileInputStream(path)) {
return fis.readAllBytes();
} catch (FileNotFoundException e) {
// Файл не существует или недоступен — бизнес-решение
logger.warn("File not found: {}", path);
return new byte[0];
} catch (IOException e) {
// Другие I/O ошибки при чтении
logger.error("Failed to read file: {}", path, e);
throw new RuntimeException("File read error", e);
}
}

FileNotFoundException наследует IOException и является восстановимым сбоем в контексте файловых операций. Приложение может предпринять альтернативные действия: использовать значение по умолчанию, создать файл, запросить другой путь. В отличие от RuntimeException, checked-природа FileNotFoundException форсирует явную обработку в коде.


#Java #для_новичков #beginner #IO #NIO #FileInputStream
👍4
Путь данных от диска до heap JVM

Уровень 1: Физическое чтение с носителя

Данные хранятся на блочном устройстве — SSD, HDD, NVMe — в секторах фиксированного размера (обычно 512 байт или 4KB). Когда ОС запрашивает чтение файла, драйвер устройства транслирует логические блоки файловой системы в физические адреса секторов. Для SSD контроллер выполняет wear leveling и garbage collection на уровне флеш-памяти, независимо от JVM.

Уровень 2: Страничный кэш ядра (Page Cache)

Операционная система поддерживает страничный кэш — область оперативной памяти ядра, где хранятся недавно прочитанные страницы файлов. Размер страницы обычно 4KB. При первом чтении файла данные загружаются с диска в page cache. При повторном чтении тех же данных ОС возвращает их из page cache без обращения к диску.
Page cache — это память ядра, недоступная напрямую из Java. JVM не управляет этой памятью и не видит её в heap. Однако интенсивное чтение больших файлов вытесняет другие страницы из кэша, что может повлиять на производительность всей системы.

Уровень 3: Системный вызов и нативный буфер

Когда FileInputStream.read() вызывается, JVM выполняет системный вызов read() через JNI (Java Native Interface). Ядро ОС копирует данные из page cache в нативный буфер в userspace — память процесса JVM за пределами heap. Это первое копирование данных.
// read() вызывает нативный метод, который выполняет системный вызов
public native int read() throws IOException;

Нативный метод read0() в FileInputStream.c из OpenJDK вызывает IO_Read на POSIX-системах, который оборачивает read(fd, buf, 1) для посимвольного чтения или read(fd, buf, len) для буферизованного.

Уровень 4: Копирование в heap JVM

После выполнения системного вызова данные копируются из нативного буфера в массив byte[] в heap JVM. Это второе копирование. Только после этого данные становятся доступны Java-коду.
// Путь данных для read():
// 1. Диск -> page cache (ядро)
// 2. page cache -> нативный буфер (userspace, вне heap)
// 3. нативный буфер -> byte[] в heap JVM
// 4. Java-код читает byte[0]

Для read(byte[] b) путь аналогичен, но шаг 3 копирует до b.length байт за одну операцию.

Пример: посимвольное чтение и нагрузка на память
public void readByteByByte(String path) throws IOException {
try (FileInputStream fis = new FileInputStream(path)) {
int byteValue;
// Каждая итерация: системный вызов + копирование в heap для 1 байта
while ((byteValue = fis.read()) != -1) {
System.out.printf("%02X ", byteValue);
}
}
}


В этом коде каждый вызов read() порождает полный путь данных для одного байта.

С точки зрения памяти:
Объект FileInputStream создается в heap и живет до выхода из try
Локальная переменная byteValue хранится в стеке потока
Никаких массивов в heap не создается при каждом вызове
Проблема не в GC, а в количестве системных вызовов
Однако при выводе в System.out каждый вызов printf создает объекты String и StringBuilder в heap для форматирования, что нагружает GC при больших файлах.


#Java #для_новичков #beginner #IO #NIO #FileInputStream
👍4
Буферизация и сокращение пути данных

BufferedInputStream добавляет промежуточный массив в heap, сокращая количество системных вызовов:
public void readBuffered(String path) throws IOException {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path))) {
int byteValue;
// Первый read(): чтение 8192 байт в buf[8192] одним системным вызовом
// Последующие read(): возврат из buf без системных вызовов
while ((byteValue = bis.read()) != -1) {
System.out.printf("%02X ", byteValue);
}
}
}


Путь данных с BufferedInputStream:

Первый read(): диск -> page cache -> нативный буфер -> buf[8192] в heap -> возврат buf[0]
Второй read(): buf[1] из heap (системный вызов отсутствует, нативный буфер не задействован)
После исчерпания buf: повторение шага 1

Массив buf создается при конструировании BufferedInputStream и живет до закрытия потока. GC не вовлечен в работу цикла чтения, так как массив переиспользуется.


Роль garbage collector

Жизненный цикл объектов I/O
try (FileInputStream fis = new FileInputStream(path)) {
// fis — ссылка в стеке, объект FileInputStream в heap
// fis.fd — объект FileDescriptor в heap, хранит int fd (файловый дескриптор ОС)
// При использовании BufferedInputStream: bis.buf — byte[] в heap
}
// После выхода из try:
// 1. Вызывается fis.close() — закрывается файловый дескриптор ОС
// 2. Ссылка fis выходит из области видимости
// 3. Объект FileInputStream становится недостижимым
// 4. GC может собрать объект и связанные FileDescriptor при следующей сборке


Важно: FileInputStream реализует AutoCloseable, и try-with-resources гарантирует вызов close(). Если бы мы использовали старый подход без try-with-resources:
// Антипаттерн: утечка файлового дескриптора
FileInputStream fis = new FileInputStream(path);
// Если здесь возникнет исключение, close() не вызовется
fis.read();
fis.close();

В этом случае при исключении между read() и close() файловый дескриптор остается открытым. Объект FileInputStream все еще достижим через локальную переменную до выхода из метода, но если исключение пробрасывается наверх, метод завершается без закрытия. GC финализирует объект и закроет дескриптор, но финализация непредсказуема по времени — может пройти секунды или минуты до освобождения ресурса.


Финализация и Cleaner

В современных версиях Java FileInputStream использует java.lang.ref.Cleaner вместо устаревшего метода finalize(). Cleaner регистрирует cleanup-действие, которое выполняется, когда объект становится фантомно достижимым (phantom reachable) — то есть недостижимым, но еще не собранным GC.
// Упрощенная логика из OpenJDK
private final Cleanable cleanable;
private final FileCleanable cleanup;

public FileInputStream(File file) throws FileNotFoundException {
// ...
this.fd = new FileDescriptor();
this.cleanup = new FileCleanable(this.fd);
this.cleanable = Cleaner.create().register(this, cleanup);
}

FileCleanable — это Runnable, который вызывает close0(fd) — нативный метод закрытия дескриптора. Этот механизм гарантирует освобождение ресурса даже при забывчивости разработчика, но не заменяет явный вызов close(): Cleaner работает в отдельном потоке с низким приоритетом, и задержка может быть значительной.

#Java #для_новичков #beginner #IO #NIO #FileInputStream
👍4
А вы еще ищете работу? 😂

Это реальный скрин, блеать
🤯4
Что выведет код?

import java.io.*;

public class Task030626 {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("missing.txt")) {
System.out.println("Opened");
} catch (IOException e) {
System.out.println(e.getClass().getSimpleName());
}
}
}


#Tasks
👍3
👍3
Как работает java.util.concurrent.locks.Condition?🤓

Ответ:

Condition
 — это интерфейс, предоставляющий более гибкий контроль потоков, чем wait()/notify().

Ассоциируется с Lock. Для объекта Lock можно создать одну или несколько Condition (через newCondition()).

Методы: 
await() (освобождает lock и ждет), 
signal() (пробуждает один поток), 
signalAll() (пробуждает все).

Преимущества: можно иметь несколько очередей ожидания для разных условий (например, для производителя и потребителя отдельные Condition).

Также поддерживает прерывания и таймауты.


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

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

Ива́н Влади́мирович Танана́ев (22 мая [4 июня] 1904 года — 28 февраля 1993 года) — советский и российский учёный-химик, специалист в области органической и аналитической химии. Под руководством Тананаева были разработаны способы переработки сырья, найдены новые области применения редкоземельных элементов, проводились исследования хроматов лантананеодима и иттрия. Впоследствии эти наработки оказались полезными при создании высокотемпературных керамических материалов. Решил важную задачу комплексного освоения минерального сырья на Кольском полуострове. Он разработал технологию выделения из руд ценных металлов и фосфора, которая и в XXI веке применяется на заводах. Также учёный одним из первых сформулировал идеи о наноматериалах.

Кристофер Кокерелл (4 июня 1910 года, Кембридж — 1 июня 1999 года, Хайт, Гэмпшир) — британский инженер, изобретатель судна на воздушной подушке. Патентную заявку на схему судна на воздушной подушке, принципиально новую конструкцию, названную им «hovercraft» («парящий аппарат»), он подал 12 декабря 1955 года. Первый прототип построенного им судна на воздушной подушке SR-N1 (англ. SR.N1) был построен весной 1959 года и всего несколько недель спустя пересёк Ла-Манш за 20 минут.


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

1896 — испытание первого автомобиля, построенного Фордом, было задержано на час, так как оказалось, что автомобиль шире, чем двери цеха, в котором его создавали.

#Biography #Birth_Date #Events #04июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤣1