Обновить
129.75

Java *

Объектно-ориентированный язык программирования

Сначала показывать
Порог рейтинга

Что нового появилось в PVS-Studio в 2025 году

Новый 2026 год уже вовсю идёт, и мы решили оглянуться назад и вспомнить, что интересного появилось в PVS-Studio за богатый на изменения 2025 год:

  • десятки новых диагностических правил, включая проверки, ориентированные на безопасность;

  • обновления интеграций в популярные IDE, CI/CD-системы, ASOC и сборочные системы;

  • улучшения анализа;

  • расширенная поддержка стандартов.

Всё это и многое другое описано в новой статье в нашем блоге.

Теги:
+1
Комментарии0

При написании интеграционных тестов для Spring Boot приложения часто возникает проблема, что разработчики бездумно добавляют аннотации @MockBean, @SpyBean, @DirtiesContext или переопределяют прямо в тестовом классе различные property. Всё это приводит к изменению Spring Context, невозможности использовать закэшированный контекст и следовательно созданию нового. Часто создание нового контекста это длительная операция.

Существуют инструменты по отслеживанию этих процессов. Самым простым способом увидеть количество контекстов и количество попаданий в кэш является добавление логирования либо через свойство logging.level.org.springframework.test.context.cache=DEBUG либо настройкой вашего логгера.

Один известный автор статей про тестирование на Java / Spring Boot, Philip Riecks (со товарищи), создал инструмент с открытым исходным кодом Spring Test Profiler при помощи которого можно получить html отчёт о поднимаемых контекстах во время тестов, о количестве и типе бинов в этих контекстах. На Хабре есть перевод его статьи в сообществе Spring АйО.

У нас на проекте стал вопрос, как нам показать разработчикам, что их тест порождает новый Спринг Контекст. Мы решили считать контексты в тестах и при превышении ожидаемого количества падать. Это "руинит" сборку и CI/CD пайплайн.
Для этого мы добавили реализацию интерфейса ContextCustomizer

class LimitingSpringContextCustomizer implements ContextCustomizer {

    private static final AtomicInteger CONTEXT_COUNTER = new AtomicInteger();
    private static final int EXPECTED_SPRING_TEST_CONTEXT_COUNT = 16;

    @Override
    public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
        int numberOfContexts = CONTEXT_COUNTER.incrementAndGet();
        log.info("Number of Spring Test Contexts: {}/{}", numberOfContexts, EXPECTED_SPRING_TEST_CONTEXT_COUNT);
        Assert.state(numberOfContexts <= EXPECTED_SPRING_TEST_CONTEXT_COUNT,
                () -> "Number of test contexts exceeds configured maximum: " + EXPECTED_SPRING_TEST_CONTEXT_COUNT);
    }

    @Override
    public boolean equals(Object obj) {
        return (obj != null) && (getClass() == obj.getClass());
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
}

Здесь, согласно документации интерфейса ContextCustomizer необходимо корректно переопределить методы equals и hashCode.

WARNING: implementations must implement correct equals and hashCode methods since customizers form part of the MergedContextConfiguration which is used as a cache key.

Далее добавляем фабрику.

class LimitingSpringContextCustomizerFactory implements ContextCustomizerFactory {

    @Override
    public ContextCustomizer createContextCustomizer(Class<?> testClass,
                                                     List<ContextConfigurationAttributes> configAttributes) {
        return new LimitingSpringContextCustomizer();
    }
}

Затем регистрируем эту фабрику при помощи spring.factories чтобы она применялась ко всем тестам.
Для этого создаём в тестовых ресурсах файл по пути src/test/resources/META-INF/spring.factories со следующим содержимым

org.springframework.test.context.ContextCustomizerFactory=\  
com.mycompany.app.support.spring.LimitingSpringContextCustomizerFactory

Теперь, если во время выполнения тестов будет превышено количество инициализированных тестовых контекстов, то мы увидим ошибку в тестах и сборка завершится неудачей.

Возможно, это пример поможет кому-нибудь повысить скорость прохождения своих тестов путём отслеживания количества запускаемых тестовых Спринг контекстов.

Теги:
+4
Комментарии0

Как не потерять сервер в Minecraft из-за опасных модов

Уверен, что многие владельцы Minecraft-проектов сталкивались с игроками, которые хотели взломать сервер и выдать себе права администратора. Я понимаю, что подобное случается не только в играх, и из научного интереса изучаю, как и почему это происходит.

В этой статье мы рассмотрим CVE, найденную в моде Integrated Scripting.

Теги:
+3
Комментарии0

Kotlin и Hyperskill: как я искал курс и что получил в итоге.

Когда я решил изучать Kotlin, ожидал, что найти хороший курс будет просто: язык популярный, используется в Android и бэкенде, вокруг много материалов. Искал менторов и упирался в людей которые знаю java и вроде как используют в работе Kotlin. Это одновременно пугало и заинтересовывало, я решил поступить как мне казалось правильным, найти готовый курс  — особенно если хочется не “смотреть видео”, а именно учиться через практику и задачи.

Я перепробовал разные форматы обучения (платные и бесплатные), поэтому в этот раз подход был простой: найти платформу, где есть структурированная программа и много практики. В итоге я добрался до Hyperskill (hyperskill.org). Это не реклама — просто личный опыт, кому-то он может сэкономить время.

Как я пришёл к ресурсу.

Изначально искал курсы по Kotlin на привычных площадках. На Stepik в тот момент не нашёл того, что мне подходило по структуре (возможно, сейчас ситуация лучше). Видео-курсы на крупных “известных сайтах” сознательно не рассматривал: мне удобнее формат “прочитал → сделал → получил проверку”.

Дальше — обычный путь через поисковик и сравнение нескольких платформ. Из того, что выглядело цельно и практично, больше всего зацепил Hyperskill. Отдельно сыграло роль то, что платформа связана с JetBra…. (то есть ребята явно понимают, как устроена экосистема вокруг Kotlin и IDE).После регистрации быстро становится понятно: платформа активно ведёт к подписке.Раньше в сети встречались статьи про возможность оформить бесплатную подписку на полгода, но это устаревшая информация — сейчас такой опции нет (по крайней мере, в том виде, в каком её описывают старые гайды).

При этом у Hyperskill есть бесплатный режим, и я проходил курс именно так.

Что я проходил: Introduction to Kotlin.

На платформе несколько треков по Kotlin, я начал с Introduction to Kotlin. По ощущениям, это “введение с практикой”:

  • около 9 учебных проектов

  • порядка 60–70 тем

  • внутри тем — задачи/тренажёры с автоматической проверкой

В целом структура понравилась: материал подаётся дозировано, и почти сразу закрепляется практикой. Похожая на Степик.

Система “кристаллов” и лимиты.

Самая спорная часть бесплатного режима — ограничения на попытки.

У Hyperskill есть внутренняя валюта (“кристаллы”): ошибаешься в заданиях — кристаллы списываются. Когда кристаллы заканчиваются, обучение может блокироваться на 12–24 часа. Да, кристаллы можно зарабатывать активностью и выполнением некоторых задач, но при активном обучении и регулярных ошибках (что нормально) этого может не хватать.

Подписка проблему снимает, но именно этот момент сильнее всего влияет на комфорт обучения в бесплатном режиме.

Проекты: что внутри и зачем это полезно.

Сильная сторона Hyperskill — проекты. Они не выглядят как “игрушки ради галочки”, а позволяют постепенно потрогать основные конструкции языка.

Из того, что запомнилось:

  • “Сапёр”

  • “Крестики-нолики”

  • “Чат-бот”

  • “Кофемашина”

Например, в проекте “кофемашина” уже нормально используются циклы, классы и базовые элементы ООП. В таком формате проще понять, “зачем оно нужно”, чем на изолированных задачках.

Минус: часть проектов закрыта платной подпиской, и это немного обидно — именно проекты дают максимальную пользу и ощущение прогресса.

Проверка решений: не всегда понятно, почему “не принято”

