(java || kotlin) && devOps – Telegram
(java || kotlin) && devOps
354 subscribers
7 photos
1 video
7 files
362 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Зоопарк консолей в Windows.

Пишу на примере Windows 11, но в 10-ке начиная с определенного билда все также.

1) Стандартная консоль Windows - теперь их стало две:
а) это связано с тем, что в Windows появился т.наз Windows Terminal. Это мультиоконная консоль, и при вызове cmd.exe вызывается именно именно. Но т.к. она мультиоконная - там же можно открыть любую другую консоль. Все в IDEA слизали)
б) а старая добрая однооконная консоль вызывается через conhost.exe. Зачем может пригодится старая консоль? Microsoft любят ломать совместимость, и новая консоль к примеру изменила API в плане скрытия окна консоли при старте программы.

2) Powershell - тоже использует Windows Terminal, и их стало даже три:
a) powershell.exe - это старая добрая синяя консоль (цвет значка остался синий, консоль по умолчанию черная), версия 5.х
б) pwsh.exe - новая черная консоль (я снова про цвет значка), версия 7.x. На данный момент ставится только руками. Ключевое замеченное мной отличие - есть API по считыванию данных в консоли, что удобно при работе AI агента, не надо выводить данные в лог.
в) conhost.exe powershell.exe - это способ запустить powershell в старом однооконном режиме

3) Git Bash - очень удобная штука, получаем консоль Linux с большим количеством утилит. Увы, не полный набор, а главное не хватает pacman - менеджера пакетов, который в свою очередь даст поставить все остальное. Еще важная особенность - там используются linux слэши и набор переменных среды хотя и наследуется, но отличается от Windows.

4) если утилит не хватает - можно поставить MSYS. Git Bash = урезанная версия MSYS без pacman + mingw64 (С-шный комполятор gcc в Windows)

5) еще можно поставить WSL - Windows Subsystem for Linux. Поверх нее работает Docker Desktop, а это значит не можно, а нужно ставить). В этом случае появляется еще консоль wsl.exe

В итоге у меня это выглядит как на картинке.
Но в целом получаем рабочую среду)

#win #dev
🤯21
Отличие сеньора от джуна

Смотрел только что видео, где обсуждается, а точнее критикуется "Чистый код" Мартина.
Критика в отдельных местах справедливая, но в большинстве кажется критикой ради критики.
Т.е. из "Чистого кода" пытаются сделать Библию с заповедями, которые якобы нужно понимать буквально. А это очевидно не так.

Но не суть.
Понравилась одна фраза:
В реальных проектах всегда будет "говнокод", т.к. есть сроки. Ключевой момент в том, что сеньор всегда может аргументировано объяснить, почему он написал именно так, а джун - нет)

#memes #dev
👍3
Концепция venv (virtualenv) в Python

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

Если вкратце о ее сути: ты создаешь для каждого проекта отдельную виртуальную среду, со своим интерпретатором Python (разные версии) и своим набором библиотек.
Это удобно, и решает проблему конфликта зависимостей. Небольшое уточнение: если бы все сервисы и библиотеки явно указывали версии зависимостей - конфликтов бы не было, но мы же говорим о реальном мире.
К слову, концепцию позаимствовала и Java, я про jenv - https://news.1rj.ru/str/javaKotlinDevOps/442 - правда, ограничить можно только версию Java.

Но блин.
Почему утилит, реализующих виртуальные окружения столько:
- venv
- virtualenv
- uv
- Poetry
- PDM
- Hatch
- Rye
- Conda
- Mamba
- Micromamba
- Pixi
- Pipenv
- pyenv-virtualenv
- virtualenvwrapper
- Tox
- Nox
- Devbox
- Flox
- Devenv.sh
- Spack
- Vex
????

Явная иллюстрация анекдота про 10 стандартов)

