Привет!
Меня зовут Саша Ланцов, и в этом канале я хочу делиться своими мыслями, наблюдениями и находками о том, что вызвало у меня интерес и любопытство.
О чём будет канал:
Java и Go, их рантаймы и особенности
Долгое время я пишу на JVM-стеке: разрабатывал несколько low-latency алготрейдинговых систем для крупных инвестиционных банков.
Сейчас работаю в главной платёжной системе страны, где помимо прикладной разработки занимаюсь вопросами производительности расчётных платежных систем.
Стремительный рост Go тоже не оставляет равнодушным - насколько он соперничает с Java, в чём их отличия, и чему можно поучиться друг у друга?
Попробуем разобраться.
Многопоточное и конкурентное программирование
Ещё со времён учебы в институте я люблю эту тему. Помимо того, что часто сталкиваюсь с ней на работе - мне нравится про неё и рассказывать!
Например, вы могли видеть записи моих докладов с конференций - о применении нестандартных семантик для написания высокопроизводительного кода или об эволюции моделей памяти в разных языках.
Многопоточность с нами уже давно, но пробелов у разработчиков хватает. Постараемся заполнить их актуальными знаниями.
Спикерство, конференции и текущее состояние IT
Я убеждён: любой профессионал (а профессионалом я называю того, кто регулярно получает деньги за своё дело) всегда может чем-то поделиться.
Хочу рассказать о своём опыте участия в конференциях - как со стороны спикера, так и со стороны участника программного комитета. Мир конференций тесно связан с внутренней жизнью IT-компаний, так что интересные инсайты - будут.
А вообще… чего уж скрывать - периодически прогреваться тоже будем.
Поехали 🔥
Меня зовут Саша Ланцов, и в этом канале я хочу делиться своими мыслями, наблюдениями и находками о том, что вызвало у меня интерес и любопытство.
О чём будет канал:
Java и Go, их рантаймы и особенности
Долгое время я пишу на JVM-стеке: разрабатывал несколько low-latency алготрейдинговых систем для крупных инвестиционных банков.
Сейчас работаю в главной платёжной системе страны, где помимо прикладной разработки занимаюсь вопросами производительности расчётных платежных систем.
Стремительный рост Go тоже не оставляет равнодушным - насколько он соперничает с Java, в чём их отличия, и чему можно поучиться друг у друга?
Попробуем разобраться.
Многопоточное и конкурентное программирование
Ещё со времён учебы в институте я люблю эту тему. Помимо того, что часто сталкиваюсь с ней на работе - мне нравится про неё и рассказывать!
Например, вы могли видеть записи моих докладов с конференций - о применении нестандартных семантик для написания высокопроизводительного кода или об эволюции моделей памяти в разных языках.
Многопоточность с нами уже давно, но пробелов у разработчиков хватает. Постараемся заполнить их актуальными знаниями.
Спикерство, конференции и текущее состояние IT
Я убеждён: любой профессионал (а профессионалом я называю того, кто регулярно получает деньги за своё дело) всегда может чем-то поделиться.
Хочу рассказать о своём опыте участия в конференциях - как со стороны спикера, так и со стороны участника программного комитета. Мир конференций тесно связан с внутренней жизнью IT-компаний, так что интересные инсайты - будут.
А вообще… чего уж скрывать - периодически прогреваться тоже будем.
Поехали 🔥
👍7
Прогревочная pinned «Привет! Меня зовут Саша Ланцов, и в этом канале я хочу делиться своими мыслями, наблюдениями и находками о том, что вызвало у меня интерес и любопытство. О чём будет канал: Java и Go, их рантаймы и особенности Долгое время я пишу на JVM-стеке: разрабатывал…»
Собираюсь на Joker 2025
Прямо сейчас собираю вещи - завтра еду в Санкт-Петербург, где через пару дней стартует Joker 2025
В этом сезоне я впервые участвовал как член программного комитета (и, вот это удивительно, это съело совершенно неприличное количество времени!)
Поэтому на этот раз выступаю лишь с небольшим лайтнингом в конце первого дня.
Пока оставлю здесь скриншот - попробуйте угадать, про что он 👀
А теперь - немного про доклады, подготовку которых я сопровождал как член ПК:
🧵 Александр Маторин: "ThreadLocal устарел? Детальное сравнение со ScopedValue"
Внутрянка
(спойлер: всё не так однозначно)
🔁 Дмитрий Фролов - "Ретраи: любовь с третьей попытки"
Концентрат базы по современной обработке ретраев. Даже опытные разработчики порой умудряются положить сервис
🦀 Денис Габайдулин - "Вызовите Rust - у нас тут медленно!"
Как подружить Java и Rust? Как прокидывать ошибки между языками, как перенаправить логирование из нативного кода в стандартный логгер?
Денис покажет практические подходы, которые реально работают, это очень интересный доклад.
UPD: Денис заболел и не смог выступить 😢
✈️ Алексей Рагозин: "JDK Flight Recorder в 2025-ом"
Доклады Алексея мне рекламировать не надо, тут и так все понятно. Будет и обзор эволюции JFR, и свежие фишки последнего релиза.
Имхо, добавилось много вкусного.
⚡️ Пётр Портнов - "Компилируем формулы в рантайме во имя перфа"
Про идеальный кейс применения JVM:
динамическая генерация кода в рантайме, который должен быстро работать после прогрева. Отличный баланс теории JIT и практических решений по производительности.
А вообще, если увидите меня на конфе - подходите, поболтаем 🙂
Прямо сейчас собираю вещи - завтра еду в Санкт-Петербург, где через пару дней стартует Joker 2025
В этом сезоне я впервые участвовал как член программного комитета (и, вот это удивительно, это съело совершенно неприличное количество времени!)
Поэтому на этот раз выступаю лишь с небольшим лайтнингом в конце первого дня.
Пока оставлю здесь скриншот - попробуйте угадать, про что он 👀
А теперь - немного про доклады, подготовку которых я сопровождал как член ПК:
🧵 Александр Маторин: "ThreadLocal устарел? Детальное сравнение со ScopedValue"
Внутрянка
ScopedValue: откуда там взялась вероятностная структура данных а-ля фильтр Блума, и всегда ли ThreadLocal медленнее нового решения?(спойлер: всё не так однозначно)
🔁 Дмитрий Фролов - "Ретраи: любовь с третьей попытки"
Концентрат базы по современной обработке ретраев. Даже опытные разработчики порой умудряются положить сервис
retry storm-ами - а это та самая категория ошибок, которую нельзя недооценивать.Как подружить Java и Rust? Как прокидывать ошибки между языками, как перенаправить логирование из нативного кода в стандартный логгер?
Денис покажет практические подходы, которые реально работают, это очень интересный доклад.
UPD: Денис заболел и не смог выступить 😢
✈️ Алексей Рагозин: "JDK Flight Recorder в 2025-ом"
Доклады Алексея мне рекламировать не надо, тут и так все понятно. Будет и обзор эволюции JFR, и свежие фишки последнего релиза.
Имхо, добавилось много вкусного.
⚡️ Пётр Портнов - "Компилируем формулы в рантайме во имя перфа"
Про идеальный кейс применения JVM:
динамическая генерация кода в рантайме, который должен быстро работать после прогрева. Отличный баланс теории JIT и практических решений по производительности.
А вообще, если увидите меня на конфе - подходите, поболтаем 🙂
🔥9👍6❤5
Новый GC в Go, async-profiler теперь в JDK и гнушно-сортировочные приколы
Привет! После Joker навалилось дел - не писал, исправляюсь 🙂
За минувшие две недели, помимо шашлычного спектакля, произошло несколько интересных событий
🍵 Новый сборщик мусора в Go
В Go 1.26 планируется переход на новый сборщик мусора Green Tea GC. Это эволюция классического concurrent mark-sweep-алгоритма, который обходит кучу в поисках живых объектов, но с важным отличием - теперь работа идет не по отдельным объектам, а целыми страницами (блоками памяти фиксированного размера, где эти объекты и хранятся). Это снижает накладные расходы и улучшает кэш-локальность. Также активно используются векторные SIMD-инструкции в процессе сканирования страниц. Некоторые уже попытались использовать этот сборщик, и результаты не столь однозначные; на мой взгляд вопрос состоит в том, насколько в реальности верна гипотеза об редкости слабозаполненных страниц с низкой плотностью живых объектов. Надо будет разобраться!
Мне особенно интересно сравнить подходы Go и Java. В OpenJDK все актуальные GC теперь используют гипотезы о поколениях (да, их несколько 😯) - и перемещают объекты в процессе своей работы. В Go все наоборот: GC не перемещает объекты, поколений нет, и куча не компактизируется.
Из этого вытекают интересные практические следствия: почему простой LRU-кэш в Java склонен к непотизму, а Go не страдает от фрагментации памяти? В общем, интересных вопросов тут много - постараюсь разобрать их в дальнейших постах.
🔍
Я часто пользуюсь этим профилировщиком и рад, что он так активно развивается. В новой версии появился latency profiling mode. Например: хотим поймать редкий (но долгий)
Помимо множества других улучшений - теперь
🦀 Эпопея с заменой GNU Sort
На недавнем лайтнинге я рассказывал, как непросто корректно обрабатывать и сравнивать произвольные Unicode-строки. И вот снова беда.
В новых версиях Ubuntu классические GNU-утилиты постепенно заменяют на версии, переписанные на Rust. И тут обнаружилось:
Насколько сложно "один в один" воспроизвести старое и сложное поведение на новом стеке, даже если сам язык декларируется как более надежный и безопасный! Переписать - зачастую не проблема, а вот воссоздать десятилетия накопленных особенностей и зависимостей старого кода трудно. Увы, но таков путь.
На сегодня всё 😉
Привет! После Joker навалилось дел - не писал, исправляюсь 🙂
За минувшие две недели, помимо шашлычного спектакля, произошло несколько интересных событий
🍵 Новый сборщик мусора в Go
В Go 1.26 планируется переход на новый сборщик мусора Green Tea GC. Это эволюция классического concurrent mark-sweep-алгоритма, который обходит кучу в поисках живых объектов, но с важным отличием - теперь работа идет не по отдельным объектам, а целыми страницами (блоками памяти фиксированного размера, где эти объекты и хранятся). Это снижает накладные расходы и улучшает кэш-локальность. Также активно используются векторные SIMD-инструкции в процессе сканирования страниц. Некоторые уже попытались использовать этот сборщик, и результаты не столь однозначные; на мой взгляд вопрос состоит в том, насколько в реальности верна гипотеза об редкости слабозаполненных страниц с низкой плотностью живых объектов. Надо будет разобраться!
Мне особенно интересно сравнить подходы Go и Java. В OpenJDK все актуальные GC теперь используют гипотезы о поколениях (да, их несколько 😯) - и перемещают объекты в процессе своей работы. В Go все наоборот: GC не перемещает объекты, поколений нет, и куча не компактизируется.
Из этого вытекают интересные практические следствия: почему простой LRU-кэш в Java склонен к непотизму, а Go не страдает от фрагментации памяти? В общем, интересных вопросов тут много - постараюсь разобрать их в дальнейших постах.
🔍
async-profiler - новая версия 4.2 !Я часто пользуюсь этим профилировщиком и рад, что он так активно развивается. В новой версии появился latency profiling mode. Например: хотим поймать редкий (но долгий)
rehashing при добавлении значений в хэш-мапу - при обычном сэмплировании такое событие легко упустить, но новый режим решает эту проблему. Помимо множества других улучшений - теперь
async-profiler входит по умолчанию в состав Amazon Corretto JDK. Очень рад за авторов этого прекрасного инструмента и жду его появления в других JDK (ребята из Axiom JDK, привет 🤓)🦀 Эпопея с заменой GNU Sort
На недавнем лайтнинге я рассказывал, как непросто корректно обрабатывать и сравнивать произвольные Unicode-строки. И вот снова беда.
В новых версиях Ubuntu классические GNU-утилиты постепенно заменяют на версии, переписанные на Rust. И тут обнаружилось:
sort из проекта uutils ведёт себя иначе, чем оригинал - он игнорирует локаль при сортировке символов вроде “à”. Вроде бы мелочь, но такие расхождения потенциально ломают скрипты и CI-пайплайны. Насколько сложно "один в один" воспроизвести старое и сложное поведение на новом стеке, даже если сам язык декларируется как более надежный и безопасный! Переписать - зачастую не проблема, а вот воссоздать десятилетия накопленных особенностей и зависимостей старого кода трудно. Увы, но таков путь.
На сегодня всё 😉
❤8🔥7💯5👍2🌚2
Доклад с конференции Т-Банка, планы на 2026 и полезности на новогодние каникулы
Привет! 2025 близок к завершению, в связи с чем хотел бы поделиться с уважаемыми подписчиками несколькими полезными вещами🎁
Доклад с JVM Days
За окном уютно лежит свежий рыхлый снег - а ведь всего несколько месяцев назад были жаркие дни конца августа, когда Т-Банк и провел свою конференцию. Все записи уже доступны, здесь же я оставлю ссылку на свой доклад, в котором рассказываю не самые тривиальные (но и не сверх-специфичные!) способы оптимизации производительности на реальном примере одной платежной системы. Рассказываю про:
🔷 многопоточные конвейеры - как искать место для точечного ускорения
🔷 улучшенные способы вставки больших батчей в Postgres и волшебную функцию unnest
🔷 и немного про GC - на примере такого явления, как spiral of death, которое может выстреливать и в Java, и в Go, и вообще практически в любом рантайме со сборкой мусора
Планируемый доклад на SnowOne и подкаст "Тысяча фичей"
Сейчас мне интересна тема актуализации и +- адекватного сравнения алгоритмов сборки мусора и их реализаций в Java и Go; пока я все еще собираю и изучаю материалы
Вопросов для разбора тут много. Например: приводит ли большое количество виртуальных потоков к увеличению времени начальной маркировки - ведь у этих потоков есть свои стеки, которые нужно как-то обойти, чтобы начать строить множество безусловно достижимых объектов
Тут у меня возникла проблема в том, что написание постов в ТГ-канале, кажется, не очень хорошо подходит именно для таких технических тем: есть существенные ограничения редактора, невозможность вставки картинок посреди текста и т.д. Пока так и не придумал формат именно серьезного технического поста (а не разгона). Выходов из этой ситуации сейчас вижу два
Во-первых, будет традиционный технический доклад на SnowOne / JPoint, на котором и будут разбираться данные вопросы. Ценовая политика у конференций разная: цена дороги до Нск + SnowOne вполне может оказаться дешевле, чем просто билет на JPoint; в любом случае, спустя ~полгода запись станет доступна всем
Во-вторых, уважаемый @apakhmv предложил мне записаться в январе на подкасте "Тысяча фичей", где я попробую рассказать про всё вот это только голосом - без каких-либо картинок и слайдов. Не знаю, удачно ли получится у меня, но сам подкаст интересный: рубать солёные огурцы для оливье под разбор внутрянки Cassandra - самое то, советую послушать на этих каникулах!
Преподавание в университете
Конец года принес мне авантюрное предложение от одного университета - сделать авторский курс по многопоточному программированию для студентов 2 курса, которые знают Go и классический Си
Авантюрное оно для меня, потому что я никогда раньше не преподавал (но всегда хотелось попробовать); лекции только-только начинают писаться, а в качестве практической работы я планирую предложить студентам написать свою простейшую реализацию LSM-based базы данных целиком в памяти - там есть большое количество шестеренок и механизмов, которые должны работать конкурентно друг с другом: начиная от потокобезопасных MemTable / SSTable и заканчивая компатизаторами и другими фоновыми механизмами
Курс будет на Go, с вкраплениями C, но не могу не поделиться прекрасным материалом от Одноклассников, который и вдохновил меня на эту идею: на курсе люди с нуля делают свою простую реализацию Cassandra на чистой Java. Чистое удовольствие!
На этом пока все. Поздравляю с наступающим Новым годом и Рождеством! До встречи в 2026🎄
Привет! 2025 близок к завершению, в связи с чем хотел бы поделиться с уважаемыми подписчиками несколькими полезными вещами
Доклад с JVM Days
За окном уютно лежит свежий рыхлый снег - а ведь всего несколько месяцев назад были жаркие дни конца августа, когда Т-Банк и провел свою конференцию. Все записи уже доступны, здесь же я оставлю ссылку на свой доклад, в котором рассказываю не самые тривиальные (но и не сверх-специфичные!) способы оптимизации производительности на реальном примере одной платежной системы. Рассказываю про:
🔷 многопоточные конвейеры - как искать место для точечного ускорения
🔷 улучшенные способы вставки больших батчей в Postgres и волшебную функцию unnest
🔷 и немного про GC - на примере такого явления, как spiral of death, которое может выстреливать и в Java, и в Go, и вообще практически в любом рантайме со сборкой мусора
Планируемый доклад на SnowOne и подкаст "Тысяча фичей"
Сейчас мне интересна тема актуализации и +- адекватного сравнения алгоритмов сборки мусора и их реализаций в Java и Go; пока я все еще собираю и изучаю материалы
Вопросов для разбора тут много. Например: приводит ли большое количество виртуальных потоков к увеличению времени начальной маркировки - ведь у этих потоков есть свои стеки, которые нужно как-то обойти, чтобы начать строить множество безусловно достижимых объектов
Тут у меня возникла проблема в том, что написание постов в ТГ-канале, кажется, не очень хорошо подходит именно для таких технических тем: есть существенные ограничения редактора, невозможность вставки картинок посреди текста и т.д. Пока так и не придумал формат именно серьезного технического поста (а не разгона). Выходов из этой ситуации сейчас вижу два
Во-первых, будет традиционный технический доклад на SnowOne / JPoint, на котором и будут разбираться данные вопросы. Ценовая политика у конференций разная: цена дороги до Нск + SnowOne вполне может оказаться дешевле, чем просто билет на JPoint; в любом случае, спустя ~полгода запись станет доступна всем
Во-вторых, уважаемый @apakhmv предложил мне записаться в январе на подкасте "Тысяча фичей", где я попробую рассказать про всё вот это только голосом - без каких-либо картинок и слайдов. Не знаю, удачно ли получится у меня, но сам подкаст интересный: рубать солёные огурцы для оливье под разбор внутрянки Cassandra - самое то, советую послушать на этих каникулах!
Преподавание в университете
Конец года принес мне авантюрное предложение от одного университета - сделать авторский курс по многопоточному программированию для студентов 2 курса, которые знают Go и классический Си
Авантюрное оно для меня, потому что я никогда раньше не преподавал (но всегда хотелось попробовать); лекции только-только начинают писаться, а в качестве практической работы я планирую предложить студентам написать свою простейшую реализацию LSM-based базы данных целиком в памяти - там есть большое количество шестеренок и механизмов, которые должны работать конкурентно друг с другом: начиная от потокобезопасных MemTable / SSTable и заканчивая компатизаторами и другими фоновыми механизмами
Курс будет на Go, с вкраплениями C, но не могу не поделиться прекрасным материалом от Одноклассников, который и вдохновил меня на эту идею: на курсе люди с нуля делают свою простую реализацию Cassandra на чистой Java. Чистое удовольствие!
На этом пока все. Поздравляю с наступающим Новым годом и Рождеством! До встречи в 2026
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥6❤4
Forwarded from Тысяча фичей
61. Лучший GC: Java и Go.
Погружение в механизмы сборки мусора в Java и Go: исследование фундаментальных алгоритмов, эволюция от сборщиков с остановкой мира до конкурентных сборщиков, а также практические последствия для разработчиков. Mark-and-sweep, уплотнение памяти, гипотеза поколений и современные сборщики: G1, ZGC, Shenandoah и Green Tea GC в Go.
В гостях Саша Ланцов https://t.me/pro_grevy
--
Авторский тгк Саши @toxic_enterprise
Альтер эго Саши @sashimi_pub
--
🎧 Слушать в Apple Podcasts | Spotify | Yutube | Яндекс | браузер
Погружение в механизмы сборки мусора в Java и Go: исследование фундаментальных алгоритмов, эволюция от сборщиков с остановкой мира до конкурентных сборщиков, а также практические последствия для разработчиков. Mark-and-sweep, уплотнение памяти, гипотеза поколений и современные сборщики: G1, ZGC, Shenandoah и Green Tea GC в Go.
В гостях Саша Ланцов https://t.me/pro_grevy
--
Авторский тгк Саши @toxic_enterprise
Альтер эго Саши @sashimi_pub
--
🎧 Слушать в Apple Podcasts | Spotify | Yutube | Яндекс | браузер
🔥9❤2👍2
Тоже устали от бесконечного снега вокруг и уверены, что зима с нами ещё надолго?
Календарь подсказывает - весна уже через месяц, и в преддверии 8 марта коллеги из Spring АйО и Axiom JDK организуют митап, куда пригласили в том числе и меня - рассказать про Юникод и неочевидные грабли при его обработке. Буду рад видеть лично!
Когда: 05.03.2026, в 18.30
Где: Москва, Лофт Casa Picassa, ул, Бауманская д.11, стр.8. Зал Кандинский
Бесплатно, но нужна регистрация
Подробная программа и регистрация:
https://java-rock-stars.timepad.ru/event/3814065/
Календарь подсказывает - весна уже через месяц, и в преддверии 8 марта коллеги из Spring АйО и Axiom JDK организуют митап, куда пригласили в том числе и меня - рассказать про Юникод и неочевидные грабли при его обработке. Буду рад видеть лично!
Когда: 05.03.2026, в 18.30
Где: Москва, Лофт Casa Picassa, ул, Бауманская д.11, стр.8. Зал Кандинский
Бесплатно, но нужна регистрация
Подробная программа и регистрация:
https://java-rock-stars.timepad.ru/event/3814065/
❤10
Пока готовил очередной семинар, решил сделать небольшой развлекательный квиз по производительности 101 🥸
Даны две целочисленные матрицы a и b размером n * n; хотим подсчитать их произведение. Посмотрев определение матричного умножения можно сходу придумать что-то такое:
Может показаться неочевидным, но математический результат работы этой функции не зависит от того, в каком порядке записать все три цикла
То есть, существует шесть разных вариантов реализации данного алгоритма умножения, и они отличаются только порядком использования переменных i, j, k в циклах
Каждую реализацию можно обозначить в виде строки:
"i → j → k" - это первая функция
Собственно, вопрос: а какая реализация из этих шести вариантов работает эффективнее?
Если есть объяснение почему - пишите в комментариях!
Пост с разбором разумеется будет
Даны две целочисленные матрицы a и b размером n * n; хотим подсчитать их произведение. Посмотрев определение матричного умножения можно сходу придумать что-то такое:
func multiply(a, b, c [][]int) {
n := len(a)
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
for k := 0; k < n; k++ {
c[i][j] += a[i][k] * b[k][j]
}
}
}
}Может показаться неочевидным, но математический результат работы этой функции не зависит от того, в каком порядке записать все три цикла
for; вот такая функция точно также в итоге умножает две матрицы:func multiply_j_k_i(a, b, c [][]int) {
n := len(a)
for j := 0; j < n; j++ {
for k := 0; k < n; k++ {
for i := 0; i < n; i++ {
c[i][j] += a[i][k] * b[k][j]
}
}
}
}То есть, существует шесть разных вариантов реализации данного алгоритма умножения, и они отличаются только порядком использования переменных i, j, k в циклах
Каждую реализацию можно обозначить в виде строки:
"i → j → k" - это первая функция
multiply (цикл по i, затем вложенный цикл по j, затем вложенный по k), а "j → k → i" - функция multiply_j_k_i Собственно, вопрос: а какая реализация из этих шести вариантов работает эффективнее?
Если есть объяснение почему - пишите в комментариях!
❤1👍1
Какая реализация умножения эффективнее?
Anonymous Poll
58%
i → j → k
33%
i → k → j
13%
j → i → k
13%
j → k → i
21%
k → i → j
17%
k → j → i
