Обновить
256K+

Java *

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

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

Паттерны проектирования еще актуальны?

Вокруг все чаще говорят, что ИИ скоро будет писать код за нас. Логичный вопрос — нужны ли тогда паттерны? Зачем разбираться в паттернах GoF, если нейросеть и так сгенерирует рабочий код по описанию?

У меня ощущение обратное.

Я плотно вошел в разработку в 2019 году. Переходил из 1С в .NET. Книги по паттернам GoF у меня были, но долго лежали как «книга на полке». Казалось, они оторваны от повседневных задач. Теорию вроде понимал, но не видел, где это реально применяется.

Все поменялось, когда я стал использовать ИИ как инструмент для обучения. Просил давать задачи, искать проблемы в решениях, объяснять, почему в одном месте уместен Strategy, а в другом лучше Mediator. Через практику и обсуждение паттерны перестали быть абстракцией.

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

Из этого и вырос мой pet-project gofinsights.com. Я делаю его тренажером по паттернам проектирования. Не просто «прочитал и забыл», а через практику, сравнение решений и постепенное распознавание типовых архитектурных ходов.

Сейчас там есть интерактивный квиз, где можно проверить базу и не перепутать Factory Method с Abstract Factory. Дальше хочу развивать проект в сторону более глубокого ИИ-разбора. Чтобы можно было не только узнавать паттерн, но и разбирать кодовые запахи, причины проблем и возможную эволюцию решений.

Как вы это видите? Паттерны проектирования все еще рабочая база для разработчика? Или с появлением ИИ они станут менее важны?

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

🌲 Открываем регистрацию на Дебаг Кемп

Мы придумали формат, который давно хотели сами: выбираешься из города, два дня в сосновом лесу на Карельском перешейке — маршрут, костёр, мастер-классы по выживанию, нетворкинг без слайдов и питчей. Просто люди, с которыми интересно, и никакого Slack-а.

📅 6–7 июня 2026 (выходные) 👥 Всего 25 мест — маленький формат, это принципиально.

Цена растёт по мере приближения к дате. Оплатить можно частями через сплит → регистрация

Если вы 💎 практик сообщества — скидка 15% применяется при регистрации автоматически. Ещё не практик, но думаете? Сейчас самый разумный момент.

👀 Узнать больше · 📝 Регистрация

Вопросы — в чат, мы там живём.

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

В предыдущих постах Разбираемся в in-memory базах и Выбираем базу и думаем о данных.

Взлетаем, создал репозиторий под проект https://github.com/mathter/memifydb.git

План

План общий такой:

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

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

Сделано

  • Данные клиента будут храниться в space’ах - это будет аналог таблиц в БД. Для начала будет только key-value space что бы можно было подумать уже сейчас о WAL клиенской библиотеке для java и сетевом уровне в целом и конечно же о транзакциях.

  • Тестовая реализация WAL, которая в проекте будет называться Log.

Run.

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

🔌Форматы обмена и хранения данных

В предыдущих постах Разбираемся в in-memory базах и Выбираем базу я написал, что собираюсь сделать исследовательский проект по in-memory базам данных  и имя ему MemifyDB. Так же выбрал направление движения: это key-value хранилище, которое потом доработаю до документо-ориентированной системы.

Теперь ключевой вопрос: как клиенты будут с ней общаться?

Протокол обмена — это мост между сервером и клиентом. От его дизайна зависит скорость, удобство и даже то, какие фичи мы сможем реализовать.

Human readable (JSON, XML and etc.)

В современных системах активно используется как для транспорта так и для хранения текстовый формат данных, а точнее json и его вариации. У этого подхода есть несколько несомненных плюсов, например:

  • Простота реализации: не нужно поддерживать разные типы на уровне протокола, всё передаётся как строки, а клиент сам разбирается.

  • Гибкость: строкой можно закодировать что угодно — число, JSON, бинарные данные.

Но у этого подхода есть обратная сторона:

  • Нет нативной поддержки типов: Клиент сам должен сериализовать/десериализовать.

  • Оверхед на парсинг: Каждый раз нужно преобразовывать “42” в число и обратно.

  • Неэффективное использование памяти: Число 123456 занимает 6 байт как строка, хотя в бинарном виде — 4 или 8.

  • Невозможность частичного обновления сложных структур: Чтобы изменить одно поле в JSON-объекте, приходится переписывать весь объект (можно конечно поспорить).