Ясно, что они не идентичны по функционалу.
1) кто-то добавляет возможность менеджера пакетов (и это правильно),
2) кто-то позволяет формировать список зависимостей проекта requirements.txt (и это тоже правильно),
3) кто-то добавляет возможность делать lock зависимостей (спорная фича IMHO).
Кто-то просто устарел. Кто-то заточен для тестов, где нужна куча разных сред. Кто-то просто добавляет небольшие фишки в другой менеджер, типа убирает необходимость явно включать использование виртуального окружения в консоли (activate).
Но все же...
Причем 4 из них имеют официальный статус)

P.S. Самой крутой и современной считается uv. На данный момент.

#python #java #virtual_env
Про практическое применение AI в разработке

"Низколежащий фрукт" - добавление в проект новых зависимостей.
В IDEA как бы есть для этого auto complete в build и pom файлах. Но работает он... плохо.

Maven. Я вбиваю любую часть имени groupId или artefactId зависимости - и IDE мне ее находит и подставляет всю конструкцию:
<dependency>
...
</dependency>
С плагинами тоже работает, правда есть один момент - у зависимостей и плагинов общий индекс, поэтому чтобы искать плагины нужно вначале вбить groupId. А у всех стандартных плагинов он одинаковый - org.apache.maven.plugins.

Вроде все работает? Нет. Заставить работать индекс по mavenCentral у меня не получилось. А что же работает? Поиск по зависимостям из локального репо. Но его вначале нужно наполнить. Причем эту проблему - поиск по удаленному репозиторию - я помню уже лет 5 минимум.

С Gradle все еще хуже. Тоже ищет только локальные зависимости, но работать нормально не возможно. Для добавления зависимости вначале нужно написать implementation, и начать набирать точное имя зависимости с начала. А плагины не ищет совсем.
Пробовал с Groovy и Kotlin DSL.

Так что тут AI спасет. Но в агентском режиме, не auto complete, т.к. для работы auto complete нужен электрод в мозг, а до этого техника еще не дошла. Т.е. нужен немного другой паттерн работы, но это в целом касается работы с AI.

#maven #gradle
С момента начала массового внедрения (хайпа) LLM прошло года 3. Концепции Machine Learning - лет 70. А вот техника prompt инжиниринга гораздо старше. Одни из первых ее упоминаний встречаются в "1000 и одной ночи") Джин, три желания и все такое)

И надо сказать, что даже на бесплатных тарифах желаний сейчас стало существенно больше) И последствия не такие разрушительные)

#ai
😁4
Еще один AI стандарт намечается.

https://agentskills.io/home

В чем суть?
Есть агенты, каждый агент может делать что-то специфичное. Возникает идея стандартизировать его функционал, чтобы переиспользовать.
Например: чтение pdf файлов, создание xlsx таблиц...
Т.е. в первую очередь это касается навыков небольшого размера, полезных множеству агентов. Но не только.

Если посмотреть что представляет собой спецификация навыка - промты, документация, описания API и скрипты.
Пример: https://github.com/anthropics/skills/tree/main/skills/docx
Т.е. навык нужно поддерживать: версии, обновления, security fixes.

Еще можно сравнить с MCP серверами.
MCP - кастомные навыки, домен-специфичные, требующие доступа к БД или другим сервисам, реализуются в отдельном сервисе (MCP сервер).
Skills - навыки общего назначения, лежат внутри агента.

Почему стандарт? Предложил Anthropic, но поддерживают кроме Claude Code уже OpenAI с Microsoft.
Т.е. как минимум 3 из ведущих dev AI агентов. Глядись и Cline подтянется. И GigaCode.

P.S. Да помню я, что в названии блога Java!))))

#ai #mcp
1
Непрерывное развитие Spring

Когда я увидел вот эту штуку: https://docs.spring.io/spring-framework/reference/core/beans/java/programmatic-bean-registration.html - Programmatic Bean Registration, т.е. новый API для программной регистрации бинов, я подумал: "Стоп, где-то я это уже слышал? А старый API чем не угодил?"
Вот тут человек прям провел расследование с экскурсом в историю https://habr.com/ru/companies/spring_aio/articles/915512/

