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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
🤣2🍾2🔥11
История технологии сегодня — 7 июня

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

Ро́берт Са́ндерсон Ма́лликен (англ. Robert Sanderson Mulliken; 7 июня 1896, Ньюберипорт, Массачусетс — 31 октября 1986, Арлингтон, Виргиния) — американский физик и химик, профессор, лауреат Нобелевской премии по химии (1966) «за фундаментальную работу по химическим связям и электронной структуре молекул, проведённую с помощью метода молекулярных орбиталей».

Чарлз Гло́вер Ба́ркла (англ. Charles Glover Barkla; 7 июня 1877, Уиднс, Чешир — 23 октября 1944, Эдинбург) — английский физик-ядерщик, лауреат Нобелевской премии по физике 1917 года «за открытие характеристического рентгеновского излучения элементов».


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

1903 — в Берлине французский учёный Пьер Кюри объявил об открытии нового химического элемента — полония.

1965 — корпорация Sony представила первый домашний видеомагнитофон по цене $995 — CV-2000.

1983 — запущена автоматическая межпланетная станция «Венера-16» для исследования Венеры.



#Biography #Birth_Date #Events #07июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Ты не хочешь стать программистом.

Ты хочешь, чтобы тебе дали 100500 рублей в минуту, удаленку и 3 рабочих часа в день 🏝

Нет? 😂
Не ври, ладно? Хотя-бы самому себе
😏

В (уже) далеких 1990-х я увидел первый компьютер.
В местном "Доме творчества" поставили несколько, и нас, детей, повели посмотреть на них. Дали поиграть в какую-то игру на зеленых экранах.
Мне кажется тогда я и заболел компьютерами. Но лишь спустя 20 лет я смог позволить себе купить его. А еще спустя 11 лет я познакомился с программированием.
Все эти годы я болел возможностью создавать что-то. Что-то свое. Ведь в детстве это казалось чудом - по экрану ездит квадратная машина и ты ей управляешь.
Много позже, разрабатывая сервера на Dayz и ARMA, реализуя в том мире все, что мог вообразить (и что позволяли знания), я все еще болел этим. Но по настоящему программировать я наверно я боялся, это казалось невозможным.
А потом пришла Java
💃
И пришла возможность написать все что я пожелаю.



А теперь задай себе вопрос - зачем ты здесь. На этом канале? В программировании?

Если Ты хочешь, чтобы программист появился внутри тебя сам, без боли, без тупежа, без стыда за глупые вопросы, особенно если ты до этого был(а) шахтером/строителем/токарем/поваром - у меня для тебя плохие новости.

Если Ты хочешь чтобы кто-то дал «тот самый» курс, «тот самый» язык, «ту самую» кнопку, нажав на которую — фьють и ты программист с зп в 500к, то как говорил наркоман Паша Техник - "ты что-то перепутал" 🤣


Так не будет.

Извини если обломал 🤷‍♀️


Сейчас, в жесткой конкуренции, начинание пути в IT, потребует от Тебя не просто уйти в минус.
Это и учеба вечерами после работы, куча пет-проектов в никуда, бесконечное количество собесов с «Мы отдали предпочтение более сильному кандидату, останемся на связи - мы вам обязательно позвоним!» верим, ага 😂

Ты заполняешь резюме на hh.ru с мыслью:
«Я считаю, что готов работать, дайте мне работу!»

Но на рынок переполнен «готовыми».
Каждый хочет сидеть в трусах перед монитором с любимой кошкой на коленях и получать за это хорошую зп.
Каждый хочет пить в офисе чай с печеньками и быть востребованным специалистом.

А чем ты лучше их?

И тогда, с этими мыслями 90% сдаются.
Уходят обратно в стабильное/известное/удобное.

Ты ведь тоже думал уйти, да? 😏
Я точно думал. И не раз 😔

Путь не будет легким.

Но он совершенно точно преодолим.
Если смог я - сможешь и ты.



Но!

Если Ты до сих пор листаешь списки курсов
, сравниваешь Java и Python, читаешь отзывы на Stepik и думаешь:
«Вот если бы найти один, но самый лучший — всё бы пошло».

Знай
- это ловушка. Курс не станет твоей волшебной палочкой.
Он не спасёт от ощущения «ничего не понятно», он не вытащит тебя в поток.
Потому что всё равно будет сложно.

Пока ты не взрастишь в себе интерес к созиданию через программирование. ☺️


