История технологии сегодня — 18 июня
ℹ️ Кто родился в этот день
Вита́лий Ио́сифович Гольда́нский (18 июня 1923, Витебск — 14 января 2001, Москва) — советский и российский учёный, физик-ядерщик и физикохимик, общественный деятель, народный депутат СССР. В 1970—1973 Гольданский показал неприменимость классического закона Аррениуса для скоростей химических реакций при низких температурах: им был открыт квантовый предел скорости реакций, протекающих за счёт туннелирования даже вблизи абсолютного нуля. Он также известен как основоположник химической физики позитрона и позитрония, показал возможность полимеризации под действием ударных волн, что было признано как научное открытие.
🌐 Знаковые события
1959 — Запуск ракеты-носителя «Восток-Л» с советской автоматической станцией «Луна-2А».
#Biography #Birth_Date #Events #18июня
Вита́лий Ио́сифович Гольда́нский (18 июня 1923, Витебск — 14 января 2001, Москва) — советский и российский учёный, физик-ядерщик и физикохимик, общественный деятель, народный депутат СССР. В 1970—1973 Гольданский показал неприменимость классического закона Аррениуса для скоростей химических реакций при низких температурах: им был открыт квантовый предел скорости реакций, протекающих за счёт туннелирования даже вблизи абсолютного нуля. Он также известен как основоположник химической физики позитрона и позитрония, показал возможность полимеризации под действием ударных волн, что было признано как научное открытие.
1959 — Запуск ракеты-носителя «Восток-Л» с советской автоматической станцией «Луна-2А».
#Biography #Birth_Date #Events #18июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
[Совет по Java #051]
Тема:
Проблема: При работе со стримами, содержащими
Такой код громоздок, содержит неявный вызов
Решение: Используйте
Для Java 8 используйте
Это естественно интегрируется с
Объяснение:
Это делает код более декларативным: вы говорите "для каждого Optional преврати его в поток значений (ноль или одно), и объедини их".
Такой подход устраняет необходимость явной проверки
#Java #советы
Тема:
flatMap на стриме может заменить filter + map, если внутри есть Optional.Проблема: При работе со стримами, содержащими
Optional, распространенной практикой является фильтрация существующих значений с последующим извлечением: stream.filter(Optional::isPresent).map(Optional::get).Такой код громоздок, содержит неявный вызов
get(), который ассоциируется с плохим тоном, и создает промежуточную операцию. Кроме того, это нарушает принцип "не используйте Optional как контейнер, который нужно разворачивать вручную". Вместо этого можно применить flatMap, который умеет сворачивать Optional в стрим из одного элемента или пустой стрим.Решение: Используйте
flatMap(Optional::stream) (доступно с Java 9). Для Java 8 используйте
flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)). Этот подход объединяет фильтрацию и преобразование в одну операцию, делая код лаконичнее и выразительнее. Optional.stream() возвращает стрим из одного элемента, если значение присутствует, или пустой стрим, если отсутствует. Это естественно интегрируется с
flatMap, который разворачивает каждый Optional в ноль или один элемент итогового стрима.import java.util.*;
import java.util.stream.*;
public class OptionalFlatMap {
public static void main(String[] args) {
List<Optional<String>> list = Arrays.asList(
Optional.of("Java"),
Optional.empty(),
Optional.of("Kotlin"),
Optional.empty()
);
//Антипаттерн: filter + map
List<String> bad = list.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
System.out.println("Filter+map: " + bad);
//Решение: flatMap с Optional.stream (Java 9+)
List<String> good = list.stream()
.flatMap(Optional::stream) // Преобразует каждый Optional в стрим
.collect(Collectors.toList());
System.out.println("flatMap: " + good); // [Java, Kotlin]
// Для Java 8: альтернатива
List<String> java8 = list.stream()
.flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
.collect(Collectors.toList());
System.out.println("Java 8 flatMap: " + java8);
// Работает и с другими Optional-подобными типами
List<OptionalInt> optionalInts = Arrays.asList(
OptionalInt.of(10),
OptionalInt.empty(),
OptionalInt.of(20)
);
// flatMap для OptionalInt требует преобразования в IntStream
// Не так прямо, но идея та же.
}
}
Объяснение:
flatMap принимает функцию, возвращающую стрим, и объединяет все такие стримы в один. Optional.stream() (Java 9+) преобразует Optional<T> в Stream<T> из одного элемента или пустой стрим. Это делает код более декларативным: вы говорите "для каждого Optional преврати его в поток значений (ноль или одно), и объедини их".
Такой подход устраняет необходимость явной проверки
isPresent и вызова get, что уменьшает вероятность ошибок. Кроме того, он естественно сочетается с другими операциями стрима, например, с map после flatMap. Для Java 8 можно использовать аналогичную конструкцию с map и orElseGet. #Java #советы
👍4
Что выведет код?
#Tasks
import java.util.*;
public class Task180626 {
public static void main(String[] args) {
List<Optional<String>> list = Arrays.asList(
Optional.of("a"),
null,
Optional.of("b")
);
list.stream()
.flatMap(Optional::stream)
.forEach(System.out::print);
}
}
#Tasks
👍3
👍4
Что такое 🤓
Ответ:
Утечка памяти — ситуация, когда объекты больше не нужны приложению, но GC не может их удалить, потому что на них всё ещё есть достижимые ссылки.
В Java это не утечка в классическом смысле, а "удерживание ссылок". Причины: статические коллекции, не закрытые ресурсы, слушатели/обработчики, неправильное кэширование, потоки, ThreadLocal без remove().
Поиск: профайлеры (VisualVM, JProfiler) смотрит heap dump, определяют самые большие объекты и пути к корням GC (GC roots).
Также помогают детекторы утечек (Eclipse Memory Analyzer).
#собеседование
Memory Leak в Java? Как найти? Ответ:
Утечка памяти — ситуация, когда объекты больше не нужны приложению, но GC не может их удалить, потому что на них всё ещё есть достижимые ссылки.
В Java это не утечка в классическом смысле, а "удерживание ссылок". Причины: статические коллекции, не закрытые ресурсы, слушатели/обработчики, неправильное кэширование, потоки, ThreadLocal без remove().
Поиск: профайлеры (VisualVM, JProfiler) смотрит heap dump, определяют самые большие объекты и пути к корням GC (GC roots).
Также помогают детекторы утечек (Eclipse Memory Analyzer).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
История технологии сегодня — 19 июня
ℹ️ Кто родился в этот день
Блез Паска́ль (фр. Blaise Pascal [blɛz pasˈkal]; 19 июня 1623, родной дом Блеза Паскаля[вд], Клермон-Ферран, Королевство Франция — 19 августа 1662, Париж, Королевство Франция) — французский математик, механик, физик, литератор, философ и теолог. Классик французской литературы, один из основателей математического анализа, теории вероятностей и проективной геометрии, создатель первых образцов счётной техники, автор основного закона гидростатики.
Оге Нильс Бор (дат. Aage Niels Bohr; 19 июня 1922, Копенгаген, Дания — 8 сентября 2009, там же) — датский учёный, физик-ядерщик. Член Датской королевской академии наук (1955), ряда других академий мира. Лауреат Нобелевской премии по физике (1975), как и его отец Нильс Бор.
🌐 Знаковые события
1999 — вышла первая версия (1.0 Beta) онлайн-шутера Counter-Strike.
#Biography #Birth_Date #Events #19июня
Блез Паска́ль (фр. Blaise Pascal [blɛz pasˈkal]; 19 июня 1623, родной дом Блеза Паскаля[вд], Клермон-Ферран, Королевство Франция — 19 августа 1662, Париж, Королевство Франция) — французский математик, механик, физик, литератор, философ и теолог. Классик французской литературы, один из основателей математического анализа, теории вероятностей и проективной геометрии, создатель первых образцов счётной техники, автор основного закона гидростатики.
Оге Нильс Бор (дат. Aage Niels Bohr; 19 июня 1922, Копенгаген, Дания — 8 сентября 2009, там же) — датский учёный, физик-ядерщик. Член Датской королевской академии наук (1955), ряда других академий мира. Лауреат Нобелевской премии по физике (1975), как и его отец Нильс Бор.
1999 — вышла первая версия (1.0 Beta) онлайн-шутера Counter-Strike.
#Biography #Birth_Date #Events #19июня
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 1. Классический Java I/O (java.io)
Правильная работа с текстовыми файлами: InputStreamReader и OutputStreamWriter
Классы
Эта неопределенность делает
InputStreamReader: декодирование байтов в символы
Конструктор принимает
Путь данных через память JVM
Путь данных детально:
Внутреннее устройство
Механика декодирования UTF-8
UTF-8 — кодировка переменной длины. Декодер должен обрабатывать мультибайтовые последовательности, разбитые между блоками чтения:
Это требует внутреннего состояния в
OutputStreamWriter: кодирование символов в байты
Путь данных через память JVM
Путь данных детально:
Кодирование и размер выходных данных
Строка "Hello, 世界! 🌍" содержит:
8 символов ASCII: 8 байт UTF-8
'世' (U+4E16): 3 байта UTF-8
'界' (U+754C): 3 байта UTF-8
'🌍' (U+1F30D): суррогатная пара, 4 байта UTF-8
Итого: 18 байт для 11 кодовых точек, 12
#Java #для_новичков #beginner #IO #NIO #InputStreamReader #OutputStreamWriter
Глава 1. Классический Java I/O (java.io)
Правильная работа с текстовыми файлами: InputStreamReader и OutputStreamWriter
Классы
FileReader и FileWriter — удобные обертки, но содержат фундаментальный архитектурный дефект: они используют кодировку платформы по умолчанию, определяемую системным свойством file.encoding. Это свойство зависит от операционной системы, locale пользователя и параметров запуска JVM.// Антипаттерн: неявная кодировка платформы
try (FileReader reader = new FileReader("text.txt")) {
// На Windows может использоваться windows-1251
// На Linux — UTF-8
// На macOS — UTF-8
// Результат непредсказуем при переносе между системами
}
Эта неопределенность делает
FileReader/FileWriter непригодными для переносимого кода. Файл, записанный на одной системе, может быть искажен при чтении на другой. Современная практика рекомендует явное указание кодировки UTF-8 для всех текстовых операций.InputStreamReader: декодирование байтов в символы
InputStreamReader — мост от байтовых потоков к символьным. Он читает байты из InputStream и декодирует их в символы char с использованием указанной кодировки.public InputStreamReader(InputStream in, Charset cs)
Конструктор принимает
InputStream — источник сырых байтов, и Charset — правило декодирования. StandardCharsets.UTF_8 — предопределенная константа, исключающая риск неподдерживаемой кодировки.Путь данных через память JVM
try (InputStreamReader reader = new InputStreamReader(
new FileInputStream("text.txt"), StandardCharsets.UTF_8)) {
int charValue;
while ((charValue = reader.read()) != -1) {
System.out.print((char) charValue);
}
}
Путь данных детально:
[Файл на диске: байты UTF-8]
-> [Page Cache ОС: байты файла]
-> [FileInputStream.read(byte[]) — системный вызов]
-> [Нативный буфер userspace]
-> [JNI: копирование в byte[] внутри InputStreamReader]
-> [InputStreamReader: накопление байт во внутреннем ByteBuffer]
-> [CharsetDecoder UTF-8: конечный автомат декодирования]
-> [CharBuffer: накопление декодированных символов]
-> [read(): возврат char как int]
-> [System.out.print(char): кодирование в байты платформы]
Внутреннее устройство
InputStreamReader из OpenJDK:// Упрощенная структура
public class InputStreamReader extends Reader {
private final StreamDecoder sd; // Делегат декодирования
// StreamDecoder содержит:
// - ByteBuffer: входные байты из потока
// - CharBuffer: выходные символы
// - CharsetDecoder: конечный автомат кодировки
}
StreamDecoder — внутренний класс, выполняющий реальную работу. Он управляет ByteBuffer для входных байт и CharBuffer для выходных символов. Буферы создаются при конструировании и живут до закрытия потока.Механика декодирования UTF-8
UTF-8 — кодировка переменной длины. Декодер должен обрабатывать мультибайтовые последовательности, разбитые между блоками чтения:
// Сценарий: 3-байтовый символ '世' (U+4E16, E4 B8 96) разбит между чтениями
// Первое чтение: получены байты [..., E4, B8] — неполная последовательность
// StreamDecoder сохраняет E4 B8 во внутреннем ByteBuffer, возвращает 0 символов
// Второе чтение: получен байт [96, ...] — завершение последовательности
// StreamDecoder комбинирует E4 B8 96, декодирует в U+4E16, возвращает '世'
Это требует внутреннего состояния в
StreamDecoder: неполные байтовые последовательности сохраняются между вызовами read(). Буфер для этих остатков — часть ByteBuffer в heap.OutputStreamWriter: кодирование символов в байты
OutputStreamWriter — зеркальный мост: принимает символы char или String, кодирует их в байты согласно указанной кодировке, и записывает в OutputStream.public OutputStreamWriter(OutputStream out, Charset cs)
Путь данных через память JVM
try (OutputStreamWriter writer = new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8)) {
writer.write("Hello, 世界! 🌍");
}
Путь данных детально:
[Java-код: String "Hello, 世界! 🌍"]
-> [String.toCharArray() или прямой доступ к внутреннему char[]]
-> [OutputStreamWriter.write(char[], off, len)]
-> [StreamEncoder: кодирование char -> байты]
-> [CharsetEncoder UTF-8: конечный автомат]
-> [ByteBuffer: накопление закодированных байт]
-> [FileOutputStream.write(byte[]): системный вызов]
-> [Нативный буфер userspace]
-> [Ядро ОС: syscall write]
-> [Page Cache: dirty pages]
-> [Фоновая запись на диск]
StreamEncoder — внутренний аналог StreamDecoder. Он управляет CharBuffer для входных символов и ByteBuffer для выходных байт. При вызове write(String) символы сначала копируются в CharBuffer, затем кодер преобразует их в байты UTF-8.Кодирование и размер выходных данных
Строка "Hello, 世界! 🌍" содержит:
8 символов ASCII: 8 байт UTF-8
'世' (U+4E16): 3 байта UTF-8
'界' (U+754C): 3 байта UTF-8
'🌍' (U+1F30D): суррогатная пара, 4 байта UTF-8
Итого: 18 байт для 11 кодовых точек, 12
char в JavaStreamEncoder должен обрабатывать суррогатные пары корректно: старший суррогат без младшего не является валидным символом и должен либо ждать дополнительных данных, либо генерировать замену (replacement character U+FFFD).#Java #для_новичков #beginner #IO #NIO #InputStreamReader #OutputStreamWriter
👍3
Практический пример: чтение UTF-8 и вывод в консоль
Путь данных с BufferedReader
Каждая строка — отдельный объект
Роль garbage collector
Жизненный цикл объектов кодирования
При обработке тысяч файлов этот код создает тысячи временных объектов. Они короткоживущие и собираются minor GC, но при высокой частоте могут вызвать частые паузы young generation.
Оптимизация: переиспользование буферов
Здесь
Запись с явной кодировкой
Буферизация записи
Для эффективной записи
#Java #для_новичков #beginner #IO #NIO
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Utf8FileProcessor {
public void readAndPrint(String path) throws IOException {
// InputStreamReader: байты из файла -> символы UTF-8
try (InputStreamReader reader = new InputStreamReader(
new FileInputStream(path), StandardCharsets.UTF_8)) {
char[] buffer = new char[1024];
int charsRead;
// Буферизованное чтение символов
while ((charsRead = reader.read(buffer)) != -1) {
// Создание String из char[] — новый объект в heap
String chunk = new String(buffer, 0, charsRead);
System.out.print(chunk);
}
}
// reader закрыт, StreamDecoder и его буферы освобождены
// buffer и chunk — недостижимы, GC собирает при следующей minor collection
}
// Альтернатива: BufferedReader для построчного чтения
public void readLines(String path) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(path), StandardCharsets.UTF_8))) {
String line;
int lineNumber = 0;
while ((line = reader.readLine()) != null) {
lineNumber++;
System.out.printf("%d: %s%n", lineNumber, line);
// Каждая line — новая String в heap
}
}
// Все String из readLine() недостижимы, если не сохранены
}
}
Путь данных с BufferedReader
BufferedReader добавляет собственный char[] cb в heap — буфер символов размером 8192 по умолчанию. readLine() накапливает символы в этот буфер до \n, затем создает String:[BufferedReader.readLine()]
-> [Заполнение cb[8192] из underlying InputStreamReader]
-> [InputStreamReader: декодирование байт -> символы]
-> [Поиск \n или \r\n в cb]
-> [new String(cb, start, length): создание String в heap]
-> [String конструктор: копирование char[] (или byte[] в современных JDK)]
-> [Возврат String]
Каждая строка — отдельный объект
String в heap. При чтении файла 100MB с ~1 000 000 строк создается 1 000 000 объектов String. Это создает значительное давление на GC, хотя строки короткоживущие и эффективно собираются minor GC.Роль garbage collector
Жизненный цикл объектов кодирования
public void processManyFiles(List<String> paths) throws IOException {
for (String path : paths) {
// Каждая итерация создает:
// - FileInputStream (heap)
// - InputStreamReader (heap)
// - StreamDecoder (heap)
// - ByteBuffer, CharBuffer внутренние (heap)
// - CharsetDecoder (heap)
// - char[] buffer (heap)
// - String chunk (heap, при каждом read)
try (InputStreamReader reader = new InputStreamReader(
new FileInputStream(path), StandardCharsets.UTF_8)) {
char[] buffer = new char[4096];
int charsRead;
while ((charsRead = reader.read(buffer)) != -1) {
process(new String(buffer, 0, charsRead));
}
}
// Все объекты становятся недостижимыми
// GC собирает их при следующей minor collection
}
}При обработке тысяч файлов этот код создает тысячи временных объектов. Они короткоживущие и собираются minor GC, но при высокой частоте могут вызвать частые паузы young generation.
Оптимизация: переиспользование буферов
// Переиспользуемый буфер для чтения
private static final ThreadLocal<char[]> CHAR_BUFFER =
ThreadLocal.withInitial(() -> new char[8192]);
public void processFileOptimized(String path) throws IOException {
char[] buffer = CHAR_BUFFER.get();
try (InputStreamReader reader = new InputStreamReader(
new FileInputStream(path), StandardCharsets.UTF_8)) {
int charsRead;
while ((charsRead = reader.read(buffer)) != -1) {
// String всё еще создается, но buffer переиспользуется
process(new String(buffer, 0, charsRead));
}
}
}
Здесь
char[] buffer переиспользуется между вызовами, устраняя одну аллокацию на файл. Однако new String(...) при каждом чтении всё еще создает объекты. Для полного устранения аллокаций требуется обработка in-place в char[] без создания String.Запись с явной кодировкой
public void writeUtf8File(String path, List<String> lines) throws IOException {
// OutputStreamWriter: символы -> байты UTF-8
try (OutputStreamWriter writer = new OutputStreamWriter(
new FileOutputStream(path), StandardCharsets.UTF_8)) {
for (String line : lines) {
writer.write(line); // Кодирование char[] -> байты UTF-8
writer.write(System.lineSeparator());
}
writer.flush(); // Сброс внутренних буферов в FileOutputStream
} // close() с неявным flush()
// StreamEncoder и его буферы освобождены
}Буферизация записи
Для эффективной записи
OutputStreamWriter оборачивается в BufferedWriter:try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(path), StandardCharsets.UTF_8))) {
for (String line : lines) {
writer.write(line);
writer.newLine(); // Платформенно-независимый разделитель
}
}
BufferedWriter содержит char[] cb в heap — буфер символов. Запись накапливается в этом буфере и сбрасывается в OutputStreamWriter при заполнении или вызове flush(). Это устраняет частые вызовы кодера и underlying потока.#Java #для_новичков #beginner #IO #NIO
👍3
Что выведет код?
#Tasks
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Task190626 {
public static void main(String[] args) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(baos, StandardCharsets.US_ASCII);
writer.write('€');
writer.flush();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
InputStreamReader reader = new InputStreamReader(bais, StandardCharsets.US_ASCII);
int ch = reader.read();
System.out.println(ch);
}
}
#Tasks
👍2
👍3
Что такое 🤓
Ответ:
JNI (Java Native Interface) — это фреймворк, позволяющий Java-коду вызывать и быть вызванным нативными приложениями (C/C++).
Используется для доступа к системным функциям, устройствам, оптимизации.
Проблемы:
1) потеря переносимости (нужно компилировать под каждую ОС/архитектуру).
2) сложность отладки (ошибки в нативном коде могут крашнуть JVM).
3) утечки памяти в нативной части не отслеживаются GC.
4) накладные расходы на маршалинг данных.
5) несовместимость с модульной системой Java 9+.
Альтернативы: Project Panama (Foreign Function API) в новых версиях Java.
#собеседование
JNI? Какие проблемы при его использовании? Ответ:
Используется для доступа к системным функциям, устройствам, оптимизации.
Проблемы:
1) потеря переносимости (нужно компилировать под каждую ОС/архитектуру).
2) сложность отладки (ошибки в нативном коде могут крашнуть JVM).
3) утечки памяти в нативной части не отслеживаются GC.
4) накладные расходы на маршалинг данных.
5) несовместимость с модульной системой Java 9+.
Альтернативы: Project Panama (Foreign Function API) в новых версиях Java.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
История технологии сегодня — 20 июня
ℹ️ Кто родился в этот день
Давид Каждан ( иврит : דוד קשדן ), урожденный Дмитрий Александрович Каждан ( русский : Дмитрий Александрович Каждан ; родился 20 июня 1946 года) — советский и израильский математик, известный своими работами в области теории представлений . Каждан является стипендиатом Макартура 1990 года . В 2012 году он получил Премию Израиля по математике и информатике.
🌐 Знаковые события
1793 — американец Эли Уитни запатентовал хлопкоочистительную машину.
1944 — экспериментальная ракета MW 18014 V-2 достигает высоты 176 км, став первым искусственным объектом, достигшим космического пространства.
#Biography #Birth_Date #Events #20июня
Давид Каждан ( иврит : דוד קשדן ), урожденный Дмитрий Александрович Каждан ( русский : Дмитрий Александрович Каждан ; родился 20 июня 1946 года) — советский и израильский математик, известный своими работами в области теории представлений . Каждан является стипендиатом Макартура 1990 года . В 2012 году он получил Премию Израиля по математике и информатике.
1793 — американец Эли Уитни запатентовал хлопкоочистительную машину.
1944 — экспериментальная ракета MW 18014 V-2 достигает высоты 176 км, став первым искусственным объектом, достигшим космического пространства.
#Biography #Birth_Date #Events #20июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
С 13.06 по 19.06
Предыдущий пост(с 30.05 по 12.06)
Запись встреч/видео:
Открытый урок: как на самом деле работают транзакции в Postgres | MVCC, уровни изоляции и блокировки
Обучающие статьи:
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 1. Классический Java I/O (java.io (https://java.io/))
BufferedOutputStream – буферизованная запись. Путь данных от heap к диску
Символьные потоки: Reader и Writer. Unicode, кодировки и путь данных в памяти
Правильная работа с текстовыми файлами: InputStreamReader и OutputStreamWriter
[Совет по Java #050]
Тема: Optional не предназначен для полей класса и для параметров методов.
[Совет по Java #051]
Тема: flatMap на стриме может заменить filter + map, если внутри есть Optional.
Полезные статьи и видео:
Java и время: часть первая
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Предыдущий пост(с 30.05 по 12.06)
Запись встреч/видео:
Открытый урок: как на самом деле работают транзакции в Postgres | MVCC, уровни изоляции и блокировки
Обучающие статьи:
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 1. Классический Java I/O (java.io (https://java.io/))
BufferedOutputStream – буферизованная запись. Путь данных от heap к диску
Символьные потоки: Reader и Writer. Unicode, кодировки и путь данных в памяти
Правильная работа с текстовыми файлами: InputStreamReader и OutputStreamWriter
[Совет по Java #050]
Тема: Optional не предназначен для полей класса и для параметров методов.
[Совет по Java #051]
Тема: flatMap на стриме может заменить filter + map, если внутри есть Optional.
Полезные статьи и видео:
Java и время: часть первая
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍2
Ребят продолжаю набор желающих обучиться Java. 🤓
Офферов конечно не обещаю, но до твердого мидла доведу.
Пишите в лс @Oleborn✌️
Офферов конечно не обещаю, но до твердого мидла доведу.
Пишите в лс @Oleborn
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14
История технологии сегодня — 21 июня
ℹ️ Кто родился в этот день
Ю́рий Васи́льевич Кондратю́к (настоящее имя — Алекса́ндр Игна́тьевич Шарге́й; 9 [21] июня 1897, Полтава, Полтавская губерния, Российская империя — 25 февраля 1942, Орловская область, СССР) — советский инженер, один из основоположников космонавтики. В начале XX века рассчитал оптимальную траекторию полёта к Луне. Эти расчёты были повторно переоткрыты НАСА в лунной программе «Аполлон». Предложенная в 1916 году Шаргеем траектория была впоследствии названа «трассой Кондратюка».
Симео́н Дени́ Пуассо́н (фр. Siméon Denis Poisson; 21 июня 1781, Питивье, Франция — 25 апреля 1840, Со, Франция) — французский математик, механик и физик. Число учёных трудов Пуассона превосходит 300. Они относятся к разным областям чистой математики, математической физики, теоретической и небесной механики.
🌐 Знаковые события
1956 — в СССР принята на вооружение ракета Р-5М — первая советская ракета с ядерным боевым зарядом.
2006 — спутники Плутона получили названия Никта и Гидра.
#Biography #Birth_Date #Events #21июня
Ю́рий Васи́льевич Кондратю́к (настоящее имя — Алекса́ндр Игна́тьевич Шарге́й; 9 [21] июня 1897, Полтава, Полтавская губерния, Российская империя — 25 февраля 1942, Орловская область, СССР) — советский инженер, один из основоположников космонавтики. В начале XX века рассчитал оптимальную траекторию полёта к Луне. Эти расчёты были повторно переоткрыты НАСА в лунной программе «Аполлон». Предложенная в 1916 году Шаргеем траектория была впоследствии названа «трассой Кондратюка».
Симео́н Дени́ Пуассо́н (фр. Siméon Denis Poisson; 21 июня 1781, Питивье, Франция — 25 апреля 1840, Со, Франция) — французский математик, механик и физик. Число учёных трудов Пуассона превосходит 300. Они относятся к разным областям чистой математики, математической физики, теоретической и небесной механики.
1956 — в СССР принята на вооружение ракета Р-5М — первая советская ракета с ядерным боевым зарядом.
2006 — спутники Плутона получили названия Никта и Гидра.
#Biography #Birth_Date #Events #21июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Как заставить себя учиться 🤓
Особенно когда тебе за 30...
Казалось бы - что может быть проще? Бери источник информации и изучай что-то новое. Но оказалось, что не все так просто...
🤬 С чем придется столкнуться:
Постоянные дела и банальная усталость с основной работы (да и лень немножко, конечно🏝 ).
Это хорошо, когда ты молод и у тебя нет обязанностей перед семьей и окружающими. Ты волен посвятить обучению все свое свободное время...
А нам, 30+ -летним "вкатунам", которые вынуждены ежедневно бороться с окружающими проблемами, кажется сложным найти время, чтобы сесть и посмотреть (и воспринять!) видео с какой-то новой концепцией.
А постоянное обучение - вообще какая-то дикость.☠️
Кружащие заблуждения🤔
Не знаю как у Вам, но мне и моему окружению, мысль о том, что за нажимание клавиш, мне будут платить прилично денег - казалась дикой.
Все эти, улыбающиеся лица в ютубе, вещающие о молочном море и кисельных берегах в IT, казались, как минимум мошенниками, отчего учиться у них казалось неправильным...
Кроме того, обычное заблуждение моего круга - что после окончания школы/института, простой человек (а не какой-то там гений или вундеркинд) теряет способности к обучению, и с трудом воспринимает новую, в том числе и сложную информацию. (Не буду скрывать, и я относился к тем людям, кто распространял это заблуждение...☺️ )
Ощущение своей непроходимой тупости🤪
Не покидает и спустя несколько лет.🤣
А если серьезно, то чем больше ты погружаешься в программирование, тем глубже кажется кроличья нора. Новые фреймворки, библиотеки, технологии, нюансы, надстройки и костыли, кажутся дремучим лесом, в котором так легко потеряться.
А периодическое стуканье головы об что-то твердое и последующее (возможно не связанное с этим процессом), озарение, со словами "Ах, б🤬, так вот оно что!", преследует меня до сих пор (ведь обучение тут не заканчивается никогда!🤫 ).
Ниже дам несколько советов, которые помогли мне (и может помогут и Вам😎 )
1. Смог он, смогу и я.
Возможно Вы слышали выражение - "не боги горшки обжигают". Верьте в свои силы, даже если кажется, что это полный идиотизм.
Ведь, если смотря на человека который рассказывает об устройстве сложной системы, Вы задаетесь вопросом "Как он смог это понять?", задайте вопрос и себе "А чем я хуже?".
Бороться и не сдаваться несмотря на все возникающие препятствия сложно. И в обучении это имеет сокровенный смысл. Понимание того, что успешный программист с зп 500к+, не родился с клавиатурой во рту, а так же как и Вы возможно учился по тому же каналу в ютубе, только несколько раньше, максимально мотивирует достичь его успехов.
2. Выбрать время для обучения (и желательно много).
Скажем так, я не смог обучаться параллельно с работой. Ну никак. Поэтому воспользовавшись накоплениями, и освободившимся после увольнения временем, я все силы бросил на учебу.
И не значит, что это ваш рецепт, ведь мы все разные. Возможно вам комфортно вялотекущее обучение и устройство в IT у вас в далекой перспективе.🙃
3. Структурируйте процесс обучения.
Сейчас в интернете гигантское количество обучающего материала. В том числе и бесплатного (да-да, это я про наш канал☺️ ) .
Выберите какой Вам нравится и начинайте учить от простого к сложному. Вычлените в приоритет те части, которые являются основой выбранного Вами рабочего стека и бросьте все силы туда. Иначе можно увязнуть в объеме информации или начать учить то, что Вам никогда не пригодится.
4. Вознаграждайте свое подсознание за успехи
Звучит глупо и странно, знаю. Но мотивировать себя станет в разы легче. Небольшой бонус: чашка любимого кофе, эпизод сериала или пятнадцать минут в соцсетях. Мозг любит вознаграждения, и это ещё один повод не бросить начатое.
5. Чёткая цель и никаких «зачем» после начала.
Наверно моя основная мотивация в ежедневной учебе. А может я просто упрямый🐏 😄 .
Поставьте себе глобально - максимально - реально достижимую цель. Продумайте шаги и ступени до нее, разбив на мелкие подцели и достигая их, начинайте путь к следующей. И не успеете оглянуться как половина пути будет пройдена. А может и весь)))
😎
#motivation
Особенно когда тебе за 30...
Казалось бы - что может быть проще? Бери источник информации и изучай что-то новое. Но оказалось, что не все так просто...
Постоянные дела и банальная усталость с основной работы (да и лень немножко, конечно
Это хорошо, когда ты молод и у тебя нет обязанностей перед семьей и окружающими. Ты волен посвятить обучению все свое свободное время...
А нам, 30+ -летним "вкатунам", которые вынуждены ежедневно бороться с окружающими проблемами, кажется сложным найти время, чтобы сесть и посмотреть (и воспринять!) видео с какой-то новой концепцией.
А постоянное обучение - вообще какая-то дикость.
Кружащие заблуждения
Не знаю как у Вам, но мне и моему окружению, мысль о том, что за нажимание клавиш, мне будут платить прилично денег - казалась дикой.
Все эти, улыбающиеся лица в ютубе, вещающие о молочном море и кисельных берегах в IT, казались, как минимум мошенниками, отчего учиться у них казалось неправильным...
Кроме того, обычное заблуждение моего круга - что после окончания школы/института, простой человек (а не какой-то там гений или вундеркинд) теряет способности к обучению, и с трудом воспринимает новую, в том числе и сложную информацию. (Не буду скрывать, и я относился к тем людям, кто распространял это заблуждение...
Ощущение своей непроходимой тупости
Не покидает и спустя несколько лет.
А если серьезно, то чем больше ты погружаешься в программирование, тем глубже кажется кроличья нора. Новые фреймворки, библиотеки, технологии, нюансы, надстройки и костыли, кажутся дремучим лесом, в котором так легко потеряться.
А периодическое стуканье головы об что-то твердое и последующее (возможно не связанное с этим процессом), озарение, со словами "Ах, б🤬, так вот оно что!", преследует меня до сих пор (ведь обучение тут не заканчивается никогда!
Ниже дам несколько советов, которые помогли мне (и может помогут и Вам
1. Смог он, смогу и я.
Возможно Вы слышали выражение - "не боги горшки обжигают". Верьте в свои силы, даже если кажется, что это полный идиотизм.
Ведь, если смотря на человека который рассказывает об устройстве сложной системы, Вы задаетесь вопросом "Как он смог это понять?", задайте вопрос и себе "А чем я хуже?".
Бороться и не сдаваться несмотря на все возникающие препятствия сложно. И в обучении это имеет сокровенный смысл. Понимание того, что успешный программист с зп 500к+, не родился с клавиатурой во рту, а так же как и Вы возможно учился по тому же каналу в ютубе, только несколько раньше, максимально мотивирует достичь его успехов.
2. Выбрать время для обучения (и желательно много).
Скажем так, я не смог обучаться параллельно с работой. Ну никак. Поэтому воспользовавшись накоплениями, и освободившимся после увольнения временем, я все силы бросил на учебу.
И не значит, что это ваш рецепт, ведь мы все разные. Возможно вам комфортно вялотекущее обучение и устройство в IT у вас в далекой перспективе.
3. Структурируйте процесс обучения.
Сейчас в интернете гигантское количество обучающего материала. В том числе и бесплатного (да-да, это я про наш канал
Выберите какой Вам нравится и начинайте учить от простого к сложному. Вычлените в приоритет те части, которые являются основой выбранного Вами рабочего стека и бросьте все силы туда. Иначе можно увязнуть в объеме информации или начать учить то, что Вам никогда не пригодится.
4. Вознаграждайте свое подсознание за успехи
Звучит глупо и странно, знаю. Но мотивировать себя станет в разы легче. Небольшой бонус: чашка любимого кофе, эпизод сериала или пятнадцать минут в соцсетях. Мозг любит вознаграждения, и это ещё один повод не бросить начатое.
5. Чёткая цель и никаких «зачем» после начала.
Наверно моя основная мотивация в ежедневной учебе. А может я просто упрямый
Поставьте себе глобально - максимально - реально достижимую цель. Продумайте шаги и ступени до нее, разбив на мелкие подцели и достигая их, начинайте путь к следующей. И не успеете оглянуться как половина пути будет пройдена. А может и весь)))
#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3 1
История технологии сегодня — 22 июня
ℹ️ Кто родился в этот день
Доктор Ко́нрад Эрнст О́тто Цу́зе (нем. Dr. Konrad Ernst Otto Zuse; 22 июня 1910, Берлин, Германская империя — 18 декабря 1995, Хюнфельд, Германия) — немецкий инженер, один из пионеров компьютеростроения. Наиболее известен как создатель первого действительно работающего электро-механического программируемого компьютера Z3 (1941) и первого языка программирования высокого уровня Планкалькюль (1948).
Гео́ргий (Ю́рий) Ви́кторович Вульф (22 июня 1863, Нежин, Российская Империя — 25 декабря 1925, Москва, СССР) — российский учёный-кристаллограф, автор «сетки Вульфа» и формулы Брэгга — Вульфа. Автор более 150 работ по кристаллографии, кристаллофизике, кристаллооптике, рентгеноструктурному анализу, минералогии.
Ге́рман Минко́вский (нем. Hermann Minkowski; 22 июня 1864, Алексоты, Августовская губерния, Мариампольский уезд, Российская империя — 12 января 1909, Гёттинген, Германская империя) — немецкий математик, разработавший геометрическую теорию чисел и геометрическую четырёхмерную модель теории относительности. Первые результаты Минковского касались теории квадратичных форм. В 1896 году опубликован результат, ныне известный как теорема Минковского о выпуклом теле — о том, что выпуклая область n-мерного пространства, объёмом >=2n и симметричная относительно начала координат, непременно содержит точку с целочисленными координатами, отличную от начала координат. По словам Касселса[17], вся геометрия чисел основана на этом результате. После создания геометрии чисел Минковский много и плодотворно работает над применением полученных результатов в других областях теории чисел: диофантовы приближения, теория многогранников и другие. Ему принадлежат фундаментальные достижения в геометрии выпуклых тел. В 1907 году Минковский предложил геометрическое представление кинематики теории относительности, введя четырёхмерное псевдоевклидово пространство (известное сейчас как пространство Минковского). В этой модели время и пространство представляют собой не различные сущности, а взаимосвязанные измерения единого пространства-времени. Все релятивистские эффекты получили наглядное геометрическое истолкование.
🌐 Знаковые события
1978 — обнаружен спутник Плутона — Харон.
#Biography #Birth_Date #Events #22июня
Доктор Ко́нрад Эрнст О́тто Цу́зе (нем. Dr. Konrad Ernst Otto Zuse; 22 июня 1910, Берлин, Германская империя — 18 декабря 1995, Хюнфельд, Германия) — немецкий инженер, один из пионеров компьютеростроения. Наиболее известен как создатель первого действительно работающего электро-механического программируемого компьютера Z3 (1941) и первого языка программирования высокого уровня Планкалькюль (1948).
Гео́ргий (Ю́рий) Ви́кторович Вульф (22 июня 1863, Нежин, Российская Империя — 25 декабря 1925, Москва, СССР) — российский учёный-кристаллограф, автор «сетки Вульфа» и формулы Брэгга — Вульфа. Автор более 150 работ по кристаллографии, кристаллофизике, кристаллооптике, рентгеноструктурному анализу, минералогии.
Ге́рман Минко́вский (нем. Hermann Minkowski; 22 июня 1864, Алексоты, Августовская губерния, Мариампольский уезд, Российская империя — 12 января 1909, Гёттинген, Германская империя) — немецкий математик, разработавший геометрическую теорию чисел и геометрическую четырёхмерную модель теории относительности. Первые результаты Минковского касались теории квадратичных форм. В 1896 году опубликован результат, ныне известный как теорема Минковского о выпуклом теле — о том, что выпуклая область n-мерного пространства, объёмом >=2n и симметричная относительно начала координат, непременно содержит точку с целочисленными координатами, отличную от начала координат. По словам Касселса[17], вся геометрия чисел основана на этом результате. После создания геометрии чисел Минковский много и плодотворно работает над применением полученных результатов в других областях теории чисел: диофантовы приближения, теория многогранников и другие. Ему принадлежат фундаментальные достижения в геометрии выпуклых тел. В 1907 году Минковский предложил геометрическое представление кинематики теории относительности, введя четырёхмерное псевдоевклидово пространство (известное сейчас как пространство Минковского). В этой модели время и пространство представляют собой не различные сущности, а взаимосвязанные измерения единого пространства-времени. Все релятивистские эффекты получили наглядное геометрическое истолкование.
1978 — обнаружен спутник Плутона — Харон.
#Biography #Birth_Date #Events #22июня
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
[Совет по Java #052]
Тема:
Проблема: В Java 8 метод
Разработчики часто используют
Решение: Используйте
Объяснение: Метод
Затем для каждого следующего элемента применяется
#Java #советы
Тема:
Stream.iterate(seed, predicate, unaryOperator) в Java 9 позволяет создавать ограниченные стримы без явного вызова limit(). Проблема: В Java 8 метод
Stream.iterate(seed, unaryOperator) генерирует бесконечный стрим, который требует явного ограничения через limit(). Это неудобно, когда условие завершения зависит от самих значений, а не от количества элементов. Разработчики часто используют
limit с заранее неизвестным числом итераций или добавляют takeWhile (Java 9), что может быть избыточно. В Java 9 появилась перегрузка iterate(seed, predicate, unaryOperator), которая позволяет задать условие продолжения. Однако важно понимать: predicate проверяется до применения unaryOperator к текущему элементу, а не после. Это значит, что если первый элемент не удовлетворяет предикату, стрим будет пустым, а не выдаст его и остановится. Ошибка в логике может привести к неожиданному пропуску элементов или бесконечному циклу, если предикат всегда true.Решение: Используйте
Stream.iterate с предикатом для компактного создания конечных последовательностей, когда условие зависит от значения элемента. Убедитесь, что предикат правильно определяет момент остановки: он проверяется перед каждой итерацией, начиная с начального значения. Если предикат возвращает false для начального элемента, стрим не сгенерирует ни одного элемента. Для условий, которые зависят от текущего элемента (например, пока число меньше 100), это работает корректно.public class StreamIteratePredicate {
public static void main(String[] args) {
//Java 8: бесконечный стрим + limit
Stream.iterate(1, i -> i * 2)
.limit(5)
.forEach(System.out::println); // 1, 2, 4, 8, 16
//Java 9: ограниченный стрим через predicate (проверка ДО генерации)
Stream.iterate(1, i -> i <= 16, i -> i * 2)
.forEach(System.out::println); // 1, 2, 4, 8, 16 (включает 16, т.к. проверка на 16 == true)
// Внимание: если начальное значение не удовлетворяет предикату — стрим пуст
Stream.iterate(100, i -> i <= 16, i -> i / 2)
.forEach(System.out::println); // Нет вывода!
//Опасный пример: предикат всегда true — бесконечный стрим (без limit)
// Stream.iterate(1, i -> true, i -> i + 1).forEach(...) // зависнет
//Альтернатива с takeWhile (Java 9) — условие проверяется ПОСЛЕ генерации
Stream.iterate(1, i -> i * 2)
.takeWhile(i -> i <= 16)
.forEach(System.out::println); // 1, 2, 4, 8, 16
// Разница: если нужно включить элемент, который не удовлетворяет условию — takeWhile подходит
// Например, генерация чисел до первого, превышающего 5
Stream.iterate(1, i -> i + 1)
.takeWhile(i -> i <= 5)
.forEach(System.out::println); // 1,2,3,4,5 (включает 5)
// Но с iterate с predicate: если i = 6, то предикат i <= 5 даст false до генерации 6, поэтому 5 включена
Stream.iterate(1, i -> i <= 5, i -> i + 1)
.forEach(System.out::println); // 1,2,3,4,5 — то же самое
}
}Объяснение: Метод
Stream.iterate(seed, predicate, unaryOperator) работает по следующему алгоритму: сначала проверяет predicate.test(seed). Если false, стрим завершается. Если true, выдает seed как первый элемент. Затем для каждого следующего элемента применяется
unaryOperator к предыдущему, и перед выдачей проверяется predicate.test(next). Таким образом, предикат определяет, должен ли следующий элемент быть включен. Это отличается от takeWhile, который проверяет условие на текущем элементе и включает его, даже если следующее нарушит условие. Выбор между ними зависит от семантики: если условие завершения относится к самому значению (например, "пока значение меньше 100"), то iterate с предикатом и takeWhile дадут одинаковый результат для корректных данных. Но если начальное значение не соответствует условию, iterate выдаст пустой стрим, а takeWhile — тоже пустой, потому что первый элемент не проходит. В сложных сценариях, где нужно включить элемент, нарушающий условие, используйте takeWhile или ручной контроль. #Java #советы
👍3