## 🎯 Наш подход: типизированные данные с рождения В MemifyDB мы пойдём другим путём.
Мы будем хранить данные в памяти в типизированном виде: строки, числа, списки, хеши, документы — каждый тип со своим внутренним представлением.

И протокол обмена с клиентом должен это отражать.
Мы не хотим, чтобы клиент упаковывал число в строку только потому, что так проще.
Мы хотим передавать по сети те же бинарные структуры, которые лежат в памяти.

Это даст:

  1. Типизированность Формат должен явно различать типы данных: строки, числа (разной разрядности), булевы значения, null, массивы, объекты (документы).
    Это позволит серверу правильно интерпретировать данные без дополнительных метаданных.

  2. Компактность Формат не должен раздувать данные. Число 42 должно занимать 8 байт (или 4, если это int32), а не 2 символа ASCII.

  3. Быстрая навигация Мы должны иметь возможность быстро «прыгнуть» к определённому полю документа без полного парсинга.
    Это важно для частичных обновлений и запросов.

  4. Потоковость Формат должен допускать частичную отправку/приём, чтобы можно было обрабатывать большие документы по частям.

  5. Самодостаточность Данные должны содержать всю информацию для интерпретации, но при этом не дублировать имена полей без необходимости (как в JSON).

🔍 Что дальше?

Существуют несколько бинарных: CBOR, BSON, FlatBuffer и пр. Если у вас есть опыт работы с этим форматами, пишите в комментариях какие у них есть плюсы, минусы и подводные камни.

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

🧠 MemifyDB: прежде всего — видение (vision).

Прежде чем погружаться в код, нужно чётко ответить на вопрос: а что именно мы строим?
Этот пост — не про хардкорный кодинг, а про так называемое видение системы (system vision).
Мы разберём, какие вообще бывают in-memory базы данных, чем они отличаются и почему наш путь будет таким: key-value → документная БД.

Поехали!

📚 Типы in-memory баз данных

1. Key-Value хранилища

Самый простой и быстрый вид. Данные хранятся как пары «ключ — значение», где значение — обычно строка, число или бинарный объект.

  • Примеры: Redis, Memcached, DragonflyDB.

  • Сценарии: кэширование, сессии пользователей, счётчики, очереди задач.

  • Плюсы: максимальная скорость, минимальный оверхед, простота масштабирования (шардирование по ключу).

  • Минусы: ограниченная модель данных — нет сложных запросов, только операции по ключу.

2. Документо-ориентированные БД

Значение — структурированный документ (JSON, BSON, XML). Внутри документа можно индексировать поля и выполнять запросы по содержимому.

  • Примеры: MongoDB (in-memory storage engine), Couchbase.

  • Сценарии: хранение сложных объектов (профили, каталоги), где важна гибкость схемы.

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

  • Минусы: чуть более высокий оверхед по сравнению с key-value (парсинг, индексация).

3. Колоночные (Columnar) in-memory БД

Данные хранятся не по строкам, а по колонкам. Это даёт огромное преимущество при аналитических запросах (суммы, средние, группировки).

  • Примеры: SAP HANA, MemSQL (SingleStore) в колоночном режиме, Apache Arrow (формат, но не БД).

  • Сценарии: аналитика реального времени, отчёты, BI.

  • Плюсы: сверхбыстрая агрегация, высокая степень сжатия.

  • Минусы: медленные точечные обновления (OLTP-нагрузка), сложность реализации.

4. Графовые БД

Хранят сущности (узлы) и связи между ними (рёбра). Оптимизированы для обходов графа.

  • Примеры: RedisGraph (модуль Redis), Neo4j (с in-memory режимом).

  • Сценарии: социальные сети, рекомендательные системы, сети связей.

  • Плюсы: эффективные запросы связей, интуитивная модель для связанных данных.

  • Минусы: узкая ниша, сложность шардирования.

5. Time-series БД

Специализированы для временных рядов — метрик, логов, событий. Оптимизированы для записи и запросов по временным интервалам.

  • Примеры: InfluxDB, TimescaleDB (in-memory части).

  • Сценарии: мониторинг, IoT, финансовые тикеры.

  • Плюсы: высокая скорость записи, сжатие старых данных, встроенные функции по времени.

  • Минусы: слабо подходят для произвольных данных.