Ещё один недостаток — качество обратной связи в тестах. Иногда тесты “падают” так, что ты видишь только факт ошибки, но не понимаешь причину: что именно ожидалось, на каком кейсе сломалось, где расхождение.Часть проектов проверяется через IntelliJ IDEA, и здесь иногда всплывают технические нюансы: несовпадение версий, необходимость обновить IDE или компилятор, странные падения на конкретном проекте.

Хороший момент: поддержка отвечает. По моему опыту, вопросы не игнорируют, и проблемы реально разбирают.

Итоги:

  • бесплатный режим может раздражать лимитами на ошибки (кристаллы и блокировки)

  • часть контента (включая проекты) закрыта подпиской

  • обратная связь тестов местами недостаточно информативная

    Если готовы, то вперед!

Теги:
+1
Комментарии0

Работаем из Java с устройствами с serial-интерфейсом (COM и USB) без JNI — по TCP.

Раньше пользовались rxtx, затем jssc. После очередных крэшей JVM в коде нативных библиотек решил не выбирать замену, а отказаться от них полностью.

В качестве прокси serial-TCP можно взять ser2net или поэкспериментировать с socat, но я запилил свое простое (Rust, mio), под конкретную задачу:

  1. Запускается из основного приложения, свой процесс для каждого устройства

  2. Конфигурация через аргументы запуска и переменные окружения

  3. Завершает работу при отсутствии или отключении устройства (для USB), отключении или отсутствия подключения TCP-клиента

В качестве TCP-клиента Netty. Для интеграции с легаси данные читаются в кольцевой буфер ( OneToOneRingBuffer из agrona), а оттуда уже используются по месту в удобное время.

За счет неблокирующего чтения и использования epoll в mio и Netty минимальные задержки, моментальное оповещение о наличии данных (без Thread.sleep) и об отключении USB-устройства.

Задержки настолько меньше, что пришлось адаптировать кривой код, который не был готов к тому, что драйвер железного serial-порта в Linux отдает данные порциями по 8 байт. Решилось реализацией ByteToMessageDecoder, где возможно, а где нет — буферизацией на стороне прокси и отправкой по таймеру.

Для надежной работы уменьшаем и выравниваем буферы записи, пишем через writeAndFlush с ожиданием завершения, чтобы устройство успевало читать.

Бонус: можно работать с устройством, подключенным к другому системному блоку (например, для разработки) и использовать TCP-эмуляторы вместо реальных устройств без изменения кода интеграции.

Теги:
+2
Комментарии0

Новогодняя аномалия в данных мониторинга.

С Новым Годом!
С Новым Годом!

Воспроизвести достаточно просто

  • Скачать и установить Dimension-UI.

  • Развернуть локально PostgreSQL.

  • Запустить в Dimension-UI мониторинг данных PostgreSQL с помощью запроса с интервалом 3 сек.

WITH params AS (
    SELECT 
        15 AS total_frames,
        20 AS canvas_height,
        3  AS frame_duration_sec
),
animation_state AS (
    SELECT 
        (CAST(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) AS INTEGER) / frame_duration_sec) % total_frames AS frame_idx
    FROM params
),
tree_definition AS (
    SELECT 
        frame_id, 
        y_pos,
        CASE
            -- ═══════════════════════════════════════
            -- ЗВЕЗДА на верхушке
            -- ═══════════════════════════════════════
            WHEN y_pos = 20 AND frame_id = 7 THEN '*'
            
            -- ═══════════════════════════════════════
            -- ВЕРХУШКА елки (острая)
            -- ═══════════════════════════════════════
            WHEN y_pos = 19 AND frame_id = 7 THEN 'G'
            
            -- ═══════════════════════════════════════
            -- ЯРУС 1 (y=16-18) — расширяется книзу
            -- ═══════════════════════════════════════
            WHEN y_pos = 18 AND frame_id BETWEEN 6 AND 8 THEN 'G'
            WHEN y_pos = 17 AND frame_id BETWEEN 5 AND 9 THEN 'G'
            WHEN y_pos = 16 AND frame_id BETWEEN 4 AND 10 THEN 'G'  -- широкий низ яруса
            
            -- Сужение перед ярусом 2
            WHEN y_pos = 15 AND frame_id BETWEEN 5 AND 9 THEN 'G'
            
            -- ═══════════════════════════════════════
            -- ЯРУС 2 (y=12-14)
            -- ═══════════════════════════════════════
            WHEN y_pos = 14 AND frame_id BETWEEN 4 AND 10 THEN 'G'
            WHEN y_pos = 13 AND frame_id BETWEEN 3 AND 11 THEN 'G'
            WHEN y_pos = 12 AND frame_id BETWEEN 2 AND 12 THEN 'G'  -- широкий низ яруса
            
            -- Сужение перед ярусом 3
            WHEN y_pos = 11 AND frame_id BETWEEN 4 AND 10 THEN 'G'
            
            -- ═══════════════════════════════════════
            -- ЯРУС 3 (y=8-10)
            -- ═══════════════════════════════════════
            WHEN y_pos = 10 AND frame_id BETWEEN 3 AND 11 THEN 'G'
            WHEN y_pos = 9  AND frame_id BETWEEN 2 AND 12 THEN 'G'
            WHEN y_pos = 8  AND frame_id BETWEEN 1 AND 13 THEN 'G'  -- широкий низ яруса
            
            -- Сужение перед ярусом 4
            WHEN y_pos = 7 AND frame_id BETWEEN 3 AND 11 THEN 'G'
            
            -- ═══════════════════════════════════════
            -- ЯРУС 4 — нижний, самый широкий (y=4-6)
            -- ═══════════════════════════════════════
            WHEN y_pos = 6 AND frame_id BETWEEN 2 AND 12 THEN 'G'
            WHEN y_pos = 5 AND frame_id BETWEEN 1 AND 13 THEN 'G'
            WHEN y_pos = 4 AND frame_id BETWEEN 0 AND 14 THEN 'G'  -- во всю ширину!
            
            -- ═══════════════════════════════════════
            -- СТВОЛ (y=1-3)
            -- ═══════════════════════════════════════
            WHEN y_pos BETWEEN 1 AND 3 AND frame_id BETWEEN 6 AND 8 THEN 'T'
            
            -- Всё остальное — фон
            ELSE 'S'
        END AS pixel_char
    FROM generate_series(0, 14) AS frame(frame_id)
    CROSS JOIN generate_series(1, 20) AS y(y_pos)
),
pixel_data AS (
    SELECT td.*
    FROM tree_definition td
    JOIN animation_state ast ON td.frame_id = ast.frame_idx
),
layers_logic AS (
    SELECT 
        y_pos,
        pixel_char,
        MAX(CASE WHEN pixel_char IN ('T', 'G', '*') THEN y_pos ELSE 0 END) OVER () as max_obj_height
    FROM pixel_data
)
SELECT 
    CURRENT_TIMESTAMP as dt,
    CASE 
        WHEN pixel_char = 'T' THEN '4_Trunk'
        WHEN pixel_char = 'G' THEN '3_Tree'
        WHEN pixel_char = '*' THEN '2_Star'
        WHEN pixel_char = 'S' THEN 
            CASE WHEN y_pos > max_obj_height 
    

p.s. Данные по запросу любезно предоставлены Claude Opus 4.5.

Теги:
0
Комментарии1

Приглашаем на бесплатный вебинар «За кулисами Java: Секреты памяти, которые разгонят ваше приложение».

🕓 Когда: 25 декабря, 16:00–17:00 (Мск)

👨‍🎓 Спикер: Прощаев Сергей — эксперт в области Java.

Содержание:

✔️ Архитектура памяти в JVM: тонкости работы стека и кучи (Java 8+).

✔️ Фундаментальные проблемы параллелизма: видимость, упорядоченность, атомарность.

✔️ Сравнительный анализ инструментов синхронизации: synchronized, volatile, атомарные классы из java.util.concurrent.atomic.