Если Ты до сих пор ждёшь вдохновения -

Знай -
оно появится в момент, когда код заработает.
Ты думаешь, что сначала надо захотеть, а потом начать.

На деле — сначала ты начинаешь, и только потом хочешь.

Мотивация приходит не в начале.

Когда твой проект сбилдится, все тесты пройдут, тогда и появляется кайф. И мотивация. И желание.

А не из мотивационных видео, моих статей или чужих успехов.


Есть хорошая цитата Марка Твена
🤓:
«Выбери себе работу по душе, и тебе не придётся работать ни одного дня в своей жизни»
(«Choose a job you love, and you will never have to work a day in your life»).


Поэтому мой совет (который я даю всем кто попросит):
"Если Ты идешь в программирование за деньгами и "легкой" работой - либо взрасти в себе желание к созиданию, либо оно превратится для тебя в один из самых страшных кошмаров, с которым ты точно не справишься."



И
помни:
Ты не ленивый.
Ты просто попал в ловушку рекламы и иллюзий.
Мы все туда попали. ☺️😉

Но если ты все-такие решил(а) стать программистом — нужно перестать ждать и начать бороться, точно понимая, зачем и для чего тебе это.

Одно я могу обещать Тебе точно: если ты болеешь как и я - все получится. 💪


#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13
Ребят, продолжаю набор желающих обучиться Java! 🤓

Пишите в лс, все обсудим (@Oleborn) 🧑‍💻


И кстати маленький эксперимент - могут ли те кто когда либо обучался у меня (за все время, в том числе может по видео), дать обратную связь по качеству? ☺️

Хаахах, после этого точно больше ко мне никто не пойдет 🤣😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣2👍1
История технологии сегодня — 8 июня

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

Гу́рий Ива́нович Марчу́к (8 июня 1925, Петрохерсонец, Самарская губерния — 24 марта 2013, Москва) — советский и российский учёный в области вычислительной математикифизики атмосферы и геофизики. Автор более 350 научных работ по вычислительной и прикладной математике, в том числе по методам расчёта ядерных реакторов, математическому моделированию в задачах физики атмосферы и океана, окружающей среды, в иммунологии и медицине.

Тимоти Джон Бе́рнерс-Ли (англ. Timothy John «Tim» Berners-Lee; род. 8 июня 1955 года, Лондон) — британский информатик, наиболее известный как создатель URIURLHTTPHTML и Всемирной паутины (совместно с Робертом Кайо) и действующий глава Консорциума Всемирной паутины. Автор концепции семантической паутины, множества других разработок в области информационных технологий. В 1989 году, работая в ЦЕРН над внутренней системой обмена документов Enquire, Бернерс-Ли предложил глобальный гипертекстовый проект, ныне известный как Всемирная паутина. Проект был утверждён и реализован. С 1991 по 1993 год Тим Бернерс-Ли продолжал работу над Всемирной паутиной. Он собирал отзывы от пользователей и координировал работу Паутины. Тогда он впервые предложил для широкого обсуждения свои первые спецификации URIHTTP и HTML.

Фрэнсис Гарри Комптон Крик (англ. Francis Harry Compton Crick; 8 июня 1916, Нортгемптон, Англия, Великобритания — 28 июля 2004, Сан-Диего, Калифорния, США) — британский молекулярный биолог, биофизик и нейробиолог. Лауреат Нобелевской премии по физиологии или медицине 1962 года — совместно с Джеймсом Д. Уотсоном и Морисом Х. Ф. Уилкинсом с формулировкой «за открытия, касающиеся молекулярной структуры нуклеиновых кислот и их значения для передачи информации в живых системах».

В статье, опубликованной в журнале 
Nature в 1961 году, Крик с соавторами предположили четыре свойства генетического кода:
три азотистых основания (триплет) кодируют одну 
аминокислоту;
триплеты генетического кода не перекрываются;
последовательности триплетов считываются с определённой начальной точки, знаки препинания внутри кодирующей последовательности отсутствуют;
генетический код вырожден — одна аминокислота может быть закодирована разными триплетами.
Также Крик известен тем, что сформулировал 
центральную догму молекулярной биологии: генетическая информация передаётся в клетке в одну сторону, от ДНК к РНК, а затем к белку.


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

1824 — Ноа Кашинг (Noah Cushing) из Квебека запатентовал одну из ранних стиральных машин.

1869 — Айвз Макгаффи (Ives W. McGaffey) из Чикаго запатентовал модель подметательной машины — один из ранних пылесосов.