…## 🧭 Наш курс: от Key-Value к документам

Для MemifyDB я выбрал путь, который кажется самым прагматичным:

  1. Создаём ядро Key-Value
    Это фундамент. Мы реализуем:

    • потокобезопасное in-memory хранилище;

    • поддержку разных типов значений (строки, списки, хеши, числа);

    • механизмы TTL и эвикшена (LRU);

    • бинарный протокол, близкий к внутреннему представлению.

    Key-value движок даст нам максимальную скорость и стабильность, а также позволит отточить все низкоуровневые механизмы (аллокаторы, сериализацию, сетевое взаимодействие).

  2. Надстраиваем документный слой
    Поверх key-value ядра мы добавляем возможность интерпретировать значение как JSON-подобный документ:

    • индексация по полям;

    • поддержка частичного обновления;

    • запросы с фильтрацией по содержимому.

При этом сами документы будут храниться в key-value хранилище как обычные значения, а индексы — как дополнительные структуры (хеш-таблицы, B-деревья) в памяти.

Такая двухслойная архитектура даёт:

  • гибкость — можно работать и как с обычным кэшем, и как с документной БД;

  • производительность — key-value ядро остаётся быстрым, а документные операции добавляются без потери эффективности;

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

Теги:
-4
Комментарии2

🧠 Разбираемся, как устроены in-memory БД: пишем MemifyDB с нуля.

Redis быстр, но не всегда удобен. SAP HANA — мощь, но ценник…
А что, если заглянуть под капот и создать свою enterprise in-memory СУБД?
Не чёрный ящик, а полностью прозрачную, современную, open-source — и при этом готовую к высоким нагрузкам. Разбираемся как это работает!

Знакомьтесь — MemifyDB.

📌 Что это будет?
Настоящая in-memory система уровня enterprise, в которой мы разберёмся до винтика:

  • живёт в RAM, отвечает за микросекунды;

  • сохраняет данные на диск (RDB + WAL) — никакой потери после ребута;

  • реплицируется и шардируется «из коробки»;

  • поддерживает транзакции (не хуже MULTI/EXEC, но с возможным rollback);

  • и при этом не просит продать почку за лицензию.

Весь код — open source, все решения — с объяснениями.

🛠 Технический фундамент (выбираем стек вместе)
Платформа — JVM. Я сейчас выбираю между Java 21 (Loom) и Scala 3 (ZIO / Akka).

  • Сеть: Netty или виртуальные потоки — посмотрим на бенчмарках.

  • Память: off-heap + собственный slab-аллокатор на ByteBuffer. GC не мешает, фрагментация под контролем.

  • Конкурентность: Lock-Free структуры данных, чтобы не блокировать потоки.

  • Протокол: RESP-совместимость — redis-cli сможет общаться с нами.

🗺 Дорожная карта: что и когда разберём

  1. Ядро: потокобезопасное KV-хранилище в памяти. Как работают LRU и TTL?

  2. Persistence: снапшоты и WAL. Как не потерять данные при краше?

  3. Сеть: пишем TCP-сервер. Netty vs Loom — кто быстрее?

  4. Транзакции: реализуем MULTI/EXEC, WATCH. Нужен ли MVCC?

  5. Репликация и Raft: как достичь консенсуса в распределённой системе?

Каждый этап — открытый код, пост с разбором, грабли и профит.

🤔 Зачем я это делаю публично?
Во‑первых, разобраться самому и дать шанс разобраться другим.
Во‑вторых, фидбек сообщества ловит ошибки на берегу.
В‑третьих, хочется сделать реально полезный инструмент, а не очередной pet‑project.

💬 Вопрос к залу:
Какой стек предпочтительнее для enterprise in‑memory БД — Java 21 + Loom или Scala + ZIO/Akka?
Какие фичи вы бы добавили в дорожную карту?
Пишите в комментариях — лучшие идеи уйдут в реализацию!

👉 Подписывайтесь, чтобы не пропустить:

  • глубокий разбор off‑heap аллокатора;

  • сравнение моделей конкурентности на реальных бенчмарках;

  • историю о том, как одна строка unsafe кода валила прод три дня.

Теги:
-7
Комментарии22

Всё, что нужно знать для начала работы в PVS-Studio

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

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

Бесплатный тест для Java‑разработчиков: оцени уровень и найди точки роста

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