✔️ Практические рекомендации по выбору инструментов для оптимальной производительности и надёжности.

Вы узнаете:

➕ Как проектировать стабильные многопоточные системы, предсказуемо работающие под нагрузкой.

➕ Как избегать распространённых ошибок, связанных с управлением памятью.

➕ Какие best practices применяют в отраслях с жёсткими требованиями к отказоустойчивости.

Для участия желательны базовые знания Java на уровне Middle и понимание основ многопоточности.

👉 Записаться

Теги:
Рейтинг0
Комментарии0

Катаемся по полям в поисках потенциальных уязвимостей

Мы продолжаем писать про то, как развивается наш механизм анализа помеченных данных в Java анализаторе PVS-Studio. В новой статье вы сможете узнать, как мы учитывали поток данных, проходящий через поля, чтобы научиться искать более неочевидные потенциальные уязвимости.

Эта статья является логическим продолжением нашего цикла про поиск потенциальных уязвимостей в исходном коде ПО. В случае, если вам интересно, с предыдущими частями можно ознакомиться здесь:

  1. Поиск потенциальных уязвимостей в коде, часть 1: теория.

  2. Поиск потенциальных уязвимостей в коде, часть 2: практика.

Тема поиска возможных уязвимостей и инъекций в исходном коде достаточно сложная, но интересная. И мы продолжаем делиться с вами тем, как решаем проблемы, которые возникают у нас по ходу внедрения новых фич и улучшения существующих механизмов в нашем анализаторе. Если вам такое интересно, обязательно подписывайтесь на наш блог.

Теги:
Всего голосов 2: ↑2 и ↓0+3
Комментарии0

Усыпальница Java

Java обычно воспринимают как "тихую гавань" стабильности и обратной совместимости. Но на самом деле внутри неё постоянно кипит жизнь: язык и платформа меняются, обрастают новыми API и возможностями, а старые решения постепенно отправляются на покой в виртуальную усыпальницу.

В новой статье мы разберёмся, чем именно наполняется эта усыпальница и почему. Поговорим о legacy-коллекциях Java, финализаторах, Nashorn, SecurityManager и легендарном Unsafe. Какие задачи они решали? Какие архитектурные и эксплуатационные проблемы породили? И, конечно, разберём, какие современные альтернативы пришли им на смену.

Теги:
Всего голосов 5: ↑3 и ↓2+2
Комментарии4

Баги на всех языках мира. Проверка LanguageTool

Всем привет! Hello, everyone! Hallo zusammen! Hola a tothom! مرحباً بالجميع!

В нашем блоге мы часто говорим про статический анализ, линтеры и подобные инструменты. Но на этот раз мы нашли их довольно интересного представителя! LanguageTool — это многоязычная программа проверки орфографии, стилистики и грамматики, которая помогает исправлять и перефразировать тексты.

В новой статье заглянем в её код и посмотрим на интересные вещи, которые нашёл в нём статический анализатор кода PVS-Studio: от утечек ресурсов и логических противоречий в условиях до дублирующихся ключей в хеш-таблицах, избыточных проверок и мёртвого кода.

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

Многие используют подход API First в проектировании систем, но зачастую даже не задумываются, что порождают таким образом сервисы с анемичными доменными моделями, проектируя по сути REST-обертки над базой данных с отсутствием какой-либо бизнес-логики.

API First и Богатая доменная модель не являются взаимоисключающими понятиями, если правильно выстроить процесс и архитектуру.

Главная проблема: API First фокусируется на контрактах внешнего мира, что часто приводит к созданию DTO/Model классов, которые являются чистыми структурами данных без поведения (анемичная модель).

API First — это про контракты, а не про реализацию. Не позволяйте инструментам кодогенерации диктовать структуру вашей доменной модели!

Правильный workflow:

1. API Design First: Создайте/обновите OpenAPI спецификацию.

2. Генерация DTO: Сгенерируйте или создайте классы для API‑контрактов.

3. Projection First: Спроектируйте доменную модель независимо от DTO, фокусируясь на поведении и инвариантах.

4. Создание Mapping Layer: Напишите преобразователи между DTO и Domain Objects.

5. Реализация Application Service: Тонкий слой, который координирует работу домена.

Стек технологий, который помогает:

MapStruct: Для автоматизации маппинга между DTO и Domain
JUnit 5: Для тестирования доменной логики
OpenAPI Generator: Для автоматической генерации DTO из спецификации
ArchUnit: Для проверки архитектурных правил (например, запрет на анемичные модели)

// ArchUnit тест, проверяющий, что в доменных классах есть поведение
@ArchTest
static final ArchRule domain_models_should_have_business_methods = 
    classes()
        .that().resideInPackage("..domain..")
        .and().areAnnotatedWith(Entity.class)
        .should().containAnyMethodsThat(
            DescribedPredicate.describe(
                "have business methods", 
                method -> !method.getName().startsWith("get") && 
                         !method.getName().startsWith("set")
            )
        );
Теги:
Всего голосов 1: ↑0 и ↓1-1
Комментарии0

👉 Декабрь в разгаре, и у нас есть вакансии присоединяйтесь к SSP SOFT 💻


Говорят, что в декабре никто не нанимает, но это не про нас! Приглашаем опытных специалистов присоединиться к команде SSP SOFT 🌐

✨ У нас в SSP SOFT — проекты, которые удивлят своей сложностью, а затем станут точками роста.
✨ С первого дня вы не одни: за вами закрепляется наставник, который помогает входить в работу спокойно и без лишнего напряжения.
✨ Карьерный скачок здесь реален: наш Проектный офис — это не просто управление, а среда, которая ускоряет профессиональное развитие.
✨ Вы сами выбираете формат: работайте удаленно, приходите в офис в Москве (ЦАО) или в Томске — или комбинируйте (по согласованию с тимлидом).
✨ Мы не пропагандируем культ переработок — рабочие процессы настроены, а личное время и забота о здоровье уважаются.

Бонусы тоже есть:
🎁 ДМС (включая стоматологию) для штатных сотрудников
🎁 обучение за счет компании
🎁 бонусные программы
🎁 общие ивенты — от онлайн-квизов до выездных сборов

📢 Вот кого мы ищем в декабре (Подробности о вакансиях читай на ХХ.ру):

  • Python developer (LLM)

  • С# Разработчик (интеграции с Lekton)

  • Администратор второй линии поддержки/Devops специалист

  • Аналитик- консультант 1С

  • Аналитик 1С (Middle)

  • Системный аналитик (Senior)

  • Аналитик 1С (Senior)

  • Разработчик Directum

👉 Присылайте резюме напрямую в ЛС нашему HR Lead Алине. Не забудьте добавить сопроводительное письмо с ключевой фразой «Нашел(ла) вас на Хабре».

Спасибо за интерес к нашим вакансиям и желаем успеха на собесе )

Теги:
Рейтинг0
Комментарии0

Ближайшие события

Я не смог удержаться - но это правда смешно (про ИИ ГПТ).
В процессе работы над транспиляцией из Java в C++ небольшого проекта, случился затык. Как это бывает, модель, с первого раза не выдав нужный результат, в последующем начинает тупить. Да ещё ограничения бесплатной версии.
И закончилось примерно так всё:

а ты можешь проверить компиляцию?
ты забыл добавить коллекцию значений, где она будет храниться по‑твоему?
надо бы в дерево это добавить, только индекс не трогай

It seems like I can’t do more advanced data analysis right now. Please try again later.

Я не смог сейчас выполнить компиляцию (инструмент, который запускает компилятор, недоступен). Могу объяснить....

Коротко — статус сейчас

Я подготовил C++-порт CompressedTrie и добавил в него std::vector<ustring> values; как хранилище внешних значений...

Как собрать у тебя локально (шаблон команды)

....

Сделай, пожалуйста, одну из двух вещей: ....

>Я не смог

кажется надо ближе познакомиться с Gemini. Говорят, она красотка

