(java || kotlin) && devOps
342 subscribers
13 photos
2 videos
7 files
419 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Forwarded from /g/'s Tech Memes
RIP

StackOverflow provided data to LLMs, LLMs replaced StackOverflow, and now no new Q&A hub exists to provide fresh data
😭2
И снова к Совершенному коду)

Там есть раздел про выбор языка.

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

И в итоге язык влияет на скорость разработки, причем несколькими путями:
1) на незнакомом языке происходит замедление разработки до 30%
2) в разных языках объем полезной работы, которую в среднем производит одна строка кода, отличается. Это не только и не столько про скорость написания кода, но и про скорость чтения и понимания. Данный показатель как раз иллюстрирует табличка из поста.

Из таблицы видно, что Java никогда не была лидером по выразительности. Но надо отметить - в последние лет 10 работа над этим ведется.

Kotlin я думаю даже выше 6-ки будет.

#lang #book_review
Немного разбавлю серию про Совершенный код, но обязательно к ней вернусь)

У меня было много постов про собеседования - и по типовым вопросам, и по ошибкам, и по разным этапам (live coding, алгоритмы). Можно найти по тэгу #interview.
Появилась мысль оценить важность разных этапов интервью разработчика. IMHO конечно же)

1) code review - как по мне самый полезный этап, т.к. разработчик чаще всего приходит в существующую команду с каким-то кодом, и с этим кодом ему придется работать. Brownfield другими словами.
Этап показывает и навыки чтения кода, и практическое применение теоретических знаний при исправлении ошибок, и способность кандидата рассуждать, уверенность в своих знаниях объясняя ошибку и способ ее исправления.

2) разбор проблем\инцидентов из практики нанимающей команды. Полезно, т.к. позволяет понять понять навыка кандидата по решению проблем и "примерить" опыт кандидата на команду. А возможно - получить "инсайты" по улучшению архитектуры\кода)
Разработка - это не только лишь код, проблемы часто съедают больше времени, чем собственно работа с кодом.

3) live coding не (!) алгоритмических задач. Ну или простых алгоритмических. Позволяет понять, как кандидат подходит к решению задач, соотношение проектирование vs кодирование, и конечно как пишет код.
Не забыл он еще с AI агентом или тимлидством, как это делать?)

4) теория. Хотя многие ругают, я считаю полезной, как показатель кругозора и\или опыта. Lazy Load, индексы, как работает GC, Atomic, как работает Spring (а это важно, есть компании его запрещающие на основании того, что никто не знает до конца, как он работает).
Тут важно докручивать вопросы, чтобы этап не превратился в проверку памяти кандидата. Не так важно, сталкивался кандидат сам с проблемой или посмотрел ролик Борисова. Важно понял ли)

5) system design - с уровня Senior обязательно, но есть нюанс. Главное противоречие этого этапа - необходимость за условный час спроектировать систему. Т.е. сделать за час то, что у обычного архитектора занимает дни, возможно неделю.
Но польза конечно же есть: как кандидат задает ли кандидат вопросы, правильные ли они - показывает способность работы с бизнесом. Все ли аспекты архитектуры затронул, как рассуждает - навыки архитектуры и проектирования.
Главное не требовать спроектировать 100% системы за час) Тогда это превратится в проверку натасканности на задачу, как часто происходит алгоритмической секцией. Или с заучиванием теории.
Второе важное замечание - практическая применимость. Если собес на архитектора - окей, но даже архитектор не проектирует систему целиком по методикам system design.
Но что важно: да, эталонного сеанса system design я в реальной работе не встречал. При этом все его части сами по себе полезны для разработчика уровня Senior+

6) алгоритмическая секция - по сути это такая "олимпиада 2.0". Или тест на IQ 120+. Если пытаемся сделать команду спецназовцев от разработки - да, иначе стоит подумать над необходимостью) Главная проблема секции - на практике алгоритмы пишут единицы процентов разработчиков.

7) знакомство с ИТ лидом и\или командой - это софт-скилы, тоже важно, один в поле не воин.

#interview
👍1
И снова минутка цитат, подтверждающая мысль, что Стив (Макконнелл) умеет жечь глаголом сердца людей:

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

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


P.S. Справедливости ради отдельно обсуждается кейс mixin - классов, не являющихся самостоятельной сущностью, а лишь содержащих какой-то общеупотребительный функционал. Пример: Comparator. То, что в Java реализуется как интерфейс с методами по умолчанию. Этот вариант - ок, но здесь множественное наследование лишь средство подмешать данный функционал в класс