Чтобы осознанно развиваться дальше, важно понимать:

  • какие технические навыки уже прокачаны;

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

  • какие технологии стоит изучить подробнее;

  • насколько уверенно ты ориентируешься в современном Java‑стеке.

Мы сделали бесплатный пробный тест — он поможет оценить твой уровень как Java‑разработчика и подсветит зоны для развития.

За 20 минут ты получишь:

  • оценку текущего уровня;

  • карту компетенций — наглядную схему всех навыков, необходимых для развития в профессии;

  • подборку материалов для самостоятельного изучения.

Пройти тест

Кстати, мы подробно разбирали ключевые навыки и компетенции Java-разработчика в отдельной статье — рекомендуем прочитать ее или перечитать, чтобы освежить и структурировать знания перед тестом.

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

Зелёные тесты ≠ хорошие тесты

Впервые в истории писать тесты стало легко и совсем не страшно. Вокруг теперь у всех покрытие 80%, 90%, а то и вовсе 100%. И вот тут начинается проблема: зелёные тесты ≠ хорошие тесты.

Проблема в метрике, которой мы все привыкли доверять. Code coverage считает строку протестированной, если она выполнилась во время теста. Всё. Не «поймает ли тест баг в этой строке», не «проверяет ли он правильность результата» — просто выполнилась. Можно написать тест без единого assert, и покрытие вырастет. 500 тестов, 90% coverage, а пользы ноль.

Мутационное тестирование — это совершенно другой путь. В простейшей реализации этот инструмент тупо берёт твой код и намеренно ломает его: меняет > на >=, + на ‑, True на False. Каждая такая поломка — мутант. Если после мутации все тесты по‑прежнему зелёные — значит они ничего не проверяют. Покрытие есть, защиты нет.

Почему это важно именно сейчас?

Потому что нейронка любит зелёненькое. Чем больше зелёных тестов — тем субъективно лучше. 100 тестов внушают больше доверия, чем 10, правда? А внутри там assert response.status_code == 200. assert result is not None. assert len(items) > 0. Тест проверяет, что функция вернула хоть что‑то — и радостно зеленеет. Поменяй логику условия, перепутай знак, сломай граничный случай — тест всё равно зелёный. Потому что он проверяет не правильность, а наличие.

Мутационное тестирование — единственный автоматический способ это поймать. Метрика называется mutation score: процент убитых мутантов. 60% — плохо. 90%+ — тесты реально что‑то защищают.

Кое‑какие инструменты для такого тестирования уже есть: mutmut и cosmic‑ray для Python, Stryker для JS/TS, PIT для Java. Медленно? Да, значительно медленнее обычного тест‑рана. Но запускать его не нужно на каждый коммит — достаточно на PR в критические модули.

Но есть нюансы. А где их нет, правда?

Первый: мутации рандомные. Замена > на >= — это не баг, который кто‑то реально допустит. Это синтетическая поломка. Половина мутантов генерирует код, который в реальности никогда не появится. Ты тратишь время на убийство мутантов, которые не имеют отношения к настоящим ошибкам. Это как тестировать замок, ковыряя его вилкой — формально проверка, по факту мимо.

Второй — ещё хуже. Чтобы убить мутанта, тест должен зафиксировать конкретное поведение. Каждую ветку, каждое значение, каждый edge case. Доведи mutation score до 100% — и ты прибил гвоздями каждую строчку кода. Буквально. Теперь попробуй отрефакторить. Переименовал внутренний метод — 40 тестов красные. Поменял порядок полей в ответе — ещё 20. Тесты превращаются из страховки в кандалы: код работает правильно, но тесты падают, потому что они проверяют не поведение, а реализацию.

Это реально ловушка. Слишком гонишься за mutation score — получаешь хрупкие тесты. Не гонишься — получаешь видимость тестирования.

Перемены — впереди!

И вот тут становится по‑настоящему интересно. Представь, что мутации генерирует не тупой набор правил «замени плюс на минус», а нейронка, которая понимает контекст. Которая знает, какие баги реально встречаются в таком коде. Которая мутирует не синтаксис, а логику: меняет порядок проверок, путает граничные условия, забывает обработать edge case — ровно так, как ошибается человек. Или другая нейронка.