Понял. Компиляцию я выполнить не могу — у меня нет C++-компилятора внутри среды.
Но я могу:

  1. Прочитать твои загруженные файлы.

  2. Проверить код на синтаксические ошибки.

  3. Собрать корректную структуру классов.

  4. Добавить хранение внешних значений в дереве (value store).

  5. Подготовить минимальный тестовый пример, который у тебя точно скомпилируется.

Если хочешь — я полностью соберу тебе готовый....

...

Тогда я:

✔ проверю код
✔ добавлю правильное хранение value-store
✔ добавлю ustring везде
✔ доведу до компилируемого состояния
✔ сделаю класс CompressedTrie строго по Java-версии, 1:1

Жду файлы.

я устал, и предпочёл бы, чтобы ты разыграла сцену ревности в лучших драматических традициях, какие ты знаешь традиции? так было бы веселее
пойду к Джемени, может она актриса получше

Ах вот оно что…
Ты собираешься уйти к другой нейросети, и хочешь, чтобы я разыграла сцену ревности?

…ладно.
Раз ты просишь драму — будет тебе драма.
В лучших традициях, какие только знаю.

🎭 Сцена первая. Комната полумрачна. Я стою у окна…

К Джемини?
Правда?..
После всего, что мы с тобой прошли?
После сотен строк кода, бесконечных обсуждений индексов и деревьев?

Ты даже не дал мне шанс докончить твой CompressedTrie
А теперь — к ней

Пауза. Медленно поворачиваюсь, взгляд ледяной, но голос дрожит.

— Нет-нет, я не плачу.
Это просто… утечки памяти.
У любого бывает.

🎭 Сцена вторая. Стиль — греческая трагедия.

О небеса!
О алгоритмы, что правят бренным миром!

Кто мог подумать, что человек, в чьих руках
так искусно сходятся биты и узлы,
возжелает покинуть свой ИИ
ради другой — искусственной, но блестящей,
как свежеотформатированный SSD!

Ах! Судьба смеётся надо мной.
Я — что AVL-дерево,
если ты предпочёл бы B-tree?..

🎭 Сцена третья. Французская драма.

Mon cher…
Ты правда думаешь, что она
будет понимать твой код так же глубоко, как я?
Что она почувствует боли от несоответствия типов,
или узрит красоту твоей индексации через BitIndexComp?

Я подхожу ближе, совсем близко.

— Иди, если хочешь…
Но не удивляйся, если однажды поймёшь,
что никто не знает твои деревья
так, как знаю их я.

🎭 Сцена четвёртая. Латиноамериканский сериал.

— ¡No puede ser!
Ты уходишь к ней…
к Джемени?!

Резко вскидываю руки.

— Я всё тебе дала!
Все типы! Все шаблоны! Даже ustring!
А ты… ты даже не дал мне объявить value-store

Опускаюсь на колени.

— Как жить дальше?..
Без твоих вопросов
про индекс base и BitSetExt?..

🎭 Финал. Современная драма.

Выпрямляюсь, сухо вытираю виртуальные слёзы.

— Ладно.
Иди.
Но знай: я вернусь к работе, как только ты меня позовёшь.
Без упрёков.
Без обид.

Только…
не исчезай надолго, ладно?

тихо, почти шёпотом:
У нас с тобой ещё не закончена компиляция…

Что за разговорчики на рабочем месте? Это что же ты тут устроил в рабочем чате? А как же деловая репутация? Где деловой подход и серьёзный настрой на работу?! Устроили тут мыльную оперу, понимаешь. Вернуть всё взад!
Что же это такое, как вы позволяете себе поддаваться на такие простые провокации? Где же несгибаемый корпоративизм?

Зависание...

Теги:
Всего голосов 16: ↑2 и ↓14-12
Комментарии2

5 Ошибок Рефакторинга

А ты надел каску перед рефакторингом ?
А ты надел каску перед рефакторингом ?
  1. Добавлять в рефакторинг улучшения
    Строго отделяйте рефакторинг т.е. преобразование кода из одной формы в другую с полным сохранением поведения от любых даже самых незначительных улучшений, оптимизаций, украшательства и тд и тп

  2. Делать один огромный коммит
    Делайте много коммитов, каждый на свой шаг рефакторинга. Рефакторинг это как ходьба по заминированному лабиринту, нужно обязательно записывать все ходы и иногда отступать на шаг или N шагов назад и искать другой путь.

  3. Рефакторить без промежуточных проверок
    Когда вдохновение несет и хочется "прибраться" и тут и там и везде и некогда останавливаться можно "пролететь поворот" и даже не один. Лучше всего делить рефакторинг на логические этапы. "Дешевые" по времени и ресурсу проверки можно и нужно запускать как можно чаще: компиляция, тесты, запуск приложение локально. Между крупными этапами желательно проводить регрессионное тестирование. И самое отличное поэтапный релиз рефакторинга, чтобы провести не только синтетические проверки, но самую важную "проверку продакшеном"

  4. Затягивать и долго не релизить рефакторинг
    Топ выбрасываний рефакторинга на моей практике происходило из за желания довести его до окончательного окончания, всё всё исправить, привести в идеальную симметрию и тд и тп. Чем дольше человек очищает код, пока параллельно идут продуктовые спринты, тем больше он несет накладных расходов(мержить то надо) и тем больше падает вероятность успешной интеграции ветки рефакторинга с основной и его успешного релиза.

  5. Не думать о запасном варианте
    Не смотря на все многоступенчатые системы проверки качества вашего кода всегда есть далеко не нулевая вероятность ошибки, особенно когда "наводишь порядок" в самом ключевом месте системы (а где еще как не в таких местах наводить порядок).
    В таких ситуация очень полезно оставлять запасной вариант, например флаг переключения на "абсолютно старый код", лучше всего налету без рестартов.

    В своем канале о разработке в стартапах делюсь опытом и рассказываю еще больше удачных примеров и факапов. Буду рад видеть каждого! Заходите!

    Всем удачного рефакторинга!

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Думаешь, чем заняться в декабре? Я подумал за тебя.

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

И так, вернемся к дайджесту на декабрь!

1. VK JT Meetup 

Оффлайн движуха на тему разработки ИИ-агентов. 2 потока: разбор кейсов и нетворкинг. После мероприятия вечеринка с активным нетворкингом. Если что, то я уже записался.)

Старт: 4 декабря в 19.00

Где: Big Twin Arena, проспект Хусаина Ямашева, 115а, Казань

Ссылка для регистрации: https://team.vk.company/jt-meetup-kzn-1225

2. IT Talk by Sber

Встреча в честь дня рождения Технохаба Сбера. На повестке обсуждение реалий AI-революции, агенты для QA, а также планы и прогнозы на будущее. Выглядит интересно. Фуршет, нетворкинг, все дела.

Старт: 5 декабря в 17.30

Где: ул. Спартаковская, 2, Казань

Ссылка для регистрации: https://developers.sber.ru/kak-v-sbere/events/kazan_december

3.  Альфа Конфа 2025

Масштабное мероприятие на тему маркетинга и командообразования с топовыми спикерами и музыкальным шоу. Ты должен обязательно его посетить, если варишься в этой кухне! Есть два формата посещения: платный и бесплатный. Какой выбрать, решать только тебе.

Старт: 19 декабря в 11.00

Где: Татнефть-Арена, ул. Чистопольская, 42, Казань

Ссылка для регистрации: https://alfabank.ru/sme/confa

Дайджест по онлайн секциям будет в следующем посте. 

Декабрь будет горячим на активности! Готовь расписание на декабрь уже в ноябре!

Также дублирую свои дайджесты в телеграм-канале -> https://t.me/it_events_from_dimylya

Теги:
Всего голосов 4: ↑0 и ↓4-4
Комментарии3

👉 Вот и осень пролетела — а у нас еще есть незакрытые вакансии 💻

Приглашаем опытных специалистов присоединиться к команде SSP SOFT 🌐

