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

Недавно на одной AI конференции услышал две довольно радикальные мысли.
1) программирование на высокоуровневых языках исчезнет повторив судьбу ассемблера. Останутся только архитекторы.
2) если модели не нравится ваш код - в смысле она не может его доработать - значит проблема в коде

Вот мои мысли по этому поводу.

1) Эти два утверждения работают только вместе. Т.е. если LLM модель пишет код, то он стандартизирован. И тогда любой нестандартный код - плохой. Т.к. он нарушает code style. Назовем его AI code style. И потому что раз уж мы отдали писать код модели - не надо ей мешать

2) С одной стороны аналогия с заменой ассемблера языками высокого уровня красива. И некие аналогии тут есть. Скорость разработки в теории может так же ускориться. Сложность систем, которые можно разработать, вырастет. А запрос как на повышение скорости разработки, так и на создание все более сложных систем, есть. Да, программирование на LLM - это тоже переход на более высокий уровень

3) Где аналогия хромает? Что общего у ассемблера и Java. Оба они детерминированы. Как и разработка в целом. Да, у нас есть место случайности, но она сосредоточена в нескольких местах - реализация функции random, генерация уникальных идентификаторов приходят на ум. А LLM принципиально недетермирована. Использование недетермированной машины для выполнения детерминированного процесса - ну такое себе.

4) Программирование уже пытались убрать из процесса разработки коммерческого ПО. Вот сейчас появилось много AI платформ для no code (low code) разработки. Знакомые же слова. Я про "no code". Да, BPMN системы. И различные проприетарные low code платформы. Свою ниши они заняли, но эти ниши достаточно узкие. Tilda самый очевидный пример. Но если говорить о глобальной замене программирования и программистов - не взлетело

Что думаете по этому поводу?

#ai #llm #lang
👍1🔥1
На какие столбцы повесить индексы?

Есть несколько способов это определить.

1) экспертное мнение. Подходит для простых случаев. Ну и ограничение - нужно быть экспертом)

2) спросить условный ChatGPT, скормив ему код. Стильно, модно, молодёжно. Но с текущим уровнем развития LLM видится, что точность не гарантирована)

3) использовать план выполнения запроса, чтобы найти там full scan (seq scan).
Но тут возникает вопрос - на каких запросах его выполнять?
На медленных либо сильно нагружающих СУБД.
Есть несколько вариантов их найти:
а) slow log - отбрасывание наиболее медленных запросов в лог. Что считать медленным - настраивается через граничное время выполнения.
Может быть включён как на уровне Hibernate https://vladmihalcea.com/hibernate-slow-query-log/, так и на уровне базы данных https://www.cybertec-postgresql.com/en/3-ways-to-detect-slow-queries-in-postgresql/ (нужен VPN).
При наличии такой возможности - лучше не уровне БД, например, во время НТ.
Данный способ хорош тем, что прямо указывает на медленные запросы. И этим же плох, т.к. он не покажет массовый запрос, который выполняется быстро, но много.

б) более подробную информацию можно получить с помощью сбора статистики выполнения запросов. Для PostgreSQL это делает модуль pg_stat_statements. Детали тут https://habr.com/ru/articles/488968/
Модуль формирует табличку с данными, в которой можно отсортировать запросы по общему времени выполнения, среднему и максимальному времени, по величине отклонения от среднего, по числу вызовов и даже по нагрузке на процессор и дисковую подсистему.
В общем куча полезной информации, с которой придётся поработать)
Также рекомендую включить его на НТ. А потом измерить влияние включённого модуля на производительность и если оно в районе 1% - включить и на ПРОМе.

P.S. У MySQL аналога pg_stat не нашёл. У Oracle - AWR. У MSSQL - Query Store.

#db #performance
👍1
Редко делаю репосты, но кажется данный пост этого достоин.

Пару замечаний.
1) как раз по итогам вот таких углубленных исследований темы у меня часто появляются посты)
2) я не понимаю, как можно полдня ... развлекаться с LLM, не получить работающего кода и главное - не получить ощущения, что ты занимаешься ерундой. У меня в таких кейсах это ощущение уже через полчаса возникает) Видимо еще не вовлекся)
3) если нужно прокопать проблему - LLM может с этим помочь. Главное не зацикливаться на получении работающего кода здесь и сейчас. И задавать правильные вопросы. IMHO замечание про LLM как раз и показывает путь, как обойти опасность "отупения" при работе с LLM не отказываясь от нее
Почему многие программисты не станут синьорами никогда

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