Ну и как всегда краткое содержание:
а) чуть более удобное API
б) новое API явно предназначено для регистрации бинов, что упрощает работу разного рода оптимизаторов старта приложения. Вот где собака порылась.

Было:

@Component
class ProgrammaticBeanRegistry implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
registry.registerBeanDefinition("withCallback",
BeanDefinitionBuilder.genericBeanDefinition(WithCallback.class).setPrimary(true).setLazyInit(false)
.setScope("prototype").getBeanDefinition());
}
}


Стало:

@Component
static class MyBeanRegistry implements BeanRegistrar {

@Override
public void register(BeanRegistry registry, Environment env) {
if (env.matchesProfiles("dev|qa")) {
registry.registerBean("testBean", WithCallback.class, spec -> spec.fallback().lazyInit().order(Ordered.HIGHEST_PRECEDENCE));
} else if (env.matchesProfiles("prod")) {
registry.registerBean("prodBean", WithCallback.class, spec -> spec.primary().prototype().lazyInit());
}
}
}


Эволюцию не остановить)

P.S. Пока все не перепишут код на новое API - оптимизации работать не будут. Как минимум сам Spring это должен сделать.

#spring
1
Немного о инициализации Spring Bean

Я думаю все или почти все Java разработчики знают аннотацию @Primary.
Это когда есть несколько бинов одного типа и корректно указать, какой из них нужно грузить не получается, приходится "прибивать гвоздями".
Корректно - это через имена бинов или привязку к профилям.
Такая необходимость возникает, если проблемный бин в библиотечном коде, и изменить его код невозможно. А автор библиотеки не предусмотрел переопределение бина.

Так вот, для авторов библиотек есть хорошее решение - @Fallback.
Как всегда статья - https://www.baeldung.com/spring-fallback-beans
Как понятно из названия аннотация определяет бин, который загрузится в контекст только тогда, когда других кандидатов не нашлось.
И кроме fallback, ее можно использовать как default. Т.е. если есть ненулевая вероятность того, что бин понадобится переопределить.

Появилась начиная с Spring Framework 6.2.0-M1.

#spring
1
Тест для проверки мозга после из новогодних праздников)

Почему? Тут будут алгоритмы)

Я уже писал про Consistent Ring Hashing - https://news.1rj.ru/str/javaKotlinDevOps/46 - решение для для равномерного распределения данных по нодам\серверам\шардам
Но это не единственное решение, особенно когда появляются требования:
1) много нод (тысячи, десятки тысяч)
2) частое добавление и удаление нод
3) минимальный объем перемещения данных при ребалансировке нод
4) простота алгоритма и, соответственно, его отладки
5) минимальное потребление памяти для хранения данных маршрутизации
6) минимальное время вычисления целевой ноды
7) максимально равномерное распределение данных
8) возможность назначать веса нодам

Естественно, единственно оптимального решения для всех этих требований нет.
Но есть варианты:
1) Consistent Ring Hashing с виртуальными нодами
2) Rendezvous Hashing
3) Jump Consistent Hashing https://iq.opengenus.org/jump-consistent-hash/ (VPN)
4) Consistent Hashing with Bounded Loads https://gweb-research2023-stg.uc.r.appspot.com/blog/consistent-hashing-with-bounded-loads/

И парочка сравнительных статей с которых стоит начать:
https://dtf.ru/gamedev/1215676-consistent-protiv-rendezvous-chem-otlichayutsya-podhody-dlya-heshirovaniya-dannyh-na-servere
https://chaotic.land/ru/posts/2024/09/data-sharding-algorithms/

Для себя сделал такие выводы:
1) Consistent Ring Hashing - база
2) Rendezvous Hashing - простой алгоритм, равномерное распределение "из коробки", но медленнее, что сказывается при большом числе нод
3) Jump Consistent Hashing - быстрый, тоже равномерный "из коробки", но плохо себя ведет при частом изменении числа нод и необходимости добавления весов

