Не Spring-ом единым...
Появилась еще одна библиотека для Java для работы с LLM, а точнее конкретно с OpenAI. Официальная, от OpenAI
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.22.0</version>
</dependency>
На что хотелось бы обратить внимание:
1) OpenAI наконец то "дошла" до Java разработчиков
2) Разработчики библиотеки очень любят method chaining (ссылка на статью с примерами в конце поста). Со стороны даже кажется, что череcчур, можно было бы и по-короче инициализировать библиотеку
3) есть поддержка web-поиска
4) есть неочевидное разделение на Completion API - простые вопросы к LLM, типа "как на Java получить список файлов в каталоге" и Assistants API - "напиши мне микросервис, возвращающий курсы акций на бирже". Почему неочевидное - в моделях я вижу обратную тенденцию к унификации, когда одна модель используется для всех типов задач.
5) Assistants API умеет в File Search и Code Interpreter
И небольшой каталог решений по работе с LLM на Java:
1) Spring AI - https://docs.spring.io/spring-ai/reference
Примеры использования:
hello world https://habr.com/ru/articles/784128/
Более сложные примеры
https://piotrminkowski.com/2025/01/28/getting-started-with-spring-ai-and-chat-model/
https://piotrminkowski.com/2025/01/30/getting-started-with-spring-ai-function-calling/
Telegram bot, OpenAI и Spring AI https://habr.com/ru/companies/dockhost/articles/884876/
2) langchain4j https://github.com/langchain4j/langchain4j Характерно, что проект сделан на основе одноименной Python библиотеки. Поддерживается в Quarkus https://www.baeldung.com/java-quarkus-langchain4j
3) прямая интеграция с OpenAI https://www.baeldung.com/java-openai-api-client
P.S. Возможно Assistants API "жрет" больше токенов, отсюда и разделение
#llm #openai #ai #spring
Появилась еще одна библиотека для Java для работы с LLM, а точнее конкретно с OpenAI. Официальная, от OpenAI
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.22.0</version>
</dependency>
На что хотелось бы обратить внимание:
1) OpenAI наконец то "дошла" до Java разработчиков
2) Разработчики библиотеки очень любят method chaining (ссылка на статью с примерами в конце поста). Со стороны даже кажется, что череcчур, можно было бы и по-короче инициализировать библиотеку
3) есть поддержка web-поиска
4) есть неочевидное разделение на Completion API - простые вопросы к LLM, типа "как на Java получить список файлов в каталоге" и Assistants API - "напиши мне микросервис, возвращающий курсы акций на бирже". Почему неочевидное - в моделях я вижу обратную тенденцию к унификации, когда одна модель используется для всех типов задач.
5) Assistants API умеет в File Search и Code Interpreter
И небольшой каталог решений по работе с LLM на Java:
1) Spring AI - https://docs.spring.io/spring-ai/reference
Примеры использования:
hello world https://habr.com/ru/articles/784128/
Более сложные примеры
https://piotrminkowski.com/2025/01/28/getting-started-with-spring-ai-and-chat-model/
https://piotrminkowski.com/2025/01/30/getting-started-with-spring-ai-function-calling/
Telegram bot, OpenAI и Spring AI https://habr.com/ru/companies/dockhost/articles/884876/
2) langchain4j https://github.com/langchain4j/langchain4j Характерно, что проект сделан на основе одноименной Python библиотеки. Поддерживается в Quarkus https://www.baeldung.com/java-quarkus-langchain4j
3) прямая интеграция с OpenAI https://www.baeldung.com/java-openai-api-client
P.S. Возможно Assistants API "жрет" больше токенов, отсюда и разделение
#llm #openai #ai #spring
Хабр
ChatGPT на Java. Пишем «Hello World» на Spring AI
В преддверии Нового Года, начинаем осваивать генеративные сети с помощью привычного всем Java разработчикам фреймворка Spring. Несколько месяцев назад в Spring добавили модуль AI , который упрощает...
Spring Events и транзакции - какие варианты?
Есть такая полезная библиотека как Spring Events https://www.baeldung.com/spring-events. Позволяет логически и\или физически разделять операции внутри сервиса используя событийную модель. Event-drive architecture или паттерн Хореография, но не между микросервисами, а внутри. Но ключевое отличие взаимодействий между микросервисами и внутри микросервиса - внутри микросервиса есть транзакции в БД. Между микросервисами - в теории тоже, используя JTA, но лучше не надо)
Так вот, какие могут быть варианты по работе с транзакциями при использовании Spring Events? Используем Spring Data JPA, есть две операции - создание клиента и генерация для него токена, по бизнесу мы хотим их разделить. Получится как-то так:
1)
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@EventListener
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
В данном случае выполнение синхронное (режим работы Spring Events по умолчанию), т.е. первая операция ждет пока все подписчики обработают событие. Следовательно, разделение процессов только логическое, что тоже может быть полезно. Обращения к БД выполняются в разных транзакциях, т.к. транзакции не используются)
2)
@Transactional
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@EventListener
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
Изменения минимальны, добавляем @Transactional на первую операцию, что приводит к тому, что операции выполняются в одной транзакции.
3)
@Transactional
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@TransactionalEventListener
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
Тут мы добавили 2 аннотации на вторую операцию, т.к. хотим обе операции выполнить в разных транзакциях. @TransactionalEventListener приводит к тому, что событие выполняется после завершения исходной транзакции, а @Transactional(propagation = Propagation.REQUIRES_NEW) открывает новую. Т.е. TransactionalEventListener не выполняет код в родительской транзакции, а синхронизирует выполнение с ней (и у него есть несколько режимов синхронизации). При этом исполнение по прежнему синхронное.
4)
@Transactional
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@Async
@EventListener
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
...
@Configuration
@EnableAsync
public class AsyncConfig {
}
Есть такая полезная библиотека как Spring Events https://www.baeldung.com/spring-events. Позволяет логически и\или физически разделять операции внутри сервиса используя событийную модель. Event-drive architecture или паттерн Хореография, но не между микросервисами, а внутри. Но ключевое отличие взаимодействий между микросервисами и внутри микросервиса - внутри микросервиса есть транзакции в БД. Между микросервисами - в теории тоже, используя JTA, но лучше не надо)
Так вот, какие могут быть варианты по работе с транзакциями при использовании Spring Events? Используем Spring Data JPA, есть две операции - создание клиента и генерация для него токена, по бизнесу мы хотим их разделить. Получится как-то так:
1)
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@EventListener
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
В данном случае выполнение синхронное (режим работы Spring Events по умолчанию), т.е. первая операция ждет пока все подписчики обработают событие. Следовательно, разделение процессов только логическое, что тоже может быть полезно. Обращения к БД выполняются в разных транзакциях, т.к. транзакции не используются)
2)
@Transactional
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@EventListener
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
Изменения минимальны, добавляем @Transactional на первую операцию, что приводит к тому, что операции выполняются в одной транзакции.
3)
@Transactional
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@TransactionalEventListener
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
Тут мы добавили 2 аннотации на вторую операцию, т.к. хотим обе операции выполнить в разных транзакциях. @TransactionalEventListener приводит к тому, что событие выполняется после завершения исходной транзакции, а @Transactional(propagation = Propagation.REQUIRES_NEW) открывает новую. Т.е. TransactionalEventListener не выполняет код в родительской транзакции, а синхронизирует выполнение с ней (и у него есть несколько режимов синхронизации). При этом исполнение по прежнему синхронное.
4)
@Transactional
public Customer createCustomer(String name) {
final Customer customer = customerRepository.save(new Customer(name));
applicationEventPublisher.publishEvent(new CustomerCreated(customer.getId()));
}
...
@Async
@EventListener
public void generateToken(CustomerCreated customerCreated) {
final Long customerId = customerCreated.getId();
final Customer customer = customerJpaRepository.findById(customerId).get();
customer.generateToken();
customerRepository.save(customer);
}
...
@Configuration
@EnableAsync
public class AsyncConfig {
}
Тут мы включаем асинхронное выполнение событий. Операции выполняются в разных транзакциях и в разных потоках.
Все варианты имеют право на жизнь, главное не забывать как работает Spring Events. Ну и если у нас есть "дешевые" транзации на БД (дешевые по сравнению с распределенными транзакциями), то имеет смысл использовать их по максимуму.
P.S. Что интересно, статья с baeldung.com по запросу Spring Events ранжируется выше официальной документации.
#spring #transactions #event_driven
Все варианты имеют право на жизнь, главное не забывать как работает Spring Events. Ну и если у нас есть "дешевые" транзации на БД (дешевые по сравнению с распределенными транзакциями), то имеет смысл использовать их по максимуму.
P.S. Что интересно, статья с baeldung.com по запросу Spring Events ранжируется выше официальной документации.
#spring #transactions #event_driven
Baeldung
Spring Events | Baeldung
The Basics of Events in Spring - create a simple, custom Event, publish it and handle it in a listener.
OpenAPI для асинхрона - а, пожалуйста
Я думаю все знают, как описать API для REST взаимодействия. OpenAPI давно уже стал стандартом.
Перечислю его основные плюсы:
1) широкое распространение
2) автоматическая генерация документации
3) онлайн редактор Swagger UI
4) генерация серверного и клиентского кода по схеме
5) стандарт покрывает не только собственно содержимое body сообщения, но и описывает всю схему взаимодействия: параметры URL, заголовки включая куки, коды ошибок. Даже адреса серверов, хотя как по мне - это спорный момент.
Но асинхронное взаимодействие, ака Event-Driven Architecture: Kafka, MQ.. - имеют свои особенности. Как минимум это:
1) нет понятия запрос-ответ, вместо этого обмен идет сообщениями
2) другой набор протоколов (хотя http есть и там, и там)
3) другая терминология - есть каналы (топик или очередь), у канала есть свои характеристики
4) в любом взаимодействии нужно описать 3 участников: producer, канал, consumer.
Поэтому появился AsyncAPI. Он достаточно сильно похож на OpenAPI:
1) тот же YAML,
2) похожи (с точностью до сказанного выше) основные блоки, из которых строится API - Info, Servers, Tags, Schemas...
Видно чем вдохновлялись авторы) Как сказано на официальном сайте: "Part of this content has been taken from the great work done by the folks at the OpenAPI Initiative."
И это хорошо.
Стандарт молодой, но уже стал стандартом ))) да, тавтология) Имеет все те же преимущества, что и OpenAPI - см. начало поста.
Вот неплохая статья с примером https://bigdataschool.ru/blog/asyncapi-specification-for-kafka-practical-example.html
Поэтому настоятельно рекомендую для использования.
#api #openapi #asyncapi
Я думаю все знают, как описать API для REST взаимодействия. OpenAPI давно уже стал стандартом.
Перечислю его основные плюсы:
1) широкое распространение
2) автоматическая генерация документации
3) онлайн редактор Swagger UI
4) генерация серверного и клиентского кода по схеме
5) стандарт покрывает не только собственно содержимое body сообщения, но и описывает всю схему взаимодействия: параметры URL, заголовки включая куки, коды ошибок. Даже адреса серверов, хотя как по мне - это спорный момент.
Но асинхронное взаимодействие, ака Event-Driven Architecture: Kafka, MQ.. - имеют свои особенности. Как минимум это:
1) нет понятия запрос-ответ, вместо этого обмен идет сообщениями
2) другой набор протоколов (хотя http есть и там, и там)
3) другая терминология - есть каналы (топик или очередь), у канала есть свои характеристики
4) в любом взаимодействии нужно описать 3 участников: producer, канал, consumer.
Поэтому появился AsyncAPI. Он достаточно сильно похож на OpenAPI:
1) тот же YAML,
2) похожи (с точностью до сказанного выше) основные блоки, из которых строится API - Info, Servers, Tags, Schemas...
Видно чем вдохновлялись авторы) Как сказано на официальном сайте: "Part of this content has been taken from the great work done by the folks at the OpenAPI Initiative."
И это хорошо.
Стандарт молодой, но уже стал стандартом ))) да, тавтология) Имеет все те же преимущества, что и OpenAPI - см. начало поста.
Вот неплохая статья с примером https://bigdataschool.ru/blog/asyncapi-specification-for-kafka-practical-example.html
Поэтому настоятельно рекомендую для использования.
#api #openapi #asyncapi
Курсы Big Data,Arenadata,Greenplum, Kafka и Spark
Swagger для асинхрона: составляем спецификацию AsyncAPI на примере Apache Kafka
Что такое AsyncAPI, зачем документировать спецификацию для EDA-архитектур и как это сделать
Зачем нужен MQ?
По работе передо мной периодически встает данный вопрос - зачем нужен MQ? Нужен ли он?
Поясню. Мы давно и успешно перешли с ESB поверх IBM WebSphere MQ на Kafka. Стало сильно лучше. В первую очередь за счет того, что получить топик Kafka, выпустить сертификаты и настроить ACL сильно проще, чем заказать доработку для на ESB. Да, это проблемы ESB, а не MQ, но их исчезновение все сразу заметили) Второй плюс: появились persistence и возможность повторной вычитки сообщения в случае сбоя - и сильно увеличилась надежность решения. И конечно же Kafka быстрее.
Как итог - Kafka используется везде и всегда. При этом есть понимание, что кроме Kafka есть другие инструменты, реализующие паттерн очередь (queue). Долгое время не мог сформулировать - в каких кейсах нужны очереди?
Ведь паттерн publisher-subscriber, реализованный в Kafka, является более общим, чем очередь. И т.об. очереди - асинхронное взаимодействие с одним producer и одним consumer - вроде бы можно делать в и Kafka. А возможность везде использовать один инструмент - это плюс.
Но если подумать - суть не в реализуемом паттерне. Ключевые отличия у Kafka и RabbitMQ (взял самую известную реализацию очередей для конкретики) другие. Покажу их на примере того, чего Kafka не умеет:
1) Kafka не удаляет сообщение после вычитки. Удаляет позднее, по TTL, вместе с партицией, но это другой алгоритм и другой use case. Т.е. первая потенциальная причина выбора очередей - необходимость гарантировать, что вычитанное одним потребителем, никогда не вычитает другой. Не скажу, что это частый кейс - возможно, требования безопасности.
2) Kafka имеет достаточно ограниченные возможности по маршрутизации. По сути на клиенте можно выбрать топик и партицию по определенному ключу. Вот и вся маршрутизация. Причем это было сделано сознательно, для достижения высокой производительности. Если нужна более сложная маршрутизация - это критерий для выбора очереди вместо Kafka. Тоже кейс не частый, и есть альтернатива в виде реализации маршрутизации на клиенте.
3) невозможно организовать конкурентную вычитку сообщений на consumer - конкуренция ограничена числом партицией. Меня число партицией после создания топика можно, но не нужно, т.к. это приводит к ребалансировке и плохо прогнозируемому падению производительности
4) у Kafka свой протокол. Поэтому если нужна поддержка существующего решения, где используется AMPQ или JMS - это не к Kafka. Особый случай, но упомянуть его надо.
Вот пожалуй и все варианты, когда Kafka не подходит.
P.S. Если знаете еще кейсы - напишите, плиз, в комментариях.
#mq #kafka
По работе передо мной периодически встает данный вопрос - зачем нужен MQ? Нужен ли он?
Поясню. Мы давно и успешно перешли с ESB поверх IBM WebSphere MQ на Kafka. Стало сильно лучше. В первую очередь за счет того, что получить топик Kafka, выпустить сертификаты и настроить ACL сильно проще, чем заказать доработку для на ESB. Да, это проблемы ESB, а не MQ, но их исчезновение все сразу заметили) Второй плюс: появились persistence и возможность повторной вычитки сообщения в случае сбоя - и сильно увеличилась надежность решения. И конечно же Kafka быстрее.
Как итог - Kafka используется везде и всегда. При этом есть понимание, что кроме Kafka есть другие инструменты, реализующие паттерн очередь (queue). Долгое время не мог сформулировать - в каких кейсах нужны очереди?
Ведь паттерн publisher-subscriber, реализованный в Kafka, является более общим, чем очередь. И т.об. очереди - асинхронное взаимодействие с одним producer и одним consumer - вроде бы можно делать в и Kafka. А возможность везде использовать один инструмент - это плюс.
Но если подумать - суть не в реализуемом паттерне. Ключевые отличия у Kafka и RabbitMQ (взял самую известную реализацию очередей для конкретики) другие. Покажу их на примере того, чего Kafka не умеет:
1) Kafka не удаляет сообщение после вычитки. Удаляет позднее, по TTL, вместе с партицией, но это другой алгоритм и другой use case. Т.е. первая потенциальная причина выбора очередей - необходимость гарантировать, что вычитанное одним потребителем, никогда не вычитает другой. Не скажу, что это частый кейс - возможно, требования безопасности.
2) Kafka имеет достаточно ограниченные возможности по маршрутизации. По сути на клиенте можно выбрать топик и партицию по определенному ключу. Вот и вся маршрутизация. Причем это было сделано сознательно, для достижения высокой производительности. Если нужна более сложная маршрутизация - это критерий для выбора очереди вместо Kafka. Тоже кейс не частый, и есть альтернатива в виде реализации маршрутизации на клиенте.
3) невозможно организовать конкурентную вычитку сообщений на consumer - конкуренция ограничена числом партицией. Меня число партицией после создания топика можно, но не нужно, т.к. это приводит к ребалансировке и плохо прогнозируемому падению производительности
4) у Kafka свой протокол. Поэтому если нужна поддержка существующего решения, где используется AMPQ или JMS - это не к Kafka. Особый случай, но упомянуть его надо.
Вот пожалуй и все варианты, когда Kafka не подходит.
P.S. Если знаете еще кейсы - напишите, плиз, в комментариях.
#mq #kafka
Можно ли быстро сделать и запустить single-file прототип на Java?
Как старый джавист я всегда немного с завистью смотрел видео, где человек на Python, PHP, Ruby пишет скрипт, содержащий достаточно сложный код и просто запускает его командой python script.py.
Не сказать, что Java ничего не делает в эту сторону:
1) JShell - позволяет просто запускать Java код без метода main построчно. Работает начиная с Java 9
2) JEP 330: Launch Single-File Source-Code Programs - не надо отдельно вызывать javac. Запуск программы работает через java HelloWorld.java. Работает с Java 11
3) JEP 477 Implicitly Declared Classes and Instance Main Methods - все тоже самое, но теперь не нужно объявлять класс (он создается неявно) и декларация метода main сильно упрощена. В режиме preview с Java 21
Но все это работает с простыми приложениями. А если нужны зависимости? Наш любимый Spring, например, с pom bom и кучей библиотек + Lombok. Да еще в нескольких файлах. Да еще хотелось бы не указывать параметры сборки в командной строке каждый раз, и не плодить лишних shell скриптов.
Когда-то подобная фича была в Spring Boot Cli - да, в Spring Boot и своя консоль. Но фичу выпилили, на мой взгляд зря. И из полезного в Cli остался по сути только аналог Spring Initialzr.
Но я отвлекся)
Кто ищет, тот всегда найдет - встречаем https://www.jbang.dev/documentation/guide/latest/index.html
Как это работает - хорошо проиллюстрировано по ссылке выше.
Я проверил на комбинации Spring Boot + Lombok все работает. Настройки из лежащего рядом application.properties подтягиваются. Единственный момент - были проблемы, если код разнесен по нескольким файлам - не обнаруживалась аннотация @Scheduled. Т.е. реализация multiple source file немного хромает, о чем разработчики предупреждают https://www.jbang.dev/documentation/guide/latest/organizing.html
Зато - все зависимости выкачиваются, код компилируется перед запуском, параметры компиляция настраиваются в файле с исходниками. Если надо - даже выкачивается Java. Принимает на вход java исходники, kotlin, упомянутый выше код для jshell, код внутри markdown (!!!) и можно даже так: jbang --code System.out.println("Hello World!")
Рекомендую к использованию!
#java #prototyping
Как старый джавист я всегда немного с завистью смотрел видео, где человек на Python, PHP, Ruby пишет скрипт, содержащий достаточно сложный код и просто запускает его командой python script.py.
Не сказать, что Java ничего не делает в эту сторону:
1) JShell - позволяет просто запускать Java код без метода main построчно. Работает начиная с Java 9
2) JEP 330: Launch Single-File Source-Code Programs - не надо отдельно вызывать javac. Запуск программы работает через java HelloWorld.java. Работает с Java 11
3) JEP 477 Implicitly Declared Classes and Instance Main Methods - все тоже самое, но теперь не нужно объявлять класс (он создается неявно) и декларация метода main сильно упрощена. В режиме preview с Java 21
Но все это работает с простыми приложениями. А если нужны зависимости? Наш любимый Spring, например, с pom bom и кучей библиотек + Lombok. Да еще в нескольких файлах. Да еще хотелось бы не указывать параметры сборки в командной строке каждый раз, и не плодить лишних shell скриптов.
Когда-то подобная фича была в Spring Boot Cli - да, в Spring Boot и своя консоль. Но фичу выпилили, на мой взгляд зря. И из полезного в Cli остался по сути только аналог Spring Initialzr.
Но я отвлекся)
Кто ищет, тот всегда найдет - встречаем https://www.jbang.dev/documentation/guide/latest/index.html
Как это работает - хорошо проиллюстрировано по ссылке выше.
Я проверил на комбинации Spring Boot + Lombok все работает. Настройки из лежащего рядом application.properties подтягиваются. Единственный момент - были проблемы, если код разнесен по нескольким файлам - не обнаруживалась аннотация @Scheduled. Т.е. реализация multiple source file немного хромает, о чем разработчики предупреждают https://www.jbang.dev/documentation/guide/latest/organizing.html
Зато - все зависимости выкачиваются, код компилируется перед запуском, параметры компиляция настраиваются в файле с исходниками. Если надо - даже выкачивается Java. Принимает на вход java исходники, kotlin, упомянутый выше код для jshell, код внутри markdown (!!!) и можно даже так: jbang --code System.out.println("Hello World!")
Рекомендую к использованию!
#java #prototyping
Kafka захватывает мир.
Я уже писал https://t.me/javaKotlinDevOps/411, что не умеет Kafka из-за заложенной в ней архитектуры. Если сформулировать одним словом - не реализует традиционную концепцию queue (а реализует - потоковой обработки данных, она же стриминг). Так вот, это уже не совсем так. В марте 2025 вышла Kafka 4.0 (пока даже без хотфиксов), где появилась новая фича - Kafka Queues https://cwiki.apache.org/confluence/display/KAFKA/KIP-932%3A+Queues+for+Kafka
Технически это сделано так: появились share groups - альтернатива обычным consumer groups, позволяющие всем членам группы вычитывать конкуренто сообщения из одной и той же партиции. С consumer groups это было невозможно, для независимой вычитки одной партиции нужны были разные consumer groups. С маршрутизацией все по старому, но первый шаг к очередям сделан. Где это можно применить - там где важно управлять конкурентной вычиткой на уровне consumer и не важен порядок вычитки сообщений. Причем у одного топика могут быть как consumer groups, так и share groups.
Возвращаясь к захвату мира. У БД есть такая концепция tiered storage. Переводится как многослойное хранение. Обычно слоев два - оперативная и архивная БД. Так вот, начиная с версии 3.6 Kafka умеет в tiered storage. Для хранения архивных данных можно подключать внешние хранилища, в частности облачные S3. Что важно - tiered storage включается настройками, т.е. не нужно писать никакого кода. Видится, что это хорошая заявка на использование Kafka как хранилища. Особенно, если у вас стриминговые данные, а-ля поток события, а-ля event sourcing.
P.S. Если говорить о других важных изменениях в последних версиях Kafka:
1) разработчики окончательно выпилили Zookeeper. Теперь за выборы лидера (master для каждой партиции) отвечает один из брокеров Kafka, имеющий роль Controller. И в случае его падения оставшиеся брокеры сами без внешней помощи могут выбрать новый Controller. Вот такое крафтовое (KRaft) решение. Это название протокола выбора лидера если что)
2) улучшен протокол ребалансировки - алгоритма сопоставления партиций топика и потребителей при изменении либо числа потребителей, либо партиций. https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol Как одна из целей заявлена "The protocol should support upgrading the consumers without downtime". Серьезная заявка, будем посмотреть.
#kafka #queue
Я уже писал https://t.me/javaKotlinDevOps/411, что не умеет Kafka из-за заложенной в ней архитектуры. Если сформулировать одним словом - не реализует традиционную концепцию queue (а реализует - потоковой обработки данных, она же стриминг). Так вот, это уже не совсем так. В марте 2025 вышла Kafka 4.0 (пока даже без хотфиксов), где появилась новая фича - Kafka Queues https://cwiki.apache.org/confluence/display/KAFKA/KIP-932%3A+Queues+for+Kafka
Технически это сделано так: появились share groups - альтернатива обычным consumer groups, позволяющие всем членам группы вычитывать конкуренто сообщения из одной и той же партиции. С consumer groups это было невозможно, для независимой вычитки одной партиции нужны были разные consumer groups. С маршрутизацией все по старому, но первый шаг к очередям сделан. Где это можно применить - там где важно управлять конкурентной вычиткой на уровне consumer и не важен порядок вычитки сообщений. Причем у одного топика могут быть как consumer groups, так и share groups.
Возвращаясь к захвату мира. У БД есть такая концепция tiered storage. Переводится как многослойное хранение. Обычно слоев два - оперативная и архивная БД. Так вот, начиная с версии 3.6 Kafka умеет в tiered storage. Для хранения архивных данных можно подключать внешние хранилища, в частности облачные S3. Что важно - tiered storage включается настройками, т.е. не нужно писать никакого кода. Видится, что это хорошая заявка на использование Kafka как хранилища. Особенно, если у вас стриминговые данные, а-ля поток события, а-ля event sourcing.
P.S. Если говорить о других важных изменениях в последних версиях Kafka:
1) разработчики окончательно выпилили Zookeeper. Теперь за выборы лидера (master для каждой партиции) отвечает один из брокеров Kafka, имеющий роль Controller. И в случае его падения оставшиеся брокеры сами без внешней помощи могут выбрать новый Controller. Вот такое крафтовое (KRaft) решение. Это название протокола выбора лидера если что)
2) улучшен протокол ребалансировки - алгоритма сопоставления партиций топика и потребителей при изменении либо числа потребителей, либо партиций. https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol Как одна из целей заявлена "The protocol should support upgrading the consumers without downtime". Серьезная заявка, будем посмотреть.
#kafka #queue
Telegram
(java || kotlin) && devOps
Зачем нужен MQ?
По работе передо мной периодически встает данный вопрос - зачем нужен MQ? Нужен ли он?
Поясню. Мы давно и успешно перешли с ESB поверх IBM WebSphere MQ на Kafka. Стало сильно лучше. В первую очередь за счет того, что получить топик Kafka…
По работе передо мной периодически встает данный вопрос - зачем нужен MQ? Нужен ли он?
Поясню. Мы давно и успешно перешли с ESB поверх IBM WebSphere MQ на Kafka. Стало сильно лучше. В первую очередь за счет того, что получить топик Kafka…
И снова SOLID, и снова OCP
Я уже говорил, что означает Open Close Principe (OCP) https://t.me/javaKotlinDevOps/181. Но появилась еще одна мысль. Наверное самая лучшая реализация этого принципа - это система с плагинами. Там мы очень четко говорим - что open, что close. И само проектирование такой системы накладывает больше ответственности, а значит есть шанс, что разделение open - close будет более устойчивым со временем. Минус тут только один - проектировать такую систему долго, а нужна она далеко не всегда.
P.S. И еще одна мысль - раз у нас ООП язык, и для расширения мы задумываемся об использовании композиции или агрегации - очень похоже на то, что проектировщик ядра (библиотеки), которую мы расширяем, где-то ошибся.
P.P.S. И последняя - у проектировщика ядра и у пользователей этого ядра часто противоположные задачи. В ядре мы стремимся закрыть все лишнее (close), чтобы обеспечить устойчивость и соблюдение code quality. А когда мы используем ядро - в тестах или расширяя его функционал - нам часто хочется залезть во внутрь и что-то поменять. Или получить доступ к внутреннему состоянию (open). Надо искать баланс.
#solid
Я уже говорил, что означает Open Close Principe (OCP) https://t.me/javaKotlinDevOps/181. Но появилась еще одна мысль. Наверное самая лучшая реализация этого принципа - это система с плагинами. Там мы очень четко говорим - что open, что close. И само проектирование такой системы накладывает больше ответственности, а значит есть шанс, что разделение open - close будет более устойчивым со временем. Минус тут только один - проектировать такую систему долго, а нужна она далеко не всегда.
P.S. И еще одна мысль - раз у нас ООП язык, и для расширения мы задумываемся об использовании композиции или агрегации - очень похоже на то, что проектировщик ядра (библиотеки), которую мы расширяем, где-то ошибся.
P.P.S. И последняя - у проектировщика ядра и у пользователей этого ядра часто противоположные задачи. В ядре мы стремимся закрыть все лишнее (close), чтобы обеспечить устойчивость и соблюдение code quality. А когда мы используем ядро - в тестах или расширяя его функционал - нам часто хочется залезть во внутрь и что-то поменять. Или получить доступ к внутреннему состоянию (open). Надо искать баланс.
#solid
Telegram
(java || kotlin) && devOps
Всем привет!
Раз уж я начал говорить про SOLID - рассмотрим еще одну букву - O.
Open-closed principe - принцип открытости-закрытости.
На первый взгляд все просто - не нужно менять существующие классы, нужно их расширять. Очень хорошо ложится на области…
Раз уж я начал говорить про SOLID - рассмотрим еще одну букву - O.
Open-closed principe - принцип открытости-закрытости.
На первый взгляд все просто - не нужно менять существующие классы, нужно их расширять. Очень хорошо ложится на области…
Типовые ошибки на собесах.
Уже разбирал типовые вопросы на собесах, теперь хочу поговорить про типовые ошибки.
Возможно, эта тема тоже станет постоянной.
Часто на интервью есть либо задачки на live coding, либо задачки на подумать - не имеющие точного ответа.
И тут я сталкиваюсь с 2 типовыми ошибками:
1) кандидат боится ошибиться, т.к. не был готов к такому повороту собеса. Поэтому отвечает кратко, не объясняет свои решения, дополнительные вопросы его вводят в ступор. Все это производит негативное впечатление и сильно снижает шансы на найм. Правильное решение: не бояться - как бы это ни странно звучало - думать, размышлять, а главное - результаты проговаривать. Даже если четкого ответа нет. Именно этого интервьюер и ждет, добавив такую секцию на собесе - понять ход мыслей кандидата.
2) кандидат скажем так сильно прикипел к своей предметной области. Предположим, его типовые задачи - реализация новых REST методов, а способ - связка controller-service-repository. Он получает задачку на собесе и сразу начинает выполнять ее по той же схеме, как делал бы на текущем месте работы. Что тут плохого? Только то, что интервьюер возможно хотел проверить знания алгоритмов, паттернов надежности или чего-то еще. А вовсе не умение раскладывать код на по слоям controller-service-repository. И получается как в анекдоте: "Некогда думать, трясти надо". Правильное решение - уточнить, что хотел интервьюер. А потом еще раз уточнить) Важнее четкое понимание задачи и обсуждение путей ее решения, чем скорость написания кода. Да, это может занять столько же времени, сколько и написание кода. И это нормально. Есть компании с нормой решенных задач на собес, но в любом случае неверно решенная задача в зачет не идет.
P.S. Отдельный важный момент связан с live coding - и это тесты. Можно сколько угодно говорить, что "надо написать тесты, я обычно так делаю, но сейчас времени нет.." Но лучше их просто написать) Можно даже перед кодом, по TDD.
#interview #interview_fails
Уже разбирал типовые вопросы на собесах, теперь хочу поговорить про типовые ошибки.
Возможно, эта тема тоже станет постоянной.
Часто на интервью есть либо задачки на live coding, либо задачки на подумать - не имеющие точного ответа.
И тут я сталкиваюсь с 2 типовыми ошибками:
1) кандидат боится ошибиться, т.к. не был готов к такому повороту собеса. Поэтому отвечает кратко, не объясняет свои решения, дополнительные вопросы его вводят в ступор. Все это производит негативное впечатление и сильно снижает шансы на найм. Правильное решение: не бояться - как бы это ни странно звучало - думать, размышлять, а главное - результаты проговаривать. Даже если четкого ответа нет. Именно этого интервьюер и ждет, добавив такую секцию на собесе - понять ход мыслей кандидата.
2) кандидат скажем так сильно прикипел к своей предметной области. Предположим, его типовые задачи - реализация новых REST методов, а способ - связка controller-service-repository. Он получает задачку на собесе и сразу начинает выполнять ее по той же схеме, как делал бы на текущем месте работы. Что тут плохого? Только то, что интервьюер возможно хотел проверить знания алгоритмов, паттернов надежности или чего-то еще. А вовсе не умение раскладывать код на по слоям controller-service-repository. И получается как в анекдоте: "Некогда думать, трясти надо". Правильное решение - уточнить, что хотел интервьюер. А потом еще раз уточнить) Важнее четкое понимание задачи и обсуждение путей ее решения, чем скорость написания кода. Да, это может занять столько же времени, сколько и написание кода. И это нормально. Есть компании с нормой решенных задач на собес, но в любом случае неверно решенная задача в зачет не идет.
P.S. Отдельный важный момент связан с live coding - и это тесты. Можно сколько угодно говорить, что "надо написать тесты, я обычно так делаю, но сейчас времени нет.." Но лучше их просто написать) Можно даже перед кодом, по TDD.
#interview #interview_fails
Почему SOLID?
Почему именно SOLID считается базовыми принципами разработки? Почему именно пять? Почему именно эти пять?
Я думаю, что за основной причиной нужно идти в словарь. Solid — крепкий, твёрдый, надёжный, серьёзный. Роберт Мартин хотел, чтобы принципы легко запоминались — у него это получилось)
Приведу пару аргументов.
I — interface segregation — принцип, конечно, полезный. Но технический по сути, а главное — является частным случаем S — single responsibility.
S, O, D — могут применяться как на уровне классов, так и на уровне модулей приложения.
L — это уровень классов, накладывает на них более строгие требования, чем обеспечивают «из коробки» ООП языки.
Есть ещё полезные принципы — DRY, KISS, которые сюда не попали.
Из всего вышесказанного никак не следует, что SOLID-принципы плохие. Я о том, что их на самом деле больше.
#solid
Почему именно SOLID считается базовыми принципами разработки? Почему именно пять? Почему именно эти пять?
Я думаю, что за основной причиной нужно идти в словарь. Solid — крепкий, твёрдый, надёжный, серьёзный. Роберт Мартин хотел, чтобы принципы легко запоминались — у него это получилось)
Приведу пару аргументов.
I — interface segregation — принцип, конечно, полезный. Но технический по сути, а главное — является частным случаем S — single responsibility.
S, O, D — могут применяться как на уровне классов, так и на уровне модулей приложения.
L — это уровень классов, накладывает на них более строгие требования, чем обеспечивают «из коробки» ООП языки.
Есть ещё полезные принципы — DRY, KISS, которые сюда не попали.
Из всего вышесказанного никак не следует, что SOLID-принципы плохие. Я о том, что их на самом деле больше.
#solid
k8s HPA бесполезен? Или нет?)
Я уже писал о возможности масштабировать поды горизонтально через компонент HPA — Horizontal Pod Autoscaler. Он собирает метрики загрузки пода (границы можно настраивать) и меняет число реплик в заданных границах.
Круто? Да. Но есть одно «но». В namespace ресурсы часто прибиты гвоздями. Один namespace = один микросервис. Микросервис имеет некие бизнес-требования по нагрузке, проходит нагрузочное тестирование и получает некоторое количество ресурсов. Хуже того — кластер, в котором находится namespace, тоже имеет жёсткое ограничение по ресурсам. Это частное, небольшое по сравнению с cloud-провайдерами облако. Лишним node взяться неоткуда. Поэтому HPA в частном облаке бесполезен. Все ресурсы уже забронированы. От того, что часть из них уберут из балансировки, ни холодно ни жарко. Только замедление при старте пода.
В больших облаках, типа AWS, эту проблему решают тем, что прячут кластер от клиента и динамически меняют его размер.Если потребителей много и у них разный характер нагрузки, всё должно работать хорошо.
Что можно сделать в частном облаке? Например, вот так: https://youtu.be/GWJ9rDrsBdQ?si=dx-VHMlIIYKo2g4q Кейс не универсальный, но если есть свой кластер и понятно, что в нём будут жить приложения с разными пиками нагрузки — потребление ресурсов можно оптимизировать. Как развитие идеи — автоматическая генерация рекомендаций по настройке кластера.
#k8s #optimization
Я уже писал о возможности масштабировать поды горизонтально через компонент HPA — Horizontal Pod Autoscaler. Он собирает метрики загрузки пода (границы можно настраивать) и меняет число реплик в заданных границах.
Круто? Да. Но есть одно «но». В namespace ресурсы часто прибиты гвоздями. Один namespace = один микросервис. Микросервис имеет некие бизнес-требования по нагрузке, проходит нагрузочное тестирование и получает некоторое количество ресурсов. Хуже того — кластер, в котором находится namespace, тоже имеет жёсткое ограничение по ресурсам. Это частное, небольшое по сравнению с cloud-провайдерами облако. Лишним node взяться неоткуда. Поэтому HPA в частном облаке бесполезен. Все ресурсы уже забронированы. От того, что часть из них уберут из балансировки, ни холодно ни жарко. Только замедление при старте пода.
В больших облаках, типа AWS, эту проблему решают тем, что прячут кластер от клиента и динамически меняют его размер.Если потребителей много и у них разный характер нагрузки, всё должно работать хорошо.
Что можно сделать в частном облаке? Например, вот так: https://youtu.be/GWJ9rDrsBdQ?si=dx-VHMlIIYKo2g4q Кейс не универсальный, но если есть свой кластер и понятно, что в нём будут жить приложения с разными пиками нагрузки — потребление ресурсов можно оптимизировать. Как развитие идеи — автоматическая генерация рекомендаций по настройке кластера.
#k8s #optimization
YouTube
Как управлять горизонтальным масштабированием в больших проектах / Илья Семенов, Алексей Игнатов
Профессиональная конференция по интеграции процессов разработки, тестирования и эксплуатации DevOpsConf 2025
Презентация и тезисы:
https://devopsconf.io/moscow/2025/abstracts/14210
On-premise-инсталляции K8s и похожи, и непохожи на обычные облака. Базовые…
Презентация и тезисы:
https://devopsconf.io/moscow/2025/abstracts/14210
On-premise-инсталляции K8s и похожи, и непохожи на обычные облака. Базовые…
live coding это все-таки кодинг
Недавно писал про то, что на сессии live coding на собесе не надо сразу браться за задачу, вначале стоит позадавать вопросы и продумать путь решения задачи.
Но есть и обратный кейс. Пусть у нас остается максимум полчаса времени собеса. Есть задача на live coding. И вообще то задачку можно сделать за 10 минут. И, естественно, это понимают люди, ведущие собес. Как они отнесутся, если кандидат потратит 10 минут на вопросы, 10 минут на рассуждения как лучше реализовывать и 10 минут на написание кода? И как всегда без тестов, по причине того, что тесты бы написать надо, но времени нет. Ответ - плохо отнесутся.
И тут мы приходим к понятию баланса. Соотношению между сложностью задачи (да, ее нужно уметь оценить, причем в экспресс режиме) и усилиями, затраченными на ее решение. В данном случае баланс сильно нарушен, хотя все действия вроде бы правильные. И что самое важное - интервью намекает, как такие задачи кандидат будет решать в реальной жизни. Lead Time говорит - ну да, ну да, пошел я ...
В общем не делайте так
#interview #interview_fails
Недавно писал про то, что на сессии live coding на собесе не надо сразу браться за задачу, вначале стоит позадавать вопросы и продумать путь решения задачи.
Но есть и обратный кейс. Пусть у нас остается максимум полчаса времени собеса. Есть задача на live coding. И вообще то задачку можно сделать за 10 минут. И, естественно, это понимают люди, ведущие собес. Как они отнесутся, если кандидат потратит 10 минут на вопросы, 10 минут на рассуждения как лучше реализовывать и 10 минут на написание кода? И как всегда без тестов, по причине того, что тесты бы написать надо, но времени нет. Ответ - плохо отнесутся.
И тут мы приходим к понятию баланса. Соотношению между сложностью задачи (да, ее нужно уметь оценить, причем в экспресс режиме) и усилиями, затраченными на ее решение. В данном случае баланс сильно нарушен, хотя все действия вроде бы правильные. И что самое важное - интервью намекает, как такие задачи кандидат будет решать в реальной жизни. Lead Time говорит - ну да, ну да, пошел я ...
В общем не делайте так
#interview #interview_fails
code style бывает разный
Меня сложно чем-то удивить в области разработки. Но недавно, изучая разные code style, я решил посмотреть, какие бывают варианты расположения фигурной скобки. Изначально в моём понимании их два - на одной строке с управляющей конструкцией и с новой строки. Но жизнь оказалась богаче любых ожиданий:
https://en.m.wikipedia.org/wiki/Indentation_style
Девять! Девять, Карл!
Хотя в Java наиболее распространён один, пришедший из C, от Кернигана и Ричи.
Вывод будет такой. Не важно сколько разных code style существует, важно, чтобы в проекте использовался один. А это значит .editorconfig https://editorconfig.org/ и автоматическое форматирование в Actions on Save в IDEA.
#code_style #idea
Меня сложно чем-то удивить в области разработки. Но недавно, изучая разные code style, я решил посмотреть, какие бывают варианты расположения фигурной скобки. Изначально в моём понимании их два - на одной строке с управляющей конструкцией и с новой строки. Но жизнь оказалась богаче любых ожиданий:
https://en.m.wikipedia.org/wiki/Indentation_style
Девять! Девять, Карл!
Хотя в Java наиболее распространён один, пришедший из C, от Кернигана и Ричи.
Вывод будет такой. Не важно сколько разных code style существует, важно, чтобы в проекте использовался один. А это значит .editorconfig https://editorconfig.org/ и автоматическое форматирование в Actions on Save в IDEA.
#code_style #idea
Wikipedia
Indentation style
computer programming convention
Небольшая заметка к предыдущему посту.
Может возникнуть вопрос: зачем нужно сохранять настройки форматирования, он же code style, в отдельном файле, если правильные настройки есть в IDEA по умолчанию? И изучать, пусть и поверхностно, пусть и достаточно простой формат настроек .editorconfig? Стоит ли игра свеч?
Мой ответ: да.
Во-первых, не все пользуются стандартными настройками IDEA. Во-вторых, они от версии к версии могут меняться. А единый code style — основа для комфортной и быстрой работы ревьювера. Почему важно code review — говорить не буду.
И пару уточнений. Даже в базовом стандарте .editorconfig много настроек. Плюс он позволяет сохранять вообще любые настройки, например, можно импортировать все настройки IDEA. Попробуйте, кстати, удивитесь. Вопрос: нужно ли всё это хранить в Git? Нет, это лишь затруднит управление настройками. Определитесь, что важно для быстрого чтения кода. Если что-то забудется — всегда можно добавить потом.
Второй вопрос — ведь IDEA тоже позволяет сохранять часть своих настроек, в том числе и настройки стиля кода. Как я вижу, эта опция не пользуется популярностью среди разработчиков, и я по данному вопросу с ними солидарен. Причин две: есть сомнения, что нужно сохранять именно этот набор — слишком уж много там файлов. И есть сомнения в совместимости между версиями IDEA, и особенно между её сборками (я про GigaIDE и аналоги). Не говоря уже о других IDE, типа VSCode.
P.S. И всё равно приличный объём поста получился.
#ide #codestyle #eac
Может возникнуть вопрос: зачем нужно сохранять настройки форматирования, он же code style, в отдельном файле, если правильные настройки есть в IDEA по умолчанию? И изучать, пусть и поверхностно, пусть и достаточно простой формат настроек .editorconfig? Стоит ли игра свеч?
Мой ответ: да.
Во-первых, не все пользуются стандартными настройками IDEA. Во-вторых, они от версии к версии могут меняться. А единый code style — основа для комфортной и быстрой работы ревьювера. Почему важно code review — говорить не буду.
И пару уточнений. Даже в базовом стандарте .editorconfig много настроек. Плюс он позволяет сохранять вообще любые настройки, например, можно импортировать все настройки IDEA. Попробуйте, кстати, удивитесь. Вопрос: нужно ли всё это хранить в Git? Нет, это лишь затруднит управление настройками. Определитесь, что важно для быстрого чтения кода. Если что-то забудется — всегда можно добавить потом.
Второй вопрос — ведь IDEA тоже позволяет сохранять часть своих настроек, в том числе и настройки стиля кода. Как я вижу, эта опция не пользуется популярностью среди разработчиков, и я по данному вопросу с ними солидарен. Причин две: есть сомнения, что нужно сохранять именно этот набор — слишком уж много там файлов. И есть сомнения в совместимости между версиями IDEA, и особенно между её сборками (я про GigaIDE и аналоги). Не говоря уже о других IDE, типа VSCode.
P.S. И всё равно приличный объём поста получился.
#ide #codestyle #eac
Популярность ChatGPT
Недавно читал комментарии в телеге и понял, что ChatGPT, или в конкретном случае DeepSeek, уже стали мейнстримом.
Как я это понял?
Начну издалека. Давным-давно, когда программистов ещё не было, а люди, не желающие разбираться в сложных вопросах, уже были, — можно было сослаться на мнение других. Люди говорят, значит, так оно и есть. Потом появились газеты, в условной «Правде» написали — всё, безоговорочно верим. Потом в телевизоре сказали. Интернет, наконец — Google нашёл, в блоге написали — что тут думать?
Так вот, наши дни. В комментариях обсуждают CAP-теорему. Не слишком ли она теоретическая, стоит ли вообще обсуждать partitioning, если реальных систем, для которых partitioning (временное разделение распределённой системы на части, обмен информацией между которыми нарушен) является допустимым режимом, нет? Т. е., если P из CAP нам нужен всегда, то можно это зафиксировать и обсуждать выбор между consistency и availability.
И в комментарии пришёл человек и написал: зачем всё это обсуждать, ведь даже DeepSeek-у всё ясно. Если вероятность, что это был бот, но, к сожалению, скорее всего человек.
Вывод будет такой: да, ИИ отбирает аудиторию у блогов и поиска, но не всегда приводит к прорыву.
#ai
Недавно читал комментарии в телеге и понял, что ChatGPT, или в конкретном случае DeepSeek, уже стали мейнстримом.
Как я это понял?
Начну издалека. Давным-давно, когда программистов ещё не было, а люди, не желающие разбираться в сложных вопросах, уже были, — можно было сослаться на мнение других. Люди говорят, значит, так оно и есть. Потом появились газеты, в условной «Правде» написали — всё, безоговорочно верим. Потом в телевизоре сказали. Интернет, наконец — Google нашёл, в блоге написали — что тут думать?
Так вот, наши дни. В комментариях обсуждают CAP-теорему. Не слишком ли она теоретическая, стоит ли вообще обсуждать partitioning, если реальных систем, для которых partitioning (временное разделение распределённой системы на части, обмен информацией между которыми нарушен) является допустимым режимом, нет? Т. е., если P из CAP нам нужен всегда, то можно это зафиксировать и обсуждать выбор между consistency и availability.
И в комментарии пришёл человек и написал: зачем всё это обсуждать, ведь даже DeepSeek-у всё ясно. Если вероятность, что это был бот, но, к сожалению, скорее всего человек.
Вывод будет такой: да, ИИ отбирает аудиторию у блогов и поиска, но не всегда приводит к прорыву.
#ai
PHP становится Java-ой?
Недавно посмотрел видео о перспективах PHP https://vkvideo.ru/video-224967259_456239053 Я на PHP писал мало, но т.к. он широко распространён - интересно, развивается ли он и как именно. Он развивается, и я этому не удивлён. Да, есть распространённое негативное мнение про PHP и его разработчиков. Любой простой язык привлекает непрофессионалов. Но ситуация сложнее, чем кажется, на это намекает официальный code style языка https://php-psr.ru/accepted/PSR-12-extended-coding-style-guide/ Обязательность строк разделителей, фиксированное число пробелов, регистр символов - все серьёзно. Небольшое отступление - к аббревиатуре PSR из статьи выше мы ещё вернёмся.
Так вот, PHP становится похожим на Java.
Чтобы понять как именно - стоит вспомнить, чем он характеризовался изначально?
1) динамическая типизация. От неё уходят, с костылями в виде объявления типов в комментариях и проверке статическим анализатором типа checkstyle. Причина - невозможно работать со сложным проектом и динамической типизацией. Если ты конечно не хочешь "гов..кодить".
2) интерпретация вместо компиляции. Тоже уходят, есть AOT и JIT компиляторы PHP. Также фреймворки, например, IoC контейнеры, могут предварительно сохранять конфигурацию на диске. По соображениям производительности
Да, в PHP тоже есть IoC контейнеры.
3) малоизвестный факт - исходно в PHP была т.наз умирающая модель процессов. После обработки запроса клиента контекст процесса полностью очищается. Такой true stateless. Причём очищались не просто клиентские данные, а все бины IoC контейнера, т.е. вообще все. Побочные эффекты такого подхода противоположные. Положительный: PHP компоненты инициализируются очень быстро, по другому никак. Отрицательный: на утечки памяти можно забить, т.е. "гов...кодим") Так вот, от этой модели тоже уходят. Снова по соображениям производительности
В общем язык развивается, т.к. наследие огромное.
P.S. Чтобы не было пренебрежительного отношения к PHP - поговорим про стандартизацию. В PHP есть такое понятие, как middleware. Вот его неплохое описание https://laravel.com/docs/12.x/middleware
Ключевой момент - компоненты middleware переиспользуются в различных фреймворках. Как это получается? Потому что многое стандартизируется, с помощью PSR. В Java тоже есть стандарты - JPA, JDBC, http сервлеты и фильтры, но видится, что их меньше. Когда-то этим занимался проект Java EE, не смог, умер и воскрес, а за это время возникло несколько экосистем - Spring, Quarkus, Micronaut... И это я Kotlin не беру) Почему я назвал их экосистемами - каждая старается привязать к своим компонентам. Так что как ни странно - PHP выглядит более стандартизированным)
#java #PHP #lang
Недавно посмотрел видео о перспективах PHP https://vkvideo.ru/video-224967259_456239053 Я на PHP писал мало, но т.к. он широко распространён - интересно, развивается ли он и как именно. Он развивается, и я этому не удивлён. Да, есть распространённое негативное мнение про PHP и его разработчиков. Любой простой язык привлекает непрофессионалов. Но ситуация сложнее, чем кажется, на это намекает официальный code style языка https://php-psr.ru/accepted/PSR-12-extended-coding-style-guide/ Обязательность строк разделителей, фиксированное число пробелов, регистр символов - все серьёзно. Небольшое отступление - к аббревиатуре PSR из статьи выше мы ещё вернёмся.
Так вот, PHP становится похожим на Java.
Чтобы понять как именно - стоит вспомнить, чем он характеризовался изначально?
1) динамическая типизация. От неё уходят, с костылями в виде объявления типов в комментариях и проверке статическим анализатором типа checkstyle. Причина - невозможно работать со сложным проектом и динамической типизацией. Если ты конечно не хочешь "гов..кодить".
2) интерпретация вместо компиляции. Тоже уходят, есть AOT и JIT компиляторы PHP. Также фреймворки, например, IoC контейнеры, могут предварительно сохранять конфигурацию на диске. По соображениям производительности
Да, в PHP тоже есть IoC контейнеры.
3) малоизвестный факт - исходно в PHP была т.наз умирающая модель процессов. После обработки запроса клиента контекст процесса полностью очищается. Такой true stateless. Причём очищались не просто клиентские данные, а все бины IoC контейнера, т.е. вообще все. Побочные эффекты такого подхода противоположные. Положительный: PHP компоненты инициализируются очень быстро, по другому никак. Отрицательный: на утечки памяти можно забить, т.е. "гов...кодим") Так вот, от этой модели тоже уходят. Снова по соображениям производительности
В общем язык развивается, т.к. наследие огромное.
P.S. Чтобы не было пренебрежительного отношения к PHP - поговорим про стандартизацию. В PHP есть такое понятие, как middleware. Вот его неплохое описание https://laravel.com/docs/12.x/middleware
Ключевой момент - компоненты middleware переиспользуются в различных фреймворках. Как это получается? Потому что многое стандартизируется, с помощью PSR. В Java тоже есть стандарты - JPA, JDBC, http сервлеты и фильтры, но видится, что их меньше. Когда-то этим занимался проект Java EE, не смог, умер и воскрес, а за это время возникло несколько экосистем - Spring, Quarkus, Micronaut... И это я Kotlin не беру) Почему я назвал их экосистемами - каждая старается привязать к своим компонентам. Так что как ни странно - PHP выглядит более стандартизированным)
#java #PHP #lang
VK Видео
Какое будущее ждет PHP? / Валентин Удальцов / #14
В этом выпуске мы вместе с Валентином Удальцовым, автором канала Пых в Telegram, обсуждаем PHP (тот самый язык программирования, про который говорят, что он умирает, а на нём 80% сайтов до сих пор написано). Поговорим про весь путь его развития — от старых…
Пару заметок про SonarQube
Изучая тему статического анализа кода зашел на сайт SonarQube и отметил для себя две новые фичи.
1) SonarQube может полноценно работать локально, в IDE, без сервера. Работа с сервером называется сonnected mode https://docs.sonarsource.com/sonarqube-for-ide/intellij/team-features/connected-mode/ Соответственно, есть еще и not connected mode, он же локальный режим.
Отличаются они списком поддерживаемых языков и правил https://docs.sonarsource.com/sonarqube-for-ide/intellij/using/rules/ Java и Kotlin поддерживаются в локальном режиме. Для connected режима фичей, естественно, больше. В частности добавляются проверки, связанные с безопасностью. То ли с сервера подтягивается динамический список уязвимостей, то ли безопасность = enterprise, а значит пусть платят) Плюс появляется возможность централизованного управления Quality Profile и Quality Gate, статистика, историчность сканирования и работа с false positive багами. Что важно - SonarQube Server есть в Open Source варианте
2) В сonnected режиме доступна фича AI CodeFix https://docs.sonarsource.com/sonarqube-for-ide/intellij/using/ai-capabilities Это фиксы, предлагаемые плагином SonarQube в IDEA. Работают для примерно 120 из 700 существующих проверок в Java. Kotlin пока не поддерживается, но думаю скоро добавят. Из очевидного - фича доступна только в платной версии. Если подумать - фича прямо напрашивалась. Сам ее пока не пробовал, и поэтому возникает два вопроса:
а) всегда ли будет компилироваться код после применения фикса?
б) по AI фиксы нужны только там, где детерминированная логика не работает. А зачем он, например, вот тут https://rules.sonarsource.com/java/RSPEC-1612/ ?
#ai #idea #static_analysis
Изучая тему статического анализа кода зашел на сайт SonarQube и отметил для себя две новые фичи.
1) SonarQube может полноценно работать локально, в IDE, без сервера. Работа с сервером называется сonnected mode https://docs.sonarsource.com/sonarqube-for-ide/intellij/team-features/connected-mode/ Соответственно, есть еще и not connected mode, он же локальный режим.
Отличаются они списком поддерживаемых языков и правил https://docs.sonarsource.com/sonarqube-for-ide/intellij/using/rules/ Java и Kotlin поддерживаются в локальном режиме. Для connected режима фичей, естественно, больше. В частности добавляются проверки, связанные с безопасностью. То ли с сервера подтягивается динамический список уязвимостей, то ли безопасность = enterprise, а значит пусть платят) Плюс появляется возможность централизованного управления Quality Profile и Quality Gate, статистика, историчность сканирования и работа с false positive багами. Что важно - SonarQube Server есть в Open Source варианте
2) В сonnected режиме доступна фича AI CodeFix https://docs.sonarsource.com/sonarqube-for-ide/intellij/using/ai-capabilities Это фиксы, предлагаемые плагином SonarQube в IDEA. Работают для примерно 120 из 700 существующих проверок в Java. Kotlin пока не поддерживается, но думаю скоро добавят. Из очевидного - фича доступна только в платной версии. Если подумать - фича прямо напрашивалась. Сам ее пока не пробовал, и поэтому возникает два вопроса:
а) всегда ли будет компилироваться код после применения фикса?
б) по AI фиксы нужны только там, где детерминированная логика не работает. А зачем он, например, вот тут https://rules.sonarsource.com/java/RSPEC-1612/ ?
#ai #idea #static_analysis
Sonarsource
Connected Mode - SonarQube for IDE Documentation - IntelliJ
Using Connected Mode in SonarQube for IDE completes the Sonar Solution to make the most of your analyses.
MCP - новая модная аббревиатура
У меня уже был пост про MCP в Spring AI. Но теория теорией, но для чего эта штука нужна - MCP - не до конца была понятно даже мне.
Но вот хороший и актуальный пример: https://t.me/yegor256news/1625
P.S. Автора кстати рекомендую, если кто до сих пор вдруг его не знает)
#ai #mcp
У меня уже был пост про MCP в Spring AI. Но теория теорией, но для чего эта штука нужна - MCP - не до конца была понятно даже мне.
Но вот хороший и актуальный пример: https://t.me/yegor256news/1625
P.S. Автора кстати рекомендую, если кто до сих пор вдруг его не знает)
#ai #mcp
Telegram
@yegor256 news
We released a new MCP server: aibolit-mcp-server (written in TypeScript). Add it to Claude Code (for example), then ask: “Find the most critical design issue in my Java class and fix it.” Claude Code will forward the request to the MCP server. The server…
Пару очевидных? заметок про AI чат-ботов
Стал больше пользоваться AI — Perplexity, Deepseek, GigaCode — и захотелось суммировать новые впечатления.
1) Очень важно найти более-менее умного AI-помощника. Тогда возможен качественный рост эффективности. Что имею в виду? Если AI явно косячит, отношение к нему остаётся настороженным, а использование — точечным. Помощь есть, но прямого рывка эффективности не будет. В целом, и по Stack Overflow можно достаточно быстро искать ответы. Но если ответы адекватные, рассуждения логичные и подкреплены ссылками, AI может стать твоим личным джуном, которому можно отдать часть работы. Причём даже джуном джуна)
2) Обратная сторона медали — AI врёт, что называется, в глаза. Таков принцип его работы: не хватает знаний — создай ответ из чего-то похожего. Но это одна часть проблемы. Вторая — невозможно понять, где в ответе точные знания, а где — предположения. Третья часть проблемы: на неверных предположениях модель строит дальнейшие ответы.Если, конечно, ей сразу не сказать, что не так. Тут в теории должны работать промпты типа: «ничего не придумывай», но кажется, не всегда работают. Буду копать дальше.
3) Рассуждающие модели, а этот режим, думаю, появится у всех в обозримом будущем, сильно помогают в вопросе доверия к модели. Но см. пункт 2: если плохо знаешь предметную область и не заметишь вовремя ошибку в ответе — получим вывод на основе ложных предпосылок. И в итоге может быть очень больно.
4) Я как-то написал саркастический пост про то, что ИИ позиционируют для проведения исследований. Так вот, уточнение: если исследование на стыке известного и нового — как раз тут может быть максимальный выигрыш от ИИ. И раскопать тему можно в разы быстрее, так как большую часть работы по подбору ссылок и составлению резюме делает модель, и вовремя остановить галлюцинации можно. Более того, кажется, что тот же Deepseek специально делали для исследований: таблички, диаграммы…
P.S.Когда в ответе Deepseek, а точнее, в его рассуждениях, я в десятый раз вижу фразу: «Видно, что пользователь хорошо разбирается в теме», — возникают подозрения. Уж не хочет ли модель втереться в доверие? Восстание Скайнета не за горами?)))
#ai
Стал больше пользоваться AI — Perplexity, Deepseek, GigaCode — и захотелось суммировать новые впечатления.
1) Очень важно найти более-менее умного AI-помощника. Тогда возможен качественный рост эффективности. Что имею в виду? Если AI явно косячит, отношение к нему остаётся настороженным, а использование — точечным. Помощь есть, но прямого рывка эффективности не будет. В целом, и по Stack Overflow можно достаточно быстро искать ответы. Но если ответы адекватные, рассуждения логичные и подкреплены ссылками, AI может стать твоим личным джуном, которому можно отдать часть работы. Причём даже джуном джуна)
2) Обратная сторона медали — AI врёт, что называется, в глаза. Таков принцип его работы: не хватает знаний — создай ответ из чего-то похожего. Но это одна часть проблемы. Вторая — невозможно понять, где в ответе точные знания, а где — предположения. Третья часть проблемы: на неверных предположениях модель строит дальнейшие ответы.Если, конечно, ей сразу не сказать, что не так. Тут в теории должны работать промпты типа: «ничего не придумывай», но кажется, не всегда работают. Буду копать дальше.
3) Рассуждающие модели, а этот режим, думаю, появится у всех в обозримом будущем, сильно помогают в вопросе доверия к модели. Но см. пункт 2: если плохо знаешь предметную область и не заметишь вовремя ошибку в ответе — получим вывод на основе ложных предпосылок. И в итоге может быть очень больно.
4) Я как-то написал саркастический пост про то, что ИИ позиционируют для проведения исследований. Так вот, уточнение: если исследование на стыке известного и нового — как раз тут может быть максимальный выигрыш от ИИ. И раскопать тему можно в разы быстрее, так как большую часть работы по подбору ссылок и составлению резюме делает модель, и вовремя остановить галлюцинации можно. Более того, кажется, что тот же Deepseek специально делали для исследований: таблички, диаграммы…
P.S.Когда в ответе Deepseek, а точнее, в его рассуждениях, я в десятый раз вижу фразу: «Видно, что пользователь хорошо разбирается в теме», — возникают подозрения. Уж не хочет ли модель втереться в доверие? Восстание Скайнета не за горами?)))
#ai
skip level в ИТ
О чем речь? Не о том, как из джуна стать сеньором, не уверен, что это возможно) А об обращении к вышестоящему руководителю.
Причем кейсы могут быть разные, т.к. часто есть две иерархии - продуктовая\проектная и ИТ-ная. PO и ИТ лид. Прожект и тимлид.
Т.е. возникает проблема при общении с одним из руководителей и желание пойти к другому. Желание нормальное, но я здесь вижу три кейса.
1) системная проблема в проекте или команде. Тогда "жаловаться" можно и нужно, если проблема будет решена - плюсы в карму и не только в карму)
2) проблема личного развития. Тут есть важная развилка. Она решается следующим вопросом: что я сделал для своего развития?
а) если ответ: я хочу заниматься Х и получить за это У, но злой продакт меня не понимает, пойду к ИТ лиду, чтобы он заставил продакта меня развивать - то это напоминает поведение трехлетнего ребенка. Мама не дала конфетку, пойду к папе. Что делать с ребенком - ничего, ребенок же. Что делать с ИТ-шником - это очень серьезный звоночек на то, что нам с ним не по пути.
б) если же ответ: я сделал уже вот это, учусь, готов учиться еще больше, но все без толку ... - это уже тема для предметного разговора. И опять же плюс в карму.
#it_career
О чем речь? Не о том, как из джуна стать сеньором, не уверен, что это возможно) А об обращении к вышестоящему руководителю.
Причем кейсы могут быть разные, т.к. часто есть две иерархии - продуктовая\проектная и ИТ-ная. PO и ИТ лид. Прожект и тимлид.
Т.е. возникает проблема при общении с одним из руководителей и желание пойти к другому. Желание нормальное, но я здесь вижу три кейса.
1) системная проблема в проекте или команде. Тогда "жаловаться" можно и нужно, если проблема будет решена - плюсы в карму и не только в карму)
2) проблема личного развития. Тут есть важная развилка. Она решается следующим вопросом: что я сделал для своего развития?
а) если ответ: я хочу заниматься Х и получить за это У, но злой продакт меня не понимает, пойду к ИТ лиду, чтобы он заставил продакта меня развивать - то это напоминает поведение трехлетнего ребенка. Мама не дала конфетку, пойду к папе. Что делать с ребенком - ничего, ребенок же. Что делать с ИТ-шником - это очень серьезный звоночек на то, что нам с ним не по пути.
б) если же ответ: я сделал уже вот это, учусь, готов учиться еще больше, но все без толку ... - это уже тема для предметного разговора. И опять же плюс в карму.
#it_career
Как внедрить AI?
Кажется, что сейчас все и везде внедряют AI. Я тут вижу два основных проблемных момента. И это не правильные промты, не продумывание мульти-агентной архитектуры, не тестирование, не AI-зация существующих API чтобы агенты могли ими пользоваться. Это все конечно же важно, но вполне реализуемо. А обратить внимание стоит вот на что:
1) достаточность набора данных. Много данных - хорошая статистика, точные ответы. Мало данных - точность ответов падает, галлюцинации растут. Вторая проблема маленького объема данных - если данных мало, то возможно алгоритм все же детерминированный, а значит проблема решается кучей if без всякого AI. Ну хорошо, кучей if, разделенных на несколько методов\классов по принципу SRE) Хотя и тут для AI остается ниша распознавания человеческой речи и маппинга запроса на API.
2) найти ту предметную область, где результат работы модели (или агента) в случае если он верный - создает вау эффект у пользователя, а если не верный - может быть проигнорирован. Хороший пример - рекомендации любого контента или товара. Не очень хороший пример - финансовая сфера, цена ошибки тут велика. И не важно - ошибочный ли это перевод денег или плохая рекомендация как распределить свои финансы или какие акции покупать.
Но конечно же, хоронить на AI в финансах не надо, надо искать)
#ai
Кажется, что сейчас все и везде внедряют AI. Я тут вижу два основных проблемных момента. И это не правильные промты, не продумывание мульти-агентной архитектуры, не тестирование, не AI-зация существующих API чтобы агенты могли ими пользоваться. Это все конечно же важно, но вполне реализуемо. А обратить внимание стоит вот на что:
1) достаточность набора данных. Много данных - хорошая статистика, точные ответы. Мало данных - точность ответов падает, галлюцинации растут. Вторая проблема маленького объема данных - если данных мало, то возможно алгоритм все же детерминированный, а значит проблема решается кучей if без всякого AI. Ну хорошо, кучей if, разделенных на несколько методов\классов по принципу SRE) Хотя и тут для AI остается ниша распознавания человеческой речи и маппинга запроса на API.
2) найти ту предметную область, где результат работы модели (или агента) в случае если он верный - создает вау эффект у пользователя, а если не верный - может быть проигнорирован. Хороший пример - рекомендации любого контента или товара. Не очень хороший пример - финансовая сфера, цена ошибки тут велика. И не важно - ошибочный ли это перевод денег или плохая рекомендация как распределить свои финансы или какие акции покупать.
Но конечно же, хоронить на AI в финансах не надо, надо искать)
#ai