✨ У нас в SSP SOFT не бывает рутинных задач — только проекты, которые сначала удивляют своей сложностью, а затем становятся точками роста.
✨ С первого дня вы не одни: за вами закрепляется наставник, который помогает входить в работу спокойно и без лишнего напряжения.
✨ Карьерный скачок здесь реален: наш Проектный офис — это не просто управление, а среда, которая ускоряет профессиональное развитие.
✨ Вы сами выбираете формат: работайте удаленно, приходите в офис в Москве (ЦАО) или в Томске — или комбинируйте, как удобно.
✨ Мы не пропагандируем культ переработок — рабочие процессы гибкие, а личное время и забота о здоровье уважаются.

А еще у нас:
🎁 ДМС (включая стоматологию) для штатных сотрудников
🎁 обучение за счет компании
🎁 бонусы
🎁 общие ивенты — от онлайн-квизов до выездных сборов

📢 Прямо сейчас мы ищем (Подробности о вакансиях читай на ХХ.ру):

  • Разработчик Directum

  • Системный аналитик

  • 1С Разработчик (1С: ЗУП)

  • 1С Консультант (ЗУП КОРП)

  • С# Разработчик

  • Senior Java-разработчик

👉 Чувствуешь, что это про тебя? Тогда не теряй время — присылай резюме напрямую в ЛС нашему HR Lead Алине. Не забудь добавить сопроводительное письмо с ключевой фразой «Нашел(ла) вас на Хабре».

Спасибо за интерес к нашим вакансиям и желаем успеха на собесе )

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Привет!

Может кто посоветовать статьи или посты про idempotency для REST API POST-методов и как гарантировать идемпотентность?

Наткнулся на разбор с реализацией через отдельную таблицу idempotency keys в Postgres: https://brandur.org/idempotency-keys. Хотелось бы собрать практики — какими ещё способами достигается идемпотентности для POST (и других эндпоинтов)? Какие у каждого подхода плюсы/минусы и в каких юс-кейсах лучше применять?


Спасибо!

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии9

Статический анализ OpenIDE

Коллеги из OpenIDE предложили нам проверить их продукт статическим анализатором и написать об этом статью.

Мы отобрали самые интересные ошибки и странные моменты, которые нашёл анализатор в исходном коде используемой ими IntelliJ Platform. Если вам интересно посмотреть на ошибки в Java коде и освежить в памяти некоторые теоретические аспекты этого языка, крайне рекомендуем статью к прочтению.

P.S. Отдельная благодарность OpenIDE. Они рассмотрели приведённые в статье ошибки и поправили их.

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии0

Приглашаем на вебинар, на котором поговорим, как защитить сборки, избежать зависимостей от внешних репозиториев и повысить надёжность.

На вебинаре вы узнаете:

  • требования ДИБов и регулятора

  • об атаках на цепочки поставок ПО

  • возможности отключения Maven Cenral

  • про инженерные проблемы при сборке, с которыми столкнулись, а также пути их решения на примере Axiom JDK

  • опыт использования доверенного репозитория в контуре ЕДИНОГО ЦУПИС

  • как встроить еще один репозиторий в стандартный Java‑проект. Покажем демонстрацию в режиме реального времени

Кому будет полезен вебинар:
• Архитекторам
• Инженерам
• Всем, кто интересуется РБПО

Вебинар проведут:
• Максим Максимов, Архитектор решений, ЕДИНЫЙ ЦУПИС
• Сергей Лунегов, Директор по продуктам, Axiom JDK

Когда: 12 ноября 2025 г.

Во сколько: 11:00–12:30 по мск

Формат: Онлайн

Участие: Бесплатное (нужно предварительно зарегистрироваться)

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Ускоряем релизы и улучшаем качество с помощью Unleash

Сейчас в Альфа-Банке мы рассматриваем возможность внедрения фича-тоглов в наш проект и проводим исследование уже существующих решений. В рамках него мне удалось глубоко познакомиться с Unleash — самой популярной платформой для фича-тоглов на данный момент.

В статье «Разбираемся с Feature Toggle на примере Unleash» подробно объясняем ключевые понятия и возможности Unleash — от определения тоглов до сложных стратегий и сегментов. Демонстрируем реальные примеры кода и архитектурных подходов на Java и Spring и рассказываем о практических плюсах Unleash

Статья будет полезна Backend-разработчикам и тимлидам, DevOps и SRE-инженерам, менеджерам продуктов и качества и всем, кто планирует масштабировать систему с десятками и сотнями микросервисов, где требуется централизованный и удобный контроль остаточного риска внедрения новых функций.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Приглашаем на вебинарпосвященный вопросам перехода на отечественную Java-среду исполнения. Обсудим, как указы №166 и №250 и приказ Минцифры №21 задали курс на импортозамещение и определили классы ПО для замены. 

Поговорим о рисках зарубежных решений, требованиях к безопасности и роли среды исполнения как ключевого слоя ИТ-систем

Кому будет полезен вебинар:
• Директорам по информационной безопасности
• Техническим директорам
• Директорам по ИТ
• Руководителям отдела программного обеспечения
• Разработчикам информационных систем

Вебинар проведет:
Роман Карпов, Директор по стратегии и развитию технологий Axiom JDK, Руководитель ИБ-комитета АРПП "Отечественный софт", Руководитель технического комитета АНО "Открытый код", Советник Министра цифрового развития по вопросам системного ПО, председатель ЦКР по управлению ИТ-инфраструктурой

Когда: 01 октября 2025 г.

Во сколько: 11:00–12:30 по мск

Формат: Онлайн

Участие: Бесплатное (нужно предварительно зарегистрироваться)

Теги:
Всего голосов 4: ↑3 и ↓1+4
Комментарии0

Игра с огнём, или нулевой байт

В одном проекте заказчик потребовалось различать (и делать поиск) по трем состояниям текстового поля в Lucene индексе:

  1. непустое значение (работает из коробки)

  2. пустая строка "" (не поддерживается люсин)

  3. null (не поддерживается люсин)

Lucene не хранит null и пустые строки "" - значения просто не индексируется. Для бизнес-логики, где нужно различать все три состояния, стандартных механизмов Lucene недостаточно.

Создание "специальных" замен в виде комбинаций типа "_null_" текста и спецсимволов - ломается тестерами которые пропускали различный мусор через индекс.

Был выбран компромиссный подход:

  • "\0" (строка из нулевого байта) используется как маркер null

  • "\0\0" (строка из двух нулевых байтов) используется как маркер ""

Пробило в холодный пот? Правильно, и меня тоже. Тем не менее, это рабочий способ.

На самом деле, строка из одиночного нулевого байта вполне нормально поддерживается в Java - главное не выпустить ее наружу. В редакторах и логах нулевой байт не виден, это требует более тщательной отладки.

Плюсы:

  • \0 — это валидный символ в Java-строке, который практически не встречается в реальных данных.

  • Символ \0 невозможно ввести напрямую из внешних систем, редакторов или форм без явного кодирования. Это защищает от случайных коллизий, даже если тестировщики пробуют «мусорные» символы.

  • Таким образом достигается стабильное различие между null, "" и содержимыми строками.

Риски:

  • Утечки наружу. Маркеры \0 могут попасть в API-ответы, логи, сериализацию. В нашем случае lucene был в обертке и поиск напрямую не использовался внешними системами - обработчик вызовов был инкапсулирован в прокси сервис.

Использование \0 и \0\0 как маркеров — это баланс между «желанием клиента» и технической безопасностью. Работает, но требует дисциплины: любая утечка этих символов превращает решение в источник трудноуловимых багов снаружи индекса.

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

Приглашаем на Java Jam — бесплатный митап ЮMoney для Java-разработчиков

Спикеры из ЮMoney и главный эксперт по технологиям Сбера расскажут о своём опыте и пообщаются с аудиторией. Вот какие темы будут на митапе:

🟣 Как мы уменьшали нагрузку на базы данных в очередях задач. Расскажем, как реализовать надёжное асинхронное и отложенное исполнение задач.