P.S. С наступающим!)

#algorithm #distributedsystem
И снова про зависимости)

В продолжение поста проблемы с поиском и добавлением зависимостей в Maven/Gradle проекты https://news.1rj.ru/str/javaKotlinDevOps/503 - в комментарии к посту пришёл @gmyasoedov и предложил решение (разработал если быть точным). Это плагин IDEA, переиспользующий движок и UI поиска зависимостей от Maven Central. Есть итеграция с редактором IDEA и поддержка Maven и Gradle. Плюс некоторые другие плюшки - типа провалиться в папку с локальной зависимостью.

Детали тут https://habr.com/ru/articles/981132/

Лично я буду пробовать.

#idea #maven #gradle
👍1
Третий репозиторий Java разработчика

Изначально был Maven Central.
Потом появился Docker Hub.
Теперь ещё и Hugging Face - хранилище opensource моделей.

И с ним возникают свои нюансы.
Например:
1) у некоторых моделей нужно зайти в UI и запросить доступ, явно согласившись с лицензией. Чем это принципиально отличается от License.md - не понятно

2) если JVM и Docker скрывают от нас железо, то LLM модели - нет. От того, что у вас - CPU, GPU или NPU - зависит выбор модели. Базовая модель может быть одинаковой, но появляется новое измерение - оптимизация под железо. Кроме того, у разных NPU - Intel, AMD, Qualcomm, Google, anyone else?)- разные SDK. А NPU выглядит перспективной штукой, так как он специализированный и более дешёвый. В общем, напрашивается новый слой абстракции.

#ai #llm #infrastructure
Локальный LLM

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

Но с запуском модели локально есть два препятствия - доступность хороших моделей и отсутствие мощного GPU.
С моделями подвижки есть - особенно с выкладыванием достаточно мощных моделей Qwen и DeepSeek в opensource. В общем смотри https://huggingface.co.
А вот с GPU все сложнее.
Все больше людей переходят на ноуты - как на работе, так и дома. И там видеокарта встроенная и слабая.
Что делать?
В последнее время появляются ноуты, а точнее процессоры со встроенным AI ядром.
Например: https://www.intel.com/content/www/us/en/products/sku/241751/intel-core-ultra-7-processor-255h-24m-cache-up-to-5-10-ghz/specifications.html
Чип как я понял у всех процессоров Intel пока один, называется NPU 3720.

Попробовал я запустить на таком чипе нормальную LLM - нормальную, в смысле LLM общего назначения, а не заточенную под embedding, обработку картинок или голоса...
Сразу наткнулся на ряд подводных камней:
1) широкоизвестная (в узких кругах запускателей LLM моделей) ollama NPU не поддерживает. Надеюсь, это временно, но сейчас так. Зато Intel сделал свой SDK - OpenVINO, с похожим функционалом.
Поддерживаются Windows и Ubuntu 22 https://docs.openvino.ai/2025/openvino-workflow/running-inference/inference-devices-and-modes/npu-device.html
2) в WSL, и далее Docker Desktop NPU не пробрасывается, работает только в native режиме. Я про Windows, но подозреваю проблемы и на Ubuntu