1940 — объявлено об открытии нептуния, 93-го элемента в таблице периодических элементов.

1948 — под руководством И. В. Курчатова в Челябинске-40 (ныне Озёрск) осуществляется пуск первого отечественного промышленного ядерного реактора.



#Biography #Birth_Date #Events #08июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
[Совет по Java #047]

Тема: clone() — опасный метод с неясной семантикой.

Проблема: Метод clone() из интерфейса Cloneable имеет множество проблем.

Во-первых, Cloneable — это маркерный интерфейс без метода clone(), объявление метода находится в Object.
Во-вторых, реализация по умолчанию делает поверхностное копирование (shallow copy), что приводит к тому, что внутренние объекты не копируются, а разделяются между оригиналом и копией.
В-третьих, метод clone() возвращает Object, требуется приведение типа.
В-четвертых, он может выбрасывать CloneNotSupportedException, если класс не реализует Cloneable. Кроме того, clone() не вызывает конструктор, что может нарушить инварианты класса.

Для полей с final модификатором клонирование также проблематично. В итоге правильно реализовать clone() с глубоким копированием сложно, и многие разработчики ошибаются в деталях.

Решение: Используйте копирующие конструкторы (конструктор, принимающий объект того же типа) или статические фабричные методы копирования.

Они явны, безопасны, работают с final полями и могут быть легко расширены для глубокого копирования. Для immutable объектов копирование вообще не нужно — можно использовать тот же экземпляр. Для сложных иерархий можно использовать интерфейс Copyable с методом copy(), возвращающим копию.

Начиная с Java 16, можно использовать record — они иммутабельны и предоставляют компактный конструктор копирования.
public class CloneVsCopy {

//Проблемный clone
static class PersonBad implements Cloneable {
String name;
List<String> hobbies;

PersonBad(String name, List<String> hobbies) {
this.name = name;
this.hobbies = new ArrayList<>(hobbies);
}

@Override
public PersonBad clone() {
try {
PersonBad cloned = (PersonBad) super.clone(); // shallow copy!
// hobbies все еще ссылается на тот же список
return cloned;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}

//Копирующий конструктор
static class PersonGood {
final String name;
final List<String> hobbies;

PersonGood(String name, List<String> hobbies) {
this.name = name;
this.hobbies = new ArrayList<>(hobbies);
}

// Копирующий конструктор
PersonGood(PersonGood other) {
this.name = other.name;
this.hobbies = new ArrayList<>(other.hobbies); // глубокое копирование
}

// Статическая фабрика
static PersonGood copyOf(PersonGood other) {
return new PersonGood(other);
}

PersonGood withName(String name) {
return new PersonGood(name, this.hobbies);
}
}

//Record (Java 16+) — идеален для immutable данных
record PersonRecord(String name, List<String> hobbies) {
PersonRecord {
// Защитное копирование в компактном конструкторе
hobbies = List.copyOf(hobbies);
}

// Record автоматически предоставляет конструктор копирования
}
}


Объяснение:
 Cloneable и clone() считаются неудачным дизайном в Java.

Проблемы: нет контракта на глубину копирования, clone() не вызывает конструктор, сложно поддерживать при наследовании. Копирующий конструктор явен, понятен и позволяет контролировать глубину копирования. Для immutable объектов делитесь ссылкой. Для сложных графов используйте сериализацию (осторожно) или библиотеки вроде com.fasterxml.jackson.databind.ObjectMapper.

#Java #советы
👍6
Что выведет код?

public class Task080626 {
static class Data implements Cloneable {
int[] values = {1, 2, 3};

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

public static void main(String[] args) throws CloneNotSupportedException {
Data original = new Data();
Data cloned = (Data) original.clone();
cloned.values[0] = 100;

System.out.println(original.values[0]);
System.out.println(cloned.values[0]);
}
}


#Tasks
👍2
Варианты ответа:
Anonymous Quiz
17%
1 100
58%
100 100
8%
1 1
17%
Исключение
👍2
Вот что нас ждет в будущем... 😂

Кто предупрежден тот вооружен💃
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯2
Что такое transferTo в FileChannel? 🤓

Ответ:

FileChannel.transferTo(long position, long count, WritableByteChannel target) — высокоэффективный метод для копирования данных из файла в другой канал (например, в сокет) в режиме ядра, без перекачки данных в пользовательское пространство.

Используется для оптимизации веб-серверов (отправка статических файлов) — так называемый zero-copy. Метод transferFrom() — аналогично для копирования в файл.

Работает не полностью zero-copy на всех ОС, но значительно быстрее, чем побайтовое чтение/запись.



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

А как вы начинаете свой день?🤨
🔥6
История технологии сегодня — 9 июня

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

Джордж Стефенсон (англ. George Stephenson; 9 июня 1781, Уилэм, графство Нортамберленд — 12 августа 1848, Честерфилд, графство Дербишир) — английский изобретатель, инженер-механик. Всемирную известность приобрёл благодаря изобретённому им паровозу. Считается одним из «отцов» железных дорог. Стефенсон предложил использовать железные рельсы (вместо чугунных), а подушки, которые в дальнейшем превратились в шпалы, делать деревянными.

Иоганн Готтфрид Га́лле (нем. Johann Gottfried Galle; 9 июня 1812, Радис — 10 июля 1910, Потсдам) — немецкий астроном. 23 сентября 1846 года получил письмо от У. Леверье с просьбой провести поиск заурановой планеты по предвычисленным им координатам. В тот же вечер Галле отыскал новую планету, получившую позже название Нептун. В его честь названы кратер на Луне и кратер на Марсе, кольцо Нептуна и астероид № 2097 (Галле).


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

1959 — на воду спущена первая подводная лодка с баллистическими ракетами на борту — американская «Джордж Вашингтон».


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

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

Проблема производительности побайтового ввода/вывода. Идея буфера

Побайтовое чтение или запись через InputStream.read() и OutputStream.write(int) кажутся простыми и интуитивными, но скрывают фундаментальную проблему: каждый вызов инициирует полный цикл системного вызова операционной системы. Этот цикл включает переключение контекста процессора из userspace в kernelspace, выполнение кода ядра, и обратное переключение. Стоимость этого цикла на современных процессорах составляет 100-1000 наносекунд, что на порядки превышает стоимость чтения байта из оперативной памяти.

Рассмотрим детальный путь одного вызова read():
Подготовка параметров в регистрах процессора. JVM помещает файловый дескриптор и адрес буфера в регистры.
Инструкция syscall или sysenter. Процессор переключается в привилегированный режим, сохраняя состояние userspace.
Обработка в ядре ОС. Ядро проверяет валидность дескриптора, ищет страницу в page cache, при промахе (page fault) инициирует чтение с диска.
Копирование данных. Ядро копирует данные из page cache в нативный буфер userspace.
Возврат в userspace. Восстановление состояния регистров, возврат управления JVM.
Копирование в heap. JNI-код копирует данные из нативного буфера в массив byte[] в heap.

Для одного байта этот цикл избыточен в 1000 раз. Файл размером 1 MB требует 1 048 576 таких циклов. При стоимости 500 нс на вызов общее время составляет 524 мс только на системные вызовы, без учета фактического чтения данных.

Демонстрация: копирование 1 MB побайтово
public class ByteByByteCopy {

public static void copyByteByByte(String source, String dest) throws IOException {
long start = System.nanoTime();
int totalBytes = 0;

try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest)) {

int byteValue;
// Каждая итерация = полный цикл системного вызова
while ((byteValue = fis.read()) != -1) {
fos.write(byteValue); // Еще один системный вызов на запись
totalBytes++;
}
}

long duration = (System.nanoTime() - start) / 1_000_000;
System.out.printf("Copied %d bytes in %d ms (byte-by-byte)%n", totalBytes, duration);
}

public static void main(String[] args) throws IOException {
// Создание тестового файла 1 MB
byte[] oneMB = new byte[1024 * 1024];
new Random().nextBytes(oneMB);
try (FileOutputStream fos = new FileOutputStream("source.bin")) {
fos.write(oneMB);
}

// Побайтовое копирование
copyByteByByte("source.bin", "dest_byte_by_byte.bin");
}
}

Ожидаемый результат на современном оборудовании: 500-2000 мс для 1 MB. Причина не в скорости диска (современные SSD читают 1 MB за 2-5 мс), а в накладных расходах системных вызовов.


Путь данных в памяти при побайтовом чтении

Каждый вызов read() создает уникальный путь через память:
Поток выполнения:
[Java-код: read()]
-> [JVM: нативный метод read0()]
-> [JNI: переход в нативный код]
-> [Ядро ОС: syscall read(fd, buf, 1)]
-> [Page Cache: поиск страницы 4KB]
-> [При промахе: чтение с диска в page cache]
-> [Копирование: 1 байт из page cache в нативный буфер]
-> [Возврат в userspace]
-> [JNI: копирование 1 байта в heap]
-> [Java: возврат int]

Критический недостаток: page cache работает со страницами 4KB. Чтение одного байта из файла загружает целую страницу в page cache. При последовательном побайтовом чтении каждый следующий байт попадает в уже загруженную страницу, но системный вызов все равно выполняется. Page cache эффективен, но syscall-ов слишком много.


#Java #для_новичков #beginner #IO #NIO #BufferedInputStream
👍4
Идея буфера: чтение и запись блоками

Буферизация решает проблему, заменяя множество мелких системных вызовов на один крупный. Вместо чтения одного байта за раз, приложение запрашивает блок данных — обычно 4KB, 8KB или 64KB — одним системным вызовом, а затем извлекает байты из блока в памяти без обращения к ОС.

Математика выигрыша
Для файла 1 MB:
Побайтово: 1 048 576 системных вызовов чтения + 1 048 576 вызовов записи = 2 097 152 syscall
Буфер 4KB: 256 системных вызовов чтения + 256 вызовов записи = 512 syscall

Сокращение: в 4096 раз
public class BufferedCopy {

public static void copyWithBuffer(String source, String dest, int bufferSize)
throws IOException {
long start = System.nanoTime();
int totalBytes = 0;

// Буфер создается в heap Eden space
// Для bufferSize = 4096: 4KB массив, быстро собирается GC если не переиспользуется
byte[] buffer = new byte[bufferSize];

try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest)) {

int bytesRead;
// Каждая итерация = один системный вызов на чтение блока
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead); // Один системный вызов на запись блока
totalBytes += bytesRead;
}
}