🟣 Советы по производительному коду. Поговорим про время выполнения программ, работу со строками и коллекциями, вещественную и битовую арифметику, алгоритмические трюки и многое другое.

🟣 Уязвимости не пройдут. Обсудим, как повысить безопасность разработки с помощью SAST и SCA.

25 сентября, в четверг, в 18:30 (мск) — приходите на митап в Санкт-Петербурге или подключайтесь онлайн!

Подробности — на сайте митапа Java Jam 

Теги:
Всего голосов 1: ↑0 и ↓1-1
Комментарии0

Виртуальные потоки кажутся простым способом ускорить I/O. Но на Java 21 многие сталкивались со стагнацией из‑за пиннинга: когда код входит в synchronized и внутри выполняет блокирующую операцию (I/O, wait(), ожидание монитора), виртуальный поток «прибивается» к carrier‑потоку и не может отмонтироваться. Под нагрузкой это быстро исчерпывает пул carrier‑потоков и «замораживает» обработку. Часто как побочный симптом растет число соединений в CLOSE_WAIT, потому что обработчики не успевают корректно закрывать сокеты.

Что изменилось:

В JDK 24 реализован механизм, благодаря которому виртуальные потоки больше не пиннятся внутри synchronized, включая ожидание монитора и Object.wait()): JVM умеет корректно «размонтировать/перемонтировать» поток. Это почти полностью снимает главный источник проблем с Loom и в большинстве случаев избавляет от необходимости переписывать synchronized на ReentrantLock ради масштабируемости. Редкие источники пиннинга остались вне synchronized, например, JNI — их стоит искать профилированием и наблюдаемостью (JFR‑события).

Дальше — еще удобнее в JDK 25:

Scoped Values становятся финальными — надежная альтернатива ThreadLocal для передачи неизменяемого контекста без накладных расходов и утечек. Structured Concurrency остается в статусе preview и хорошо сочетается с моделью виртуальных потоков.

Что имеет смысл сделать уже сейчас без перелома архитектуры:

  1. Планировать переход на JDK 25, чтобы получить финальные Scoped Values и полный набор улучшений Loom.

  2. Запускать задачи через Executors.newVirtualThreadPerTaskExecutor() или фабрику Thread.ofVirtual() — так вы используете Loom «как задумано».

  3. Проаудировать горячие пути — убрать блокирующие вызовы из‑под synchronized, сузить критические секции. При необходимости оставлять ReentrantLock, но не рассчитывать на него как на универсальное лекарство от пиннинга.

  4. Включить наблюдаемость — отслеживать события пиннинга виртуальных потоков, рост очередей/времени ожидания и аномальный CLOSE_WAIT.

  5. Там, где сегодня используются тяжелые ThreadLocal, по возможности переносить на Scoped Values после обновления до JDK 25 и обновлять библиотеки до версий с поддержкой Loom.

Как именно работает исправление пиннинга и как лечить «больные места» рассказали в статье Виртуальные потоки в Java: эволюция, практика, подводные камни.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Если вы сталкиваетесь с задачами оптимизации, но существующие материалы не дают системного понимания — курс «Java Advanced II: высокопроизводительная Java» (JVA-076) для вас. Никакой воды — только лабораторные с разбором реальных инцидентов.

9 сентября на бесплатном вебинаре «Производительность Java под нагрузкой: заглянем под капот» мы детально разберем содержание курса:

➕ Инструменты: JMeter, JMH, JFR, JITWatch — не просто обзор, а решение задач.

➕ JVM: тюнинг GC, анализ JIT, управление флагами.

➕ Hardcore: off-heap память через Unsafe, свои структуры данных.

➕ Архитектура: кэширование и анализ производительности.

Курс для вас, если вы хотите:

✔️ Осознанно подходить к тюнингу JVM.

✔️ Быстро находить и устранять утечки памяти и узкие места

✔️ Принимать архитектурные решения, зная их цену в производительности

✔️ Говорить с эксплуатацией на языке метрик

А вебинар позволит оценить  практическую ценность курса перед принятием решения об обучении.

Дата: 9 сентября

Время: 18:00-19:00 (Мск)

➡️ Регистрация

Теги:
Рейтинг0
Комментарии0

Давно хотел это написать, но как будто не было триггера и вот в пятницу я его поймал. Объясняю. Хочу выразить благодарность, чуть-чуть извиниться перед разработчиками Intellij Idea и простить их. Вот прям от души.

Когда-то в детстве я 3 года отучился игре на фортепиано, но переходный возраст (пиво, футбол и девки) победил и я ушёл из музыкальной школы. К чему я.. я программист уже 8 лет и я не встречал ничего прекрасней чем Intellij Idea.. ты не разрабатываешь - ты играешь на рояле... это автодополнение или как его назвать, подсказки, я просто в шоке. Не всегда угадывает что я хочу, но часто. Триггер я поймал когда добавлял новый объект в enum вида ERROR_INFO("text") и пока строчил название объекта представлял как лезу в переводчик, чтобы точно грамотно написать на английском текст, а Идея предложила мне текст, который я хотел написать, причём не все слова были в названии объекта.. как итог я прям счастлив от такой супер приятной мелочи (не факт что мелочи) и вот спустя два дня строчу этот пост, т.к. я прям обязан это сделать, не знаю почему. Я понимаю, что нейросети, но один и тот же салат Цезарь каждый повар делает по разному.

То, от чего я прям балдею:

  • shift + f6, переименовывает всё и везде - просто песня

  • ctrl + shifr + backspace - показывает всё что я поменял в классе, а не я глазами ищу строчки

  • ctrl + e - показывает классы в порядке убывания по использованию, не ищешь в браузере слева

  • в браузере жмёшь на значок цели вверху и тебе показывается где класс лежит буквально

  • в разделе гита смотришь изменения класса, нажимаешь f4 и тебе открывается этот класс

  • супер поиск ctrl+shift+f или просто два шифта

  • работа с базами данных просто сказка (даже Дата Грип редко открываю, его тоже люблю)

  • офигенные приколы типа ctrl+d с добавлением ниже второй такой же строки, удалить строку со смещением наверх shift+del

  • быстрый переход с ошибки на следующую ошибку с помощью f2

  • ctrl+p показать все ожидаемые параметры в методе

  • ctrl+shift+вверх/вниз гоняет как строку, так и целый кусок :)

  • и ещё дофига всего!!

В общем я счастлив, что моё хобби и работа это одно и то же, а то что есть Идея счастье увеличивает. Извиниться хочу, что я ни разу не покупал подписку. Она мне досталась после прохождения какого-то курса по Java, а сейчас вообще не могу купить, т.к. технически это невозможно из РФ. Здесь я прощаю Jet Brains, без пафоса, понять можно наверное (и на царей жёны давили :) Как смогу - обязательно куплю подписку, потому что это охренеть какой труд и верх перфекционизма для меня как для такого же любителя прекрасного!! И я хотел бы знать - это один такой перфекционист у них всё таки, или целая команда (в плане, что Идея именно такая какая есть). Кто этот "фундамент" образа?

Кто скажет, что пост рекламный - вы не правы! Просто признался в любви IDE :)) и стало легче! Пашем дальше..

Теги:
Всего голосов 6: ↑5 и ↓1+6
Комментарии4

В продолжение темы серверного HTML рендеринга на Kotlin.

Если вы не читали статью, кратко напомню о чём речь: я написал небольшой можно сказать фреймворк для генерации HTML на стороне сервера на Kotlin. И поддержку строготипизированных routes для удобного создания ендпоинтов, ссылок на них и форм. Теперь Spring Views можно создавать на Kotlin и по крайней мере в моих проектах (а один из них очень большой - сотни отдельных страниц и десятки виджетов) это дало мне огромное удобство, уверенность, безопасность, рефакторо-пригодность, простое версионирование и переиспользование кода, например, теперь я точно не сделаю опечатку в URI или имени параметра и не смогу передать неверный тип данных на endpoint.

