Надо задавать вопросы.
Есть такое понятие - "сеньорность". Синоним опыта разработки по сути, насмотренность.
Так вот, один из ее секретов - задавать правильные вопросы.
Какие вопросы правильные? Предположим у меня есть знания в некой предметной области разработки ПО. И я вижу или слышу что-то такое, касающееся этой области, что вызывает у меня вопрос - почему так? Так вот - этот вопрос нужно задать явно. И проанализировать ответ, конечно.
Потенциальные проблемы я вижу две:
1) сеньору или тимлиду может быть просто стыдно задавать "глупые" вопросы. Т.к. это может показать, что он чего-то не знает. Решение - забить на это чувство, не знать что-то - это нормально) По моему опыту до половины вопросов приводят к вскрытию каких-то проблем, причин потенциальных багов или замедления сроков внедрения. Т.е. оно того стоит.
2) если ты плохо знаешь предметную область, например, ты больше ИТ менеджер, чем тимлид. Тогда можно в самом деле можно перебрать с "глупыми" вопросами, что скажется на доверии команды. Тут решения могут быть такие: "покурить" тему перед вопросом, проконсультироваться с независимым экспертом или "прореживать" такие вопросы. В любом случае баги или ошибки будут, вопросы от тимлида команде - это лишь еще одна сеть для ловли багов. А таких сетей должно быть много.
#seniority
Есть такое понятие - "сеньорность". Синоним опыта разработки по сути, насмотренность.
Так вот, один из ее секретов - задавать правильные вопросы.
Какие вопросы правильные? Предположим у меня есть знания в некой предметной области разработки ПО. И я вижу или слышу что-то такое, касающееся этой области, что вызывает у меня вопрос - почему так? Так вот - этот вопрос нужно задать явно. И проанализировать ответ, конечно.
Потенциальные проблемы я вижу две:
1) сеньору или тимлиду может быть просто стыдно задавать "глупые" вопросы. Т.к. это может показать, что он чего-то не знает. Решение - забить на это чувство, не знать что-то - это нормально) По моему опыту до половины вопросов приводят к вскрытию каких-то проблем, причин потенциальных багов или замедления сроков внедрения. Т.е. оно того стоит.
2) если ты плохо знаешь предметную область, например, ты больше ИТ менеджер, чем тимлид. Тогда можно в самом деле можно перебрать с "глупыми" вопросами, что скажется на доверии команды. Тут решения могут быть такие: "покурить" тему перед вопросом, проконсультироваться с независимым экспертом или "прореживать" такие вопросы. В любом случае баги или ошибки будут, вопросы от тимлида команде - это лишь еще одна сеть для ловли багов. А таких сетей должно быть много.
#seniority
Что заменит AI?
Нашел очень хороший пример. Есть такая библиотечка - Datafaker https://www.datafaker.net/. faker - это обманщик если что) Генерирует правдоподобные тестовые данные: имена, улицы и т.д. с помощью разных провайдеров https://www.datafaker.net/documentation/providers/
Полезная штука. Сказал бы я год или два назад. А сейчас смотрим на историю версий https://www.datafaker.net/releases/2.4.2/ и видим, что в 2025 году что-то случилось. Новые версии перестали выходить.
Кейс очень похож на генерацию каркаса приложения https://t.me/javaKotlinDevOps/383, о которой я уже писал. Т.к. закодить можно счетное число вариантов генерации, а в LLM мы можем считать в неком приближении хранятся данные обо всем. Плюс она может что-то генерировать новое исходя из похожести данных. Хотя, последнее может как быть полезным, так и являться галлюцинацией)
#ai #rare_test_libs #unittests
Нашел очень хороший пример. Есть такая библиотечка - Datafaker https://www.datafaker.net/. faker - это обманщик если что) Генерирует правдоподобные тестовые данные: имена, улицы и т.д. с помощью разных провайдеров https://www.datafaker.net/documentation/providers/
Полезная штука. Сказал бы я год или два назад. А сейчас смотрим на историю версий https://www.datafaker.net/releases/2.4.2/ и видим, что в 2025 году что-то случилось. Новые версии перестали выходить.
Кейс очень похож на генерацию каркаса приложения https://t.me/javaKotlinDevOps/383, о которой я уже писал. Т.к. закодить можно счетное число вариантов генерации, а в LLM мы можем считать в неком приближении хранятся данные обо всем. Плюс она может что-то генерировать новое исходя из похожести данных. Хотя, последнее может как быть полезным, так и являться галлюцинацией)
#ai #rare_test_libs #unittests
www.datafaker.net
Random Data Generator for Java and Kotlin - Datafaker
Create fake data for your JVM programs within minutes, using our wide range of more than 250 data providers
Что возвращать при ошибке?
Какие есть варианты?
1) exception
2) false
3) Optional и аналоги
4) NullObject
5) null
Для начала я бы отбросил (ну или отложил для особых случаев) вариант с null. Он давно уже "проклят", как приводящий к NPE.
Оставшиеся варианты я предлагаю разделить на две группы - NullObject vs все остальные
Основная разница между ними - первый не требует немедленной обработки ошибок, другие - требуют. Отсутствие такого требования - это преимущество, т.к. дает нам гибкость. Если надо - проверили на ошибку сразу, не надо - позже. Но у гибкости есть обратная сторона - увеличивается сложность. Т.к. NullObject выглядит как настоящий объект - он может пролезть достаточно далеко по коду. Вплоть до сохранения в БД, где ошибка и произойдёт. Или не произойдёт, что видится ещё худшим вариантом. Итого - для отложенной обработки ошибок NullObject выглядит оптимальным даже учитывая описанные выше риски.
exception vs false vs Optional.
false плох тем, что не дает ничего вернуть из метода. Иногда это ок, но в общем случае - не ок. Ну и method chaining конечно же ломает.
exception vs Optional
Да начала exception бывают checked и unchecked. Первые с точки зрения обработки ошибок надёжнее - сложнее забыть обработать ошибку (если только использовать @sneakythrows и аналоги). Но checked exception имеют свои минусы, не даром нигде, кроме Java, они не прижились.
unchecked exception vs Optional
У exception есть один большой минус. Unchecked exception из чужого, плохо документированного кода, да к тому же возникающий редко - проблема, т.к. может дойти не до того уровня обработки ошибок, который планировался. Еще одна проблема - прерывание потока выполнения. Если этим злоупотреблять - имеем аналог go to, антипаттерн.С другой стороны exception достаточно гибкий - можно отлавливать локально, на уровне сервиса или контроллера или на уровне фреймворка (Spring @ExceptionHandler). Код обработки ошибок может быть любым.
Плюсы Optional - его можно свести либо exception, либо к NullObject. Минусы - если захочешь тащить его выше - читаемость кода ухудшается. Т.е. Optional - это как правило короткоживущий объект. Он не совместим с JPA и с Java сериализацией. Еще важный минус - Optional не предоставляет средств для хранения деталей ошибки. Для меня минусы перевешивают плюсы. И судя по коду, который я вижу - не только для меня)
Если поставить вопрос: "Когда лучше обработать ошибку?" - то мой ответ: "Лучше сразу, это надёжнее".
Ну и традиционный итог: разработка - искусство компромиссов)
#dev_compromises #null_safety #error_handling
Какие есть варианты?
1) exception
2) false
3) Optional и аналоги
4) NullObject
5) null
Для начала я бы отбросил (ну или отложил для особых случаев) вариант с null. Он давно уже "проклят", как приводящий к NPE.
Оставшиеся варианты я предлагаю разделить на две группы - NullObject vs все остальные
Основная разница между ними - первый не требует немедленной обработки ошибок, другие - требуют. Отсутствие такого требования - это преимущество, т.к. дает нам гибкость. Если надо - проверили на ошибку сразу, не надо - позже. Но у гибкости есть обратная сторона - увеличивается сложность. Т.к. NullObject выглядит как настоящий объект - он может пролезть достаточно далеко по коду. Вплоть до сохранения в БД, где ошибка и произойдёт. Или не произойдёт, что видится ещё худшим вариантом. Итого - для отложенной обработки ошибок NullObject выглядит оптимальным даже учитывая описанные выше риски.
exception vs false vs Optional.
false плох тем, что не дает ничего вернуть из метода. Иногда это ок, но в общем случае - не ок. Ну и method chaining конечно же ломает.
exception vs Optional
Да начала exception бывают checked и unchecked. Первые с точки зрения обработки ошибок надёжнее - сложнее забыть обработать ошибку (если только использовать @sneakythrows и аналоги). Но checked exception имеют свои минусы, не даром нигде, кроме Java, они не прижились.
unchecked exception vs Optional
У exception есть один большой минус. Unchecked exception из чужого, плохо документированного кода, да к тому же возникающий редко - проблема, т.к. может дойти не до того уровня обработки ошибок, который планировался. Еще одна проблема - прерывание потока выполнения. Если этим злоупотреблять - имеем аналог go to, антипаттерн.С другой стороны exception достаточно гибкий - можно отлавливать локально, на уровне сервиса или контроллера или на уровне фреймворка (Spring @ExceptionHandler). Код обработки ошибок может быть любым.
Плюсы Optional - его можно свести либо exception, либо к NullObject. Минусы - если захочешь тащить его выше - читаемость кода ухудшается. Т.е. Optional - это как правило короткоживущий объект. Он не совместим с JPA и с Java сериализацией. Еще важный минус - Optional не предоставляет средств для хранения деталей ошибки. Для меня минусы перевешивают плюсы. И судя по коду, который я вижу - не только для меня)
Если поставить вопрос: "Когда лучше обработать ошибку?" - то мой ответ: "Лучше сразу, это надёжнее".
Ну и традиционный итог: разработка - искусство компромиссов)
#dev_compromises #null_safety #error_handling
Зачистка пропертей
Не люблю фразу "как я уже говорил". Ладно, кого я обманываю)
Но как я уже говорил - рефакторинг и чистка нужна не только коду, но и настройкам. https://t.me/javaKotlinDevOps/328
Проблема в том, что до настроек часто не доходят руки. По понятным причинам - код важнее.
Вот если бы проверку автоматизировать. Например, встроить в процесс сборки.
А пожалуйста https://www.baeldung.com/spring-properties-cleaner
Плагин работает со Spring Properties.
Умеет:
1) находить дубли
2) группировать по объекту настройки (по префиксу ключа настройки по сути)
3) выносить повторяющиеся настройки разных профилей в общий файл properties
4) повторяющиеся части - в отдельные настройки
5) форматировать и удалять лишние пробелы
В целом - рекомендую.
P.S. Искать неиспользуемые настройки не умеет. Но не все сразу)
#spring #configuration
Не люблю фразу "как я уже говорил". Ладно, кого я обманываю)
Но как я уже говорил - рефакторинг и чистка нужна не только коду, но и настройкам. https://t.me/javaKotlinDevOps/328
Проблема в том, что до настроек часто не доходят руки. По понятным причинам - код важнее.
Вот если бы проверку автоматизировать. Например, встроить в процесс сборки.
А пожалуйста https://www.baeldung.com/spring-properties-cleaner
Плагин работает со Spring Properties.
Умеет:
1) находить дубли
2) группировать по объекту настройки (по префиксу ключа настройки по сути)
3) выносить повторяющиеся настройки разных профилей в общий файл properties
4) повторяющиеся части - в отдельные настройки
5) форматировать и удалять лишние пробелы
В целом - рекомендую.
P.S. Искать неиспользуемые настройки не умеет. Но не все сразу)
#spring #configuration
Telegram
(java || kotlin) && devOps
Всем привет!
Я часто вижу в проектах лишние настройки. Как правило, они попадают в проект следующими путями:
1) скопировали из каркаса\образца\соседнего сервиса не задумываясь - нужны эти настройки или нет. Да, принцип "работает - не трогай" встречается…
Я часто вижу в проектах лишние настройки. Как правило, они попадают в проект следующими путями:
1) скопировали из каркаса\образца\соседнего сервиса не задумываясь - нужны эти настройки или нет. Да, принцип "работает - не трогай" встречается…
Жонглирование JDK
Иногда нужно вести разработку нескольких сервисов, требующих разных версий JDK. Или нескольких релизов одного и того же сервиса. Или какое-то ПО на компьютере требует одной версии JDK, а разработка другой.
Все эти проблемы решает утилита jenv.
Неплохая статья по ней https://habr.com/ru/companies/surfstudio/articles/764442/
Прям скопирую оттуда абзац с ключевыми фичами:
1. Управление версиями Java: jenv позволяет установить и использовать несколько версий Java на одной машине.
2. Поддержка различных ОС: jenv может использоваться на macOS, Linux и Windows;
3. Управление переменными окружения Java: jenv может автоматически установить переменные окружения Java;
4. Управление настройками JVM: jenv позволяет настраивать параметры JVM для каждой версии Java, такие как размер кучи, аргументы командной строки и т. д.
Жаль, что я не знал о ней раньше. Рекомендую!
Что важно - утилита следует принципу единой ответственности, поэтому за установку JDK она не отвечает.
Но для этого есть другая утилита - sdkman
Как всегда статья https://www.baeldung.com/java-sdkman-intro
Да, JDK можно ставить любым менеджером пакетов или даже через IDEA.
Но у sdkman очень хороший выбор jdk https://sdkman.io/jdks и не только jdk https://sdkman.io/sdks
И тоже есть поддержка всех 3 основных ОС.
#java #jdk #tools
Иногда нужно вести разработку нескольких сервисов, требующих разных версий JDK. Или нескольких релизов одного и того же сервиса. Или какое-то ПО на компьютере требует одной версии JDK, а разработка другой.
Все эти проблемы решает утилита jenv.
Неплохая статья по ней https://habr.com/ru/companies/surfstudio/articles/764442/
Прям скопирую оттуда абзац с ключевыми фичами:
1. Управление версиями Java: jenv позволяет установить и использовать несколько версий Java на одной машине.
2. Поддержка различных ОС: jenv может использоваться на macOS, Linux и Windows;
3. Управление переменными окружения Java: jenv может автоматически установить переменные окружения Java;
4. Управление настройками JVM: jenv позволяет настраивать параметры JVM для каждой версии Java, такие как размер кучи, аргументы командной строки и т. д.
Жаль, что я не знал о ней раньше. Рекомендую!
Что важно - утилита следует принципу единой ответственности, поэтому за установку JDK она не отвечает.
Но для этого есть другая утилита - sdkman
Как всегда статья https://www.baeldung.com/java-sdkman-intro
Да, JDK можно ставить любым менеджером пакетов или даже через IDEA.
Но у sdkman очень хороший выбор jdk https://sdkman.io/jdks и не только jdk https://sdkman.io/sdks
И тоже есть поддержка всех 3 основных ОС.
#java #jdk #tools
Хабр
jenv — удобный инструмент для управления версиями Java
Иногда может возникнуть необходимость использовать какую-то определенную версию Java для вашего проекта. Мы тоже в Surf с таким столкнулись при работе над одним из Flutter приложений-долгожителей....
Заглушка может стать умной
Я уже писал про заглушки в Java для отладки и тестов - https://t.me/javaKotlinDevOps/344
Там чемпионом по функционалу был WireMock.
Собственно для Java разработчика он им и остается, но есть и альтернатива, пришедшая из мира Go - HoverFly https://docs.hoverfly.io/en/latest/pages/keyconcepts/modes/modes.html
Но имеющая при этом native binding для Java https://docs.hoverfly.io/en/latest/pages/bindings/java.html
Вообще если их сравнивать по основным параметрам:
1) возможность гибкой настройки симуляции и проксирования запросов (spy и mock в терминологии Mockito)
2) захват ответов (capturing)
3) гибкое сопоставление запросов и ответов (request matching)
4) гибкая шаблонизация ответов (response templating): доступ к параметрам запроса, в т.ч. xpath, jsonpath, генерация случайных данных
5) сценарный режим = использование состояния в ответах (stateful mode)
6) проверка запросов в стиле Mockito, пример: verify(exactly(5), postRequestedFor(urlEqualTo("/many")))
7) в целом DSL в стиле Mockito
8) различные источники данных для заглушек: код, json, внешний сервер
9) проксирование запросов прямое и обратное
то будет примерный паритет.
В чем же разница, и зачем я пишу этот пост?
Сначала про плюсы WireMock:
1) Java экосистема и, следовательно, все фичи доступны в Java
2) embedded режим, в котором нет лишних процессов
3) больше встроенных возможностей по симуляции ошибок
4) ориентация на разработчика
Но у HoverFly есть свои "фишки":
1) работа в forward proxy режиме из коробки. Напомню про forward proxy - это то самое окошко в браузере, где можно указать через какой прокси должен проходить весь трафик. Известная реализация - Charles proxy, популярна среди мобильных разработчиков для отладки без бэкэнда. Плюсы такого режима проявляются на тестовых стендах - прозрачный для клиента перехват трафика. WireMock так тоже умеет, но это для него не основной режим https://wiremock.org/docs/proxying/#running-as-a-browser-proxy
2) middleware - к HoverFly можно создавать и подключать свои модули, модифицирующие запросы или генерирующие ответы https://docs.hoverfly.io/en/latest/pages/keyconcepts/middleware.html К сожалению, не на Java. Казалось бы модифицировать поведение заглушки можно в своем коде? Да, но ключевой момент middleware - это простая модульная система, т.е. стандартизация и переиспользование модулей.
3) упор на захват трафика, который выражается в наличии таких интересных режимов https://docs.hoverfly.io/en/latest/pages/keyconcepts/modes/modes.html, как Diff - сравнение реального трафика с заглушкой и Modify - реализует Man in the Middle, т.е. замену трафика на ходу, но не для злоумышленика, а для тестовых целей. Возможности по подмене трафика есть и у WireMock https://wiremock.org/docs/proxying/#remove-path-prefix, но их сильно меньше.
4) наличие CLI API - https://docs.hoverfly.io/en/latest/pages/reference/hoverctl/hoverctlcommands.html
Итог - видится, что HoverFly стоит рассмотреть автоматизаторам тестирования и нагрузочным тестировщикам, и иметь в виду - Java разработчикам.
Еще интересный итог - разработчики и автотестеры используют достаточно много общих инструментов - JUnit, WireMock\HoverFly...
#rare_test_libs #mocks
Я уже писал про заглушки в Java для отладки и тестов - https://t.me/javaKotlinDevOps/344
Там чемпионом по функционалу был WireMock.
Собственно для Java разработчика он им и остается, но есть и альтернатива, пришедшая из мира Go - HoverFly https://docs.hoverfly.io/en/latest/pages/keyconcepts/modes/modes.html
Но имеющая при этом native binding для Java https://docs.hoverfly.io/en/latest/pages/bindings/java.html
Вообще если их сравнивать по основным параметрам:
1) возможность гибкой настройки симуляции и проксирования запросов (spy и mock в терминологии Mockito)
2) захват ответов (capturing)
3) гибкое сопоставление запросов и ответов (request matching)
4) гибкая шаблонизация ответов (response templating): доступ к параметрам запроса, в т.ч. xpath, jsonpath, генерация случайных данных
5) сценарный режим = использование состояния в ответах (stateful mode)
6) проверка запросов в стиле Mockito, пример: verify(exactly(5), postRequestedFor(urlEqualTo("/many")))
7) в целом DSL в стиле Mockito
8) различные источники данных для заглушек: код, json, внешний сервер
9) проксирование запросов прямое и обратное
то будет примерный паритет.
В чем же разница, и зачем я пишу этот пост?
Сначала про плюсы WireMock:
1) Java экосистема и, следовательно, все фичи доступны в Java
2) embedded режим, в котором нет лишних процессов
3) больше встроенных возможностей по симуляции ошибок
4) ориентация на разработчика
Но у HoverFly есть свои "фишки":
1) работа в forward proxy режиме из коробки. Напомню про forward proxy - это то самое окошко в браузере, где можно указать через какой прокси должен проходить весь трафик. Известная реализация - Charles proxy, популярна среди мобильных разработчиков для отладки без бэкэнда. Плюсы такого режима проявляются на тестовых стендах - прозрачный для клиента перехват трафика. WireMock так тоже умеет, но это для него не основной режим https://wiremock.org/docs/proxying/#running-as-a-browser-proxy
2) middleware - к HoverFly можно создавать и подключать свои модули, модифицирующие запросы или генерирующие ответы https://docs.hoverfly.io/en/latest/pages/keyconcepts/middleware.html К сожалению, не на Java. Казалось бы модифицировать поведение заглушки можно в своем коде? Да, но ключевой момент middleware - это простая модульная система, т.е. стандартизация и переиспользование модулей.
3) упор на захват трафика, который выражается в наличии таких интересных режимов https://docs.hoverfly.io/en/latest/pages/keyconcepts/modes/modes.html, как Diff - сравнение реального трафика с заглушкой и Modify - реализует Man in the Middle, т.е. замену трафика на ходу, но не для злоумышленика, а для тестовых целей. Возможности по подмене трафика есть и у WireMock https://wiremock.org/docs/proxying/#remove-path-prefix, но их сильно меньше.
4) наличие CLI API - https://docs.hoverfly.io/en/latest/pages/reference/hoverctl/hoverctlcommands.html
Итог - видится, что HoverFly стоит рассмотреть автоматизаторам тестирования и нагрузочным тестировщикам, и иметь в виду - Java разработчикам.
Еще интересный итог - разработчики и автотестеры используют достаточно много общих инструментов - JUnit, WireMock\HoverFly...
#rare_test_libs #mocks
Telegram
(java || kotlin) && devOps
Всем привет!
Продолжение про тесты, на этот раз интеграционные.
Доминирующий протокол для интеграции сейчас - http(s). REST, GraphQL, разные кастомные реализации. Если мы получаем данные по http - значит где-то есть http client. Он куда-то стучится. Как…
Продолжение про тесты, на этот раз интеграционные.
Доминирующий протокол для интеграции сейчас - http(s). REST, GraphQL, разные кастомные реализации. Если мы получаем данные по http - значит где-то есть http client. Он куда-то стучится. Как…
Обработка ошибок - не только Java
Как справедливо заметил @ort_gorthaur в комментах к посту об обработке исключений в Java https://t.me/javaKotlinDevOps/440
в других языках есть интересные варианты для обработки исключений.
Try в Scala
https://www.baeldung.com/scala/exception-handling
def trySuccessFailure(a: Int, b: Int): Try[Int] = Try {
Calculator.sum(a,b)
}
val result = trySuccessFailure(-1,-2)
result match {
case Failure(e) => assert(e.isInstanceOf[NegativeNumberException])
case Success(_) => fail("Should fail!")
}
Целых два варианта в Kotlin:
Try
https://www.javacodegeeks.com/2017/12/kotlin-try-type-functional-exception-handling.html
fun divideFn(dividend: String, divisor: String): Try<Int> {
val num = Try { dividend.toInt() }
val denom = Try { divisor.toInt() }
return num.flatMap { n -> denom.map { d -> n / d } }
}
val result = divideFn("5t", "4")
when(result) {
is Success -> println("Got ${result.value}")
is Failure -> println("An error : ${result.e}")
}
и Result
https://www.baeldung.com/kotlin/result-class
fun divide(a: Int, b: Int): Result {
return runCatching {
a / b
}
}
val resultValid = divide(10, 2)
assertTrue(resultValid.isSuccess)
assertEquals(5, resultValid.getOrNull())
Тоже два варианта - Option и Result - в Rust
https://habr.com/ru/articles/270371/
fn extension_explicit(file_name: &str) -> Option<&str> {
match find(file_name, '.') {
None => None,
Some(i) => Some(&file_name[i+1..]),
}
}
fn double_number(number_str: &str) -> Result<i32, ParseIntError> {
match number_str.parse::<i32>() {
Ok(n) => Ok(2 * n),
Err(err) => Err(err),
}
}
Основные особенности у всех этих вариантов:
1) автоматическое оборачивание исключения в класс
2) сохранение информации об ошибке
3) сопоставление типа (class pattern matching)
Что интересно, class pattern matching появился в Java в виде JEP 406: Pattern Matching for switch, а значит можно реализовать что-то похожее. Например, вот так:
https://habr.com/ru/articles/721326/
#error_handling #null_safety #java #comparision #kotlin #scala #rust
Как справедливо заметил @ort_gorthaur в комментах к посту об обработке исключений в Java https://t.me/javaKotlinDevOps/440
в других языках есть интересные варианты для обработки исключений.
Try в Scala
https://www.baeldung.com/scala/exception-handling
def trySuccessFailure(a: Int, b: Int): Try[Int] = Try {
Calculator.sum(a,b)
}
val result = trySuccessFailure(-1,-2)
result match {
case Failure(e) => assert(e.isInstanceOf[NegativeNumberException])
case Success(_) => fail("Should fail!")
}
Целых два варианта в Kotlin:
Try
https://www.javacodegeeks.com/2017/12/kotlin-try-type-functional-exception-handling.html
fun divideFn(dividend: String, divisor: String): Try<Int> {
val num = Try { dividend.toInt() }
val denom = Try { divisor.toInt() }
return num.flatMap { n -> denom.map { d -> n / d } }
}
val result = divideFn("5t", "4")
when(result) {
is Success -> println("Got ${result.value}")
is Failure -> println("An error : ${result.e}")
}
и Result
https://www.baeldung.com/kotlin/result-class
fun divide(a: Int, b: Int): Result {
return runCatching {
a / b
}
}
val resultValid = divide(10, 2)
assertTrue(resultValid.isSuccess)
assertEquals(5, resultValid.getOrNull())
Тоже два варианта - Option и Result - в Rust
https://habr.com/ru/articles/270371/
fn extension_explicit(file_name: &str) -> Option<&str> {
match find(file_name, '.') {
None => None,
Some(i) => Some(&file_name[i+1..]),
}
}
fn double_number(number_str: &str) -> Result<i32, ParseIntError> {
match number_str.parse::<i32>() {
Ok(n) => Ok(2 * n),
Err(err) => Err(err),
}
}
Основные особенности у всех этих вариантов:
1) автоматическое оборачивание исключения в класс
2) сохранение информации об ошибке
3) сопоставление типа (class pattern matching)
Что интересно, class pattern matching появился в Java в виде JEP 406: Pattern Matching for switch, а значит можно реализовать что-то похожее. Например, вот так:
https://habr.com/ru/articles/721326/
#error_handling #null_safety #java #comparision #kotlin #scala #rust
Telegram
(java || kotlin) && devOps
Что возвращать при ошибке?
Какие есть варианты?
1) exception
2) false
3) Optional и аналоги
4) NullObject
5) null
Для начала я бы отбросил (ну или отложил для особых случаев) вариант с null. Он давно уже "проклят", как приводящий к NPE.
Оставшиеся варианты…
Какие есть варианты?
1) exception
2) false
3) Optional и аналоги
4) NullObject
5) null
Для начала я бы отбросил (ну или отложил для особых случаев) вариант с null. Он давно уже "проклят", как приводящий к NPE.
Оставшиеся варианты…
AI на практике или учимся читать с помощью AI)
Вот есть неплохая статья - введение в тему работы с ElasticSearch и JPA на Java+Spring https://habr.com/ru/companies/rostelecom/articles/851658/
Всем она хороша, кроме одного - 1700 строк, 120 кб текста, время для чтения - 41 минута. И как нетрудно догадаться - статья покрывает все основные темы по поиску с помощью Elasticsearch, но там прям много воды. Может автору за символы платят, хз)
Но повторюсь по сути все ок.
И тут казалось бы - вот звездный час AI. Тем более они теперь с интернетом дружат.
Скормил статью разным AI чатам, попросил сократить, сохранив код, основные классификации и описания атрибутов.
Итоги такие:
0) вне конкурса - пересказ в браузере Яндекс. Сокращает - отлично, но очень тезисно получается, ничего не понятно. Незачет
1) YaGPT - сказал, что не умеет, отправил на внешние сайты. Незачет
2) DeepSeek - полное фиаско. Во-первых забавный факт - когда я забыл отжать галочку: "искать в вебе" - модель стала пересказывать какую-то левую статью про работу с LLM. Включил галочку - модель увидела в ссылке слово rostelecom и стала пересказывать тарифы оператора. Ок, включаю режим рассуждений. Снова мимо, причем с дико странной формулировкой: "Мы не можем напрямую загрузить и обработать веб-страницу, но я могу вспомнить или найти ключевые моменты статьи, основываясь на ее содержании, если я с ней знаком." И далее снова левая статья и ее пересказ. В общем No comments, не пересказ - не конек DeepSeek
3) GigaChat - пересказал всю статью, сильно лучше Яндекс браузера, но потом пошли глюки. В первой версии пересказа был только код, почти без текста. Непонятно. Попросил добавить текста - исчез весь код. Попросил совместить - начал придумывать какие-то левые классы, т.е. потерял контекст. Еще работает медленно. Незачет
4) Perplexity - в целом неплохо пересказал с первого раза. Но - потерял последнюю треть документа - похоже на оптимизацию. Добавил недостающее после указания конкретных глав. Если просишь добавить без конкретики какие главы пропущены - все равно пропускает. Причем чем больше просишь - тем компактнее становится итоговый текст, т.е. видно, что модель экономит контекст. Еще минусы:
а) переставляет местами главы, причем не релевантно смыслу.
б) оставляет мало текста, приходится просить добавлять текстовые описания для атрибутов и вариантов реализации
5) Mistral - примерно все тоже самое, только в первой версии пересказа вообще практически не было текста, только код. Хотя просил я другое. После просьбы добавить текста - добавил. В остальном работает также, как Perplexity, с теми же минусами
Вывод: похоже с первого раза выдать нормальный пересказ большой статьи современные LLM не могут. И это даже не книга. Причина в оптимизации из-за ограниченного контекста. Но в режиме переписки работать можно.
P.S. И статья на 120 кб - это конечно перебор) Я люблю читать - но все равно перебор)
#ai #llm #elasticsearch #java #spring
Вот есть неплохая статья - введение в тему работы с ElasticSearch и JPA на Java+Spring https://habr.com/ru/companies/rostelecom/articles/851658/
Всем она хороша, кроме одного - 1700 строк, 120 кб текста, время для чтения - 41 минута. И как нетрудно догадаться - статья покрывает все основные темы по поиску с помощью Elasticsearch, но там прям много воды. Может автору за символы платят, хз)
Но повторюсь по сути все ок.
И тут казалось бы - вот звездный час AI. Тем более они теперь с интернетом дружат.
Скормил статью разным AI чатам, попросил сократить, сохранив код, основные классификации и описания атрибутов.
Итоги такие:
0) вне конкурса - пересказ в браузере Яндекс. Сокращает - отлично, но очень тезисно получается, ничего не понятно. Незачет
1) YaGPT - сказал, что не умеет, отправил на внешние сайты. Незачет
2) DeepSeek - полное фиаско. Во-первых забавный факт - когда я забыл отжать галочку: "искать в вебе" - модель стала пересказывать какую-то левую статью про работу с LLM. Включил галочку - модель увидела в ссылке слово rostelecom и стала пересказывать тарифы оператора. Ок, включаю режим рассуждений. Снова мимо, причем с дико странной формулировкой: "Мы не можем напрямую загрузить и обработать веб-страницу, но я могу вспомнить или найти ключевые моменты статьи, основываясь на ее содержании, если я с ней знаком." И далее снова левая статья и ее пересказ. В общем No comments, не пересказ - не конек DeepSeek
3) GigaChat - пересказал всю статью, сильно лучше Яндекс браузера, но потом пошли глюки. В первой версии пересказа был только код, почти без текста. Непонятно. Попросил добавить текста - исчез весь код. Попросил совместить - начал придумывать какие-то левые классы, т.е. потерял контекст. Еще работает медленно. Незачет
4) Perplexity - в целом неплохо пересказал с первого раза. Но - потерял последнюю треть документа - похоже на оптимизацию. Добавил недостающее после указания конкретных глав. Если просишь добавить без конкретики какие главы пропущены - все равно пропускает. Причем чем больше просишь - тем компактнее становится итоговый текст, т.е. видно, что модель экономит контекст. Еще минусы:
а) переставляет местами главы, причем не релевантно смыслу.
б) оставляет мало текста, приходится просить добавлять текстовые описания для атрибутов и вариантов реализации
5) Mistral - примерно все тоже самое, только в первой версии пересказа вообще практически не было текста, только код. Хотя просил я другое. После просьбы добавить текста - добавил. В остальном работает также, как Perplexity, с теми же минусами
Вывод: похоже с первого раза выдать нормальный пересказ большой статьи современные LLM не могут. И это даже не книга. Причина в оптимизации из-за ограниченного контекста. Но в режиме переписки работать можно.
P.S. И статья на 120 кб - это конечно перебор) Я люблю читать - но все равно перебор)
#ai #llm #elasticsearch #java #spring
Хабр
Полнотекстовый поиск в java приложениях с помощью Elasticsearch
Введение В современном мире объёмы данных растут экспоненциально, и эффективное управление информацией становится критически важным для успеха любого приложения. Полнотекстовый поиск играет ключевую...
Пост для AI скептиков.
Собственно вот https://www.reuters.com/business/ai-slows-down-some-experienced-software-developers-study-finds-2025-07-10/
Результат неожиданный для меня.
То, что не любой код проще писать с помощью AI - да, понятно. Но тот факт, что в целом производительность может упасть - мне даже объяснить сложно...
Из того, что пришло на ум - сеньоры не пишут типовой код, часто дорабатывают существующие core сервисы, потому AI агенты плохо понимают их требования. Ну и, соответственно, код приходится долго допиливать до нужного состояния.
И второе условие - похоже их заставили писать весь код с помощью AI.
Ваши идеи на этот счёт?
#ai
Собственно вот https://www.reuters.com/business/ai-slows-down-some-experienced-software-developers-study-finds-2025-07-10/
Результат неожиданный для меня.
То, что не любой код проще писать с помощью AI - да, понятно. Но тот факт, что в целом производительность может упасть - мне даже объяснить сложно...
Из того, что пришло на ум - сеньоры не пишут типовой код, часто дорабатывают существующие core сервисы, потому AI агенты плохо понимают их требования. Ну и, соответственно, код приходится долго допиливать до нужного состояния.
И второе условие - похоже их заставили писать весь код с помощью AI.
Ваши идеи на этот счёт?
#ai
Reuters
AI slows down some experienced software developers, study finds
Contrary to popular belief, using cutting-edge artificial intelligence tools slowed down experienced software developers when they were working in codebases familiar to them, rather than supercharging their work, a new study found.
Борьба с длинной контекста
Два поста назад я проводил эксперимент с LLM - пытался прочитать статью быстрее, скормив ее AI и попросив пересказать.
Ни одна из протестированных моделей с этим не справилась с первого раза, в лучшем случае приходилось подсказывать с указанием пропущенных при пересказе частей.
И я уверен, что причиной является ограниченность контекста модели.
Есть ли тут выход?
Но во-первых очевидный - линейное увеличение размера контекста модели.
Но есть и менее тяжелый с точки зрения железа вариант.
Совместить LLM c RAG.
Документ, или набор документов загружается в RAG. Это фаза анализа.
Далее можно задавать вопросы по загруженному контенту.
Можно даже базовые вопросы вынести в UI - сформируй оглавление, перескажи...
Основной "прикол" такой архитектуры - данные хранятся не в контексте, а в RAG-е, не вытесняются из него с новыми запрсоами.
А при запросе пользователя вначале производится "поиск" в RAG и обогащение контекста, далее - запрос к LLM модели. Самое главное - при этом передается только часть содержимого RAG.
Инструментов с такой архитектурой много, вот здесь проведено небольшое исследование https://dzen.ru/a/Zu8KfXtWcUk-ngpo?ysclid=mczw93o1xo25962418
Причем есть и локальные версии, где на сервер "к дяде" ничего не передается.
Я же попробовал скормить ту же статью NotebookLM (статья общедоступная, решил не заморачиваться).
И результат был существенно лучше: я с первого раза получил полный пересказ без пропусков глав в том же порядке, как и в исходной статье.
Но не идеален - в статье много кода, и весь код уехал в сноски. В целом подход нормальный для всех, кроме разработчиков(
Как заставить NotebookLM не прятать код под сноски - не нашел( Возможно, не был достаточно убедителен) Возможно - системные промты сильнее)
Кажется это был бы последний штрих для идеального инструмента...
#ai #llm #rag
Два поста назад я проводил эксперимент с LLM - пытался прочитать статью быстрее, скормив ее AI и попросив пересказать.
Ни одна из протестированных моделей с этим не справилась с первого раза, в лучшем случае приходилось подсказывать с указанием пропущенных при пересказе частей.
И я уверен, что причиной является ограниченность контекста модели.
Есть ли тут выход?
Но во-первых очевидный - линейное увеличение размера контекста модели.
Но есть и менее тяжелый с точки зрения железа вариант.
Совместить LLM c RAG.
Документ, или набор документов загружается в RAG. Это фаза анализа.
Далее можно задавать вопросы по загруженному контенту.
Можно даже базовые вопросы вынести в UI - сформируй оглавление, перескажи...
Основной "прикол" такой архитектуры - данные хранятся не в контексте, а в RAG-е, не вытесняются из него с новыми запрсоами.
А при запросе пользователя вначале производится "поиск" в RAG и обогащение контекста, далее - запрос к LLM модели. Самое главное - при этом передается только часть содержимого RAG.
Инструментов с такой архитектурой много, вот здесь проведено небольшое исследование https://dzen.ru/a/Zu8KfXtWcUk-ngpo?ysclid=mczw93o1xo25962418
Причем есть и локальные версии, где на сервер "к дяде" ничего не передается.
Я же попробовал скормить ту же статью NotebookLM (статья общедоступная, решил не заморачиваться).
И результат был существенно лучше: я с первого раза получил полный пересказ без пропусков глав в том же порядке, как и в исходной статье.
Но не идеален - в статье много кода, и весь код уехал в сноски. В целом подход нормальный для всех, кроме разработчиков(
Как заставить NotebookLM не прятать код под сноски - не нашел( Возможно, не был достаточно убедителен) Возможно - системные промты сильнее)
Кажется это был бы последний штрих для идеального инструмента...
#ai #llm #rag
Дзен | Статьи
AnythingLLM или локальный RAG c человеческим интерфейсом
Статья автора «Нейрошторм» в Дзене ✍: Ниже поговорим о том, как более практично использовать нейросети.
👍1
Единый дистрибутив IntelliJ IDEA сделает жизнь проще
Вопрос кому именно?)
Собственно новость: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/
Суть: Community и Ultimate ставятся одним дистрибутивом, коммерческим.
Раньше Community Edition была open source https://github.com/JetBrains/intellij-community
А чтобы получить Open Source версию нужно собрать ее самому из исходников. Пайплайн для GitLab предоставляется.
Картинка, объясняющая изменения:
https://lh7-rt.googleusercontent.com/docsz/AD_4nXcxDXSX1AFFsk_FYAyjS1E1pTsC112LutXZzgLZx4fGw-pm_OwZeeTBReOvxWIqcAbRdN6CvQywz8xQxJ2KmwG1Url7GzSXSOnUta5wEssY56eXFi2MY2yPe9370dYvQ5vXIjqvyg?key=ZR2g5w9gVWABHMj44SECZQ
Очевидно, что легче станет самим JetBrains - меньше дистрибутивов тестировать.
Разработчикам тоже легче - при переходе с Ultimate на Community и обратно не нужно заново ставить дистрибутив.
Плюс JetBrains бонусом добавили в Community ряд фич из Ultimate: судя по описанию это lite версии плагинов Spring, JPA, Kubernetes и некоторых других с доступной подсветкой синтаксиса и базовый DB Explorer.
А вот в Open source версии ряд старых фичей, не являющихся open source убрали - в частности AI, WSL и синхронизация настроек IDE.
Что получается?
Во-первых - в России нельзя будет скачать без VPN не только плагины, но и саму IDE.
Это не критично, есть VPN.
Во-вторых - в IDEA Community появились фичи, которых там сильно не хватало. А вот использовать их в open source версии для построения на основе их своей IDE - нельзя.
Да, JetBrains на имеет на это полное право.
Но видится, что кроме упрощения жизни себе и пользователям, о чем сказано в статье, у нововведения есть и другая цель - уменьшить отток пользователей на другие IDE. Даже не смотря на VPN.
И об этом в статье не сказано)
#ide #idea
Вопрос кому именно?)
Собственно новость: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/
Суть: Community и Ultimate ставятся одним дистрибутивом, коммерческим.
Раньше Community Edition была open source https://github.com/JetBrains/intellij-community
А чтобы получить Open Source версию нужно собрать ее самому из исходников. Пайплайн для GitLab предоставляется.
Картинка, объясняющая изменения:
https://lh7-rt.googleusercontent.com/docsz/AD_4nXcxDXSX1AFFsk_FYAyjS1E1pTsC112LutXZzgLZx4fGw-pm_OwZeeTBReOvxWIqcAbRdN6CvQywz8xQxJ2KmwG1Url7GzSXSOnUta5wEssY56eXFi2MY2yPe9370dYvQ5vXIjqvyg?key=ZR2g5w9gVWABHMj44SECZQ
Очевидно, что легче станет самим JetBrains - меньше дистрибутивов тестировать.
Разработчикам тоже легче - при переходе с Ultimate на Community и обратно не нужно заново ставить дистрибутив.
Плюс JetBrains бонусом добавили в Community ряд фич из Ultimate: судя по описанию это lite версии плагинов Spring, JPA, Kubernetes и некоторых других с доступной подсветкой синтаксиса и базовый DB Explorer.
А вот в Open source версии ряд старых фичей, не являющихся open source убрали - в частности AI, WSL и синхронизация настроек IDE.
Что получается?
Во-первых - в России нельзя будет скачать без VPN не только плагины, но и саму IDE.
Это не критично, есть VPN.
Во-вторых - в IDEA Community появились фичи, которых там сильно не хватало. А вот использовать их в open source версии для построения на основе их своей IDE - нельзя.
Да, JetBrains на имеет на это полное право.
Но видится, что кроме упрощения жизни себе и пользователям, о чем сказано в статье, у нововведения есть и другая цель - уменьшить отток пользователей на другие IDE. Даже не смотря на VPN.
И об этом в статье не сказано)
#ide #idea
The JetBrains Blog
IntelliJ IDEA Moves to the Unified Distribution | The IntelliJ IDEA Blog
We are excited to announce the next step for IntelliJ IDEA: we are moving to a single, unified distribution. And yes, before you ask, our commitment to open source remains as strong as ever. There
❤1
(java || kotlin) && devOps
Пост для AI скептиков. Собственно вот https://www.reuters.com/business/ai-slows-down-some-experienced-software-developers-study-finds-2025-07-10/ Результат неожиданный для меня. То, что не любой код проще писать с помощью AI - да, понятно. Но тот факт, что…
И ещё мысль по влиянию AI на скорость разработки.
Предположим, в описанном выше кейсе дело было в том, что проект сложный: с большим количеством кастомных правил, многослойная архитектура, сложная доменная модель и все такое.
Тогда занесение в RAG его исходников и, возможно, текстового описания правил кодирования скорее всего сильно увеличило бы качество ответов модели и, соответственно, скорость разработки
Предположим, в описанном выше кейсе дело было в том, что проект сложный: с большим количеством кастомных правил, многослойная архитектура, сложная доменная модель и все такое.
Тогда занесение в RAG его исходников и, возможно, текстового описания правил кодирования скорее всего сильно увеличило бы качество ответов модели и, соответственно, скорость разработки
Должен ли код быть сложным?
Для ответа на данный вопрос предлагаю разделить сложность кода на 2 категории - естественная и, соответственно, искусственная.
Естественная сложность кода будет всегда, т.к. причина ее появления - сложность предметной области. Это может быть сложная логика бизнес-процесса. Или возьмем Spring Core - там достаточно сложный жизненный цикл бинов, множество способов описания этих бинов, способов конфигурации, профили.... Я уже не говорю про JDK: модель байт-кода, компиляция, виртуальная машина, classloading, верификация байт-кода, JIT и оптимизации\отмена оптимизаций, сборка мусора, модель памяти, многопоточка и синхронизация доступа, поддержка различных архитектур процессора и ОС, отладка, профилирование, версионирование и обратная совместимость...
Есть понятные пути борьбы с естественной сложностью - микросервисы, слоистая архитектура, DDD и собственно объектно-ориентированное проектирование. Особенность этой сложности - она будет всегда.
Чего быть не должно - так это искусственной сложности. Причем тут бы я снова выделил две подкатегории:
1) то, на что указывают такие штуки как "большой ком грязи" или "божественный класс". Т.е. когда логика выполнения запутана потому, что за этим перестали следить. Или, в худшем случае, изначально не уделяли внимания проектированию. Усугубляет ситуацию здесь отсутствие базовой документации или ее неактуальность, огромное число ненужных настроек, плохой нейминг. Особенность этой категории сложности - вряд ли кто-то, кто увидит такой код, будет его хвалить. Все признают проблему, в т.ч. авторы. Решение - рефакторинг или переписывание кода с нуля.
2) искусственная сложность, сделанная с соблюдением принципов SOLID, ООП и слоистой архитектуры. Типичный пример здесь: микросервис с минимумом бизнес-логики, который можно сделать с использованием паттерна Transaction Script, но вместо этого появляется 3+ слоя, доменная модель, куча интерфейсов с одной реализацией, цепочка из вызовов сервисов, каждый из которых отвечает за одну функциональность по SOLID - авторизация, валидация, маппер, мониторинг, аудит, инициализация сетевых параметров, еще маппер, интеграционные логи, Circuit Breaker... Вроде все по правилам, а из простого сервиса сделан монстр, разобраться в котором очень сложно. Хотя на самом деле - правила нарушается. Как минимум правило KISS - Keep It Simple Stupid. Как максимум - не надо в том же Single Responsibility из SOLID идти до конца и для каждой функциональности, занимающей одну строчку код, делать класс. Как минимум делать это прямо сейчас. У нас же архитектура в коде. Код можно менять. В отличие от архитектуры здания, например. А разработка - это искусство компромиссов. Ну а главная проблема этой категории сложности - авторы кода точно ее не признают. Раз пишут такой код)
Итого - с любой сложностью можно и нужно бороться. Но особенно вредна искусственная сложность. По определению)
#arch #solid #complexity #principles #dev_compomisses
Для ответа на данный вопрос предлагаю разделить сложность кода на 2 категории - естественная и, соответственно, искусственная.
Естественная сложность кода будет всегда, т.к. причина ее появления - сложность предметной области. Это может быть сложная логика бизнес-процесса. Или возьмем Spring Core - там достаточно сложный жизненный цикл бинов, множество способов описания этих бинов, способов конфигурации, профили.... Я уже не говорю про JDK: модель байт-кода, компиляция, виртуальная машина, classloading, верификация байт-кода, JIT и оптимизации\отмена оптимизаций, сборка мусора, модель памяти, многопоточка и синхронизация доступа, поддержка различных архитектур процессора и ОС, отладка, профилирование, версионирование и обратная совместимость...
Есть понятные пути борьбы с естественной сложностью - микросервисы, слоистая архитектура, DDD и собственно объектно-ориентированное проектирование. Особенность этой сложности - она будет всегда.
Чего быть не должно - так это искусственной сложности. Причем тут бы я снова выделил две подкатегории:
1) то, на что указывают такие штуки как "большой ком грязи" или "божественный класс". Т.е. когда логика выполнения запутана потому, что за этим перестали следить. Или, в худшем случае, изначально не уделяли внимания проектированию. Усугубляет ситуацию здесь отсутствие базовой документации или ее неактуальность, огромное число ненужных настроек, плохой нейминг. Особенность этой категории сложности - вряд ли кто-то, кто увидит такой код, будет его хвалить. Все признают проблему, в т.ч. авторы. Решение - рефакторинг или переписывание кода с нуля.
2) искусственная сложность, сделанная с соблюдением принципов SOLID, ООП и слоистой архитектуры. Типичный пример здесь: микросервис с минимумом бизнес-логики, который можно сделать с использованием паттерна Transaction Script, но вместо этого появляется 3+ слоя, доменная модель, куча интерфейсов с одной реализацией, цепочка из вызовов сервисов, каждый из которых отвечает за одну функциональность по SOLID - авторизация, валидация, маппер, мониторинг, аудит, инициализация сетевых параметров, еще маппер, интеграционные логи, Circuit Breaker... Вроде все по правилам, а из простого сервиса сделан монстр, разобраться в котором очень сложно. Хотя на самом деле - правила нарушается. Как минимум правило KISS - Keep It Simple Stupid. Как максимум - не надо в том же Single Responsibility из SOLID идти до конца и для каждой функциональности, занимающей одну строчку код, делать класс. Как минимум делать это прямо сейчас. У нас же архитектура в коде. Код можно менять. В отличие от архитектуры здания, например. А разработка - это искусство компромиссов. Ну а главная проблема этой категории сложности - авторы кода точно ее не признают. Раз пишут такой код)
Итого - с любой сложностью можно и нужно бороться. Но особенно вредна искусственная сложность. По определению)
#arch #solid #complexity #principles #dev_compomisses
Давненько не писал про свои факапы.
Вспомнился один, древний. Когда давным-давно я работал в компании, где разработка была на Delphi. И уже тогда было понятно, что Delphi не жилец, и нужно переходить на другую платформу.
Ремарка - а Delphi то еще жив: https://habr.com/ru/articles/928810/ Может зря с него слезли?))))
Вводные следующие: небольшая компания, переход от коробочных решений к заказной разработке на основе свой платформы, CRM\MIS системы.
Так вот, на тот момент у нас было два пути - .NET и Java.
Из стека Microsoft уже использовался MS SQL Server, для хранения OLTP данных и OLAP кубов. Ну и Windows с Office само собой.
И надо сказать, что Microsoft тогда (и думаю до 2022 года) активно работала с мелким бизнесом. Несколько конференций в год, бесплатные лицензии для разработки. Прямо кейсы с CD дисками по почте присылали с новыми версиями ПО.
Они еще для Linux решение как раз в то время пилили, так что и этот потенциальный вопрос снимался.
И как язык C# был лучше Java, особенно если смотреть ее начальные версии. Он ведь как раз исходя из уроков Delphi и Java был создан бывшим архитектором Delphi. Java более менее его догоняет только сейчас.
И видимо по этой причине - знакомая компания, частично знакомый стек - я как лид разработки сильно топил за .NET.
Причем лично мне Microsoft ничего не предлагал - на всякий случай)
Сила бренда. Ну и возможно конференции)
В итоге после жарких баталий выбрали Java. По прошествии времени могу сказать - и правильно сделали.
И дело даже не в языке. Сравним https://www.tiobe.com/tiobe-index/java/ vs https://www.tiobe.com/tiobe-index/csharp/
Да, позиции Java выше, C# так и не обогнал Java. И уже не обгонит) Но тренды у обоих языков не очень не очень.
Дело в vendor lock. Все-таки большинство компонентов от Microsoft - коммерческие. VS Code из бесплатных приходит на ум. Завязка на экосистему Windows велика, а эта экосистема больше клиентская, чем серверная. Сообщество разработчиков меньше. Не сравнивал количество библиотек, но почему-то уверен, что для Java их сильно больше.
Ну и все мы живем в мире победившего open source. Сервера приложений, ESB, Windows на серверах ушли. В области SQL хранилищ - Oracle и MSSQL пока держаться, но их теснят. В noSQL практически все open source. CI\CD - тоже. Вот разве что IntelliJ IDEA остается вне конкуренции. Eclipse и NetBeans не смогли, а наследники IDEA вряд ли станут open source.
Вывод философский: иногда стоит отказаться от привычных инструментов и шагнуть в неизведанное. Предварительно прикинув все плюсы и минусы, конечно. Оно может стать мейнстримом)
#fuckups #java #dotnet #delphi
Вспомнился один, древний. Когда давным-давно я работал в компании, где разработка была на Delphi. И уже тогда было понятно, что Delphi не жилец, и нужно переходить на другую платформу.
Ремарка - а Delphi то еще жив: https://habr.com/ru/articles/928810/ Может зря с него слезли?))))
Вводные следующие: небольшая компания, переход от коробочных решений к заказной разработке на основе свой платформы, CRM\MIS системы.
Так вот, на тот момент у нас было два пути - .NET и Java.
Из стека Microsoft уже использовался MS SQL Server, для хранения OLTP данных и OLAP кубов. Ну и Windows с Office само собой.
И надо сказать, что Microsoft тогда (и думаю до 2022 года) активно работала с мелким бизнесом. Несколько конференций в год, бесплатные лицензии для разработки. Прямо кейсы с CD дисками по почте присылали с новыми версиями ПО.
Они еще для Linux решение как раз в то время пилили, так что и этот потенциальный вопрос снимался.
И как язык C# был лучше Java, особенно если смотреть ее начальные версии. Он ведь как раз исходя из уроков Delphi и Java был создан бывшим архитектором Delphi. Java более менее его догоняет только сейчас.
И видимо по этой причине - знакомая компания, частично знакомый стек - я как лид разработки сильно топил за .NET.
Причем лично мне Microsoft ничего не предлагал - на всякий случай)
Сила бренда. Ну и возможно конференции)
В итоге после жарких баталий выбрали Java. По прошествии времени могу сказать - и правильно сделали.
И дело даже не в языке. Сравним https://www.tiobe.com/tiobe-index/java/ vs https://www.tiobe.com/tiobe-index/csharp/
Да, позиции Java выше, C# так и не обогнал Java. И уже не обгонит) Но тренды у обоих языков не очень не очень.
Дело в vendor lock. Все-таки большинство компонентов от Microsoft - коммерческие. VS Code из бесплатных приходит на ум. Завязка на экосистему Windows велика, а эта экосистема больше клиентская, чем серверная. Сообщество разработчиков меньше. Не сравнивал количество библиотек, но почему-то уверен, что для Java их сильно больше.
Ну и все мы живем в мире победившего open source. Сервера приложений, ESB, Windows на серверах ушли. В области SQL хранилищ - Oracle и MSSQL пока держаться, но их теснят. В noSQL практически все open source. CI\CD - тоже. Вот разве что IntelliJ IDEA остается вне конкуренции. Eclipse и NetBeans не смогли, а наследники IDEA вряд ли станут open source.
Вывод философский: иногда стоит отказаться от привычных инструментов и шагнуть в неизведанное. Предварительно прикинув все плюсы и минусы, конечно. Оно может стать мейнстримом)
#fuckups #java #dotnet #delphi
Хабр
Жив ли Delphi в 2025 году? Погружение в технологии, релизы и мнение сообщества
Немного истории и контекста Delphi — легендарная RAD-среда, известная с середины 90-х. Её эпоха расцвета пришлась на Delphi 5-7 и Borland'овский бум. Многие разработчики (включая автора этой статьи)...
👍1
image_2025-07-30_16-31-11.png
290.4 KB
Хочу порекомендовать попробовать такую фичу IDEA, как Kotlin Notebook.
Это конечно заимствование из ML и Python. Суть на картинке выше, но я дам краткое описание.
У нас есть один файл, который содержит как куски кода, так и текст с картинками в формате Markdown. Куски кода (snippet) можно исполнять прямо в файле, т.е. output появляется под кодом. Исполнять можно как сразу все - не интересно - так и по очереди. Результат исполнения сохраняется в контексте. Т.е. если в первом snippet-е объявили функцию, вызвали его, то во-втором можно ее использовать. Она даже красным перестает в этот момент светится. Т.к. autocomplete, подсказки IDE, документация - все работает.
Как по мне - удобная штука для разработки и отладки алгоритмов. Да, их в энтрепрайзе мало, но они есть)
Почему удобная - рядом и аналитика, и код.
Создать новый Notebook можно в Kotlin или Java проекте через меню New.
P.S. Для Java такое можно сделать - с помощью того же jshell. Но IDEA пока не умеет.
P.P.S Да, как и всегда (почти) в мире Java - инициализация ноутбука долгая)))
#kotlin #java #idea
Это конечно заимствование из ML и Python. Суть на картинке выше, но я дам краткое описание.
У нас есть один файл, который содержит как куски кода, так и текст с картинками в формате Markdown. Куски кода (snippet) можно исполнять прямо в файле, т.е. output появляется под кодом. Исполнять можно как сразу все - не интересно - так и по очереди. Результат исполнения сохраняется в контексте. Т.е. если в первом snippet-е объявили функцию, вызвали его, то во-втором можно ее использовать. Она даже красным перестает в этот момент светится. Т.к. autocomplete, подсказки IDE, документация - все работает.
Как по мне - удобная штука для разработки и отладки алгоритмов. Да, их в энтрепрайзе мало, но они есть)
Почему удобная - рядом и аналитика, и код.
Создать новый Notebook можно в Kotlin или Java проекте через меню New.
P.S. Для Java такое можно сделать - с помощью того же jshell. Но IDEA пока не умеет.
P.P.S Да, как и всегда (почти) в мире Java - инициализация ноутбука долгая)))
#kotlin #java #idea
В продолжение предыдущей темы.
Вижу одну опасность при работе с noteboook-ом. Главная задача - отладить какой-то сложный алгоритм. Про структуру модулей, разделение на слои и классы никто понятное дело в это время не думает. Да и не предоставляет notebook для этого никаких средств.
Но настанет момент, и придётся вернуться к проектированию. Главное - не забыть об этом)
#notebooks
Вижу одну опасность при работе с noteboook-ом. Главная задача - отладить какой-то сложный алгоритм. Про структуру модулей, разделение на слои и классы никто понятное дело в это время не думает. Да и не предоставляет notebook для этого никаких средств.
Но настанет момент, и придётся вернуться к проектированию. Главное - не забыть об этом)
#notebooks
Что станет с языками программирования?
Недавно на одной 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
Недавно на одной 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) экспертное мнение. Подходит для простых случаев. Ну и ограничение - нужно быть экспертом)
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
Vlad Mihalcea
Hibernate slow query log - Vlad Mihalcea
Learn how you can activate the slow query log for JPQL, Criteria API, and native SQL queries when using JPA and Hibernate.
👍1
Редко делаю репосты, но кажется данный пост этого достоин.
Пару замечаний.
1) как раз по итогам вот таких углубленных исследований темы у меня часто появляются посты)
2) я не понимаю, как можно полдня ... развлекаться с LLM, не получить работающего кода и главное - не получить ощущения, что ты занимаешься ерундой. У меня в таких кейсах это ощущение уже через полчаса возникает) Видимо еще не вовлекся)
3) если нужно прокопать проблему - LLM может с этим помочь. Главное не зацикливаться на получении работающего кода здесь и сейчас. И задавать правильные вопросы. IMHO замечание про LLM как раз и показывает путь, как обойти опасность "отупения" при работе с LLM не отказываясь от нее
Пару замечаний.
1) как раз по итогам вот таких углубленных исследований темы у меня часто появляются посты)
2) я не понимаю, как можно полдня ... развлекаться с LLM, не получить работающего кода и главное - не получить ощущения, что ты занимаешься ерундой. У меня в таких кейсах это ощущение уже через полчаса возникает) Видимо еще не вовлекся)
3) если нужно прокопать проблему - LLM может с этим помочь. Главное не зацикливаться на получении работающего кода здесь и сейчас. И задавать правильные вопросы. IMHO замечание про LLM как раз и показывает путь, как обойти опасность "отупения" при работе с LLM не отказываясь от нее
Forwarded from Организованное программирование | Кирилл Мокевнин (Kirill Mokevnin)
Почему многие программисты не станут синьорами никогда
И годы опыта не помогут. Сразу к сути: Ключевой критерий развития это то, как происходит отладка кода, когда мы впираемся в какие-то проблемы и не понимаем как их решить. И речь идет не о том, пользуетесь ли вы отладчиком, логами или просто принтами выводите инфу на экран, а речь идет о том, как вы разбираетесь с проблемой в принципе.
Запоминайте паттерн решения любого затыка в кодинге:
1. 5-10 минут пробуем применить какие-то быстрые догадки и метод тыка
2. 10-20 минут тратим на поиск готовых решений в ИИ и на reddit (стековерфлоу прости, ты больше не нужен)
3. И примерно спустя 30 минут тыкания останавливаемся. На этом этапе мы должны перейти в режим, а что это вообще за проблема? Начинаем читать по теме пытаясь понять как в целом работает эта штука, которая сломалась, что за ней стоит, какая теория подходы и все в этом духе. Разбираемся за час-два и фиксим
4. Если не помогло, тут уже надо с кем-то поговорить. Нельзя висеть на одной задаче без движения больше 2 часов.
Вы делаете все правильно, если спустя час отладки можете остановится и рассказать про новые вещи, которые вы узнали, как что-то работает и почему вообще возникла проблема.
Если спустя час отладки вы ничему не научились и не узнали ничего нового (не как факт, а системно, как что-то работает), то ваше развитие как девелопера не присходит вообще. Поэтому что при годе опыта, что при десяти, вы будете наталкиваться на одни и те же проблемы и скорость их решения будет такой же медленной, если эта проблема проявляется хотя бы немного по другому.
На практике так происходит очень часто. Человек тыкается не 5 минут, а часами никак не разбираясь в том, что он делает.
Сейчас ситуация еще хуже из-за ИИ, который позволяет входить в цикл "спросил-попробовал" на полдня без ощущения делания какой-то херни. Полдня общаться с ИИ нужно и можно, но только если вы тратите это время на попытку разобраться в вопросе, а не "поправь/вот ошибка", когда вы находитесь в цикле отладки.
Видео на эту тему одно из первых у меня на канале: https://www.youtube.com/watch?v=9iwYRcw3A8A
Ссылки: Телеграм | Youtube | VK
И годы опыта не помогут. Сразу к сути: Ключевой критерий развития это то, как происходит отладка кода, когда мы впираемся в какие-то проблемы и не понимаем как их решить. И речь идет не о том, пользуетесь ли вы отладчиком, логами или просто принтами выводите инфу на экран, а речь идет о том, как вы разбираетесь с проблемой в принципе.
Запоминайте паттерн решения любого затыка в кодинге:
1. 5-10 минут пробуем применить какие-то быстрые догадки и метод тыка
2. 10-20 минут тратим на поиск готовых решений в ИИ и на reddit (стековерфлоу прости, ты больше не нужен)
3. И примерно спустя 30 минут тыкания останавливаемся. На этом этапе мы должны перейти в режим, а что это вообще за проблема? Начинаем читать по теме пытаясь понять как в целом работает эта штука, которая сломалась, что за ней стоит, какая теория подходы и все в этом духе. Разбираемся за час-два и фиксим
4. Если не помогло, тут уже надо с кем-то поговорить. Нельзя висеть на одной задаче без движения больше 2 часов.
Вы делаете все правильно, если спустя час отладки можете остановится и рассказать про новые вещи, которые вы узнали, как что-то работает и почему вообще возникла проблема.
Если спустя час отладки вы ничему не научились и не узнали ничего нового (не как факт, а системно, как что-то работает), то ваше развитие как девелопера не присходит вообще. Поэтому что при годе опыта, что при десяти, вы будете наталкиваться на одни и те же проблемы и скорость их решения будет такой же медленной, если эта проблема проявляется хотя бы немного по другому.
На практике так происходит очень часто. Человек тыкается не 5 минут, а часами никак не разбираясь в том, что он делает.
Сейчас ситуация еще хуже из-за ИИ, который позволяет входить в цикл "спросил-попробовал" на полдня без ощущения делания какой-то херни. Полдня общаться с ИИ нужно и можно, но только если вы тратите это время на попытку разобраться в вопросе, а не "поправь/вот ошибка", когда вы находитесь в цикле отладки.
Видео на эту тему одно из первых у меня на канале: https://www.youtube.com/watch?v=9iwYRcw3A8A
Ссылки: Телеграм | Youtube | VK
YouTube
Как быстро находить ошибки в коде? Советы для начинающих
Ошибки начинающих разработчиков:
* Вера в магию
* Путаница между причиной и следствием
* Stackoverflow Driven Development
Эффективная отладка:
1. Локализация проблемы
2. Поиск точки опоры
3. Пошаговое подключение кода
* Вера в магию
* Путаница между причиной и следствием
* Stackoverflow Driven Development
Эффективная отладка:
1. Локализация проблемы
2. Поиск точки опоры
3. Пошаговое подключение кода