Открытый урок: как на самом деле работают транзакции в Postgres | MVCC, уровни изоляции и блокировки
Прошу прощения за звук, Егора почти не слышно...🤷♀️
В этом открытом уроке разбираю, как на самом деле работают транзакции в PostgreSQL и почему одного @Transactional недостаточно для защиты от проблем конкурентного доступа.
Поговорим не только о теории, но и о том, что реально происходит внутри PostgreSQL и Spring-приложений.
В уроке:
• Что такое MVCC и зачем PostgreSQL хранит несколько версий строк
• Почему читатели не блокируют писателей
• Dirty Read, Non-repeatable Read, Phantom Read, Lost Update и Write Skew
• READ COMMITTED, REPEATABLE READ и SERIALIZABLE в PostgreSQL
• Как работают снимки данных (snapshots)
• Строковые, табличные и индексные блокировки
• FOR UPDATE и FOR SHARE
• Почему SELECT может не видеть строку, а INSERT уже конфликтует по UNIQUE индексу
• Optimistic Locking (@Version) в Hibernate
• Pessimistic Locking (PESSIMISTIC_WRITE, PESSIMISTIC_FORCE_INCREMENT)
• Как выбирать стратегию блокировок для реальных задач
• Практические примеры на Spring Boot + PostgreSQL
Этот урок является частью моего подхода к менторингу Java Backend-разработчиков, где основной акцент делается не на запоминании аннотаций, а на понимании механизмов, которые стоят за ними.
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!✌️
Жду ваших реакций и оценок🙂
Прошу прощения за звук, Егора почти не слышно...
В этом открытом уроке разбираю, как на самом деле работают транзакции в PostgreSQL и почему одного @Transactional недостаточно для защиты от проблем конкурентного доступа.
Поговорим не только о теории, но и о том, что реально происходит внутри PostgreSQL и Spring-приложений.
В уроке:
• Что такое MVCC и зачем PostgreSQL хранит несколько версий строк
• Почему читатели не блокируют писателей
• Dirty Read, Non-repeatable Read, Phantom Read, Lost Update и Write Skew
• READ COMMITTED, REPEATABLE READ и SERIALIZABLE в PostgreSQL
• Как работают снимки данных (snapshots)
• Строковые, табличные и индексные блокировки
• FOR UPDATE и FOR SHARE
• Почему SELECT может не видеть строку, а INSERT уже конфликтует по UNIQUE индексу
• Optimistic Locking (@Version) в Hibernate
• Pessimistic Locking (PESSIMISTIC_WRITE, PESSIMISTIC_FORCE_INCREMENT)
• Как выбирать стратегию блокировок для реальных задач
• Практические примеры на Spring Boot + PostgreSQL
Этот урок является частью моего подхода к менторингу Java Backend-разработчиков, где основной акцент делается не на запоминании аннотаций, а на понимании механизмов, которые стоят за ними.
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Жду ваших реакций и оценок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
История технологии сегодня — 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