long duration = (System.nanoTime() - start) / 1_000_000;
System.out.printf("Copied %d bytes in %d ms (buffer=%d bytes)%n",
totalBytes, duration, bufferSize);
}

public static void main(String[] args) throws IOException {
// Тест с разными размерами буфера
int[] sizes = {128, 512, 1024, 4096, 8192, 65536};
for (int size : sizes) {
copyWithBuffer("source.bin", "dest_" + size + ".bin", size);
}
}
}


Ожидаемые результаты для 1 MB файла на SSD:
128 bytes: ~50 ms
512 bytes: ~15 ms
4096 bytes: ~5 ms
8192 bytes: ~4 ms
65536 bytes: ~4 ms

Выигрыш снижается после 8KB, так как это типичный размер страницы ОС и размер блока файловой системы. Большие буферы не дают дополнительного выигрыша, но увеличивают потребление памяти в heap.

Путь данных в памяти при буферизованном чтении
Первая итерация read(buffer[4096]):
[Java-код: read(buffer)]
-> [JVM: нативный метод readBytes()]
-> [JNI: переход в нативный код]
-> [Ядро ОС: syscall read(fd, buf, 4096)]
-> [Page Cache: поиск страниц, загрузка при необходимости]
-> [Копирование: 4096 байт из page cache в нативный буфер]
-> [Возврат в userspace]
-> [JNI: копирование 4096 байт в buffer[4096] в heap]
-> [Java: возврат 4096]