#book_review
Небольшое дополнение по принципу Liskov к https://t.me/javaKotlinDevOps/182

Краткое содержание предыдущей серии - основной способ нарушить это принцип в Java - сломать семантический контракт метода.

А еще нарушение этого принципа может подсветить плохую абстракцию, выбранную для класса.
Пример: кто-то решил сделать один базовый класс для вклада и кредита. В этом случае метод monthlyPayment() покажет, что это была плохая идея. Т.к. в вызывающем классе нам в зависимости от конкретного потомка - вклада или кредита - придется брать знак минус или плюс для вычислений. Что нарушает принцип Liskov.

P.S. Это тоже Совершенный код)

#solid #book_review
Нужно ли читать чужой код?
Я не про код-ревью, а про процесс разработки.

С одной стороны я всегда топлю за то, что если есть проблемы с внешней библиотекой - не понятно, почему метод возвращает такой результат или ошибку - залезь в ее код, и посмотри.
Но Стив Макконнелл (да, снова Совершенный код) подсвечивает один интересный момент - разницу между синтаксической и семантической инкапсуляцией внутренностей класса.
С синтаксической все просто - объявил по максимуму все private и профит.
А вот семантическая, а точнее ее нарушение - это наши догадки насчет внутреннего устройства чужого класса, влияющие на наш код.
А догадки эти обычно возникают после чтения кода...
Тут еще хорошая аналогия с работой разработчика и тестировщика. Для тестировщика код - это черный ящик. А для разработчика - нет. Или все же да?)

Я для себя решил так. Если найдено неочевидное\неправильное поведение внешней библиотеки, ее автор доступен и готов к сотрудничеству - стоит по советам Стива зайти к нему и попросить поправить.
А если хотя бы одно из этих условий не выполняется - можно и нужно залезть в код. И возможно даже завязаться на его внутренние детали реализации. Да, да, я про костыль.
Но с обязательными условиями:
1) proxy слой
2) с подробным комментарием что делается и почему.
И с заведением техдолга если все же есть возможность поправить эту проблему прямым образом.

#book_review #code
👍1💯1
assert в боевом коде?

На всякий случай напомню https://docs.oracle.com/javase/8/docs/technotes/guides/language/assert.html

Пример:

Connection conn = getConnection();
assert conn != null;


Важной особенностью assert-ов является тот факт, что по умолчанию проверки, выполняемые в assert, выключены.
Для включения нужно передать опцию -ea (-enableassertions) при запуске, просто или с указанием пакета.
И как раз этот факт является одним из двух гвоздей, убивающих данную фичу.
Второй гвоздь - позиционирование assert-ов примерно такое же, как и у отладочных логов.
Это я читаю как в Совершенном коде (да, он спонсор данного поста))), так и в статье выше обсуждается как бы их удалить из кода.

Теперь на отойдем на шаг назад.
Все ошибки во входящих данных можно разделить на две категории - ожидаемые и нет.
Это деление не дискретное, а непрерывное, но в любом случае приводит к вопросу - как проверять данные на неожиданные ошибки? Нужно ли это делать вообще?
С ожидаемыми все понятно - пишем проверку, if и далее возврат кода ошибки\exception\запись в лог.
А неожиданные - что с ними делать?
Самый яркий пример - проблема nullability в Java. Объекты у нас везде, тогда в теории почти в любом методе нужна проверка на null.
Или не нужна, т.к. это сильно увеличивает объем кода и ухудшает читаемость.

Тут как раз предлагается использовать assert - для ошибок, которых при нормальной работе программы быть не должно.
Почему мне это не нравится.
Как раз по двум причинам выше - мы решили проверить данные и вроде закрылись assert-ом.
А потом кто-то убрал -ea в ПРОМе. И вообще говоря такой путь часто рекомендуют - разработка с assert, ПРОМ - без.
Или кто-то удалил assert посчитав его отладочным. Проект то живет долго, люди меняются.

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

Еще предлагаемый кейс для assert - pre-condition, post-condition, инварианты - т.е. реализация контрактов для методов и классов в коде.
Причем часто основная идея здесь не проверка условий, а именно документирование контракта с помощью assert.
И тут снова вступает в силу ненулевая вероятность удаления assert-ов, т.к. в боевом коде они выглядят чужеродно.
Я тут за JavaDoc, т.к. по JavaDoc можно построить отдельный jar с документацией, который может использовать IDE.
С контрактами есть отдельный важный момент: контракт - это часть класса, выносить его в слой валидации плохо.
Но в таком случае лучше его реализовать или обычным кодом или JavaDoc.