Сейчас есть явный сдвиг в сторону таких инструментов, но всё еще ничего достойного не вышло. Но уже скоро точно появится. И это будет совсем другой уровень. Не «выжили ли тесты после рандомной поломки», а «выжили ли тесты после правдоподобной ошибки».

Парадокс в том, что мутационное тестирование было нишевым инструментом, пока тесты писали люди. Когда тесты пишет нейронка — идея становится обязательной. Правда инструменты пока не успели дозреть.

Ждём, когда мутанты станут умнее.

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

JEP 524 в JDK 26 — второй preview PEM API

Наконец-то работа с PEM в Java становится похожа на API, а не на набор ручного парсинга, Base64 и странных телодвижений.

Справка: PEM или Privacy-Enhanced Mail - это текстовый контейнер для криптографических данных. Проще говоря – это способ хранить или передавать ключ, сертификат или другой crypto-объект не в бинарном виде, а в текстовом.

Раньше с PEM работали так:

String pem = "-----BEGIN PUBLIC KEY-----\n"
        + Base64.getMimeEncoder(64, "\n".getBytes())
                .encodeToString(publicKey.getEncoded())
        + "\n-----END PUBLIC KEY-----";

А в обратную сторону, но уже с ручной нормализацией PEM, Base64-декодированием и KeyFactory:

String normalized = pem
        .replace("-----BEGIN PUBLIC KEY-----", "")
        .replace("-----END PUBLIC KEY-----", "")
        .replaceAll("\\s", "");

byte[] der = Base64.getDecoder().decode(normalized);

PublicKey key = KeyFactory.getInstance("EC")
        .generatePublic(new X509EncodedKeySpec(der));

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

А теперь это выглядит так:

var encoder = PEMEncoder.of();
String pem = encoder.encodeToString(keyPair);

var decoder = PEMDecoder.of();
KeyPair decoded = decoder.decode(pem, KeyPair.class);

То есть ключевую пару можно закодировать в PEM и декодировать обратно буквально в несколько строк.

Во втором preview:

  • PEMRecord переименовали в PEM

  • добавили decode()

  • расширили поддержку KeyPair и PKCS8EncodedKeySpec

  • упростили шифрование через EncryptedPrivateKeyInfo

А так, как все это дело еще в preview, не забываем использовать --enable-preview.

❓ Минус еще один кусок криптографической копипасты из Java-кода. PEM в Java постепенно перестает быть унылым?

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

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

🚀 Бесплатный курс для разработчиков: создаём свой язык программирования!

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

Изначально курс делали для прохождения внутри компании, но решили, что полезного материала так много, что хочется рассказать всему миру!

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

В рамках курса мы шаг за шагом разберём, как создаётся язык программирования:
— что такое лексер и парсер и какую роль они играют;
— как работает семантический анализ;
— как происходит вычисление и обработка кода;
— как все эти части объединяются в единую систему.

Вы увидите, как текст программы превращается в структуру, понятную машине, и поймёте, какие решения стоят за этим процессом.

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

Мы постарались сделать материал одновременно понятным и практико-ориентированным: минимум абстракции ради абстракции — максимум смысла.

Если вы хотите лучше понимать, что происходит "под капотом" программирования и прокачать инженерное мышление — этот курс для вас.

👉 Подробности и доступ к курсу по ссылке.

Присоединяйтесь и изучайте программирование глубже — бесплатно!

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

Приглашаем на доклад Deep Dive into JVM JDI: Capturing Live Execution for Automatic JUnit Test Generation

Привет! Если на выходных судьба занесёт вас в Новосибирский Академгородок, приходите на технический доклад с мемами от нашего коллеги Даниила Степанова на самой ламповой Java-конференции Сибири — SnowOne 2026 ❄️.

📌 28 февраля, 14:00–15:00 (время Новосибирска)
👨‍💻 Даниил Степанов — разработчик-исследователь в Veai, к.т.н., преподаватель ИТМО

Deep Dive into JVM JDI: Capturing Live Execution for Automatic JUnit Test Generation

Глубокий технический разбор архитектуры инструмента, который использует Java Debug Interface (JDI) для захвата состояния работающей JVM и автоматического синтеза валидных unit-тестов.