Вторая итерация read(buffer[4096]):
[Java-код: read(buffer)]
-> [JVM: нативный метод readBytes()]
-> [JNI: переход в нативный код]
-> [Ядро ОС: syscall read(fd, buf, 4096)]
-> [Page Cache: страницы уже в кэше]
-> [Копирование: 4096 байт]
-> [Возврат]
-> [JNI: копирование 4096 байт в buffer в heap]
-> [Java: возврат 4096]

// Всего 256 итераций для 1 MB вместо 1 048 576



Роль garbage collector и памяти

Буфер в Eden space
Массив byte[], созданный как буфер, размещается в Eden space young generation. Если метод copyWithBuffer вызывается редко, буфер собирается при следующем minor GC.

Если метод вызывается в цикле обработки множества файлов, буфер может быть повышен до survivor space или даже old generation при частом выделении других объектов.
// Антипаттерн: создание буфера внутри цикла
for (String file : files) {
byte[] buffer = new byte[8192]; // Создание при каждой итерации
copyFile(file, buffer);
// buffer становится мусором, GC собирает его
}



#Java #для_новичков #beginner #IO #NIO #BufferedInputStream
👍4
Этот код создает множество короткоживущих массивов, нагружая GC. Правильный подход — переиспользование:

// Паттерн: переиспользование буфера
byte[] buffer = new byte[8192]; // Один буфер на все итерации
for (String file : files) {
copyFile(file, buffer); // Передача по ссылке, без создания
}
// Буфер живет до выхода из метода, собирается одним GC