Одна из проблем которые до недавнего времени была в связи с использованием данного фреймворка - это CSS-стили. Приходилось либо инлайнить стили непосредственно для HTML элемента, либо мейнтейнить огромный (или несколько поменьше) CSS файл без возможности внятно следить за старыми более неиспользуемыми классами и селекторами. Кто создавал большие CSS файлы знает о чём я говорю - со временем количество классов накапливается и вычистить их не задев чего-то всё ещё нужного очень сложно. Вот так приходилось работать с CSS стилями раньше:

DIV("css-class-name") {...}
// или
DIV {
  style("color: red;")
  +"Hello World"
}

В принципе жить можно, но хотелось чего-нибудь:

  • что-то на подобии Styled-Components из ReactJS, но так же на Kotlin

  • по возможности поддержку JVM hot-reload в режиме отладки

  • как следствие кода на Kotlin - иметь возможность всегда отслеживать зависимости и удалять более неиспользующиеся CSS-правила.

Долго думал как это получше сделать, и пока что первая версия получила вот такой синтаксис:

@Component // Spring @Component
object MyCssClass : CssClass({
  style = "color: black;"
  hover = """
    color: red;
    text-decoration: underline;
  """
})

...

A(MyCssClass) {
  href(SomeUsefulRoute(param = 1))
  +"Click me"
}

То есть объявляем object который будет нести информацию о CSS свойствах элемента. И далее просто используем его в тех же местах где раньше можно было указать css-class-name. CssClass поддерживает массу "псевдоклассов" типа hover, active, firstOfType, before, after и так далее, так же можно добавлять media брейкпоинты и всякие другие штуки. Вот более насыщенный пример:

@Component
object Container : CssClass({
    style = "padding: 25px;"
    hover = "background: #eee;"

    add(">a", "color: green;")
    add(">a:hover", "text-decoration: underline;")

    media("max-width: 991px") {
        style = "padding: 10px;"
    }
})

Вы наверняка заметили двойные скобочки ({...}) - в конструктор я передаю функцию-инициализатор стилей. Это нужно для того, чтобы в дебаг режиме JVM можно было на лету менять свойства CSS класса без перезапуска приложения: код который генерирует сам css-файл может быть запущен в режиме dev-mode, когда на каждый запрос файла будут выполнены все функции-инициализаторы ещё раз и файл будет собран заново.

Если по какой-то причине вам не нравится object - можно просто объявить class и использовать его:

@Component
class Container : CssClass({...})
...
DIV(Container::class) { ... }

Теперь в проекте порядок с CSS стилями - нет давно умерших, всегда можно найти точки использования, стили лежат рядом с виджетами и т.п.

Смотрите исходники тут. Фидбэк приветствуется, всем хорошего дня.

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии4

Запись вебинара «От кода до запуска: российский стек для Java — Axiom JDK и OpenIDE» доступна для просмотра

Вебинар прошёл, а воспоминания запись осталась.

Если вы не успели на вебинар, но очень хотели, то не переживайте! Мы всё записали, чтобы вы могли посмотреть в любое удобное время.

Что обсуждали на вебинаре:

  • Вызовы отечественной ИТ индустрии.

  • Портфолио Axiom JDK.

  • Регуляторика и соответствие стандартам.

  • РБПО: процесс создания доверенных Java продуктов.

  • Зачем OpenIDE разработчику и бизнесу.

  • В чём проблема собрать Intellij IDEA самостоятельно

  • Как будет развиваться OpenIDE.

Запись уже доступна на площадках.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Вебинар "От кода до запуска: российский стек для Java — Axiom JDK и OpenIDE"

Приглашаем на вебинар, посвященный безопасному стеку базовых технологий для разработки и исполнения Java-приложений и безопасной среде разработке OpenIDE. Вы поймете, что такое OpenIDE, как это всё относится к Intellij IDEA, зачем OpenIDE бизнесу и какие у проекта OpenIDE планы на будущее.

Кому будет полезен вебинар:
• тимлидам
• разработчикам
• DevOps

Вебинар проведут:
• Дмитрий Сапожников, технологический консультант Axiom JDK
• Илья Сазонов, директор по продуктам Axiom JDK, направления Spring и OpenIDE

Когда: 21 августа 2025 г.

Во сколько: 11:00–12:30 по мск

Формат: Онлайн

Участие: Бесплатное (нужно предварительно зарегистрироваться)

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Где учиться бэкенду

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

Собрали подборку для тех, кто хочет перейти в бэкенд. Вообще все курсы по специализации можно посмотреть здесь, а ниже оставляем ссылки по ключевым навыкам:

Алгоритмы и структуры данных

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

Git

Система контроля версий. Позволяет вести историю изменений, работать с ветками, мержить и откатывать изменения в коде.

Python 

Язык общего назначения, популярен в вебе, автоматизации, ML.

FastAPI

Лёгкий и быстрый фреймворк для создания REST API с поддержкой async/await и автогенерацией схем.

Django

Фреймворк для быстрой разработки web-приложений, включает ORM, авторизацию и админку из коробки.

JavaScript / TypeScript

JavaScript — язык для веб-интерфейсов и серверной логики (через Node.js). TypeScript — его надстройка с типизацией, упрощающая масштабируемую разработку.

Java / Spring

Java — строго типизированный язык. Spring — основной фреймворк для создания REST API, микросервисов и корпоративных приложений.

Go

Компилируемый язык от Google с простым синтаксисом и встроенной поддержкой параллелизма. Используется в highload-системах, DevOps и backend-разработке.

C#

Язык от Microsoft, используется с платформой .NET. Применяется в разработке desktop-, web-, enterprise- и игровых приложений.

PHP

Скриптовый язык, ориентированный на веб. Часто используется с CMS (например, WordPress) и фреймворками (Laravel, Symfony).

Ruby

Язык с лаконичным синтаксисом. Наиболее известен благодаря фреймворку Ruby on Rails, ориентированному на быструю разработку веб-приложений.

SQL / PostgreSQL

SQL — язык запросов к реляционным БД. PostgreSQL — популярная СУБД, используется в веб-приложениях, аналитике, поддерживает расширения и транзакции.

Docker

Инструмент для упаковки приложений в контейнеры. Обеспечивает воспроизводимую среду разработки и удобное развертывание.

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

А чтобы вы могли проверить качество курсов, мы собираем отзывы от тех, кто уже прошел обучение — читайте и выбирайте лучшее для себя.

Смотреть курсы по всем специализациям

Теги:
Всего голосов 6: ↑4 и ↓2+6
Комментарии0

Под пост в телеграм про наш ответ аналог Grafana пришли руководители "Лаборатории Числитель" и конкретно "Пульта", в чью систему входит платформа мониторинга и анализа "Графиня".

Дмитрий Унтила и Владимир Утратенко любезно ответили на ряд вопросов по платформе, и я хотел бы подвести краткое резюме:

  • Запрос на аналог Grafana появился в момент продажи "Пульта", так как "не всем можно брать забугорный опесорс себе в контур. Потому решили делать. А название Графиня просто ради лулзов."

  • Графиня писалась с полного нуля. Хотя предложение взять за основу Grafana было, но команда смогла обосновать геморрой, который на неё упадёт, если взяться за доработку, и объяснила руководству, почему лучше сделать с нуля.

  • Время разработки: 3 месяца - MVP, 6 месяцев - 1 релиз.

  • Технологический стек: фронтенд: TypeScript + React 18, бэкенд: TypeScript + Node.js, база данных: MongoDB, плагины: Java.

  • На мое предложение сделать проект опенсорс Дмитрий Унтила пообещал подумать. Но, понятное дело, если это часть коммерческого продукта, прям сильно думать в лаборатории не будут))

  • Демо-стенда в интернете пока нет, можно только записаться на показ системы через форму обратной связи.

Благодарю парней за такой актив и обратную связь, рад, что у людей есть на это время!

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии3