Итого остается редкий кейс разработки кусочка монолита, когда нет уверенности, что контракты соблюдаются. Условно разработка чего-то уровня JDK.

Используете ли assert в боевом коде? Для чего?

#book_review #contracts #validations
"Цените легкость чтения кода выше, чем удобство его написания"

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

Т.к. если не задумываться об удобстве чтения кода, то мы получаем:
1) дублирование - проще же скопировать, чем выделить новую абстракцию
2) вечный техдолг из-за не проведенного вовремя рефакторинга
3) божественные классы: пусть новый метод Y не вписывается в абстракцию класса Х, но чтобы это заметить - надо выйти за рамки текущей задачи
4) огромные иерархии классов, длинные методы - проще добавить код по аналогии
5) слабое покрытие тестами - код работает, мне он на данный момент абсолютно понятен. Зачем тесты писать - ради тестов?
6) методы и классы с неактуальными названиями
7) все методы в классе являются public - они же вызываются из public метода, да и вдруг кому-то пригодятся
8) спагетти-код
...
и получаем легаси в итоге.

#book_review
Рубрика "Загадки от Стива".

Если объект класса создается в коде всего один раз - стоит заменить такой класс объектом.
О чем речь?

Пример:
у нас есть разные виды карт: Мир, Мир Supreme, Visa Classic, Visa Digital..
Можно завести под каждый тип отдельный подкласс, но в большинстве случае достаточно параметризовать все отличия разных типов карт и просто создавать объекты одного класса.


#book_review #oop
Ещё один элемент AI-пазла.

Сделаю паузу по книжке.

У нас есть стандарт для получения данных из внешних источников (MCP), потенциальный протокол для запросов в LLM (TOON, хотя тут борьба ещё впереди), паттерн локальной БД (RAG), стандарт памяти для контекста (GAM), навыков агентов (Agent Skills), реестр opensource-моделей (HuggingFace).

Если смотреть на агентов и их локальные возможности, в частности для разработки и смежных активностей, то тут можно найти место для стандарта. Что делает такой агент: читает файлы (код), создаёт и меняет их, запускает команды в консоли и анализирует вывод, возможно запускает браузер. Также — запуск скилов и вызов MCP. Плюс мультиагентность — отдельно агенты для планирования, правки кода, возможно тестирования...

Вот всё это реализует OpenCode https://opencode.ai/. Плюс работа с сессиями, аутентификация у разных провайдеров LLM, выбор модели и даже sharing сессии. Обещают, что, кроме режима sharing, на сервер ничего не шлют.На свой сервер, на сервер LLM конечно же шлют.
Но есть поддержка Ollama для запуска моделей локально. Ещё интересно, что инструмент поддерживает три типа взаимодействия: консоль, web и TUI. TUI — Terminal User Interface. И это реальный консольный UI. Вспоминается MS DOS и  Norton Commander. Попробовал — мне понравилось. Удобно.

Минусы:
- для установки и шаринга сессии нужен VPN;
- кроме основной модели есть ещё так называемая small model, в качестве которой у меня OpenCode сам выбрал платную модель OpenRouter (а основную модель я выбрал там же бесплатную) и втихаря сожрал 5 центов за час.

А вообще классная штука, в первую очередь для разработки, но вижу пользу и для анализа данных, тестирования...

P. S. Вот только в стане фреймворков разработки агентов всё ещё разброд и шатание, хотя для Python выделяется пара LangChain/LangGraph.

#ai #llm
Еще одна загадка "от Стива":

Цитата:
"В одном исследовании 450 методов было обнаружено, что дефекты отсутствовали у 50% методов, обладающих высокой связностью,
и только в 18% методов с низкой связностью (Card, Church, and Agresti, 1986).
Другое исследование методов (это просто совпадение, хотя и весьма необычное) показало,
что в сравнении с методами, имеющими самое низкое отношение «сопряжение/связность» (coupling-to-cohesion),
методы с максимальным отношением «сопряжение/связность» содержали в 7 раз больше ошибок,
а исправление этих методов было в 20 раз более дорогим (Selby and Basili, 1991)."

Речь про то, что в методах с высокой связностью кода - single responsibility по сути - меньше ошибок.
Почему?