ThreadLocal для многопоточности

В многопоточном приложении совместное использование одного буфера требует синхронизации. ThreadLocal предоставляет каждому потоку свой буфер, устраняя contention:
public class ThreadLocalBuffer {
// Каждый поток получает свой буфер 8KB
private static final ThreadLocal<byte[]> BUFFER =
ThreadLocal.withInitial(() -> new byte[8192]);

public void copyFileThreadSafe(String source, String dest) throws IOException {
byte[] buffer = BUFFER.get(); // Буфер потока, без синхронизации

try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest)) {
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
// Буфер остается в ThreadLocal, не собирается GC между вызовами
}
}

Память: N потоков * 8KB = N * 8KB в heap на протяжении жизни потоков. Это компромисс между памятью и производительностью. Буферы в ThreadLocal живут долго и могут быть повышены в old generation, что увеличивает размер heap, но устраняет аллокации в hot path.


Humongous objects и G1 GC


Буферы размером более половины размера G1-региона (обычно > 512KB для региона 1MB) считаются humongous objects. Они размещаются в специальных humongous-регионах old generation и не перемещаются при minor GC.

Это увеличивает фрагментацию heap и может вызвать преждевременный full GC.
// Потенциально проблематично: 1MB буфер как humongous object
byte[] largeBuffer = new byte[1024 * 1024];

// Предпочтительнее: несколько итераций с 8KB буфером
byte[] smallBuffer = new byte[8192];
for (int i = 0; i < 128; i++) { // 128 * 8KB = 1MB
fis.read(smallBuffer);
// Обработка
}



BufferedInputStream: встроенная буферизация

Java предоставляет готовую обертку BufferedInputStream, которая инкапсулирует логику буферизации:
// Внутреннее устройство BufferedInputStream
public class BufferedInputStream extends FilterInputStream {
protected volatile byte[] buf; // Буфер в heap
protected int count; // Количество доступных байт
protected int pos; // Текущая позиция чтения
protected int markpos = -1; // Позиция маркера

// Конструктор по умолчанию: buf = new byte[8192]
public BufferedInputStream(InputStream in) {
this(in, 8192);
}
}


При чтении BufferedInputStream сначала проверяет, есть ли данные в buf. Если есть — возвращает байт из буфера без системного вызова. Если буфер пуст — выполняет fill(), который читает до buf.length байт из underlying потока одним системным вызовом.
// Использование: прозрачная буферизация
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("source.bin"))) {

int byteValue;
// Чтение выглядит побайтовым, но фактически буферизовано
while ((byteValue = bis.read()) != -1) {
processByte(byteValue);
}
}

Путь данных с BufferedInputStream:
Первый read(): fill() читает 8192 байт в buf (heap), возвращает buf[0]
Второй read(): возвращает buf[1] из heap, системный вызов отсутствует
8193-й read(): буфер пуст, fill() выполняет новый системный вызов

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

#Java #для_новичков #beginner #IO #NIO #BufferedInputStream
👍4
Что выведет код?

import java.io.*;

public class Task090626 {
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter("out.txt");
pw.print("Hello");
try (BufferedReader br = new BufferedReader(new FileReader("out.txt"))) {
System.out.println(br.readLine());
}
}
}


#Tasks
👍3
👍3
Я думал так только в анекдотах бывает 😂
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯7
Что такое DirectByteBuffer и off-heap memory? 🤓

Ответ:

DirectByteBuffer — это класс, который выделяет память вне кучи (off-heap), напрямую через операционную систему.

Такая память не управляется GC (но объект-буфер — в куче).

Преимущества:
1) эффективный ввод-вывод (можно передать ядру без копирования).
2) снижение нагрузки на GC.
3) работа с большими блоками памяти.

Недостатки:
сложность управления (ручное освобождение через Cleaner или sun.misc.Unsafe).

Используется в NIO, Netty, Cassandra. Утечки off-heap памяти могут привести к OutOfMemoryError типа "Direct buffer memory".



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Let's Encrypt присоединился к санкциям

https://news.ycombinator.com/item?id=48453275#48465754

Тревожных новостей вам с утра, для тех кто в теме 🧑‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM