Прогревочная
192 subscribers
7 photos
8 links
Java, Go и их рантаймы, многопоточность, конференции и немного IT-внутрянки. Прогреваемся разумно.

Null enjoyer: @lantsov_aleksander
Download Telegram
Channel photo updated
Привет!

Меня зовут Саша Ланцов, и в этом канале я хочу делиться своими мыслями, наблюдениями и находками о том, что вызвало у меня интерес и любопытство.

О чём будет канал:

Java и Go, их рантаймы и особенности

Долгое время я пишу на JVM-стеке: разрабатывал несколько low-latency алготрейдинговых систем для крупных инвестиционных банков.
Сейчас работаю в главной платёжной системе страны, где помимо прикладной разработки занимаюсь вопросами производительности расчётных платежных систем.

Стремительный рост Go тоже не оставляет равнодушным - насколько он соперничает с Java, в чём их отличия, и чему можно поучиться друг у друга?
Попробуем разобраться.



Многопоточное и конкурентное программирование

Ещё со времён учебы в институте я люблю эту тему. Помимо того, что часто сталкиваюсь с ней на работе - мне нравится про неё и рассказывать!

Например, вы могли видеть записи моих докладов с конференций - о применении нестандартных семантик для написания высокопроизводительного кода или об эволюции моделей памяти в разных языках.
Многопоточность с нами уже давно, но пробелов у разработчиков хватает. Постараемся заполнить их актуальными знаниями.

Спикерство, конференции и текущее состояние IT

Я убеждён: любой профессионал (а профессионалом я называю того, кто регулярно получает деньги за своё дело) всегда может чем-то поделиться.

Хочу рассказать о своём опыте участия в конференциях - как со стороны спикера, так и со стороны участника программного комитета. Мир конференций тесно связан с внутренней жизнью IT-компаний, так что интересные инсайты - будут.

А вообще… чего уж скрывать - периодически прогреваться тоже будем.
Поехали 🔥
👍7
Прогревочная pinned «Привет! Меня зовут Саша Ланцов, и в этом канале я хочу делиться своими мыслями, наблюдениями и находками о том, что вызвало у меня интерес и любопытство. О чём будет канал: Java и Go, их рантаймы и особенности Долгое время я пишу на JVM-стеке: разрабатывал…»
Собираюсь на Joker 2025

Прямо сейчас собираю вещи - завтра еду в Санкт-Петербург, где через пару дней стартует Joker 2025

В этом сезоне я впервые участвовал как член программного комитета (и, вот это удивительно, это съело совершенно неприличное количество времени!)
Поэтому на этот раз выступаю лишь с небольшим лайтнингом в конце первого дня.
Пока оставлю здесь скриншот - попробуйте угадать, про что он 👀

А теперь - немного про доклады, подготовку которых я сопровождал как член ПК:

🧵 Александр Маторин: "ThreadLocal устарел? Детальное сравнение со ScopedValue"
Внутрянка ScopedValue: откуда там взялась вероятностная структура данных а-ля фильтр Блума, и всегда ли ThreadLocal медленнее нового решения?
(спойлер: всё не так однозначно)

🔁 Дмитрий Фролов - "Ретраи: любовь с третьей попытки"
Концентрат базы по современной обработке ретраев. Даже опытные разработчики порой умудряются положить сервис retry storm-ами - а это та самая категория ошибок, которую нельзя недооценивать.

🦀 Денис Габайдулин - "Вызовите Rust - у нас тут медленно!"
Как подружить Java и Rust? Как прокидывать ошибки между языками, как перенаправить логирование из нативного кода в стандартный логгер?
Денис покажет практические подходы, которые реально работают, это очень интересный доклад.

UPD: Денис заболел и не смог выступить 😢

✈️ Алексей Рагозин: "JDK Flight Recorder в 2025-ом"
Доклады Алексея мне рекламировать не надо, тут и так все понятно. Будет и обзор эволюции JFR, и свежие фишки последнего релиза.
Имхо, добавилось много вкусного.

⚡️ Пётр Портнов - "Компилируем формулы в рантайме во имя перфа"
Про идеальный кейс применения JVM:
динамическая генерация кода в рантайме, который должен быстро работать после прогрева. Отличный баланс теории JIT и практических решений по производительности.

А вообще, если увидите меня на конфе - подходите, поболтаем 🙂
🔥9👍65
Новый 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 не страдает от фрагментации памяти? В общем, интересных вопросов тут много - постараюсь разобрать их в дальнейших постах.



🔍 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🎄
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥64
пока искал иллюстрации для лекций, наткнулся на сайт, посвященный истории появления вычислительной техники с её первых дней. Конкретно эта фотография: программистка и её программа, 62 500 карточек, ~ 5 Мб, 1955 год

поздравляю с окончанием первой рабочей недели 📝
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43🔥3😁1
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 | Яндекс | браузер
🔥92👍2
Тоже устали от бесконечного снега вокруг и уверены, что зима с нами ещё надолго?

Календарь подсказывает - весна уже через месяц, и в преддверии 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; хотим подсчитать их произведение. Посмотрев определение матричного умножения можно сходу придумать что-то такое:

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