Мой ответ:
низкая связность может иметь одну из двух причин:
1) плохое проектирование = больше ошибок
2) плохо проведенный\не проведенный вовремя рефакторинг, когда в метод добавили новый функционал, "гвоздями прибив" его к существующему без нормального тестирования
Ну и банально - больше функционала в методе = больше метод = больше вероятность ошибки. Но тут зависимость не линейная, при нормальном проектировании.


#book_review #quest
🔥1
И еще один вопрос от Стива, попроще:
"Используйте утвердительные имена булевых переменных"
Почему?

Ответ:
чтобы избежать вот такого кода:

if ((!notFound) && ... )

затрудняющего чтение.

А кстати в Python все еще хуже:

if (not notFound) and ...:



#book_review
Долговременное хранение контекста AI агента - можно ли попроще?

Я уже писал про GAB - систему хранения контекста диалога https://t.me/javaKotlinDevOps/495.
Напомню тем кто забыл - там два компонента Memorizer (фоновое сохранение данных) и Researcher (компиляция ответа под конкретный запрос пользователя) и два вида памяти: весь диалог и короткие сводки (кэш).
И в целом GAB - это научная работа без практического внедрения.
Когда появится реализация - это будет отдельный сервис а-ля RAG.

Так вот - как можно сделать примерно тоже самое проще? Например, в контексте агента для разработки

Краткий ответ - можно. Подробный - давайте напишем промт для агента с просьбой собрать, сохранить и поддерживать актуальность информации по проекту внутри проекта в текстовых файлах.
Пусть это будет Markdown как некий стандарт, сложившийся не только в AI.
Т.е. процесс выглядит так:
1) инициализируем память собрав всю информацию по проекту и сохранив ее
2) при старте любого диалога подтягиваем информацию
2) после успешного выполнения любых действий над проектом обновляем\чистим информацию в долговременной памяти

Как говорится - ближе к делу.
Встречаем Cline Memory Bank https://docs.cline.bot/prompting/cline-memory-bank

На что стоит обратить внимание:
1) лично я когда говорил о долговременной памяти - я подразумевал контекст сессии.
На самом деле не обязательно им ограничиваться.
В случае разработки - сессия = таска, а контекст по проекту имеет смысл хранить постоянно.
Т.е по сути он разделяется на постоянную часть и текучку.

На примере Cline Memory Bank постоянная часть:
`projectbrief.md`
- Foundation document that shapes all other files
- Created at project start if it doesn't exist
- Defines core requirements and goals
- Source of truth for project scope

`productContext.md`
- Why this project exists
- Problems it solves
- How it should work
- User experience goals

`systemPatterns.md`
- System architecture
- Key technical decisions
- Design patterns in use
- Component relationships
- Critical implementation paths

`techContext.md`
- Technologies used
- Development setup
- Technical constraints
- Dependencies
- Tool usage patterns


Текучка:

`activeContext.md`
- Current work focus
- Recent changes
- Next steps
- Active decisions and considerations
- Important patterns and preferences
- Learnings and project insights

`progress.md`


2) Является ли такая структура памяти оптимальной? Хз, но я бы с нее начал.

3) что с поддержкой данной штуки в других агентах? без проблем, т.к. по сути memory bank = промт + способность агента читать и писать в файл.
Пример для Cursor https://www.youtube.com/watch?v=azXNHRtzd5s
Roo Code решили обвернуть это в MCP сервер https://skywork.ai/skypage/en/roo-code-memory-bank-ai-agent/1980851096638783488
Почему бы и нет, поможет при разработке других агентов, причем это могут быть агенты с разным назначением.

4) в Memory Bank хранится информация по архитектуре\структуре проекта, его стек, команды запуска, code style и прочие правила работы.
И если они уже есть в проекте - можно просто их переиспользовать, стандартизировав место хранения.

5) что из этого хранить в git? постоянную часть точно, текучку - наверное нет, т.к. у каждого она своя, но надо смотреть

В общем - рекомендую, сам буду настраивать на всех проектах.

P.S. если сравнить два подхода GAB vs Memory Bank - это как JIT и AoT компиляция

#ai #ai_agents #mcp
Что не докрутили в record-ах?

Для начала кратко о том, что докрутили:
1) компактное объявление, типовые методы из коробки
2) иммутабельность
3) минимально необходимая расширяемость - дополнительные конструкторы, интерфейсы, обычные методы, статические поля, методы и внутренние классы.

Получаем аналог data class в Kotlin. Или структур из древних языков типа C.

Но с небольшим отличием - не хватает метода копирования "из коробки".

Почему так сделали? Есть же Cloneable интерфейс. И его даже можно добавить в record руками.