Ну ок, пробуем OpenVINO, благо на huggingface есть коллекция LLMs optimized for NPU, в документации к модели есть инструкция по запуску, например: https://huggingface.co/OpenVINO/gemma-3-4b-it-int4-cw-ov
Но и тут сплошные нюансы:
1) обязательно нужен последний драйвер от Intel, у моего кажется версия от 25.12.2025, что намекает на то, что "тема горячая". На исходной версии драйвера, поставленной Windows, запуск LLM падал с ошибкой компиляции. Об фазе активной разработки говорит раздел "Supported Features and properties" по ссылке ниже.
2) нельзя так просто взять и запустить модель на NPU (c). Требуются модели с квантизацией - это по сути сжатая модель, когда веса преобразуются из Double в Int с минимальным влиянием на точность ответа (так обещают). В случае NPU лучше даже в int4, чем в int8, цифры приведу позже.
Список моделей можно найти тут: https://docs.openvino.ai/2025/documentation/compatibility-and-support/supported-models.html или вот так https://huggingface.co/OpenVINO
3) модели с числом параметров больше 4b (4 млрд) лучше не брать. Они возможно запустятся, но время ответа уйдет за 1 минуту
4) рекомендую внимательно прочитать https://docs.openvino.ai/2025/openvino-workflow-generative/inference-with-genai/inference-with-genai-on-npu.html, оттуда станет ясно, что сейчас при запуске модели через NPU происходит долгая компиляция. Я к чему - кэширование обязательно, оно раза в 3-4 увеличивает скорость запуска. Второго и последующих естественно.
Другие опции - performance hints и AOT (Ahead of Time) компиляция пока сыроваты, а там, где они у меня завелись AOT Weightless - результат был примерно такой же, как с кэшем.
Кэш и AOT по сути являются альтернативами. AOT должен быть быстрее, но он еще сырой и требует двух запусков с разными параметрами, в то время как подключение кэша прозрачно.

Еще что интересно.
Если вернуться с списку моделей от Intel - https://docs.openvino.ai/2025/documentation/compatibility-and-support/supported-models.html, то там порядка 1000 моделей совместимы с NPU. Это сильно меньше, чем CPU\GPU, но много.
А вот если посмотреть на категорию этих моделей, то Large Language Model будет меньше чем у сотни.
Остальные - это Object Detection, Speech Recognition, Image\Video classification, Text To Speech, Natural Language Processing, Audio, Image generation, Image to Image. Вообще говоря классификация интересна сама по себе, но я бы хотел заострить внимание на том, что LLM меньше 10%.
Это говорит о том, для чего Intel делала свой чип.
И о главном - скорость ответа.
Тестировал на двух типах моделей, Python, OpenVINO 2025.4.1 GenAi API, Windows 11, Intel Core Ultra 7 255H:
1) анализ изображения, модель gemma-3-4b-it-int4-cw-ov, пайплайн openvino_genai.VLMPipeline
CPU 30c
CPU+cache 22c
NPU 80c
NPU+cache 25c
GPU 20c
GPU+cache 14c

2) режим чата, модель qwen2.5-1.5b-instruct-int4-ov, пайплайн openvino_genai.LLMPipeline
CPU 6c
CPU+cache 5c
NPU 40c
NPU+cache 10c
NPU+AOT 9c
GPU 9c
GPU+cache 5c

Это не полноценный бенчмарк, но пару прогонов делал.

Итог: для картинок быстрее GPU, для текста - паритет CPU и GPU. Чуда не произошло.
Но. Одним NPU ядром разгрузить 14 ядер CPU - в целом уже неплохо.
И кэширование гораздо важнее для NPU, не понимаю почему.

P.S. Интересный момент - железо сильно влияет на ответ на одной и той же модели и промте. Т.е. смысл везде похож, но текст ответа сильно отличается:

Here's what's unusual in the picture:
The cat is lying completely flat inside a cardboard box! It's a very relaxed and adorable pose for a cat, but it’s not typical behavior – cats usually prefer to be curled up or have some space around them.
Let me know if you want to analyze the picture further!

Here's what's unusual about the picture:
* **The cat is in a box!** It's not just *near* a box, but it's completely curled up and lying down *inside* a cardboard box. It’s a classic, adorable, and slightly unusual behavior for cats.
Let me know if you'd like me to elaborate on why it’s unusual!

Here's what's unusual in the picture:
* **The cat is lying in a cardboard box.** Cats are known for enjoying boxes, but it's particularly amusing to see one completely relaxed and stretched out inside one!
Let me know if you'd like to analyze another image!

Повторяемость на одном и том же типе железа при этом хорошая.

#ai #hardware
🔥1