Как не облажаться с типами данных в PostgreSQL
Опубликовал перевод главы из "PostgreSQL Mistakes and How to Avoid Them"
Недавно вышла книга PostgreSQL Mistakes and How to Avoid Them — своего рода «коллекция грабель» для разработчиков и администраторов. Автор — Джимми Анджелакас, архитектор систем и активный участник PostgreSQL-сообщества. Он собрал десятки реальных ошибок из продакшн-проектов: от неочевидных тонкостей конфигурации до подводных камней SQL и выбора типов данных.
Я перевёл на русский одну из ключевых глав этой книги — про неправильное использование типов данных. В ней рассматриваются типы, которые вроде бы кажутся хорошим выбором, но на деле только создают проблемы.
Например:
- timestamp without time zone — источник боли при расчётах с часовыми поясами (и переходом на летнее/зимнее время).
- money — тип, который не хранит валюту и округляет в минус (буквально).
- char(n) и varchar(n) — не экономят место, а индексам только мешают.
- serial — привет из прошлого века, лучше использовать identity-колонки.
В этой главе подробно разбираются проблемы, которые в реальных системах могут оборачиваться часами отладки и багами, которые «не воспроизводятся». Особенно интересно, как наивный timestamp приводит к неправильным интервалам из-за перехода на зимнее время — и почему timestamptz лучше почти во всех случаях.
Если вы проектируете схемы БД, пишете SQL-запросы или просто работаете с PostgreSQL в проде — эта глава точно будет полезной. Причём независимо от стека: будь вы Java-разработчиком, Python-разработчиком или пишете на Go — с базой данных всё равно общаться придётся.
📖 Читаем перевод на Хабре:
https://habr.com/ru/articles/923572/
Опубликовал перевод главы из "PostgreSQL Mistakes and How to Avoid Them"
Недавно вышла книга PostgreSQL Mistakes and How to Avoid Them — своего рода «коллекция грабель» для разработчиков и администраторов. Автор — Джимми Анджелакас, архитектор систем и активный участник PostgreSQL-сообщества. Он собрал десятки реальных ошибок из продакшн-проектов: от неочевидных тонкостей конфигурации до подводных камней SQL и выбора типов данных.
Я перевёл на русский одну из ключевых глав этой книги — про неправильное использование типов данных. В ней рассматриваются типы, которые вроде бы кажутся хорошим выбором, но на деле только создают проблемы.
Например:
- timestamp without time zone — источник боли при расчётах с часовыми поясами (и переходом на летнее/зимнее время).
- money — тип, который не хранит валюту и округляет в минус (буквально).
- char(n) и varchar(n) — не экономят место, а индексам только мешают.
- serial — привет из прошлого века, лучше использовать identity-колонки.
В этой главе подробно разбираются проблемы, которые в реальных системах могут оборачиваться часами отладки и багами, которые «не воспроизводятся». Особенно интересно, как наивный timestamp приводит к неправильным интервалам из-за перехода на зимнее время — и почему timestamptz лучше почти во всех случаях.
Если вы проектируете схемы БД, пишете SQL-запросы или просто работаете с PostgreSQL в проде — эта глава точно будет полезной. Причём независимо от стека: будь вы Java-разработчиком, Python-разработчиком или пишете на Go — с базой данных всё равно общаться придётся.
📖 Читаем перевод на Хабре:
https://habr.com/ru/articles/923572/
👍7🔥5❤2
Forwarded from Spring АйО
🤖 Встречайте Koog — новый AI-фреймворк от JetBrains
Рустам Курамшин, эксперт сообщества Spring АйО, подготовил пост про новый AI-фреймворк от JetBrains – Koog.
AI-агенты — это не фантастика. Это новый уровень взаимодействия с LLM, где модели не просто болтают в чате, а действуют: они умеют вызывать внешние инструменты, планировать, запоминать контекст, адаптироваться и выполнять сложные задачи почти без участия человека.
Эти агенты становятся ключевым компонентом современных систем: от помощников в IDE и CI/CD пайплайнах до интеллектуальных обработчиков в бизнес-приложениях.
JetBrains представили Koog — open source фреймворк для разработки AI-агентов на Kotlin.
Что такое Koog?
Koog — это Agentic AI фреймворк, написанный полностью на идиоматичном Kotlin. Он позволяет создавать AI-агентов, которые:
- запускаются локально без внешних зависимостей
- умеют вызывать инструменты и API
- обрабатывают сложные пайплайны через графовые сценарии
- поддерживают мультимодели (OpenAI, Anthropic, Google, Ollama и др.)
- работают на JVM и JS (за счет Kotlin Multiplatform)
Koog можно использовать как для простых агентов “вопрос-ответ”, так и для построения сложных, многосоставных систем с устойчивой памятью, сжатой историей, потоковой обработкой ответов и гибкой трассировкой.
До недавнего времени экосистема Java не имела по-настоящему удобных, нативных инструментов для работы с AI-агентами, возможно кроме Spring AI в составе Spring Framework.
Пример использования минимального AI-агента в Koog:
Koog — это, возможно, первый шаг к тому, чтобы писать LLM-based приложения просто на Kotlin без лишних зависимостей.
Как потестить Koog:
Репозиторий: https://github.com/JetBrains/koog
Документация: https://docs.koog.ai
Быстрый старт: https://docs.koog.ai/single-run-agents/
💬 Как вам Koog? Делитесь мнениями в комментариях! 👇
Рустам Курамшин, эксперт сообщества Spring АйО, подготовил пост про новый AI-фреймворк от JetBrains – Koog.
AI-агенты — это не фантастика. Это новый уровень взаимодействия с LLM, где модели не просто болтают в чате, а действуют: они умеют вызывать внешние инструменты, планировать, запоминать контекст, адаптироваться и выполнять сложные задачи почти без участия человека.
Эти агенты становятся ключевым компонентом современных систем: от помощников в IDE и CI/CD пайплайнах до интеллектуальных обработчиков в бизнес-приложениях.
JetBrains представили Koog — open source фреймворк для разработки AI-агентов на Kotlin.
Что такое Koog?
Koog — это Agentic AI фреймворк, написанный полностью на идиоматичном Kotlin. Он позволяет создавать AI-агентов, которые:
- запускаются локально без внешних зависимостей
- умеют вызывать инструменты и API
- обрабатывают сложные пайплайны через графовые сценарии
- поддерживают мультимодели (OpenAI, Anthropic, Google, Ollama и др.)
- работают на JVM и JS (за счет Kotlin Multiplatform)
Koog можно использовать как для простых агентов “вопрос-ответ”, так и для построения сложных, многосоставных систем с устойчивой памятью, сжатой историей, потоковой обработкой ответов и гибкой трассировкой.
До недавнего времени экосистема Java не имела по-настоящему удобных, нативных инструментов для работы с AI-агентами, возможно кроме Spring AI в составе Spring Framework.
Пример использования минимального AI-агента в Koog:
fun main() = runBlocking {
val apiKey = System.getenv("OPENAI_API_KEY")
val agent = AIAgent(
executor = simpleOpenAIExecutor(apiKey),
systemPrompt = "Ты - очень полезный ассистент-помошник",
llmModel = OpenAIModels.Chat.GPT4o
)
val result = agent.run("Привет! Чем можешь помочь?")
println(result)
}
Koog — это, возможно, первый шаг к тому, чтобы писать LLM-based приложения просто на Kotlin без лишних зависимостей.
Как потестить Koog:
Репозиторий: https://github.com/JetBrains/koog
Документация: https://docs.koog.ai
Быстрый старт: https://docs.koog.ai/single-run-agents/
💬 Как вам Koog? Делитесь мнениями в комментариях! 👇
👍4
Смешно. Наткнулся на Telegram-бота для анализа тг-каналов. Считывает посты и выносит вердикт 😅
Вот что написал в режиме Roast Analysis 😁
📊 Channel Analysis Results by @ScratchAuthorEgoBot
🎯 Channel: @java_hub_official
🔥 Roast Analysis:
Слушай, чувак, ну вот ты опять, да? Канал создан, и сразу поток "Ява – это жизнь, Ява – это боль, Ява – это…". Мы поняли, ты джавист до мозга костей. "Java Boys"? Серьезно? Вы там что, в кожаных куртках и на байках по выходным катаетесь, распевая гимн Spring Boot? Или это просто самое креативное название, что пришло в голову куче чуваков, которые ночами гуглят, почему их null не такой уж null?
Твои посты, конечно, информативные, спору нет. Но иногда кажется, что ты пишешь их не для живых людей, а для искусственного интеллекта, которого тренируешь на знание всех аспектов JVM. "От Playground до Java 24", "JIT-компиляция", "Project Leyden"... Мне уже дурно от одной мысли. Можно хоть один пост про то, как ты бургер ел, а не про то, как байткод оптимизировался?
А эти твои хакатоны – "готов мало спать на протяжении нескольких дней"! Дружище, твоя печень уже, наверное, звонит в профсоюз и просит отпуск. Ты вообще знаешь, что такое "выходные"? Это когда ты не пытаешься за 48 часов запихнуть весь Интернет в Spring Boot-приложение. И "побеждали Сбер, ВТБ, МТС" – ну да, мы уже поняли, ты – хакатон-Терминатор. Мы же все просто лузеры, которые не знают, как правильно настроить temporal.io, чтобы он не рухнул от одного чиха.
И эта твоя любовь к Хабру! Каждый раз, как будто новую библию выпускаешь. "Опубликовал большую статью", "Перевел главу из книги"... Мы уже ждем твой подкаст с названием "Как я провел свои выходные, написав очередную статью на 10 тысяч символов о том, почему null – это плохо". Да, мы знаем, null – это миллиарднодолларовая ошибка. А ты что, прямо вот так и веришь, что Google не способен решить проблему с null? Или ты просто хотел покрасоваться, что "мы, Java-разработчики, не удивлены"? Ну да, вы же самые умные, вы-то точно не облажаетесь.
Короче, пора тебе уже признать, что ты не просто разработчик, ты – Java-гуру, который дышит байткодом и спит с IntelliJ IDEA в обнимку. Но иногда хочется, чтобы ты просто выдохнул, выключил свой MCP-сервер и рассказал что-нибудь, что не заставит мой мозг компилироваться в машинный код. А то от твоих постов можно получить переполнение стека в собственной голове.
Вот что написал в режиме Roast Analysis 😁
📊 Channel Analysis Results by @ScratchAuthorEgoBot
🎯 Channel: @java_hub_official
🔥 Roast Analysis:
Слушай, чувак, ну вот ты опять, да? Канал создан, и сразу поток "Ява – это жизнь, Ява – это боль, Ява – это…". Мы поняли, ты джавист до мозга костей. "Java Boys"? Серьезно? Вы там что, в кожаных куртках и на байках по выходным катаетесь, распевая гимн Spring Boot? Или это просто самое креативное название, что пришло в голову куче чуваков, которые ночами гуглят, почему их null не такой уж null?
Твои посты, конечно, информативные, спору нет. Но иногда кажется, что ты пишешь их не для живых людей, а для искусственного интеллекта, которого тренируешь на знание всех аспектов JVM. "От Playground до Java 24", "JIT-компиляция", "Project Leyden"... Мне уже дурно от одной мысли. Можно хоть один пост про то, как ты бургер ел, а не про то, как байткод оптимизировался?
А эти твои хакатоны – "готов мало спать на протяжении нескольких дней"! Дружище, твоя печень уже, наверное, звонит в профсоюз и просит отпуск. Ты вообще знаешь, что такое "выходные"? Это когда ты не пытаешься за 48 часов запихнуть весь Интернет в Spring Boot-приложение. И "побеждали Сбер, ВТБ, МТС" – ну да, мы уже поняли, ты – хакатон-Терминатор. Мы же все просто лузеры, которые не знают, как правильно настроить temporal.io, чтобы он не рухнул от одного чиха.
И эта твоя любовь к Хабру! Каждый раз, как будто новую библию выпускаешь. "Опубликовал большую статью", "Перевел главу из книги"... Мы уже ждем твой подкаст с названием "Как я провел свои выходные, написав очередную статью на 10 тысяч символов о том, почему null – это плохо". Да, мы знаем, null – это миллиарднодолларовая ошибка. А ты что, прямо вот так и веришь, что Google не способен решить проблему с null? Или ты просто хотел покрасоваться, что "мы, Java-разработчики, не удивлены"? Ну да, вы же самые умные, вы-то точно не облажаетесь.
Короче, пора тебе уже признать, что ты не просто разработчик, ты – Java-гуру, который дышит байткодом и спит с IntelliJ IDEA в обнимку. Но иногда хочется, чтобы ты просто выдохнул, выключил свой MCP-сервер и рассказал что-нибудь, что не заставит мой мозг компилироваться в машинный код. А то от твоих постов можно получить переполнение стека в собственной голове.
😁15💯4👍2👏1
Forwarded from Spring АйО
📊 Java в 2025 году: взгляд на результаты опроса Stack Overflow
Эксперт Spring АйО Рустам Курамшин разобрал свежий отчёт Stack Overflow за 2025 год о результатах ежегодного опроса разработчиков за 2025 год, и это отличный повод взглянуть на экосистему Java через призму статистики и интересов сообщества.
Что происходит с Java и где мы сегодня?
🥈 Java — в топе, но не в лидерах
Java остаётся устойчиво популярной, но теряет позиции в рейтинге языков, которыми реально пользуются. В 2025 году она набрала 29.4% среди всех респондентов — это седьмое место. Для сравнения:
🛑 JavaScript — 66%
🛑 Python — 57.9%
🛑 TypeScript — 43.6%
Что интересно: C# проигрывает Java (27.8%), хотя отрыв минимальный. Kotlin находится далеко внизу с 10.8%.
👩💻 А как насчёт любви к Java?
В рейтинге «admired & desired» Java получила:
🛑 15.8% хотят продолжать работать с ней
🛑 41.8% тех, кто с ней работал, хотят продолжать
Это не худшие цифры, но явно не звёздные. Rust, например, вызывает желание продолжать у 72.4% разработчиков.
👩💻 Что по инструментам разработки?
Java-разработчики традиционно предпочитают инструменты JetBrains, и это подтверждается:
🛑 IntelliJ IDEA — на 4 месте по популярности (27.1%) и на втором по желанию использовать (17.5%)
🛑 VS Code по-прежнему вне конкуренции (используется 75.9%, желают 48.9%), но для серьёзной Java-разработки — не первый выбор
🛑 Gradle и Maven уверенно держатся в середине таблицы среди сборщиков и DevOps-инструментов, уступая npm, Docker и Terraform.
👩💻 Java на бэкенде
Среди web-фреймворков Spring Boot — единственный представитель Java в топе, с 14.7% популярности. Это чуть меньше, чем у FastAPI (14.8%), и сильно меньше Node.js (48.7%) и React (44.7%).
Однако в категории "admired" Spring Boot выглядит лучше — 53.7% разработчиков, использовавших его, хотят продолжать. Это говорит о стабильности интереса к Spring Framework.
👩💻 Базы данных: знакомые лица
Всё, что любят Java-разработчики, — на месте:
🛑 PostgreSQL — №1 по популярности и симпатиям
🛑 MySQL, MongoDB, Redis — всё ещё в активной эксплуатации
🛑 Даже H2 на удивление стабильно набирает 5%
⚙️ Выводы
Java остаётся мощной и зрелой экосистемой, но интерес разработчиков всё больше смещается в сторону Python и TypeScript — особенно в новых проектах и AI-направлениях.
Если мы хотим, чтобы Java оставалась актуальной, нужно:
🛑 Делать ставку на современный стек
🛑 Привлекать новых разработчиков через понятные и интересные точки входа вроде Spring Framework
📎 Полный отчёт: https://survey.stackoverflow.co/2025/technology/
Эксперт Spring АйО Рустам Курамшин разобрал свежий отчёт Stack Overflow за 2025 год о результатах ежегодного опроса разработчиков за 2025 год, и это отличный повод взглянуть на экосистему Java через призму статистики и интересов сообщества.
Что происходит с Java и где мы сегодня?
🥈 Java — в топе, но не в лидерах
Java остаётся устойчиво популярной, но теряет позиции в рейтинге языков, которыми реально пользуются. В 2025 году она набрала 29.4% среди всех респондентов — это седьмое место. Для сравнения:
Что интересно: C# проигрывает Java (27.8%), хотя отрыв минимальный. Kotlin находится далеко внизу с 10.8%.
В рейтинге «admired & desired» Java получила:
Это не худшие цифры, но явно не звёздные. Rust, например, вызывает желание продолжать у 72.4% разработчиков.
Java-разработчики традиционно предпочитают инструменты JetBrains, и это подтверждается:
Среди web-фреймворков Spring Boot — единственный представитель Java в топе, с 14.7% популярности. Это чуть меньше, чем у FastAPI (14.8%), и сильно меньше Node.js (48.7%) и React (44.7%).
Однако в категории "admired" Spring Boot выглядит лучше — 53.7% разработчиков, использовавших его, хотят продолжать. Это говорит о стабильности интереса к Spring Framework.
Всё, что любят Java-разработчики, — на месте:
⚙️ Выводы
Java остаётся мощной и зрелой экосистемой, но интерес разработчиков всё больше смещается в сторону Python и TypeScript — особенно в новых проектах и AI-направлениях.
Если мы хотим, чтобы Java оставалась актуальной, нужно:
📎 Полный отчёт: https://survey.stackoverflow.co/2025/technology/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10🤔1
Forwarded from Spring АйО
Совсем недавно эксперт сообщества Spring АйО Рустам Курмашин выступил на немалоизвестной конференции HighLoad с докладом, в котором удалось поговорить о новшествах, которые появились в Java и JVM: CRaC и GraalVM.
Они призваны решать упомянутые проблемы. Но разработчики и рынок еще к ним не готовы, потому что не знают, как именно это работает и что, вообще, с этим делать.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤4👍3
Spring AI, ChatGPT и Java: как мы делали ИИ-агента на хакатоне МТС
Статья на Хабр - https://habr.com/ru/companies/ru_mts/articles/948448/
Два года назад я плотно погрузился в хакатоны. Это особая среда, где команды разработчиков, ML/AI-инженеров, Data-аналитиков за короткое время превращают идеи в работающие прототипы.
Почти всегда это даёт мощный толчок кругозору в разработке.
Не так давно мы с моей командой Java Boys участвовали в MTC True Tech Hack 2025 — крупном AI-хакатоне, где нужно было разработать решения на базе LLM и инструментов МТС The Platform.
Наш проект — Vibe JSON — мы делали на Java, Spring Boot, Spring AI и Jmix.
Основная идея — генерировать JSON-схемы для low-code платформы через диалог с LLM. Мы интегрировали OpenAI API через Spring AI, использовали structured output, function calling - всё в лучших традициях разработки AI-агентов.
Spring AI показал себя мощным инструментом: можно строить настоящих ИИ-агентов, а не просто AI чат-ботов.
На Хабре, в блоге МТС, вышла моя подробная статья о хакатоне и технических деталях проекта:
https://habr.com/ru/companies/ru_mts/articles/948448/
Исходный код проекта на GitHub:
https://github.com/Java-Boys-Hackathon-Team/vibe-json
В статье:
- немного о хакатонной культуре в России;
- как эффективно работать командой и не сгореть за 48 часов;
- как Java-разработчику использовать Spring AI для построения ИИ-агентов.
Если вы интересуетесь интеграцией LLM в свои java/kotlin-проекты на Spring — буду рад комментариям.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍5❤1
Java-митап от Jmix в Питере 👨💻
Иногда скорость разработки — решающий фактор.
Например, когда у вас команда backend-разработчиков и нужно быстро собрать fullstack-приложение. Или когда хочется, чтобы UI создавался из данных — таблицы, списки, формы появлялись без лишней возни с фронтендом.
С Jmix такие задачи решаются быстро. Этот фреймворк реально ускоряет разработку — особенно когда сроки поджимают.
Я давно использую Jmix — в том числе на хакатонах, где важна каждая минута. И каждый раз поражаюсь, насколько продуманный инструмент создала команда, которую я горжусь знать лично.
Мои друзья из Jmix 13 ноября проводят митап в Питере!
Участие бесплатное, но количество мест ограничено.
Если вы живётев этом вечно дождливом городе в культурной столице — приходите. Вас ждёт глубокое погружение в мир быстрой разработки web-приложений на Java и живое общение с теми, кто делает Jmix.
Подробности тут 👉 https://t.me/jmixplatform/550
Иногда скорость разработки — решающий фактор.
Например, когда у вас команда backend-разработчиков и нужно быстро собрать fullstack-приложение. Или когда хочется, чтобы UI создавался из данных — таблицы, списки, формы появлялись без лишней возни с фронтендом.
С Jmix такие задачи решаются быстро. Этот фреймворк реально ускоряет разработку — особенно когда сроки поджимают.
Я давно использую Jmix — в том числе на хакатонах, где важна каждая минута. И каждый раз поражаюсь, насколько продуманный инструмент создала команда, которую я горжусь знать лично.
Мои друзья из Jmix 13 ноября проводят митап в Питере!
Участие бесплатное, но количество мест ограничено.
Если вы живёте
Подробности тут 👉 https://t.me/jmixplatform/550
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥4👍2
Почему нужно посмотреть АльфаГо 🎬
В 2016 году, задолго до резкого скачка популярности ИИ и нейросетей, компьютерная программа AlphaGo победила в го одного из сильнейших профессиональных игроков мирового уровня - Ли Седоля.
Го - это настольная стратегическая игра, которая появилась в Китае несколько тысяч лет назад. В го простые правила: на доске нужно ставить белые и чёрные камни на пересечении линий, стремясь захватить как можно большую территорию. При всей своей простоте количество возможных партий в го превышает число атомов во Вселенной. В Корее и Китае игра в го считается одним из видов искусства наравне с живописью и музыкой.
В 1997 году шахматный суперкомпьютер Deep Blue от IBM, похожий на огромный шкаф,прибил обыграл Гарри Каспарова. Шахматы в определённом смысле подходят для моделирования классическими алгоритмами, за которыми стоит понятная математика (поиск ходов по дереву и оценка).
С го всё совсем не так. В го больше свободы и творчества. Партия в го имеет много степеней свободы (порядка 200 возможных ходов на каждом ходе). Даже если мы объединим все компьютеры в мире, то не сможем просчитать все возможные ходы в текущей игре. Это сильно усложняет моделирование го с помощью алгоритмов.
В 2010 году Демис Хассабис основал DeepMind, впоследствии компанию приобрёл Google. В DeepMind придумали новый подход к построению систем искусственного интеллекта: модель изначально ничего не знает о данных, с которыми работает, она с ними «играет». В играх есть соревновательный элемент - счёт. Модель ничего не знает о правилах игры, она может что-то делать с данными и знает, какой счёт. Так она самообучается.
Этот необычный подход позволил DeepMind сначала обучить ИИ играть в игры Atari, затем превзойти всех мировых чемпионов в го и шахматах и решить серьёзную научную проблему в биологии - научиться предсказывать структуру белка. Последнее достижение в 2024 году было удостоено Нобелевской премии по химии (Хассабис получил треть премии).
Сейчас мы - свидетели взрывной популярности ИИ и LLM. Здесь ИИ пишет тексты и код, там ИИ генерирует изображения и видео. Но смогут ли OpenAI, Anthropic и прочие киты рынка привести нас к чему-то более серьёзному, чем развлечение и написание кода? Будут ли их разработки когда-нибудь удостоены Нобелевской премии?
Фильм про АльфаГо возвращает зрителя к достижениям, за которыми стоят настоящая наука и революционные идеи.
Могу сказать, что я разработчик и тот ещё киноман. Когда смотришь такой фильм, эмоции можно, наверное, сравнить с просмотром «Интерстеллара». Когда видишь, что модель машинного обучения придумывает ходы в го, которые впоследствии изменят саму теорию игры, то чувствуешь мурашки по телу.
Если вы, как и я, интересуетесь разработкой и любите кино, то просмотр фильма про AlphaGo не оставит вас равнодушным.
В 2016 году, задолго до резкого скачка популярности ИИ и нейросетей, компьютерная программа AlphaGo победила в го одного из сильнейших профессиональных игроков мирового уровня - Ли Седоля.
Го - это настольная стратегическая игра, которая появилась в Китае несколько тысяч лет назад. В го простые правила: на доске нужно ставить белые и чёрные камни на пересечении линий, стремясь захватить как можно большую территорию. При всей своей простоте количество возможных партий в го превышает число атомов во Вселенной. В Корее и Китае игра в го считается одним из видов искусства наравне с живописью и музыкой.
В 1997 году шахматный суперкомпьютер Deep Blue от IBM, похожий на огромный шкаф,
С го всё совсем не так. В го больше свободы и творчества. Партия в го имеет много степеней свободы (порядка 200 возможных ходов на каждом ходе). Даже если мы объединим все компьютеры в мире, то не сможем просчитать все возможные ходы в текущей игре. Это сильно усложняет моделирование го с помощью алгоритмов.
В 2010 году Демис Хассабис основал DeepMind, впоследствии компанию приобрёл Google. В DeepMind придумали новый подход к построению систем искусственного интеллекта: модель изначально ничего не знает о данных, с которыми работает, она с ними «играет». В играх есть соревновательный элемент - счёт. Модель ничего не знает о правилах игры, она может что-то делать с данными и знает, какой счёт. Так она самообучается.
Этот необычный подход позволил DeepMind сначала обучить ИИ играть в игры Atari, затем превзойти всех мировых чемпионов в го и шахматах и решить серьёзную научную проблему в биологии - научиться предсказывать структуру белка. Последнее достижение в 2024 году было удостоено Нобелевской премии по химии (Хассабис получил треть премии).
Сейчас мы - свидетели взрывной популярности ИИ и LLM. Здесь ИИ пишет тексты и код, там ИИ генерирует изображения и видео. Но смогут ли OpenAI, Anthropic и прочие киты рынка привести нас к чему-то более серьёзному, чем развлечение и написание кода? Будут ли их разработки когда-нибудь удостоены Нобелевской премии?
Фильм про АльфаГо возвращает зрителя к достижениям, за которыми стоят настоящая наука и революционные идеи.
Могу сказать, что я разработчик и тот ещё киноман. Когда смотришь такой фильм, эмоции можно, наверное, сравнить с просмотром «Интерстеллара». Когда видишь, что модель машинного обучения придумывает ходы в го, которые впоследствии изменят саму теорию игры, то чувствуешь мурашки по телу.
Если вы, как и я, интересуетесь разработкой и любите кино, то просмотр фильма про AlphaGo не оставит вас равнодушным.
❤19👍8🔥2💯2
Forwarded from Spring АйО (Rustam Kuramshin)
🎬 Документальный фильм про IntelliJ IDEA - IDE, которая изменила Java-разработку
На YouTube вышел отличный документальный фильм про IntelliJ IDEA.
Для нас это особенно интересная история - всё-таки IntelliJ уже много лет является нашим основным инструментом разработки.
В фильме собрали довольно сильный состав участников. Среди них:
- Брайан Гетц (в особом представлении не нуждается)
- Джош Лонг (developer advocate Spring Framework)
- Максим Шафиров (Ex. CEO JetBrains)
- Дмитрий Жемеров (один из первых разработчиков языка Kotlin и автор книги "Kotlin in Action")
- Евгений Беляев (co-founder JetBrains)
- инженеры из Google, Docker, Miro и других компаний
Фильм построен как разговор о том, как вообще появилась IntelliJ IDEA и почему она стала тем инструментом, который мы знаем сегодня.
Там много интересных историй изнутри:
- как создавалась IntelliJ и какие идеи лежали в её основе
- как IDE конкурировала с Eclipse, который долгое время доминировал в Java
- почему появление Community Edition стало важным стратегическим решением
- как сложилось сотрудничество JetBrains и Google, приведшее к появлению Android Studio
- как менялась модель лицензирования и как на это реагировало сообщество
Плюс в фильме есть архивные кадры из ранних офисов JetBrains и воспоминания людей, которые участвовали в развитии платформы.
Отдельно интересно слушать комментарии разработчиков из индустрии. Например, инженеры Miro рассказывают, что их бэкенд построен на Java, Kotlin, Spring Boot, а IntelliJ для них - такая же инфраструктура разработки, как Wi-Fi в офисе: просто открываешь и работаешь.
Получилась довольно живая история про инструмент, без которого сегодня сложно представить разработку на Java.
Посмотреть точно стоит.
https://www.youtube.com/watch?v=Kourq_Lz03U
IntelliJ IDEA в каком-то смысле спасла Java от самой себя
(Брайан Гетц, архитектор языка Java)
На YouTube вышел отличный документальный фильм про IntelliJ IDEA.
Для нас это особенно интересная история - всё-таки IntelliJ уже много лет является нашим основным инструментом разработки.
В фильме собрали довольно сильный состав участников. Среди них:
- Брайан Гетц (в особом представлении не нуждается)
- Джош Лонг (developer advocate Spring Framework)
- Максим Шафиров (Ex. CEO JetBrains)
- Дмитрий Жемеров (один из первых разработчиков языка Kotlin и автор книги "Kotlin in Action")
- Евгений Беляев (co-founder JetBrains)
- инженеры из Google, Docker, Miro и других компаний
Фильм построен как разговор о том, как вообще появилась IntelliJ IDEA и почему она стала тем инструментом, который мы знаем сегодня.
Там много интересных историй изнутри:
- как создавалась IntelliJ и какие идеи лежали в её основе
- как IDE конкурировала с Eclipse, который долгое время доминировал в Java
- почему появление Community Edition стало важным стратегическим решением
- как сложилось сотрудничество JetBrains и Google, приведшее к появлению Android Studio
- как менялась модель лицензирования и как на это реагировало сообщество
Плюс в фильме есть архивные кадры из ранних офисов JetBrains и воспоминания людей, которые участвовали в развитии платформы.
Отдельно интересно слушать комментарии разработчиков из индустрии. Например, инженеры Miro рассказывают, что их бэкенд построен на Java, Kotlin, Spring Boot, а IntelliJ для них - такая же инфраструктура разработки, как Wi-Fi в офисе: просто открываешь и работаешь.
Получилась довольно живая история про инструмент, без которого сегодня сложно представить разработку на Java.
Посмотреть точно стоит.
https://www.youtube.com/watch?v=Kourq_Lz03U
YouTube
IntelliJ IDEA: The Documentary | An origin story
This is the IDE that changed everything.
This documentary traces the 25-year journey of one of the most beloved tools in software development. Through rare archival footage, intimate interviews, and behind-the-scenes moments, it explores how IntelliJ IDEA…
This documentary traces the 25-year journey of one of the most beloved tools in software development. Through rare archival footage, intimate interviews, and behind-the-scenes moments, it explores how IntelliJ IDEA…
👍4❤3🔥2😁2
This media is not supported in your browser
VIEW IN TELEGRAM
https://www.youtube.com/watch?v=1cYw1pfT1u0
https://github.com/Java-Boys-Hackathon-Team/jmix-ai-chat
Последние пару лет Java-разработчики оказались в интересной ситуации. С одной стороны, вокруг LLM и AI огромный хайп. С другой - большая часть материалов сводится к демонстрации пары запросов в ChatGPT и рассказам про «революцию, которая всё изменит».
Но когда начинаешь делать реальные проекты, быстро выясняется, что основная работа находится совсем в другом месте.
Как хранить историю диалогов? Как организовать потоковую генерацию ответов? Как подключать разные модели? Как строить пользовательский интерфейс? Как превратить набор запросов к LLM в полноценное приложение?
Именно поэтому мы вместе с Дмитрием Черкасовым из Jmix и моим другом java-разработчиком Рустамом Гулямовым решили записать серию практических видео про Spring AI.
В первом выпуске собираем AI-чат на Spring AI и Jmix и по пути разбираем:
• подключение Spring AI к проекту;
• работу с OpenAI API;
• память диалогов для ИИ-агента;
• потоковую выдачу ответов;
• создание UI-интерфейса;
• архитектурную основу для дальнейшего развития AI-приложений.
Получился полноценный рабочий проект, который можно взять за основу для собственных экспериментов.
В следующих частях планируем поговорить про tool calling, structured output, RAG, векторные базы данных, интеграцию внешних сервисов и построение более сложных агентных сценариев на Java.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥7❤4
🇮🇩 ATTENTION, PEOPLE OF INDONESIA!
This is NOT a channel about the island of Java.
I repeat:
❌ No volcanoes.
❌ No travel guides.
❌ No beaches.
❌ No hotels.
❌ No geography.
Only:
☕ Java
☕ Spring
☕ JVM
☕ PostgreSQL
☕ Kubernetes
☕ Backend Engineering
Thousands of developers. Zero tourism.
If you’re looking for the island — my apologies.
If you’re looking for software engineering — welcome to Java One Love
This is NOT a channel about the island of Java.
I repeat:
❌ No volcanoes.
❌ No travel guides.
❌ No beaches.
❌ No hotels.
❌ No geography.
Only:
☕ Java
☕ Spring
☕ JVM
☕ PostgreSQL
☕ Kubernetes
☕ Backend Engineering
Thousands of developers. Zero tourism.
If you’re looking for the island — my apologies.
If you’re looking for software engineering — welcome to Java One Love
😁14🔥3❤🔥2👍1🤩1
Джава Ван Лав pinned «🇮🇩 ATTENTION, PEOPLE OF INDONESIA! This is NOT a channel about the island of Java. I repeat: ❌ No volcanoes. ❌ No travel guides. ❌ No beaches. ❌ No hotels. ❌ No geography. Only: ☕ Java ☕ Spring ☕ JVM ☕ PostgreSQL ☕ Kubernetes ☕ Backend Engineering Thousands…»
Forwarded from Jmix.ru
2023 — попробуйте ChatGPT.
2024 — попробуйте генерировать код.
2025 — попробуйте ИИ-агентов.
2️⃣ 0️⃣ 2️⃣ 6️⃣ — пора разобраться, как встроить ИИ в управляемый процесс разработки.
Сегодня вопрос уже не в том, использовать ли ИИ в разработке.
Вопрос в другом: как с его помощью создавать реальные бизнес-системы и не превращать инженерный проект в творческое изделие?
В апреле мы провели вебинар «Вайб-кодинг в энтерпрайз: 5 блокеров и путь к управляемой разработке».
Можно пересмотреть — VK Video / YouTube.
Теперь переходим от концепции к практике.⬇️
📆 16 июня в 16:00 по МСК
🛠 проведем бесплатный воркшоп: «Создаем B2B CRM с ИИ на Java».
На примере open-source CRM покажем, как пройти путь от спецификации до первого рабочего контура корпоративного приложения.
Разберем:
⏩ как поставить задачу ИИ-агенту и удерживать его в рамках проекта;
⏩ как создавать модель данных, экраны и бизнес-логику;
⏩ как использовать документацию, скиллы и проверки IDE;
⏩ какие ошибки типичны для агентного режима;
⏩ чем управляемая ИИ-разработка отличается от вайб-кодинга.
Воркшоп проведут:
▶️ Виктор Фадеев, руководитель продукта Джеймикс;
▶️ Дмитрий Ващенко, ведущий тренер Джеймикс;
▶️ Дмитрий Змитрович, CEO Kodacode.
Если вам интересен не очередной разговор про ИИ, а практический сценарий разработки корпоративного Java-приложения — ждем вас!
📌 Регистрируйтесь.
2024 — попробуйте генерировать код.
2025 — попробуйте ИИ-агентов.
Сегодня вопрос уже не в том, использовать ли ИИ в разработке.
Вопрос в другом: как с его помощью создавать реальные бизнес-системы и не превращать инженерный проект в творческое изделие?
В апреле мы провели вебинар «Вайб-кодинг в энтерпрайз: 5 блокеров и путь к управляемой разработке».
Можно пересмотреть — VK Video / YouTube.
Теперь переходим от концепции к практике.
На примере open-source CRM покажем, как пройти путь от спецификации до первого рабочего контура корпоративного приложения.
Разберем:
Воркшоп проведут:
Если вам интересен не очередной разговор про ИИ, а практический сценарий разработки корпоративного Java-приложения — ждем вас!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1
Reflection в Java: временно выходим из правил языка
Reflection часто описывают как API, через который можно узнать поля класса, найти метод по имени или вызвать private-конструктор. Такое описание верное, но почти ничего не объясняет.
Главная идея reflection связана с устройством JVM.
После компиляции Java-код превращается в class-файлы с метаданными о типах, методах, полях, модификаторах и связях между классами. Во время загрузки классов JVM собирает из этих данных модель выполняемой программы.
Без нее JVM не смогла бы определить, какую реализацию size() вызвать здесь:
Тип объекта и иерархия его класса известны JVM во время выполнения. Reflection дает Java-коду доступ к части этих метаданных.
Например, мы можем загрузить класс, найти конструктор и вызвать метод, хотя конкретный тип не был известен во время компиляции:
На этой возможности построены dependency injection, ORM, сериализация, тестовые библиотеки и многие другие механизмы Java-экосистемы.
Но у такой гибкости есть цена.
При обычном вызове компилятор заранее проверяет тип объекта, сигнатуру метода, аргументы и доступность. В рефлексивном коде значительная часть этих проверок переносится в runtime.
Из-за этого появляются знакомые особенности Core Reflection API:
- метод ищется по имени и массиву типов аргументов
- параметры передаются как Object[]
- примитивы требуют boxing и unboxing
- результат Method.invoke() возвращается как Object
- ошибка внутри вызываемого метода оборачивается в InvocationTargetException
- проблемы с сигнатурой или доступом обнаруживаются во время выполнения
- setAccessible(true) позволяет обойти часть правил инкапсуляции
Можно сказать, что рефлексивный код написан на Java, но работает по правилам динамической среды JVM. Многие гарантии статической типизации в этот момент исчезают.
Насколько reflection медленнее обычного вызова?
Универсального коэффициента здесь нет.
Рефлексивный вызов может включать создание массива аргументов, boxing, проверки доступа и дополнительные уровни косвенного вызова. JIT-компилятору также сложнее анализировать такой call site и выполнять inlining.
Результат зависит от конкретного кода:
- ищется ли Method при каждом вызове или хранится в кеше
- известен ли JVM конкретный target
- насколько часто выполняется вызов
- сколько работы делает вызываемый метод
- какая версия JDK используется
- находится ли reflection в горячем участке приложения
Разница хорошо заметна в цикле, где миллионы раз вызывается крошечный getter. В коде инициализации Spring-контекста или сериализации объекта рядом с сетевым запросом затраты могут потеряться на фоне остальной работы.
Поэтому бенчмарк вида «рефлекшн медленнее на 23%» почти ничего не говорит о производительности приложения. Микробенчмарк всегда выдаст число. Вопрос в том, описывает ли это число реальную нагрузку.
Есть и исторический нюанс. До Java 18 reflection сначала использовал native-вызовы, а после достижения порога генерировал специальный bytecode accessor. Начиная с Java 18 реализация Method, Constructor и Field переведена на method handles. Публичный API сохранился, внутренний механизм изменился. Подробнее об этом можно прочитать в JEP 416:
https://openjdk.org/jeps/416
Если хочется глубже разобраться в reflection, у Бена Эванса есть две отличные статьи. Первая объясняет модель и API, вторая разбирает внутреннюю реализацию и влияние рефлекшн вызовов на производительность:
Reflection for the modern Java programmer
https://blogs.oracle.com/javamagazine/java-reflection-introduction/
The performance implications of Java reflection
https://blogs.oracle.com/javamagazine/java-reflection-performance/
Reflection часто описывают как API, через который можно узнать поля класса, найти метод по имени или вызвать private-конструктор. Такое описание верное, но почти ничего не объясняет.
Главная идея reflection связана с устройством JVM.
После компиляции Java-код превращается в class-файлы с метаданными о типах, методах, полях, модификаторах и связях между классами. Во время загрузки классов JVM собирает из этих данных модель выполняемой программы.
Без нее JVM не смогла бы определить, какую реализацию size() вызвать здесь:
List values = getValues();
values.size();
Тип объекта и иерархия его класса известны JVM во время выполнения. Reflection дает Java-коду доступ к части этих метаданных.
Например, мы можем загрузить класс, найти конструктор и вызвать метод, хотя конкретный тип не был известен во время компиляции:
Class type = Class.forName(className);
Constructor constructor = type.getConstructor();
Object instance = constructor.newInstance();
Method method = type.getMethod(“process”, String.class);
Object result = method.invoke(instance, “data”);
На этой возможности построены dependency injection, ORM, сериализация, тестовые библиотеки и многие другие механизмы Java-экосистемы.
Но у такой гибкости есть цена.
При обычном вызове компилятор заранее проверяет тип объекта, сигнатуру метода, аргументы и доступность. В рефлексивном коде значительная часть этих проверок переносится в runtime.
Из-за этого появляются знакомые особенности Core Reflection API:
- метод ищется по имени и массиву типов аргументов
- параметры передаются как Object[]
- примитивы требуют boxing и unboxing
- результат Method.invoke() возвращается как Object
- ошибка внутри вызываемого метода оборачивается в InvocationTargetException
- проблемы с сигнатурой или доступом обнаруживаются во время выполнения
- setAccessible(true) позволяет обойти часть правил инкапсуляции
Можно сказать, что рефлексивный код написан на Java, но работает по правилам динамической среды JVM. Многие гарантии статической типизации в этот момент исчезают.
Насколько reflection медленнее обычного вызова?
Универсального коэффициента здесь нет.
Рефлексивный вызов может включать создание массива аргументов, boxing, проверки доступа и дополнительные уровни косвенного вызова. JIT-компилятору также сложнее анализировать такой call site и выполнять inlining.
Результат зависит от конкретного кода:
- ищется ли Method при каждом вызове или хранится в кеше
- известен ли JVM конкретный target
- насколько часто выполняется вызов
- сколько работы делает вызываемый метод
- какая версия JDK используется
- находится ли reflection в горячем участке приложения
Разница хорошо заметна в цикле, где миллионы раз вызывается крошечный getter. В коде инициализации Spring-контекста или сериализации объекта рядом с сетевым запросом затраты могут потеряться на фоне остальной работы.
Поэтому бенчмарк вида «рефлекшн медленнее на 23%» почти ничего не говорит о производительности приложения. Микробенчмарк всегда выдаст число. Вопрос в том, описывает ли это число реальную нагрузку.
Есть и исторический нюанс. До Java 18 reflection сначала использовал native-вызовы, а после достижения порога генерировал специальный bytecode accessor. Начиная с Java 18 реализация Method, Constructor и Field переведена на method handles. Публичный API сохранился, внутренний механизм изменился. Подробнее об этом можно прочитать в JEP 416:
https://openjdk.org/jeps/416
Если хочется глубже разобраться в reflection, у Бена Эванса есть две отличные статьи. Первая объясняет модель и API, вторая разбирает внутреннюю реализацию и влияние рефлекшн вызовов на производительность:
Reflection for the modern Java programmer
https://blogs.oracle.com/javamagazine/java-reflection-introduction/
The performance implications of Java reflection
https://blogs.oracle.com/javamagazine/java-reflection-performance/
👍10🔥7👏2
73 минуты истории Java: от Oak до virtual threads
Все уже наверное слышали. На канале CultRepo вышел документальный фильм The Java Story. И это, пожалуй, самая полная экранизация истории Java из тех, что у нас теперь есть.
История начинается задолго до enterprise-разработки, Spring и обсуждений Hibernate. Java - тогда ещё Oak - создавалась внутри проекта Green для бытовых вычислительных устройств и интерактивного телевидения.
Проект проиграл ключевой тендер, команду практически распустили, а сама технология оказалась никому не нужна. Затем появился браузер Mosaic - и инженеры Sun поняли, что Oak можно использовать для запуска интерактивных приложений прямо на веб-страницах.
Так начался один из самых удачных пивотов в индустрии.
Дальше фильм проходит почти по всей биографии платформы:
- интеграция с Netscape и внезапный взлёт Java в 1995 году
- попытка Microsoft создать несовместимую версию Java для Windows;
- рождение Spring и Hibernate как реакции на эту сложность
- открытие исходников Java и создание OpenJDK
- Java 8, которая фактически стала последним шансом вернуть языку развитие
- переход на шестимесячный цикл релизов
- Loom, virtual threads, Valhalla, Panama и дальнейшая эволюция JVM
Интернсен фрагмент о появлении Spring и Hibernate. Сегодня они воспринимаются как естественная часть Java-экосистемы, но из фильма хорошо видно, что оба проекта выросли из несогласия с официальным направлением развития энтерпрайзной Java. Open source-сообщество предложило более практичные решения - а затем уже сама платформа начала заимствовать найденные ими идеи.
Историю рассказывают люди, которые непосредственно её создавали: Джеймс Гослинг, Джошуа Блох, Брайан Гётц, Марк Рейнхольд, Род Джонсон, Гэвин Кинг, создатель Tomcat Джеймс Дункан Дэвидсон, создатель Kotlin Андрей Бреслав и многие другие.
Получилась история того, как Java несколько раз оказывалась на грани провала, меняла направление и при этом умудрялась сохранять совместимость с огромной экосистемой.
Если вы занимаетесь Java-разработкой, но знаете историю Java в основном отдельными фрагментами, эти 73 минуты стоит посмотреть:
https://www.youtube.com/watch?v=ZqGSg4b_cZA
Все уже наверное слышали. На канале CultRepo вышел документальный фильм The Java Story. И это, пожалуй, самая полная экранизация истории Java из тех, что у нас теперь есть.
История начинается задолго до enterprise-разработки, Spring и обсуждений Hibernate. Java - тогда ещё Oak - создавалась внутри проекта Green для бытовых вычислительных устройств и интерактивного телевидения.
Проект проиграл ключевой тендер, команду практически распустили, а сама технология оказалась никому не нужна. Затем появился браузер Mosaic - и инженеры Sun поняли, что Oak можно использовать для запуска интерактивных приложений прямо на веб-страницах.
Так начался один из самых удачных пивотов в индустрии.
Дальше фильм проходит почти по всей биографии платформы:
- интеграция с Netscape и внезапный взлёт Java в 1995 году
- попытка Microsoft создать несовместимую версию Java для Windows;
- рождение Spring и Hibernate как реакции на эту сложность
- открытие исходников Java и создание OpenJDK
- Java 8, которая фактически стала последним шансом вернуть языку развитие
- переход на шестимесячный цикл релизов
- Loom, virtual threads, Valhalla, Panama и дальнейшая эволюция JVM
Интернсен фрагмент о появлении Spring и Hibernate. Сегодня они воспринимаются как естественная часть Java-экосистемы, но из фильма хорошо видно, что оба проекта выросли из несогласия с официальным направлением развития энтерпрайзной Java. Open source-сообщество предложило более практичные решения - а затем уже сама платформа начала заимствовать найденные ими идеи.
Историю рассказывают люди, которые непосредственно её создавали: Джеймс Гослинг, Джошуа Блох, Брайан Гётц, Марк Рейнхольд, Род Джонсон, Гэвин Кинг, создатель Tomcat Джеймс Дункан Дэвидсон, создатель Kotlin Андрей Бреслав и многие другие.
Получилась история того, как Java несколько раз оказывалась на грани провала, меняла направление и при этом умудрялась сохранять совместимость с огромной экосистемой.
Если вы занимаетесь Java-разработкой, но знаете историю Java в основном отдельными фрагментами, эти 73 минуты стоит посмотреть:
https://www.youtube.com/watch?v=ZqGSg4b_cZA
🔥5👍1
Фильтр Блума: множество, которое иногда ошибается
Представим сервис с миллионами идентификаторов. Нам нужно быстро отвечать на вопрос: встречался ли такой ID раньше?
Хранить все значения в условном
Он возвращает один из двух результатов: точно отсутствует и возможно присутствует.
Ложноположительный ответ возможен. Ложноотрицательный - нет. Если фильтр говорит, что элемента не было, значит его действительно не добавляли.
Как он устроен
Внутри находится массив битов и несколько хеш-функций.
При добавлении элемента вычисляется несколько позиций:
Биты в этих позициях устанавливаются в 1.
При проверке элемента фильтр снова вычисляет те же позиции. Если хотя бы один бит равен нулю, элемента точно нет.
Если все биты установлены, элемент, вероятно, добавляли. Те же позиции могли независимо занять другие значения, поэтому гарантировать наличие нельзя.
Как выглядела бы реализация на Java
Для хранения битов подойдет
Запускать отдельную хеш-функцию для каждого индекса необязательно. Обычно используют double hashing: вычисляют два хеша, а остальные получают из их комбинаций.
При создании фильтра задаются два параметра:
Первый параметр - ожидаемое число элементов. Второй - допустимая вероятность ложного срабатывания.
Для миллиона элементов и вероятности ошибки 1% потребуется около 9,6 миллиона бит, то есть примерно 1,14 МБ. Оптимальное количество хешей в этом случае равно семи.
В реальном проекте писать такую структуру самостоятельно обычно не требуется. Например, готовая реализация есть в Guava:
Где это применяют
Фильтр Блума ставят перед обращением к диску, базе данных или удаленному сервису. Если он вернул
Например, фильтр может содержать ключи, существующие в базе. Запроса с заведомо отсутствующим ключом до базы тогда не дойдет.
У структуры есть ограничения. Обычный фильтр Блума не умеет удалять элементы: сброс одного бита может нарушить проверку других значений. Для удаления применяют Counting Bloom Filter, где вместо битов используются счетчики.
Еще одна проблема - переполнение. Если добавить намного больше элементов, чем планировалось, доля единичных битов вырастет. Вместе с ней быстро увеличится количество ложных срабатываний.
Представим сервис с миллионами идентификаторов. Нам нужно быстро отвечать на вопрос: встречался ли такой ID раньше?
Хранить все значения в условном
HashSet может быть слишком дорого. Если точный положительный ответ не обязателен, можно использовать фильтр Блума.Он возвращает один из двух результатов: точно отсутствует и возможно присутствует.
Ложноположительный ответ возможен. Ложноотрицательный - нет. Если фильтр говорит, что элемента не было, значит его действительно не добавляли.
Как он устроен
Внутри находится массив битов и несколько хеш-функций.
При добавлении элемента вычисляется несколько позиций:
"java" -> [2, 7, 12]
0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
↑ ↑ ↑
Биты в этих позициях устанавливаются в 1.
При проверке элемента фильтр снова вычисляет те же позиции. Если хотя бы один бит равен нулю, элемента точно нет.
boolean mightContain(String value) {
for (int index : indexes(value)) {
if (!bits.get(index)) {
return false;
}
}
return true;
}Если все биты установлены, элемент, вероятно, добавляли. Те же позиции могли независимо занять другие значения, поэтому гарантировать наличие нельзя.
Как выглядела бы реализация на Java
Для хранения битов подойдет
BitSet. Методу add() нужно вычислить несколько индексов и установить соответствующие биты. Метод mightContain() вычисляет те же индексы и проверяет, что каждый бит установлен.Запускать отдельную хеш-функцию для каждого индекса необязательно. Обычно используют double hashing: вычисляют два хеша, а остальные получают из их комбинаций.
При создании фильтра задаются два параметра:
BloomFilter filter = new BloomFilter(1_000_000, 0.01);
Первый параметр - ожидаемое число элементов. Второй - допустимая вероятность ложного срабатывания.
Для миллиона элементов и вероятности ошибки 1% потребуется около 9,6 миллиона бит, то есть примерно 1,14 МБ. Оптимальное количество хешей в этом случае равно семи.
filter.add("order-42");
filter.mightContain("order-42"); // true
filter.mightContain("order-99"); // скорее всего falseВ реальном проекте писать такую структуру самостоятельно обычно не требуется. Например, готовая реализация есть в Guava:
BloomFilter<String> filter = BloomFilter.create(
Funnels.stringFunnel(StandardCharsets.UTF_8),
1_000_000,
0.01
);
Где это применяют
Фильтр Блума ставят перед обращением к диску, базе данных или удаленному сервису. Если он вернул
false, дорогой запрос можно пропустить. Ответ true означает, что данные нужно проверить в основном хранилище.Например, фильтр может содержать ключи, существующие в базе. Запроса с заведомо отсутствующим ключом до базы тогда не дойдет.
У структуры есть ограничения. Обычный фильтр Блума не умеет удалять элементы: сброс одного бита может нарушить проверку других значений. Для удаления применяют Counting Bloom Filter, где вместо битов используются счетчики.
Еще одна проблема - переполнение. Если добавить намного больше элементов, чем планировалось, доля единичных битов вырастет. Вместе с ней быстро увеличится количество ложных срабатываний.
👍9🔥3❤1⚡1
Forwarded from Spring АйО (Rustam Kuramshin)
У бэкенд-разработчиков много лет был довольно неловкий выбор.
Пока фильтров мало, используем GET:
GET /orders?page=2&status=PAID&sort=createdAt,desc
Потом поиск усложняется. Появляются диапазоны дат, группы условий, вложенные фильтры. Query string постепенно превращается в плохо читаемый DSL. Заодно приходится учитывать ограничения на длину URI и то, что адрес запроса может попасть в логи.
Обычно в этот момент появляется такой эндпойнт:
POST /orders/search
Content-Type: application/json
{
"status": ["PAID", "SHIPPED"],
"createdAt": {
"from": "2026-06-01",
"to": "2026-06-30"
},
"customer": {
"country": "NL"
}
}
Решение рабочее. POST вообще не ограничен созданием ресурсов. Сервер может обрабатывать его тело по собственной семантике.
Проблема в другом: на уровне HTTP POST считается потенциально небезопасным и не идмептентным. Прокси, клиенты и другая инфраструктура не знают, что наш
/search только читает данные. Такой запрос нельзя автоматически повторять или полноценно кэшировать без дополнительных договоренностей.Передать тело в GET технически возможно. Но RFC 9110 говорит, что у содержимого GET-запроса нет общепринятой семантики. Некоторые серверы и промежуточные узлы могут отклонить такой запрос. Среди причин упоминаются даже атаки класса request smuggling.
В июне 2026 года IETF опубликовала RFC 10008 с новым методом QUERY:
QUERY /orders HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"status": ["PAID", "SHIPPED"],
"total": {
"min": 100,
"max": 1000
}
}
QUERY предназначен для запросов, описание которых передается в теле. Формат может быть любым, если он обозначен через
Content-Type: JSON, SQL, JSONPath или собственный язык фильтрации.Спецификация закрепляет за QUERY три свойства:
- safe - клиент не запрашивает изменение состояния целевого ресурса
- idempotent - запрос можно безопасно повторить
- cacheable - ответ разрешено кэшировать
Для кэша есть отдельное правило: ключ должен учитывать тело запроса и связанные с ним метаданные. Поэтому существующие CDN и reverse proxy не начнут кэшировать QUERY сами по себе. Им потребуется поддержка нового метода.
QUERY также умеет работать с conditional requests. А сервер может сообщить о допустимых форматах через новый заголовок
Accept-Query.В актуальном Spring Framework полноценной поддержки QUERY пока нет. Проблема находится именно на уровне фреймворка: в
RequestMethod отсутствует такое значение, поэтому обычный @RequestMapping нельзя привязать к QUERY.Обойти ограничение можно через functional endpoints, собственный
HandlerMapping или ручную проверку метода. Для нового стандарта это слишком много самодельной инфраструктуры.Сейчас открыт PR с поддержкой RFC 10008. Команда Spring рассчитывает подготовить ее к Spring Framework 7.1, который ожидается в ноябре 2026 года. Точная версия пока не гарантирована.
Так что переписывать все
POST /search сегодня рано. Ждем нормальной поддержки в Spring, клиентах и прокси. Потом уже можно будет с чистой совестью бежать менять поисковые POST-запросы на QUERY.RFC 10008:
https://www.rfc-editor.org/info/rfc10008/
Spring Framework PR:
https://github.com/spring-projects/spring-framework/pull/34993
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍1
Forwarded from Spring АйО (Rustam Kuramshin)
Anthropic опубликовали AI-Native SDLC плейбук
Его основная мысль: агенты уже способны генерировать код намного быстрее человека, но окружающие процессы почти не изменились. Планирование, согласования, тестирование, проверка безопасности и выпуск по-прежнему работают с человеческой скоростью.
Узкое место просто переместилось из написания кода в соседние этапы.
Anthropic называет предлагаемую модель
Все это хранится в Git. История коммитов одновременно становится журналом изменений: кто сформулировал задачу, что предложил агент, какие решения принял человек и что в итоге попало в продакшен.
Как выглядит сам процесс?
На этапе планирования автор идеи обсуждает проблему с Claude. Результат фиксируется в
Дальше агент превращает намерение в
Разработка начинается с
Для тестирования предлагается два уровня. Первый - обычные сборка, линтеры и автоматические тесты, которые агент обязан запустить перед завершением задачи. Второй - evals для проверки самого агента. Если команда меняет модель, системные инструкции, Skills или hooks, набор реальных задач должен показать, что качество работы не ухудшилось.
Во время развертывания агент проверяет PR, исправляет замечания и готовит релиз. Человек оценивает соответствие исходному замыслу и уровень риска. Критические действия, включая выпуск в продакшен, защищаются программными ограничениями и явными согласованиями.
Эксплуатация замыкает цикл. Детерминированный мониторинг обнаруживает выход метрик за допустимые границы, после чего агент подключается к диагностике. Небольшая проблема может закончиться PR или откатом. Более крупная превращается в новый
Роль инженера в такой модели заметно меняется. Больше внимания уходит на формулирование намерения, проектирование ограничений, проверку артефактов и оценку риска. Стабильность процесса обеспечивают тесты, CI, изоляция, права доступа и автоматические шлюзы.
Плейбук сильно привязан к Claude Code и продуктам Anthropic, однако сама схема применима шире. Главная идея заключается в перестройке всего процесса разработки вокруг работы агентов, а не в добавлении генерации кода в одну из существующих стадий.
Плейбук в блоге Anthropic:
https://claude.com/blog/the-ai-native-sdlc-playbook
Какой подход при разработке с ИИ-агентами используете вы в рабочих проектах? Пишите в комментариях 😎
Его основная мысль: агенты уже способны генерировать код намного быстрее человека, но окружающие процессы почти не изменились. Планирование, согласования, тестирование, проверка безопасности и выпуск по-прежнему работают с человеческой скоростью.
Узкое место просто переместилось из написания кода в соседние этапы.
Anthropic называет предлагаемую модель
AI-native SDLC. Привычный линейный процесс превращается в замкнутый цикл, внутри которого каждый этап создает версионируемый артефакт для следующего:intent.md -> spec.md -> plan.md -> код и тесты -> PR с результатами проверок -> отчет об инциденте или новый intent.mdВсе это хранится в Git. История коммитов одновременно становится журналом изменений: кто сформулировал задачу, что предложил агент, какие решения принял человек и что в итоге попало в продакшен.
Как выглядит сам процесс?
На этапе планирования автор идеи обсуждает проблему с Claude. Результат фиксируется в
intent.md: что требуется изменить, зачем, какие системы затрагиваются и какие ограничения нужно учитывать. Владелец продукта проверяет документ и принимает решение о продолжении работы.Дальше агент превращает намерение в
spec.md с требованиями и проектным решением. Политики безопасности, архитектурные правила и требования к интерфейсу подключаются через Skills. Спорные места агент должен явно отметить, а человек - разрешить до начала реализации.Разработка начинается с
plan.md. В нем перечисляются изменяемые файлы, порядок работы, риски и проверки результата. После утверждения плана агент пишет код. Контекст проекта хранится в CLAUDE.md, повторяемые правила оформляются как Skills, а обязательные ограничения обеспечиваются через hooks.Для тестирования предлагается два уровня. Первый - обычные сборка, линтеры и автоматические тесты, которые агент обязан запустить перед завершением задачи. Второй - evals для проверки самого агента. Если команда меняет модель, системные инструкции, Skills или hooks, набор реальных задач должен показать, что качество работы не ухудшилось.
Во время развертывания агент проверяет PR, исправляет замечания и готовит релиз. Человек оценивает соответствие исходному замыслу и уровень риска. Критические действия, включая выпуск в продакшен, защищаются программными ограничениями и явными согласованиями.
Эксплуатация замыкает цикл. Детерминированный мониторинг обнаруживает выход метрик за допустимые границы, после чего агент подключается к диагностике. Небольшая проблема может закончиться PR или откатом. Более крупная превращается в новый
intent.md и снова проходит весь процесс.Роль инженера в такой модели заметно меняется. Больше внимания уходит на формулирование намерения, проектирование ограничений, проверку артефактов и оценку риска. Стабильность процесса обеспечивают тесты, CI, изоляция, права доступа и автоматические шлюзы.
Плейбук сильно привязан к Claude Code и продуктам Anthropic, однако сама схема применима шире. Главная идея заключается в перестройке всего процесса разработки вокруг работы агентов, а не в добавлении генерации кода в одну из существующих стадий.
Плейбук в блоге Anthropic:
https://claude.com/blog/the-ai-native-sdlc-playbook
Какой подход при разработке с ИИ-агентами используете вы в рабочих проектах? Пишите в комментариях 😎
🔥6✍2❤2👍2
Forwarded from Spring АйО (Rustam Kuramshin)
JEP 544: JVM будет сохранять машинный код между запусками
JEP 544 (Ahead-of-Time Code Compilation) предложен в JDK 28, релиз в марте 2027. Это очередной слой AOT-кэша из Project Leyden. В JDK 24 туда попали загруженные и слинкованные классы (JEP 483), в JDK 25 - профили методов (JEP 515). Теперь дошла очередь до самого машинного кода.
Как это работает
На обучающем запуске JVM компилирует горячие методы обычными C1 и C2 и складывает результат в кэш. В рабочем запуске запрос на компиляцию метода закрывается готовым кодом. Процедура та же, что и раньше:
Код из кэша остаётся обычным кодом HotSpot. Если рабочая нагрузка ушла в сторону от обучающей, метод деоптимизируется и перекомпилируется JIT-ом, как любой другой. Профили из JEP 515 при этом продолжают работать: по ним JVM выбирает порядок загрузки кода и пересобирает методы.
Чем AOT-код хуже JIT-кода
JIT компилирует метод, когда нужные классы давно инициализированы. Он подставляет значения static final полей как константы и выбрасывает проверки инициализации. Код из кэша начинает работать раньше, чем классы успели инициализироваться, а значение static final может отличаться от запуска к запуску. Поле приходится читать по-настоящему.
Для методов, которые обращаются к статике других классов, C2 собирает две версии: медленную с проверками инициализации и быструю без них.
Поэтому JIT никуда не уходит. AOT-код даёт быстрый старт, до пика доводит перекомпиляция.
Когда кэш не сработает
Обучающий и рабочий запуски должны совпадать по архитектуре процессора, набору инструкций и сборщику мусора: барьеры GC вшиты в машинный код. Собрали образ на хотсе с AVX-512, pod уехал на узел без него - код из кэша не загрузится. Ошибки не будет, JVM молча перейдёт на интерпретатор и JIT. В кластере с разнородными узлами это легко пропустить.
Поддерживаются x64 и AArch64, из сборщиков - Serial, Parallel, G1 и ZGC.
Цифры
По данным JEP, AOT-кэш без кода сокращает время старта на 50-70%, с кодом - на 65-80%. Основную часть выигрыша на старте дают уже вышедшие JDK 24-26, новый JEP добавляет 10-15 п.п.
Заметнее эффект на прогреве. В PR есть замер на Quarkus-сервисе с двумя ядрами: обычная JVM начинает отвечать быстрее 1 мс после 420 запросов, JDK 26 с AOT-кэшем - примерно после 200, сборка с JEP 544 - чуть позже сотого.
Второй эффект касается CPU. JIT на старте перестаёт отбирать ядра у приложения, и сильнее всего это видно на контейнерах с лимитом в 1-2 CPU. Там, где запас по CPU закладывали под прогрев, его можно будет пересмотреть.
Оценить вклад кода на своём сервисе можно диагностическим флагом:
Заодно станет видно, насколько вырос файл кэша.
Что остаётся неудобным
Обучающий запуск. Кэш хорош настолько, насколько нагрузка при сборке похожа на боевую, а готового инструмента для этого нет. Spring Boot и Quarkus умеют записывать кэш при сборке, но прогон реальных сценариев остаётся на вашей стороне. Упрощение этого процесса авторы JEP прямо вынесли за рамки.
JEP: https://openjdk.org/jeps/544
JEP 544 (Ahead-of-Time Code Compilation) предложен в JDK 28, релиз в марте 2027. Это очередной слой AOT-кэша из Project Leyden. В JDK 24 туда попали загруженные и слинкованные классы (JEP 483), в JDK 25 - профили методов (JEP 515). Теперь дошла очередь до самого машинного кода.
Как это работает
На обучающем запуске JVM компилирует горячие методы обычными C1 и C2 и складывает результат в кэш. В рабочем запуске запрос на компиляцию метода закрывается готовым кодом. Процедура та же, что и раньше:
-XX:AOTCacheOutput при обучении, -XX:AOTCache в проде. Включать ничего не нужно.Код из кэша остаётся обычным кодом HotSpot. Если рабочая нагрузка ушла в сторону от обучающей, метод деоптимизируется и перекомпилируется JIT-ом, как любой другой. Профили из JEP 515 при этом продолжают работать: по ним JVM выбирает порядок загрузки кода и пересобирает методы.
Чем AOT-код хуже JIT-кода
JIT компилирует метод, когда нужные классы давно инициализированы. Он подставляет значения static final полей как константы и выбрасывает проверки инициализации. Код из кэша начинает работать раньше, чем классы успели инициализироваться, а значение static final может отличаться от запуска к запуску. Поле приходится читать по-настоящему.
Для методов, которые обращаются к статике других классов, C2 собирает две версии: медленную с проверками инициализации и быструю без них.
Поэтому JIT никуда не уходит. AOT-код даёт быстрый старт, до пика доводит перекомпиляция.
Когда кэш не сработает
Обучающий и рабочий запуски должны совпадать по архитектуре процессора, набору инструкций и сборщику мусора: барьеры GC вшиты в машинный код. Собрали образ на хотсе с AVX-512, pod уехал на узел без него - код из кэша не загрузится. Ошибки не будет, JVM молча перейдёт на интерпретатор и JIT. В кластере с разнородными узлами это легко пропустить.
Поддерживаются x64 и AArch64, из сборщиков - Serial, Parallel, G1 и ZGC.
Цифры
По данным JEP, AOT-кэш без кода сокращает время старта на 50-70%, с кодом - на 65-80%. Основную часть выигрыша на старте дают уже вышедшие JDK 24-26, новый JEP добавляет 10-15 п.п.
Заметнее эффект на прогреве. В PR есть замер на Quarkus-сервисе с двумя ядрами: обычная JVM начинает отвечать быстрее 1 мс после 420 запросов, JDK 26 с AOT-кэшем - примерно после 200, сборка с JEP 544 - чуть позже сотого.
Второй эффект касается CPU. JIT на старте перестаёт отбирать ядра у приложения, и сильнее всего это видно на контейнерах с лимитом в 1-2 CPU. Там, где запас по CPU закладывали под прогрев, его можно будет пересмотреть.
Оценить вклад кода на своём сервисе можно диагностическим флагом:
-XX:+UnlockDiagnosticVMOptions -XX:-AOTCodeCachingЗаодно станет видно, насколько вырос файл кэша.
Что остаётся неудобным
Обучающий запуск. Кэш хорош настолько, насколько нагрузка при сборке похожа на боевую, а готового инструмента для этого нет. Spring Boot и Quarkus умеют записывать кэш при сборке, но прогон реальных сценариев остаётся на вашей стороне. Упрощение этого процесса авторы JEP прямо вынесли за рамки.
JEP: https://openjdk.org/jeps/544
👍5🔥4