Запоминайте паттерн решения любого затыка в кодинге:

1. 5-10 минут пробуем применить какие-то быстрые догадки и метод тыка
2. 10-20 минут тратим на поиск готовых решений в ИИ и на reddit (стековерфлоу прости, ты больше не нужен)
3. И примерно спустя 30 минут тыкания останавливаемся. На этом этапе мы должны перейти в режим, а что это вообще за проблема? Начинаем читать по теме пытаясь понять как в целом работает эта штука, которая сломалась, что за ней стоит, какая теория подходы и все в этом духе. Разбираемся за час-два и фиксим
4. Если не помогло, тут уже надо с кем-то поговорить. Нельзя висеть на одной задаче без движения больше 2 часов.

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

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

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

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

Видео на эту тему одно из первых у меня на канале: https://www.youtube.com/watch?v=9iwYRcw3A8A

Ссылки: Телеграм | Youtube | VK
Java vs Python, часть не помню какая)

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

Вот еще пример.

Важной частью Data Science является веб скрапинг (Web Scraping) - обход сайтов в сети интернет и получение из них определенного рода данных. И если вбить эти два слова "веб скрапинг" в поиск - он сразу подставит python)
Вот типичная статья из выдачи Яндекса https://habr.com/ru/companies/ruvds/articles/796885/
Основные python инструменты оттуда - BeautifulSoup, Scrapy, Selenium, lxml, pyquery

А что есть в Java? Есть ли что-то?)

BeautifulSoup - собственно парсинг страниц сайтов. Аналог в Java - jSoup https://www.baeldung.com/java-with-jsoup
Scrapy - тоже парсинг, но с многопоточкой, работой с сессией, куками. Т.е. для массового скрейпинга и работы со сложными сайтами. В Java - Webmagic https://www.baeldung.com/java-webmagic-web-crawler Возможностей поменьше, но инструмент в наличии
Selenium - не зависит от языка, вообще говоря написан на Java. В интеграционных тестах на Java я его еще лет 15 назад использовал.
lxml - быстрый парсер xml\html. Вообще у Java большой выбор парсеров: DOM, SAX, Stax. Но тут речь про работу с HTML, а HTML - это конечно подмножество XML, но, как правило - XML с ошибками. Зато в Java есть библиотечка TagSoup, цитата: "SAX-compliant parser written in Java that, instead of parsing well-formed or valid XML, parses HTML as it is found in the wild".
pyquery - работа с HTML в стиле jquery. Вот тут аналога не нашел, но, кажется, не критично.

Итого - экосистемы не изолированы, хорошие идеи перетекают из одной в другую. Java хоронить рано)

#java #python #data_science
👍21🔥1
Нужны ли sidecar?

Напомню, sidecar - это паттерн распределенных систем. Суть - есть 2+ контейнера. Один главный — контейнер собственно сервиса, содержит основную логику. Второй - "прицепной" (это дословный перевод sidecar) контейнер. Его роль - дополнить и улучшить контейнер сервиса. Причем часто основной сервис даже не предполагает о его существовании. Удобно для прозрачного навешивания нового функционала. Примеры: добавление Service Mesh, логирования, шифрования, работа с секретами...

У себя в компании я наблюдаю тренд по отказу от sidecar.