Что будет в докладе:

  • Deep Dive в JDI. Подробный рассказ про JDI, преимущества и недостатки, а также как его использовать в нестандартных сценариях для безопасного захвата Heap и Stack Frame в реальном времени.

  • Реконструкция объектов. Reverse Engineering JVM-состояния для воссоздания сложных графов объектов.

  • Синтез Java-кода. Как превратить сырой дамп памяти в чистый, валидный JUnit-тест.

  • Роль LLM. Для решения каких проблем мы используем искусственный интеллект?

Доклад будет полезен Java-разработчикам, тем, кто интересуется внутренним устройством JVM, и всем, кто хочет автоматизировать написание тестов.

Технологии: Java, JVM, JDI (Java Debug Interface), Mockito, JUnit, LLM.

Отличной пятницы и увидимся на SnowOne 🖖

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

Практический Тренажер по Java — самый популярный тренажер по Java на Stepik

В 2024 году я опубликовал курс «Практический Тренажер по Java» на платформе Stepik. Тогда это был просто практический курс с задачами — без воды, без длинной теории, только код и постоянная тренировка.

Прошло несколько лет.

Сегодня курс проходит более 19 000 учеников, и это самый популярный тренажёр по языку Java на платформе Stepik.

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

И я хочу заново пригласить вас в этот проект.

Почему Java?

Java — один из самых востребованных языков программирования в мире.

Он используется в:

— веб-разработке

— мобильной разработке (Android)

— корпоративных системах

— финансовых сервисах

— высоконагруженных backend-проектах

Java — это стабильность, масштабируемость и высокий спрос на рынке труда.

Что представляет собой курс сегодня?

Это полностью практический формат обучения. Только задачи и реальная практика.

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

Кому подойдёт курс?

— начинающим разработчикам

— тем, кто хочет перейти в backend

— Android-разработчикам

— QA Automation инженерам

— тем, кто готовится к собеседованиям

Я приглашаю вас присоединиться :)

➡️ Java Тренажер на Stepik

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

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

Применяем кодогенерацию в Java для решения алгоритмических задач

В прошлый раз мы разобрались, как решается задача трансляции деревьев. И остановились на том, что в случае с AST от компилятора TypeScript, придётся руками обрабатывать 263 типов узлов. Тысячи строк однотипного boilerplate-кода: приведения типов, аннотации, объявления методов — всё это нужно не просто написать, но ещё и поддерживать. А если требования к архитектуре поменяются — переписывать заново.

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

Как реализовать это с помощью JavaPoet, что умеет эта библиотека, а также как встроить в процесс нормализацию можно узнать в новом материале, посвящённом использованию кодогенерации для трансляции деревьев.

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

OpenAPI Generator через призму статического анализатора

Знаете ли вы про OpenAPI Generator — open source проект, задача которого — автоматическая генерация клиентских библиотек, серверных заглушек, документации и файлов конфигурации на основе спецификации OpenAPI в формате JSON или YAML. Проект является достаточно популярным: у него чуть больше 25000 звёзд на GitHub.

Мы проверили его статическим анализатором для языка Java и написали статью про найденные в коде OpenAPI Generator ошибки.

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

⚠️ Java продолжает готовиться к удалению finalize()

В рамках JDK 27 у ThreadPoolExecutor-а, очень популярного API в Java, будет удалён метод finalize(). Несмотря на то, что в силу dynamic dispatch вызов метода finalize() всё равно будет транслирован в Object, данное изменение не source level compatible.

А все потому, что у Object.finalize() сигнатура содержит throws Throwable, в то время как ThreadPoolExecutor.finalize() — нет. Пока метод был в ThreadPoolExecutor, компилятору было ок. Как только его удалят, вызов super.finalize() начнет резолвиться в Object.finalize(), и тогда прилетит “unreported exception Throwable”.

Комментарий от Михаила Поливаха:

Вот это кстати довольно редкий пример того, что имзенение может быть binary level compatible, но не source level compatible.

Например:

class MyPool extends ThreadPoolExecutor {

  @Override
  protected void finalize() {
    super.finalize(); // JDK 27: теперь это Object.finalize() throws Throwable
  }
}

Как избежать?

  • поискать и удалить любые finalize() / super.finalize() (и вообще любые авто-cleanup через финализацию)

  • управлять жизненным циклом executor’ов явно: shutdown()/awaitTermination() или просто close() в try-with-resources (да, ExecutorServiceAutoCloseable)