Думаю, причина в иммутабельности record и скажем так скомпрометированности clone().

Для иммутабельной сущности нет смысла в полной копии - можно использовать текущий объект.

С clone() основная проблема в том, что "из коробки" он делает поверхностную копию, но при переопределении может дать полную. И вообще полную копию автоматически сделать сложно. А это приводит к путанице - метод один, а поведение может отличаться.

В итоге приходим к тому, что иметь возможность быстро сделать поверхностную копию записи с изменением пары полей было бы неплохо. И такой JEP есть https://openjdk.org/jeps/468
Надеюсь внедрят.

#java #иммутабельность
AI как база знаний.

В разработке есть проблема передачи знаний.
Есть разные способы - обучение, книги, онлайн контент, конференции, поиск, общение с коллегами и вот теперь AI.
Я уже писал, что AI вытесняет поиск и т.об. приводит к смерти сайтов типа stack-overflow.
Но может ли общение с LLM заменить все источники?
Т.е. есть разраб и сильная LLM, и больше ничего не надо?

Если говорить про источник знаний, то ключевые его характеристики IMHO - скорость поиска, структурированность изложения, полнота и точность.
В плане скорости AI пожалуй лучший. Это реальный прорыв
Структурированность - по большинству ответом LLM видно, что системные промты у них заточены на это.
Там и объяснения, и ссылки, и вывод, и рекомендации. А это важно, чтобы разработчик понимал, почему предлагается то или иное решение.

А вот с полнотой и точностью вечные проблемы.
Почему вечные?
В LLM по определению не может попасть вся информация.
Части нет в цифровом виде вообще. Часть "под замком" - во внутренних сетях компаний.
Часть потерялась при "сжатии" как несущественная. И к слову теряется еще сильней при квантизации LLM для запуска на более слабых устройствах.
С точностью главная беда в том, что модели почему-то не могут четко разграничить - вот точные знания, вот предположение и ссылки для самостоятельного изучения.
А пытаются скомпилировать ответ из того, что знают. Не знаю, насколько это можно пофиксить в будущем обучением, но пока так.
В теории можно фиксить проверками кода перед выдачей пользователю, хотя это более трудоемкий и концептуально плохой путь (перебор по сути).
Второй источник проблем с точностью - отсутствие метаданных в модели, в частности по версиям ПО, ОС, железа ... для которых применим тот или иной код.

В итоге что мы получаем?

LLM может сильно ускорить разработку, если ты в целом знаешь предметную область, умеешь искать информацию и критически ее анализировать.
Т.е. поможет миддлам и синьорам.
А вот джуну кажется AI способен навредить, убив в зародыше навыки, упомянутые выше.
Ну и разраб, принципиально отказывающий от AI, будет в проигрыше.

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

#ai #knowledge_base
👍1
Может ли бюрократия быть полезной?)

Я про разработку.
И если вы сейчас думаете, что я расскажу, как многочисленные согласования:
1) текстовок и дизайна
2) рисков
3) квоты на железо (а планировать ее надо было в прошлом году...)
4) концептуальной архитектуры и архитектуры АС
5) тестовой модели
6) профиля нагрузки
7) требований сопровождения
8) и конечно же безопасности
приносит пользу команде... то нет.
Определенную пользу команде они приносят, но сейчас хочу сделать акцент на другом.

Мы живем в мире победивших микросервисов.
Я наблюдаю за тем, как люди проектируют новые сервисы и как говорят о существующих.
Вот несколько зарисовок:
1) давайте условный сервис блогов сразу разделим на микросервисы для создания постов, чтения постов, работы с комментами...
И при этом пусть работают с одной БД(
2) ну вот тут у нас большой сервис, можно сказать монолит (и чувствуется, что это слово ругательное), т.к не дали нам его нормально на микросервисы распилить.

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

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

#microservices #arch
AI везде...

В Windows Task Manager появилась отдельная вкладка, отображающая нагрузку на NPU. Удобно.
Так вот - при включении Zoom там появляется стабильная загрузка в районе 10-15%.
Это наверняка Zoom AI companion.
Но... размытие фона у меня выключено, как и в принципе видео камера, расшифровка речи тоже, нагрузка не только во время разговора (убрать шумы).

Вопрос - что он там считает?)

#ai
Немного о протекании абстракций.