Почему?
У нас микросервисы. Мы не делаем их большими, требования к ресурсам стараемся оптимизировать - получаем реалистичные бизнес-требования, проводим НТ, устанавливаем requests и limits. Так по крайней мере должно быть)
Но что получается в итоге?
Предположим у нас service mesh. Предположим есть требование безы - весь входящий и исходящий трафик идет через ingress\egress. Это уже минимум +3 контейнера envoy proxy со своими limits. Если один контейнер сервиса = один envoy proxy, + ingress + egress.
А если каждый из них нужно "обмазать" sidecar для шифрования. А еще для хранения секретов. А еще для логирования. И еще какие-то требования платформы.
Итого я видел кейсы, когда на один контейнер простого бизнесового сервиса в namespace было 7 или 8 служебных контейнеров. И даже если каждый из них потребляет меньше ресурсов, чем бизнес сервис - в итоге мы получаем х3 накладных расходов по ресурсам. Грустно(
Проблема на самом деле не только в контейнерах - любые служебные pod в namespace тоже вносят свой вклад.

Как же решается проблема?
Путей несколько:
1) часть функционала можно встроить в сам приклад. Если в прикладе уже есть клиентский модуль сервиса X и его все равно надо периодически обновлять с пересборкой - сделать этот клиентский модуль чуть толще вполне себе можно.
2) у k8s есть такая штука как операторы. Это сервис, работающий где-то рядом с ядром k8s, который может отслеживать изменения конфигурации в любом namespace и по этому событию делать что-то полезное. Например, по наличию определенной аннотации у пода подгружать для него секреты. Или собирать метрики с пода, опрашивая url Prometheus, построенный по определенному шаблону. Или настраивать Rate Limiter на envoy proxy при его старте. Оператор можно создать самому, это по сути plugin для k8s
3) если продолжить мысль из предыдущего пункта - по такому же сценарию можно поступить и с Istio proxy (он же envoy). Встречайте - Ambient Mesh. Вот статья про технологию https://habr.com/ru/articles/807117/, а вот как это внедряется в Сбере https://yandex.ru/video/preview/3928252140575819915 Все прокси не исчезают, трафик в облаке большой, оператор не может маршрутизировать его сам. Но прокси создаются на каждой node, а не на каждом контейнере. Требования к ресурсам у них будут побольше, но все равно получаем экономию по ресурсам в разы.

P.S. еще одна проблема, которую решает отказ от sidecar - с разработчика снимается обязанность отслеживать появление новых версий sidecar и их обновления.

#k8s #cloud #optimization
🔥21👌1
И снова AI агенты...

AI агент по определению должен делать что-то полезное, делать это с использованием AI, автономно и недетерминировано.
Сейчас я хочу рассмотреть свойство полезности.

AI агент в чем-то похож на умный proxy. Ум обеспечивает LLM (или не обеспечивает, тут идут споры))) ). А далее агент вызывает некую существующую функцию. Или несколько функций.
В терминологии AI это tool:
1) https://python.langchain.com/docs/concepts/tools/
2) https://docs.spring.io/spring-ai/reference/api/tools.html

tool - вообще говоря это просто метод Java, Python или любого другого языка, аннотированый соответствующим образом.
Как агент понимает, что умеет tool? Аннотации с описанием назначения тула, входных и выходных параметров.

Но если подумать - мы же живем в REST мире, в нем победил OpenAPI, а там вся необходимая информация есть. И текстовые описания, и граничные значения, и примеры. Даже адреса серверов на разных средах можно в спеке указать.
Нельзя ли это как-то переиспользовать? DRY все таки!

Можно. https://python.langchain.com/docs/integrations/tools/openapi/ на примере Python
Загружаем спеку, преобразуем в формат, понятный AI и создаем агента:

with open("spotify_openapi.yaml") as f:
raw_spotify_api_spec = yaml.load(f, Loader=yaml.Loader)
spotify_api_spec = reduce_openapi_spec(raw_spotify_api_spec)
...
spotify_agent = planner.create_openapi_agent(
spotify_api_spec,
requests_wrapper,
llm,
allow_dangerous_requests=ALLOW_DANGEROUS_REQUEST,
)


Почему не Java?
https://github.com/langchain4j/langchain4j/issues/1307
Ждем-с.
Что-то делается и для Spring AI, но пока сторонними разработчиками https://readmedium.com/connect-existing-openapis-to-llms-with-spring-ai-039ccabde406

Это самый простой способ вызвать существующий функционал.
Если он не подходит по одной следующих причин:

1) нет готового адаптера OpenAPI
2) нет OpenAPI спецификации, или она сделана криво, а доработка ее другой командой требует времени
3) хочется объединить несколько запросов в один tool или обогатить ответ tool-а локальной информацией
4) нужно убрать лишнее из ответа

то можно вернуться к исходному варианту - написать свой кастомный tool, возвращающий только то, что нужно и документированный так, как нужно.

Ну и третий вариант - отдельный MCP сервер https://t.me/javaKotlinDevOps/376.
У него два плюса:
1) MCP API - это специализированное API, адаптированное для использования LLM
2) tool-ом в виде MCP сервера может в теории воспользоваться любой AI агент

#ai #llm #spring #python
👍1