История технологии сегодня — 31 мая
ℹ️ Кто родился в этот день
Евгений Павлович Тверитинов (19 [31] мая 1850, Кронштадт, Санкт-Петербургская губерния — 3 апреля 1920, Кронштадт, Петроградская губерния) — офицер Российского императорского флота, первый русский флотский электрик, специалист по минной и корабельной электротехнике, изобретатель и создатель нового типа электрического аккумулятора. Впервые в России оборудовал боевые корабли установками электрического освещения, организовал электрическую иллюминацию Кремля и колокольни Ивана Великого при коронации императора Александра III и его супруги.
Джей Глен Майнер (англ. Jay Glenn Miner, также Джей Майнер; 31 мая 1932 года — 20 июня 1994 года) — знаменитый разработчик микросхем, известный прежде всего как человек, благодаря которому стало возможным воплощение концепций, позднее получивших название мультимедиа. Основной разработчик первого в мире мультимедийного персонального компьютера Amiga 1000 (1985 год). Взгляды Джея Майнера настолько опережали время, что сегодня он воспринимается многими как провидец, который, прежде всего, сам внёс посильную лепту в осуществление своей мечты.
Джон Роберт Шри́ффер (англ. John Robert Schrieffer; 31 мая 1931, Ок-Парк, Иллинойс, США — 27 июля 2019) — американский физик, лауреат Нобелевской премии по физике (1972, совместно с Джоном Бардином и Леоном Н. Купером) за создание БКШ-теории, названной по их инициалам. В 1956 году Шриффер, Бардин и Купер разработали теорию сверхпроводимости кристаллических твёрдых тел, основанную на представлении о сверхтекучести куперовских пар электронов.
🌐 Знаковые события
1946 — образовано самолётостроительное ОКБ О. К. Антонова.
#Biography #Birth_Date #Events #31мая
Евгений Павлович Тверитинов (19 [31] мая 1850, Кронштадт, Санкт-Петербургская губерния — 3 апреля 1920, Кронштадт, Петроградская губерния) — офицер Российского императорского флота, первый русский флотский электрик, специалист по минной и корабельной электротехнике, изобретатель и создатель нового типа электрического аккумулятора. Впервые в России оборудовал боевые корабли установками электрического освещения, организовал электрическую иллюминацию Кремля и колокольни Ивана Великого при коронации императора Александра III и его супруги.
Джей Глен Майнер (англ. Jay Glenn Miner, также Джей Майнер; 31 мая 1932 года — 20 июня 1994 года) — знаменитый разработчик микросхем, известный прежде всего как человек, благодаря которому стало возможным воплощение концепций, позднее получивших название мультимедиа. Основной разработчик первого в мире мультимедийного персонального компьютера Amiga 1000 (1985 год). Взгляды Джея Майнера настолько опережали время, что сегодня он воспринимается многими как провидец, который, прежде всего, сам внёс посильную лепту в осуществление своей мечты.
Джон Роберт Шри́ффер (англ. John Robert Schrieffer; 31 мая 1931, Ок-Парк, Иллинойс, США — 27 июля 2019) — американский физик, лауреат Нобелевской премии по физике (1972, совместно с Джоном Бардином и Леоном Н. Купером) за создание БКШ-теории, названной по их инициалам. В 1956 году Шриффер, Бардин и Купер разработали теорию сверхпроводимости кристаллических твёрдых тел, основанную на представлении о сверхтекучести куперовских пар электронов.
1946 — образовано самолётостроительное ОКБ О. К. Антонова.
#Biography #Birth_Date #Events #31мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
История технологии сегодня — 1 июня
ℹ️ Кто родился в этот день
Ма́ркус Алексе́й Пе́рссон (швед. Markus Alexej Persson [ˈmǎrkɵs ˈpæ̌ːʂɔn] о файле, также известный под никнеймом Notch; род. 1 июня 1979, Стокгольм, Швеция) — шведский программист и геймдизайнер, бывший владелец компании Mojang Studios. Является создателем популярной компьютерной игры Minecraft. Самый популярный проект Перссона — компьютерная игра в жанре песочницы с элементами симулятора выживания и открытым миром Minecraft, выпущенная 18 ноября 2011 года. Ради работы над игрой Перссон уволился с поста гейм-дизайнера. В начале 2011 года Mojang AB продала первый миллион копий игры, через несколько месяцев — второй и через ещё несколько месяцев — третий. Mojang наняла нескольких разработчиков в команду Minecraft после того, как Перссон передал пост главного разработчика Йенсу Бергенстену (jeb_). Игра была адаптирована под iOS и Android. Версия для Xbox появилась 9 мая 2012 года и включает несколько нововведений, например, возможность обучения и несколько текстур-паков и скинов. После продажи Mojang Microsoft за 2,5 миллиарда долларов Перссон прекратил работу над проектом, а его место занял программист Йенс Бергенстен.
Эдвард Чарльз Титчмарш (англ. Edward Charles Titchmarsh, 1 июня 1899, Ньюбери, Беркшир, Англия, Великобритания — 18 января 1963, Оксфорд, Оксфордшир, Англия, Великобритания) — английский математик, специалист по математическому анализу и аналитической теории чисел. Написал около 130 статей по математике, а также пять монографий, один учебник («Теория функций») и одну популярную книгу. Его работы были посвящены рядам Фурье, интегралам Фурье, целым функциям, интегральным уравнениям, дифференциальным уравнениям второго порядка, исследованию свойств дзета-функции Римана, а также другим математическим проблемам.
🌐 Знаковые события
1936 — открылась первая в СССР трансконтинентальная авиалиния из Москвы во Владивосток. В те времена перелёты совершались с промежуточными посадками — за 4 суток.
#Biography #Birth_Date #Events #01июня
Ма́ркус Алексе́й Пе́рссон (швед. Markus Alexej Persson [ˈmǎrkɵs ˈpæ̌ːʂɔn] о файле, также известный под никнеймом Notch; род. 1 июня 1979, Стокгольм, Швеция) — шведский программист и геймдизайнер, бывший владелец компании Mojang Studios. Является создателем популярной компьютерной игры Minecraft. Самый популярный проект Перссона — компьютерная игра в жанре песочницы с элементами симулятора выживания и открытым миром Minecraft, выпущенная 18 ноября 2011 года. Ради работы над игрой Перссон уволился с поста гейм-дизайнера. В начале 2011 года Mojang AB продала первый миллион копий игры, через несколько месяцев — второй и через ещё несколько месяцев — третий. Mojang наняла нескольких разработчиков в команду Minecraft после того, как Перссон передал пост главного разработчика Йенсу Бергенстену (jeb_). Игра была адаптирована под iOS и Android. Версия для Xbox появилась 9 мая 2012 года и включает несколько нововведений, например, возможность обучения и несколько текстур-паков и скинов. После продажи Mojang Microsoft за 2,5 миллиарда долларов Перссон прекратил работу над проектом, а его место занял программист Йенс Бергенстен.
Эдвард Чарльз Титчмарш (англ. Edward Charles Titchmarsh, 1 июня 1899, Ньюбери, Беркшир, Англия, Великобритания — 18 января 1963, Оксфорд, Оксфордшир, Англия, Великобритания) — английский математик, специалист по математическому анализу и аналитической теории чисел. Написал около 130 статей по математике, а также пять монографий, один учебник («Теория функций») и одну популярную книгу. Его работы были посвящены рядам Фурье, интегралам Фурье, целым функциям, интегральным уравнениям, дифференциальным уравнениям второго порядка, исследованию свойств дзета-функции Римана, а также другим математическим проблемам.
1936 — открылась первая в СССР трансконтинентальная авиалиния из Москвы во Владивосток. В те времена перелёты совершались с промежуточными посадками — за 4 суток.
#Biography #Birth_Date #Events #01июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😱1
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 1. Классический Java I/O (java.io)
Байтовые потоки: абстрактные классы InputStream и OutputStream
Байтовые потоки в Java представляют собой фундаментальный слой абстракции для работы с данными в их сыром, двоичном виде. Классы
Это разделение ответственности — транспорт без интерпретации — является ключевым архитектурным решением Java I/O. Байтовые потоки отвечают только за перемещение сырых данных между источником и назначением. Интерпретация этих данных — декодирование текста, парсинг изображений, десериализация объектов — возлагается на более высокие уровни абстракции, которые строятся поверх байтовых потоков через паттерн декоратора.
Использование байтовых потоков обязательно для любых бинарных форматов, где побитовая точность критична. Попытка чтения бинарного файла через символьные потоки (
Путь данных в памяти JVM: от диска до heap
Когда
Уровень 1: Диск и страничный кэш ОС. Файловая система читает данные с блочного устройства в страничный кэш ядра (page cache). Это память ядра операционной системы, недоступная напрямую из Java. Размер страницы обычно 4KB, и чтение меньшего объема все равно загружает целую страницу.
Уровень 2: Нативный буфер и системный вызов. JVM выполняет системный вызов
Уровень 3: Копирование в heap JVM. Данные из нативного буфера копируются в массив
Каждый вызов
Буферизация и сокращение пути данных
При первом вызове
Путь данных с буферизацией:
Первый
Второй
После исчерпания
Это сокращает количество системных вызовов с N до N/8192, где N — размер файла.
#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
Глава 1. Классический Java I/O (java.io)
Байтовые потоки: абстрактные классы InputStream и OutputStream
Байтовые потоки в Java представляют собой фундаментальный слой абстракции для работы с данными в их сыром, двоичном виде. Классы
InputStream и OutputStream оперируют единицей данных размером в 8 бит — байтом — и не накладывают никакой семантической интерпретации на прочитанные или записанные значения. Байт может быть частью изображения JPEG, аудиофрейма MP3, сериализованного объекта, зашифрованного пакета или любого другого бинарного формата.Это разделение ответственности — транспорт без интерпретации — является ключевым архитектурным решением Java I/O. Байтовые потоки отвечают только за перемещение сырых данных между источником и назначением. Интерпретация этих данных — декодирование текста, парсинг изображений, десериализация объектов — возлагается на более высокие уровни абстракции, которые строятся поверх байтовых потоков через паттерн декоратора.
Использование байтовых потоков обязательно для любых бинарных форматов, где побитовая точность критична. Попытка чтения бинарного файла через символьные потоки (
Reader/Writer) приведет к повреждению данных, так как символьные потоки применяют кодировку, трансформирующую последовательности байт в Unicode-символы. Для форматов вроде PNG, PDF, ZIP, MP4 или собственных бинарных протоколов единственно корректный выбор — байтовые потоки.Путь данных в памяти JVM: от диска до heap
Когда
FileInputStream.read() читает байт из файла, данные проходят через несколько уровней памяти прежде чем стать доступными Java-коду. Этот путь критичен для понимания производительности и поведения garbage collector.Уровень 1: Диск и страничный кэш ОС. Файловая система читает данные с блочного устройства в страничный кэш ядра (page cache). Это память ядра операционной системы, недоступная напрямую из Java. Размер страницы обычно 4KB, и чтение меньшего объема все равно загружает целую страницу.
Уровень 2: Нативный буфер и системный вызов. JVM выполняет системный вызов
read(), который копирует данные из страничного кэша ядра в нативный буфер в userspace. Это прямое копирование между kernel space и user space управляется DMA (Direct Memory Access) контроллером без участия CPU для самих данных, но требует переключения контекста процессора из userspace в kernelspace.Уровень 3: Копирование в heap JVM. Данные из нативного буфера копируются в массив
byte[], расположенный в heap JVM. Это вторая копия данных, и именно здесь начинает работать garbage collector.// read() возвращает int, но данные прошли путь: диск -> page cache -> нативный буфер -> heap
int byteValue = fileInputStream.read();
Каждый вызов
read() без буферизации порождает этот полный путь для одного байта. Системный вызов и переключение контекста стоят дороже самого чтения, что делает посимвольное чтение катастрофически неэффективным.Буферизация и сокращение пути данных
BufferedInputStream решает проблему, вводя промежуточный буфер в heap JVM:// BufferedInputStream внутренне содержит byte[] buf размером по умолчанию 8192 байт
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("data.bin"))) {
int b;
while ((b = bis.read()) != -1) {
processByte(b);
}
}
При первом вызове
read() BufferedInputStream читает до 8192 байт из underlying потока одним системным вызовом, заполняя внутренний массив buf. Последующие вызовы read() извлекают байты из этого массива без системных вызовов. Данные в buf — это обычный массив в heap, управляемый garbage collector.Путь данных с буферизацией:
Первый
read(): диск -> page cache -> нативный буфер -> buf[8192] в heap -> возврат buf[0]Второй
read(): buf[1] из heap (системный вызов отсутствует)После исчерпания
buf: повторение шага 1Это сокращает количество системных вызовов с N до N/8192, где N — размер файла.
#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
👍5
Роль garbage collector
Массив
Его жизненный цикл определяется ссылками:
Внутренний буфер
Объект
При выходе из блока
Если
Важный нюанс: при использовании
Крупные массивы и GC-pressure
При чтении больших файлов размер буфера влияет на поведение garbage collector:
Буфер в 1MB выделяется в heap как единый массив. В G1 GC массивы размером более половины размера региона (обычно > 512KB для региона 1MB) считаются humongous objects и размещаются в специальных humongous-регионах. Эти регионы освобождаются только полным циклом concurrent mark-sweep, что может увеличить паузы GC.
Для приложений с интенсивным I/O рекомендуется переиспользование буферов через пулы объектов, что устраняет накладные расходы на выделение и сборку:
Здесь буфер привязан к потоку через
#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
Массив
byte[], используемый как буфер, является обычным объектом в heap JVM.Его жизненный цикл определяется ссылками:
Внутренний буфер
BufferedInputStream удерживается ссылкой из самого объекта BufferedInputStreamОбъект
BufferedInputStream удерживается локальной переменной в стеке потока выполненияПри выходе из блока
try-with-resources вызывается close(), который обнуляет ссылку на underlying потокЕсли
BufferedInputStream становится недостижимым, GC помечает внутренний byte[] как мусорВажный нюанс: при использовании
BufferedInputStream внутри try-with-resources буфер освобождается предсказуемо при выходе из блока. Однако если ссылка на поток сохраняется в поле класса или передается в другие компоненты, GC не может освободить буфер до тех пор, пока объект BufferedInputStream остается достижимым. Утечки памяти в I/O-коде обычно связаны именно с забытыми ссылками на потоки, а не с самими данными.Крупные массивы и GC-pressure
При чтении больших файлов размер буфера влияет на поведение garbage collector:
// Маленький буфер: частые системные вызовы, но быстрое освобождение GC
byte[] smallBuffer = new byte[1024];
// Большой буфер: редкие системные вызовы, но большое выделение памяти
byte[] largeBuffer = new byte[1024 * 1024]; // 1MB
Буфер в 1MB выделяется в heap как единый массив. В G1 GC массивы размером более половины размера региона (обычно > 512KB для региона 1MB) считаются humongous objects и размещаются в специальных humongous-регионах. Эти регионы освобождаются только полным циклом concurrent mark-sweep, что может увеличить паузы GC.
Для приложений с интенсивным I/O рекомендуется переиспользование буферов через пулы объектов, что устраняет накладные расходы на выделение и сборку:
// Переиспользование буфера вместо создания нового при каждой операции
private static final ThreadLocal<byte[]> BUFFER = ThreadLocal.withInitial(() -> new byte[8192]);
public void processFile(String path) throws IOException {
byte[] buffer = BUFFER.get(); // Переиспользование, не создание
try (InputStream in = new FileInputStream(path)) {
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
processChunk(buffer, bytesRead);
}
}
// Буфер остается в ThreadLocal, не подлежит GC между вызовами
}
Здесь буфер привязан к потоку через
ThreadLocal и не создается заново при каждом вызове. Это устраняет аллокации в hot path, но требует осторожности: буфер занимает память на протяжении жизни потока, даже когда не используется.#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
👍2
InputStream: чтение байтов
Контракт read(): возврат -1 при конце потока
Контракт метода
Этот контракт определяет стандартный паттерн чтения:
Этот код функционально корректен, но крайне неэффективен: каждый вызов
Правильный подход — буферизованное чтение:
Здесь
#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
InputStream — абстрактный класс, определяющий контракт для всех входных байтовых потоков. Его методы реализуют семантику последовательного чтения: данные извлекаются из источника в порядке FIFO, и невозможно вернуться назад без специальных механизмов (mark/reset, доступных не во всех реализациях).int read() — читает один байт из потока. Возвращает значение в диапазоне 0-255 как int, что позволяет различать валидные байты (0-255) от признака конца потока. Когда достигнут конец потока, метод возвращает -1. Этот контракт фундаментален: -1 — единственный способ узнать, что данные в источнике исчерпаны. Возврат int вместо byte обусловлен необходимостью представления 256 возможных значений байта плюс специальное значение -1 для EOF. Тип byte в Java знаковый и имеет диапазон -128..127, что не позволил бы различить байт 0xFF (255 беззнаковый, -1 знаковый) от признака конца потока.int read(byte[] b) — читает байты в предоставленный массив, заполняя его полностью или частично. Возвращает количество фактически прочитанных байт, или -1 при достижении конца потока. Этот метод существенно эффективнее посимвольного чтения, так как уменьшает количество системных вызовов. Однако он не гарантирует заполнение всего массива — при неполных данных возвращается меньшее количество байт, и приложение должно обработать эту ситуацию.int read(byte[] b, int off, int len) — читает до len байт в массив b, начиная с позиции off. Возвращает количество прочитанных байт или -1. Этот метод предоставляет максимальный контроль над буферизацией.
long skip(long n) — пропускает до n байт в потоке. Возвращает количество фактически пропущенных байт, которое может быть меньше n.int available() — возвращает оценку количества байт, которые можно прочитать без блокирования. Для файловых потоков это обычно оставшийся размер файла, для сетевых — количество данных в сокет-буфере. Значение 0 не означает конец потока, а только отсутствие немедленно доступных данных.void close() — закрывает поток и освобождает связанные системные ресурсы: файловые дескрипторы, сокеты, соединения с базой данных. Реализации InputStream не объявляют close() как AutoCloseable, но все конкретные подклассы реализуют этот интерфейс, что позволяет использовать try-with-resources.void mark(int readlimit) и void reset() — поддержка маркировки позиции в потоке для последующего возврата. Доступность проверяется через boolean markSupported(). Большинство потоков, основанных на внешних ресурсах (файлы, сети), не поддерживают эту операцию.Контракт read(): возврат -1 при конце потока
Контракт метода
read() требует особого внимания. Метод блокирует выполнение до тех пор, пока не станет доступен хотя бы один байт, не произойдет IOException, или не будет достигнут конец потока. При нормальном завершении потока возвращается -1, и все последующие вызовы read() также возвращают -1.Этот контракт определяет стандартный паттерн чтения:
// Антипаттерн: чтение байта за байтом без буферизации
public void readByteByByte(InputStream in) throws IOException {
int byteValue;
while ((byteValue = in.read()) != -1) {
processByte(byteValue);
}
}
Этот код функционально корректен, но крайне неэффективен: каждый вызов
read() порождает системный вызов для чтения одного байта. Для файлов это означает обращение к диску, для сети — ожидание пакета.Правильный подход — буферизованное чтение:
// Паттерн: буферизованное чтение с обработкой частичного заполнения
public void readBuffered(InputStream in) throws IOException {
byte[] buffer = new byte[8192]; // 8KB — типичный размер страницы ОС
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
processBuffer(buffer, bytesRead);
}
}
Здесь
read(buffer) читает до 8192 байт за один системный вызов. Возвращаемое значение bytesRead обязательно проверяется: оно может быть меньше размера буфера, особенно при чтении из сети или при достижении конца файла. Признак конца потока -1 завершает цикл.#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
👍5
OutputStream: запись байтов
Контракт flush(): гарантия доставки
Метод
Для гарантии физической записи используется
Цепочка оберток: паттерн декоратора
Архитектура Java I/O построена на паттерне декоратора: базовые потоки (
Важное правило: закрывается только внешняя обертка. Вызов
Практический пример: копирование бинарного файла
Этот пример демонстрирует ключевые практики: буферизованное чтение для минимизации системных вызовов, проверку возвращаемого значения
#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
OutputStream — абстрактный класс, определяющий контракт для всех выходных байтовых потоков. Семантика записи также последовательная: байты отправляются в назначение в порядке вызова методов write.void write(int b) — записывает один байт. Параметр типа int, но записываются младшие 8 бит. Старшие 24 бита игнорируются. Это согласовано с read(), возвращающим int.void write(byte[] b) — записывает весь массив байт.void write(byte[] b, int off, int len) — записывает len байт из массива b, начиная с позиции off.void flush() — принудительно сбрасывает буферизованные данные в назначение. Многие реализации OutputStream используют внутреннюю буферизацию для повышения производительности: данные накапливаются в памяти и записываются пачками. flush() гарантирует, что все накопленные данные немедленно отправлены. Это критично для сценариев, где задержка недопустима: протоколы запрос-ответ, логирование в реальном времени, интерактивные сессии.void close() — закрывает поток, освобождает ресурсы и неявно вызывает flush() для сброса оставшихся буферизованных данных. После закрытия потока любые последующие операции выбрасывают IOException.Контракт flush(): гарантия доставки
Метод
flush() не гарантирует физическую запись на диск или отправку по сети — он гарантирует только передачу данных из пользовательского буфера в операционную систему. Фактическая запись на носитель контролируется ОС и может быть отложена.Для гарантии физической записи используется
FileChannel.force(true) в NIO.// Пример: flush перед ожиданием ответа
public void sendRequest(OutputStream out, byte[] request) throws IOException {
out.write(request);
out.flush(); // Гарантирует, что запрос отправлен до чтения ответа
// Теперь можно читать ответ, не рискуя deadlock из-за буферизации
}
Цепочка оберток: паттерн декоратора
Архитектура Java I/O построена на паттерне декоратора: базовые потоки (
FileInputStream, SocketInputStream) предоставляют минимальную функциональность, а обертки (BufferedInputStream, DataInputStream, GZIPInputStream) добавляют возможности без изменения базового интерфейса.// Цепочка оберток: буферизация + типизированное чтение + сжатие
try (InputStream fis = new FileInputStream("data.bin");
BufferedInputStream bis = new BufferedInputStream(fis, 8192);
DataInputStream dis = new DataInputStream(bis);
GZIPInputStream gzis = new GZIPInputStream(dis)) {
int magicNumber = dis.readInt(); // Чтение 4-байтового int
long timestamp = dis.readLong(); // Чтение 8-байтового long
double value = dis.readDouble(); // Чтение 8-байтового double
String label = dis.readUTF(); // Чтение строки в модифицированном UTF-8
}
Важное правило: закрывается только внешняя обертка. Вызов
close() на GZIPInputStream проксируется через всю цепочку к FileInputStream, корректно освобождая все ресурсы. try-with-resources обрабатывает это автоматически.Практический пример: копирование бинарного файла
public void copyBinaryFile(String sourcePath, String destPath) throws IOException {
// Буфер 8KB — оптимальный размер для большинства файловых систем
byte[] buffer = new byte[8192];
try (InputStream in = new FileInputStream(sourcePath);
OutputStream out = new FileOutputStream(destPath)) {
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
out.flush(); // Явный flush перед закрытием
}
}Этот пример демонстрирует ключевые практики: буферизованное чтение для минимизации системных вызовов, проверку возвращаемого значения
read для корректной обработки частичного чтения, запись ровно прочитанного количества байт, и явный flush перед закрытием. try-with-resources гарантирует закрытие обоих потоков даже при исключении.#Java #для_новичков #beginner #IO #NIO #InputStream #OutputStream
👍5
Вакансия_Backend_Разработчик_2026_МИС3.pdf
95.2 KB
Требования:
- как я понял, от 1 года, но в резюме этого нет
- вилка 90-120к, не фонтан, но требования, возможно будут проще
- гибрид или удаленка для ответственных
- наличие практического опыта работы с нейросетями/ИИ для ускорения разработки (не говорите, что у вас нет)
Контакт:
https://t.me/OlesyaSbytova
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1🤯1
Что выведет код?
#Tasks
import java.io.*;
public class Task010626 {
public static void main(String[] args) throws IOException {
byte[] data = {10, 20, 30, 40, 50};
InputStream is = new BufferedInputStream(new ByteArrayInputStream(data), 2);
is.mark(1);
is.read();
is.read();
is.reset();
System.out.println(is.read());
}
}
#Tasks
👍2
👍2
Как работает finally с return?🤓
Ответ:
Если в блоках try или catch есть оператор return, то блок finally всё равно выполнится перед фактическим возвратом значения.
Если finally также содержит return, то он переопределит возвращаемое значение из try/catch.
Исключение, выброшенное в finally, будет иметь приоритет над исключением из try/catch. Поэтому в finally не рекомендуется использовать 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июня
Оле́г Бори́сович Лупа́нов (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😎
Возьму еще буквально пару человек.
Пишите @oleborn
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
[Совет по Java #045]
Тема:
Проблема: Ключевое слово
Однако оно не делает операции атомарными. Операция инкремента (
Решение: Для атомарных счетчиков используйте классы из пакета
Их методы
Для простых флагов (
Объяснение:
Инкремент — это read-modify-write. Даже если переменная
#Java #советы
Тема:
volatile не гарантирует атомарность.Проблема: Ключевое слово
volatile обеспечивает видимость изменений между потоками (запись в volatile переменную происходит в main memory, чтение — также из main memory) и запрещает переупорядочивание инструкций. Однако оно не делает операции атомарными. Операция инкремента (
count++) состоит из трех действий: чтение значения, увеличение на 1, запись нового значения. Два потока могут одновременно прочитать одно и то же значение, увеличить его и записать обратно. В результате один инкремент будет потерян, и финальное значение будет меньше ожидаемого. Решение: Для атомарных счетчиков используйте классы из пакета
java.util.concurrent.atomic: AtomicInteger, AtomicLong. Их методы
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
Что выведет код?
#Tasks
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
👍2