Сегодня про кейс из жизни - как работает Docker на Windows.
Есть тестовый проект суть которого - работа с локальной LLM. Модель - gemma с 4b параметров. Для запуска модели (инференса) используется Docker образ ollama. Запускаю все это в Windows, что немаловажно.
Да, Docker в Windows это не тоже самое, что Docker в Linux, т.к. появляется новый слой трансляции.
Ну ок, не 5% накладные расходы, а скажем 10. Или 15.

А что в реальности?

gemma, запущенная напрямую в Windows выдает на глаз 10 токенов\с.
А в Docker скорость падает раз в 10, что уже больно.
При этом - все ядра процессора загружены на 100%.
И по использованию памяти видно, что модель полностью загрузилась в RAM. Это, кстати, отдельная тема - как LLM используют RAM.
Но вернемся к проблеме.
В 10 раз отличие по скорости...
Диалог с ChatGPT и Gemini дал пару наводок - все мимо. Docker видит все ядра процессора, доступна вся RAM, все наборы инструкций процессора, требуемые LLM, ollama видит.
Есть подсказка, что плохо пробрасывать том файловой системы с хоста Windows в Docker - ок, качаем модель внутрь файловой системы Linux. Не помогает. Да и сомнительно, т.к. модель полностью грузится в RAM, иначе LLM не работают, т.е. замедление должно быть лишь в момент запуска.
В итоге я забил смирился.

Но факт остается - по всем признакам Docker в Windows жизнеспособен для задач отладки. И в большинстве задач вполне себе нормально работает. А в конкретном кейсе - разница в 10 раз.

#docker #win #ai
Что такое совершенный код?

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

По каждой казалось бы простой теме: переменные, методы, классы, условные операторы, циклы... - есть есть что сказать, и сказать много.
И в большинстве случаев - по делу.

Пример.
Я всегда топлю за читаемость кода.
Но никогда не задумывался о расположении локальных переменных.
А Стив задумывался)
Он вводит понятия частоты использования и времени жизни переменной.

var fileFound = false;
var noteFound = false;
...
while (!found) {
...
}
...
noteFound = findNotes(...);


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

Т.е. частота использования (число строк с переменной/число строк от первого до последнего появления переменной) должна быть высокой, время жизни - коротким.
И это увеличивает читаемость. Вроде простая штука, но отдельно о ней не задумываешь.

#book_review
Как-то я упустил важное обновление в IDEA - MCP сервер.

Почему важное и зачем вообще это нужно?

AI агенты уже умеют многое. Их стандартные навыки, они же тулы - просмотр содержимого каталогов, чтение и изменение файлов, выполнение скриптов в CLI. Примерный список навыков можно посмотреть на примере OpenCode https://opencode.ai/docs/tools/

Но IDEA умеет гораздо больше - поиск проблем в коде, разного рода рефакторинги, более умный поиск, уже готовые конфигурации запуска... Вот это бы это все агент мог делать за нас...

Ну собственно уже может)
https://www.jetbrains.com/help/idea/mcp-server.html

Список тулов на старте неплох:
- create_new_file
- execute_run_configuration
- execute_terminal_command

- find_files_by_glob
- find_files_by_name_keyword
- get_all_open_file_paths
- get_file_problems
- get_file_text_by_path
- get_project_dependencies
- get_project_modules
- get_repositories
- get_run_configurations
- get_symbol_info
- list_directory_tree
- open_file_in_editor
- reformat_file
- rename_refactoring
- replace_text_in_file
- search_in_files_by_regex
- search_in_files_by_text

Особенно радуют reformat_file и get_file_problems - даже за самым хорошим агентом приходилось исправлять.
rename_refactoring конечно же надо делать средствами IDE, т.к. в этом случае вероятность ошибок стремится к нулю.
execute_terminal_command - меня постоянно раздражают мелкие окошки терминала в чате, по возможности стоит использовать терминал IDEA.
ну и работа с run configuration ускорит процесс отладки для агента (не нужен подбор команд) и уберет дублирование (не надо дублировать в промте)
Фича в Community, поэтому появится в форках - уже в OpenIDE https://habr.com/ru/articles/989716/ и скоро в GigaIDE.

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

Лично я буду тестить. Да, по умолчанию MCP сервер выключен. И для части агентов есть автоконфигурация - Cline, Cloude Code. Но даже там, где ее нет это не проблема.

#ide #idea #ai #mcp
И чтобы "зафиналить" тему с множественными отрицаниями в условиях пару цитат из книжки)))

Я не не нетупой.

Гомер Симпсон
(Homer Simpson)


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


P.S. Кто-нибудь пробовал вычислить вторую фразу?)

#book_review
🔥1