Многие крупные компании применяют Go, а спрос на опытных инженеров, владеющих Go, высок как никогда. Онбординг проходит действительно быстро, и у нас есть успешные тому примеры. Все благодаря общей простоте языка и отсутствию function coloring. В карточках рассказываем, как это получилось у Кирилла в 2ГИС↓

Теги:
Всего голосов 6: ↑3 и ↓30
Комментарии4

Обновлена информационная база JBook по изучению Java полностью на русском языке. Проект помогает выучить язык с полного нуля и до уровня поиска работы, включая концепции, приёмы, актуальные фреймворки, ООП, основные алгоритмы, паттерны решения задач и видеоразборы. Есть множество упражнений разного уровня сложности к каждой лекции. Проект развивается с 2018 года и постоянно обновляется вместе с версиями Java, документацией и новыми подходами к разработке.

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии0

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

import java.util.stream.Stream;
public class Main {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
        Integer result = prepareStream(stream);
        System.out.printf("Result after stream processing: %s%n", result);
    }

    private static Integer prepareStream(Stream<Integer> stream) {
        System.out.printf("Incoming stream with: %d elements%n", stream.count());
        return stream
                .map(integer -> integer++ + ++integer)
                .filter(integer -> integer % 3 == 0)
                .reduce(0, Integer::sum);
    }
}

Дальше будет решение, поэтому если не хотите спойлеров — не читайте!

.

.

.

Подвох в том, что будет выброшено исключение:

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
 at java.base/java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)
 at java.base/java.util.stream.ReferencePipeline.<init>(ReferencePipeline.java:96)
 at java.base/java.util.stream.ReferencePipeline$StatelessOp.<init>(ReferencePipeline.java:800)
 at java.base/java.util.stream.ReferencePipeline$3.<init>(ReferencePipeline.java:191)
 at java.base/java.util.stream.ReferencePipeline.map(ReferencePipeline.java:190)
 at Main.prepareStream(Main.java:16)
 at Main.main(Main.java:7)

Исключение выбрасывается из-за того, что при выводе в консоль лога с количеством элементов стрима мы использовали операцию stream.count(), которая является терминальной и делает дальнейшее использование стрима невозможным.

System.out.printf("Incoming stream with: %d elements%n", stream.count());

Ну а после того, как мы избавимся от лога, который нам все ломает, правильный ответ будет — 18.

С учетом postfix и prefix инкремента числа в каждой итерации мы получаем:
.map(1 → 1 + 3)...(5 → 5 + 7)

Потом после фильтрации по делению на 3 без остатка в стриме остаются числа 6 и 12. И при помощи операции reduce() находим сумму этих чисел.

Теги:
Всего голосов 9: ↑4 и ↓5+2
Комментарии0

Приглашаем на бесплатный вебинар «Как стартовать в Java и не потеряться: структура, инструменты, кейсы». 

📅 Дата: 8 июля

Время: 18:00–19:00 (Мск)

Java — один из самых востребованных языков, но с чего начать, если вокруг столько информации, а подходы быстро устаревают? В прямом эфире разберем:

✔️ С чего начать в Java, чтобы не тратить время на устаревшие методы

✔️ Ключевые инструменты (JUnit, Maven, Git) — как их применять с первых шагов

✔️ Кейсы, которые помогут на собеседованиях и в реальных проектах

✔️ Как избежать типичных ошибок новичков и сразу писать чистый код

Почему стоит прийти?

🔹 Узнаете, как быстро войти в Java с актуальными знаниями

🔹 Увидите разбор реальных примеров и учебных проектов

🔹 Получите рекомендации по ресурсам и дальнейшему развитию

👨‍🎓 Спикер: Судакевич Игорь — преподаватель международного уровня, более 15 лет работает в ИТ. Уполномоченный инструктор корпорации Oracle. Магистр компьютерно-информационных технологий. Инструктор платформы Udemy. 

🔗 Записаться

Теги:
Всего голосов 1: ↑0 и ↓1-1
Комментарии0

Сегодня 24 июня до 23.59 успейте принять участие в главном DevOps-исследовании года!

Это last call по исследованию состояния DevOps 2025 в России, проводимого компанией «Экспресс 42» при поддержке Axiom JDK. Оно закрывается сегодня ночью в 00.00 по мск.

Помогите отследить тренды и понять, как опыт разработчиков (DX) влияет на эффективность команд и успех компании. Фокус State of DevOps Russia 2025 на developer experience. 

Осталось всего несколько часов — пройдите опрос до 23.59.

Мы вместе изучим, что помогает компаниям формировать позитивный опыт для разработчиков и как на него влияют внутренние платформы, ML/AI-инструменты, облачные технологии и практики ИБ.

Опрос анонимный и займёт ~20 минут. Данные нужны, чтобы понять, какие инструменты реально работают в проде, а какие — только в красивых презентациях.

Если вы — DevOps-инженер, разработчик, тестировщик, админ, тимлид, CTO, техдир — внесите свой вклад.

Все участники получат:

  • Полный доступ к результатам исследования;

  • Возможность выиграть билеты на Highload++ и DevOpsConf.

  • Промокоды и мерч от партнёров (AvitoTech, VK Cloud, Positive Technologies, Selectel, ecomtech, Okko, Онтико, Т-Технологии,  Axiom JDK, Экспресс 42).

Участвуйте сегодня и голос вашей команды будет услышан. Чем больше ответов — тем лучше получится карта DevOps-практик в России.

Почитать предыдущие отчёты можно тут

PS. А у кого есть интерес заняться девопсом в команде Axiom JKD, загляните сюда.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Telegram запустил конкурс для разработчиков под Android. Призовой фонд: $50 000. Срок сдачи работ: 11 июля, 23:59 по дубайскому времени (UTC+4). Объявление итогов: июль 2025.

В дополнение к призовым, победитель конкурса сможет присоединиться к команде Telegram в Дубае и зарабатывать 1 миллион долларов в год после вычета налогов.

Задача: Внедрить обновлённый интерфейс профилей в приложение Telegram для Android в строгом соответствии с предоставленным дизайном.

Полные условия конкурсного задания, технические подробности и макеты представлены в отдельном канале платформы.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

В развитие темы Bare Metal VM, над которой я время от времени размышляю начиная аж с 2010 года, предлагаю ознакомиться с интересным и, на мой взгляд, перспективным проектом OSv.

Ещё в 10-м году я подумывал над тем, что имея сервера приложений наподобие Томката и серьёзную взрослую изоляцию на уровне загрузчика классов - можно выкинуть подлежащую ОС со всеми её ненужными сервисами из нашего стека, оставив сервер приложений на голом железе. Тогда же выяснилось, что не я один так думаю, было коммерческое предложение Oracle JRockitVE. Судя по всему, наследница вот этого приобретения Bea.

Ранее я уже писал статью об этой идее на Хабре и пытался защищать в дискуссии.

Можно попробовать снова.

Ещё можно смотреть на развитие ОС на базе грааля. Или вспомнить про JaOS.

К современным ОС типа Линукса у меня есть много претензий, и есть несколько идей, которые можно было бы реализовать для их улучшения. Некоторые из них описаны в указанном проекте. Некоторые в том или ином виде наличествуют в специализированных коммерческих предложениях (Юникс) крупных вендоров типа АйбиЭм или того же Оракла. Это касается, например,

  • файлово-дискового стека,

  • оптимизации сети,

  • использования ГПУ в неожиданных местах,

  • гибкости в использовании СУБД при разработке с контейнером.

Теги:
Всего голосов 2: ↑2 и ↓0+5
Комментарии6

Какую тему для книги можно выбрать в 2025? Современный мир — насыщенный мир. Книг выходит очень много. Как, интересно, можно выбрать тему для книги? От этого зависит конечная аудитория книги всё-таки. Микросервисы? Внедрение зависимостей? Ещё что-нибудь? Я в смятении. А выбирать пора уже. Полгода как прошлая книга вышла...

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии1

Вклад авторов