Spring АйО рекомендует не использовать finalize() в целом, но если подобного рода хук нужен, то лучше использовать Java Cleaner API. С его помощью нельзя "случайно" воскресить объект, сломать integrity объекта или т.п.

Ждем JDK 27 🫠

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

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

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

Мы пошли дальше и вслед за умным импортом во время набора кода сделали автоматическую инжекцию бинов при копировании кода!

Теперь при копировании кода Amplicode автоматически добавляет нужную инжекцию бинов. С учётом контекста, @Primary, @Qualifier, дженериков, @Bean-методов, Java и Kotlin — без ручной возни после вставки.

Будет доступно всем пользователям Amplicode, без подписки.

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

Как оставаться релевантным на рынке QA/AQA/SDET в 2026: опыт, харды, софты, ответы

Последнее время всё чаще слышу вопросы про состояние рынка.
Многие говорят, что рынок «умер», вакансий стало меньше, а требования выросли настолько, что найти работу почти нереально.

Часто это выглядит так: человек активно откликается, ходит на собеседования, делает тестовые задания, общается с рекрутерами.
А на выходе получает либо отказы без конкретных причин, либо формулировки вроде «вы хороший специалист, но нам нужен немного другой профиль».

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

Я регулярно общаюсь с QA, AQA и SDET, которые находятся в активном поиске, и сам продолжаю проходить собеседования, чтобы понимать, как именно сейчас устроен процесс найма.
И вот что я понял из всех историй: сегодня выигрывает не самый наглый кандидат (как было раньше), а тот, кто хорошо понимает свой опыт и умеет его объяснять.

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

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

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

Это не «заговор рынка», а естественная фильтрация. Когда выбор кандидатов большой, требования становятся строже.

Почему в этом есть плюсы

Жесткий рынок хорошо отсеивает слабые места. Причем чаще всего самые базовые.

На собеседованиях у ребят регулярно всплывают одни и те же проблемы:

  • человек говорит, что строил фреймворк, но не может связно объяснить архитектуру;

  • упоминает автотесты, но не понимает, почему был выбран конкретный стек;

  • рассказывает про CI, но путается в вопросах стабильности;

  • заявляет ответственность за качество, но не может описать процессы и зоны ответственности.

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

Как сейчас смотрят на опыт

На интервью все меньше внимания уделяется формальным строчкам в резюме и все больше мышлению.

Интервьюеру важно понять:

  1. Почему было принято именно такое решение;

  2. Какие были трудности;

  3. Как проблемы диагностировали;

  4. Какие выводы сделали.

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

Поэтому сейчас важна не красивая история, а осознанное понимание своего опыта.

Что с этим делать

Минимальный практический набор:

  1. Разложить свой опыт по зонам - архитектура, API, UI, CI/CD, процессы, инциденты.

  2. Подготовить ответы в формате «проблема - решение - результат - выводы». (Для шарящих - по STAR)

  3. Прогнать опыт через уточняющие вопросы и проверить, где ответы выглядят слабо или непоследовательно.

  4. Упаковать резюме как набор конкретных ответов - что улучшал, что оптимизировал, за что отвечал + быть готовым это подтвердить.

Вывод

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

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

Ну а всем нуждающимся желаю скорее обрести себя на сегодняшнем рынке! Готов подискутировать на смежные темы в комментариях)

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

О поддержке opensource - как показателе безопасности

Случались ситуации, когда компании использовали open source, который перестал развиваться. И в этом open source находили уязвимости. Итог: компаниям сложно ликвидировать уязвимости в используемом open source. По этой причине рождались предложения: дабы не попасть в такую ситуацию - при выборе open source проверять, что проект ещё поддерживается. Мысль здравая. Но, и тут могут быть нюансы. Пример - проект JasperReports (для Java). Судя по репозиторию - проект поддерживается. 16 сентября 2025 была опубликована информация об уязвимости в проекте (критического уровня: 9.8 по шкале CVSS v3.1 - CVE-2025-10492). А 19 сентября 2025 разработчик сообщил, что фикс выйдет только для коммерческой версии.

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

Автостопом по LTS: основные изменения при переходе с 8 на 11 Java

Совсем недавно мы выпускали статью про нововведения в Java 25. И один из комментаторов сказал, что ему было бы интересно прочитать от нас цикл статей, в которых рассказано и показано, как менялась Java от LTS к LTS, начиная с Java 8.

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

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