Pull to refresh
6
0
Денис Орехов @javadev

Техлид Java

Send message

Всем привет!

Есть много способов получить данные из БД с помощью JPA:

  1. JPQL

  2. JPQL Native Query

  3. HQL

  4. Spring Data JPA Repository

  5. Criteria API

  6. QueryDSL

  7. ...

Предположим, нам нужно вернуть набор строк. Задать параметры запроса можно по-разному, а итог будет один - List или другая коллекция (Collection) с набором данных.

Верно? Не совсем)
Если посмотреть на список возвращаемых Spring Data JPA данных https://docs.spring.io/spring-data/jpa/reference/repositories/query-return-types-reference.html#appendix.query.return.types то там можно увидеть много чего интересного. В т.ч. Stream. А вот пример его использования: https://vladmihalcea.com/spring-data-jpa-stream/
Аналогично можно вернуть Stream и из обычного JPA - см. метод getResultStream, вот пример: https://thorben-janssen.com/jpa-2-2s-new-stream-method-and-how-you-should-not-use-it/

Зачем это может быть нужно?

Во-первых это просто красиво... Шучу. Если вы используете Stream в бизнес-логике - то кажется логичным использовать их и при обращении к БД.
А во-вторых: главная особенность стриминга - равномерная выборка данных. И в каждый момент данных в обработке будет одна запись.
Рассмотрим кейс, когда нужно обработать на клиенте миллион записей.

Ремарка: если у вас такой кейс - подумайте, нет ли проблем в архитектуре. Данные лучше обрабатывать на сервере СУБД. Если все же проблем нет - продолжим)

Так вот, какие у нас варианты:

  1. вытащить на клиент миллион записей. Запрос к БД будет один, она выдержит, но с неплохой вероятностью можно убить клиент через Out of Memory.

  2. организовать пагинацию, например, вот так: https://www.baeldung.com/spring-data-jpa-iterate-large-result-sets. Данных на клиенте в моменте не много, по размеру страницы, но запросов к БД ... тысячи.

  3. использовать стримы. Запрос к БД один, данных на клиенте немного. Не обязательно одна запись, но в любом случае немного, детали ниже.

К слову, стриминг по БД с JPA аналогичен перемещению курсора по ResultSet в JDBC. С накладными расходами и плюшкам, которые дает сессия JPA, конечно.

И про объем данных на клиенте. Казалось бы - вытаскиваем записи поштучно. Но если не указать fetch size - объем предварительной выборки - для некоторых СУБД Hibernate вытащит на клиента все данные за раз, и мы вернемся к варианту 1 (((

Tags:
Total votes 2: ↑2 and ↓0+2
Comments2

Всем привет!

Давненько не было постов на канале, что поделать - конец квартала, авральный режим on. Но я вернулся)

Java всегда славилась своим boiler plate кодом. Ремарка - конечно же не только boiler plate, но сейчас про него и про борьбу с ним. Борьба идет, и в Java 16 (а точнее в Java 14 но в режиме preview) появились records, они же записи.
Делаешь вот такое объявление:
public record Point(int x, int y) {}
и получаешь из коробки конструктор, getter, equals(), hashСode() и toString().
Т.е все то, что раньше приходилось писать руками или использовать Lombok. Ага, Lombok. Т.е. он стал не нужен? Не совсем. Если внимательно глянуть на список того, что под капотом делает record, то можно заметить, что там нет setter-а. Т.е. record - это иммутабельный объект и value object. Две записи с одним и тем же набором полей всегда равны. Это не баг, это фича. Маленькое дополнение - record еще меняет классический getter c getXyz на просто xyz(), но это детали. Еще дополнение - вот тут среди прочих фичей Java 17 достаточно интересно о работе с record.

Т.е. получается, что record заменяет @Value из Lombok.

Но не заменяет:

  1. полноценный @Data - изменяемый класс без boiler plate

  2. кейс, когда мы не хотим все сразу getter, toString() ... а хотим только часть этих методов

  3. @Builder - тут проще показать, чем объяснять:
    Person.builder().name("Adam Savage").city("San Francisco").build();

  4. @Log - простое добавление логгера в класс

  5. и наконец @SneakyThrows - если вы не любите checked exception

Tags:
Total votes 7: ↑4 and ↓3+5
Comments0

Всем привет!

Наткнулся сегодня на еще одну книжку про AI.
Что опять?)
Для начала у нее интересное название - "Охота на электроовец".
Но есть еще две причины, по которым я решил про нее написать.

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

  2. автор - Сергей Марков - из России, что встречается не часто. Более того - автор живет в России на данный момент. Т.е. его можно в теории встретить на какой-либо конференции и позадавать вопросы. Ну и проблем перевода точно не будет)

Скачать можно бесплатно, бумажную версию скоро выпустят тут.
Я лично планирую прочитать.
Да, о минусах - иллюстрация на обложке для электронной версии .. ну такое. Ну и 2 тома, 1200 страниц - не всякую дорогу осилит идущий)

P.S. Угадайте, в какой компании работает автор?)

Tags:
Total votes 5: ↑5 and ↓0+11
Comments5

Всем привет!

Расскажу про один поучительный факап из моей практики.

Более 10 лет назад. Стартап. Я на тот момент и СТО, и разработчик в одном лице. Есть задача, в целом понятная. Декомопозирую на микросервисы и подзадачи, начинаю пилить. Дохожу до XML binding - преобразования XML в объекты. Тогда API в основном были XML. Решил погуглить - что есть на рынке. Кроме известного многим JAXB нахожу JiXB. Не известный тогда, тихо умерший сейчас. Читаю описание и нахожу бенчмарк, показывающий что он ... скажем в 1.5 раза быстрее JAXB. Думаю - о, круто, надо брать. Начинаю прикручивать к Spring. Наталкиваюсь на кучу подводных камней - это не работает, документации мало, ошибки не информативные и не гуглятся. В общем убил неделю на прикручивание к проекту одной библиотеки. В итоге все заработало, конечно. А проект не был доведен до работающего состояния и так и не взлетел.

Итоги. До сих пор стыдно за такое решение по следующим причинам:

  1. речь про стартап, т.е. нужно быстро создать работающий прототип, а не исследовать новые технологии

  2. преждевременная оптимизация - данных по требуемому RPS и доступному железу на тот момент у меня не было. Нагрузочное тестирование не проводилось. Стал бы JAXB узким местом - не факт

  3. использовать в промышленной разработке не доказавшие свою зрелость библиотеки - это риск. Очень важны сообщество и работающие без бубна связки, например, Spring+JAXB. А риск должен быть оправдан, а еще должен быть план отката. Не взлетело, сыро - откатываемся на надежный вариант

Tags:
Total votes 8: ↑8 and ↓0+12
Comments0

Всем привет!

Вопрос - где применяется подход DDD?
Аналитика, разработка, тестирование. Конечно архитектура АС, с нее все начинается.
Но это еще не все.
Есть такой класс систем как Data Warehouse (DWH) или аналитическое хранилище данных. В это хранилище попадают данные из всех бизнес-сервисов компании для дальнейшего анализа. Т.об. мы разделяем оперативную БД и аналитическую, снимая лишнюю нагрузку с оперативной БД. Особенность Data Warehouse - технологии обработки и хранения данных отличаются от используемых в системах оперативной обработки данных. Hadoop, Greenplum, ClickHouse... А значит нужны специалисты, которые подготовят хранилище под ваши данные и настроят синхронизацию с оперативной БД. Но эти специалисты не знают ваш домен, в отличие от команды. Плюс они часто становятся "бутылочным горлышком". Плюс структура данных постоянно меняется...
Что делать?
Data Warehouse специалисты готовят инфраструктуру, а за подготовку и синхронизацию данных, актуальность их структуры и способ предоставления этих данных потребителям отвечает бизнес команда. Это же ее bounded context. Подход называется Data Mesh. Вот неплохая статья на эту тему.
P.S. На самом деле DevOps в своем идеальном виде о том же - DevOps инженеры готовят инфраструктуру, а за сборку и деплой отвечает команда.

Tags:
Total votes 2: ↑2 and ↓0+6
Comments0

Всем привет!

Поговорим снова о микросервисах. Я уже писал, почему не стоит делать слишком мелкие микросервисы https://t.me/javaKotlinDevOps/305 (блог в телеге я стал вести сильно раньше, чем на Хабре)
Но встает закономерный вопрос - "сколько вешать в граммах", в смысле - а какого размера должны быть микросервисы?
Обозначим нижний и верхний предел, а для этого придется вспомнить DDD.

Для начала рассмотрим понятие ограниченного контекста (bounded context). Это связанный набор сущностей из реального мира, для наименования которых используется "единый язык" (ubiquitous language) - непротиворечивый набор терминов. Эти сущности описываются в аналитике, тест-кейсах и превращаются в классы в нашем сервисе и в таблицы в БД. Контекстом как правило занимается одна команда - так проще всего поддерживать "единый язык". И за микросервис тоже должна отвечать одна команда. Т.е. ограниченный контекст - это отличный кандидат на микросервис. Но при этом у одной команды может быть несколько микросервисов. И контекст может быть достаточно большим. Т.е. у нас есть верхняя граница микросервиса.

Теперь рассмотрим понятие агрегата - группу сущностей, имеющую уникальный идентификатор, изменение которой производится атомарно. Т.е. агрегат - граница транзакции в БД. А т.к. возможность делегировать управление транзакцией СУБД - это очень крутая штука, то разделять агрегат между разными БД не стоит. При этом один микросервис = одна БД. Поэтому агрегат - нижняя граница микросервиса.

Tags:
Total votes 3: ↑1 and ↓2+1
Comments0

Всем привет!

Немного мыслей по AI чатам.

Существует достаточно много open source моделей - LLama от запрещенной Meta, Mistral, DeepSeek, Grok 1 от Twitter. Если говорить про предыдущие, не самые мощные версии моделей - есть Gemma от Google, специализированные модели от OpenAI. Это хорошо, так как дает возможность подключения к разработке моделей команд, не имеющих большого числа GPU. Дообучение моделей (fine tuning) дешевле первичного обучения. Запуск обученной модели - тоже. Плюс open source - это гарантия, что к AI будет доступ даже если конкретный сервис по тем или иным причинам закроется. И Мета выделяется тем, что отдала в open source последнюю тяжелую (большое число параметров) версию модели.

Второй момент: в тестах и в новостях сравниваются модели общего назначения и специализированные. Общего назначения - ChatGPT, Claude, Gemini, Llama, Grok, DeepSeek, Mistral, YandexGPT. Специализированные, на примере разработки - DeepSeek-Coder-V2, Codestral, CodeLlama, Phind, GigaCode. Можно сделать вывод, что модели последнего поколения достаточно мощные, чтобы хорошо справляться со специализированными задачами. Но любую модель можно подтюнить, и тогда она или превзойдет модель общего назначения или будет сравнима с ней требуя меньше железа.

Еще тренд - разделение моделей на легкие и тяжелые. Например, LLama 8b, 70b и 405b, это число параметров в billions. Т.е. большие модели - это дорого в облуживании, при этом во многих случаях применяются для "стрельбы из пушки по воробьям".

Tags:
Total votes 1: ↑1 and ↓0+1
Comments0

Всем привет!

Запилил небольшое сравнение AI чатов для задач разработки
Почему в Git - потому что там есть полноценный Markdown и таблицы.

Фокус на бесплатных инструментах - для тех, кто хочет попробовать. Сравнение функциональное + бенчмарки, без реальных запросов. По реальным задачам сделаю отдельный пост.

Пока мне больше всего нравится Perplexity. Работает без VPN, есть ссылки на источники, под капотом несколько мощных моделей, можно загружать книжки для пересказа и есть упор на точный поиск в интернете. Далеко не все инструменты в принципе умеют искать в интернете. Но даже те, что умеют - часто галлюцинируют. Примеры:

  1. что нового в Java 22 - все, кто умеют искать, ответили более менее точно

  2. первая тройка на Олимпиаде 2024 и разбивка по медалям - точно ответила только Perplexity, остальные показали рандомные цифры и даже страны.

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

Также выглядят интересными ChatGPT, Deepseek Coder и Mistral.

P.S. Я не спец по ML инструментам, я только учусь)

Tags:
Total votes 2: ↑2 and ↓0+4
Comments4

Всем привет!

И "последняя серия" про convention over configuration.
Я уже говорил, чем данный принцип полезен разработчику. Но можно посмотреть чуть шире.

1) с настройками приложения работают люди, не относящиеся к команде - тестировщики, DevOps-инженеры (да, они не должны этим заниматься, но ...), сопровождение ПРОМ. И у них будут похожие проблемы:
а) слишком много настроек
б) не понятно, что важно
в) не понятно, у всех одинаковые настройки (скопированные из каркаса) или у кого-то есть особенности, требующие внимания. По-хорошему, все должно быть описано в документации к релизу, но случается всякое)

2) для разработчика библиотеки или сервиса вывалить на пользователей сотню настроек, давая им возможность настроить "под себя" - самый простой, но не самый правильный вариант. Даже если ко всем настройкам есть подробная документация, но как я уже написал выше - случается всякое) Правильный подход - подумать, как этим сервисом будут пользоваться. Это на самом деле проблема. Не для всех, open sourse библиотека, которую неудобно использовать, скорее всего не пройдет "естественный отбор". А вот в "кровавом enterprise" проблема проявляется во всей красе. Не всегда пользователи могут отказаться от использования какой-то части платформы. Так вот, чтобы понять оптимальные настройки по умолчанию - надо поставить себя на место пользователя. Или собрать обратную связь, или пользоваться своим продуктом. Т.е. convention over configuration способствует движению в правильном направлении

Tags:
Total votes 1: ↑1 and ↓0+3
Comments0

Всем привет!

Снова попробую сам с собой поспорить ... санитары, ау ... так ли хорош принцип convention over configuration.

  1. Первое возражение я уже упомянул в предыдущем посте. А как же полный контроль над настройками проекта? Мало ли что там в значениях по умолчанию.
    Ответ: при текущей модульности и сложности ПО - это видимость контроля. Невозможно вынести все настройки в один файл. А даже если и возможно - как потом с этим работать?
    С другой стороны достаточный набор модульных и регрессионных тестов плюс нагрузочное тестирование дает некую уверенность, что все настроено верно. А тесты нужны в любом случае.

  2. Если система прячет от нас настройки - она менее гибка, и в нестандартном use case ее придется настраивать "через одно место". И это в самом деле важный момент. convention over configuration не означает, что разработчик компонента спрятал все настройки в "черный ящик". Это неправильный convention over configuration. Правильный - разработчик продумал некие настройки по умолчанию, удовлетворяющие основные use cases, но оставил возможность подтюнить при необходимости.
    Это может быть application.yaml в Spring Boot, код на Kotlin или Groovy DSL в Gradle или даже написание плагина в Maven. Последний кейс может показаться антипримером - настроить что-то под себя достаточно сложно. Но как раз за это многие и любят Maven - сделать из скрипта сборки "большой ком грязи" на Maven гораздо сложнее, чем в том же Gradle. Так что кажется, что и такой вариант допустим.

Tags:
Total votes 1: ↑1 and ↓0+3
Comments1

Всем привет!

Я часто вижу в проектах лишние настройки. Они попадают в проект следующими путями:

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

  2. решили явно прописать какие-то настройки, для надежности

Я считаю, что так делать не надо. Почему?

  1. лишние настройки раскрывают лишние детали, которые или не нужны, или нужны, но не сейчас. Повышается когнитивная сложность кода. Знать все детали своего сервиса - это хороший подход, был, лет 10-20 назад. ПО очень сильно развилось в плане специализации, количество зависимостей среднего проекта - несколько сотен, поэтому знать все детали просто невозможно

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

  3. среди скопированных настроек могут быть не нужные в данный момент. Код легко меняется, ТЗ - тоже, поэтому добавлять что-то "на вырост" не стоит

  4. настройки со временем могут превратится в некий аналог "большого кома грязи", который будут боятся трогать. Как разработчики, так и сопровождение. Чтобы этого не допускать - настройки нужно чистить. Чтобы меньше было чистить - не нужно добавлять лишнее

А вообще есть такой хороший принцип - convention over configuration. Тоже моя любимая тема) Принцип говорит о том, что должны быть настройки по умолчанию, устраивающие большинство потребителей. Эти настройки потребитель не задает явно, они уже заданы.

Tags:
Total votes 1: ↑1 and ↓0+1
Comments0

Всем привет!

Я уже писал о пользе стандартизации на примере формата данных для сохранения информации о сборке - cyclonedx. А недавно в посте про работу с исключениями упоминал библиотечку для возврата ошибок в API - jdoctor.


Так вот - стандартизация добралась и сюда)


Во-первых, как выяснилось - уже с 2016 года есть стандарт "Problem Details for HTTP APIs"
Во-вторых - в Spring Boot 3, т.е. с 2021 года, появилась его имплементация. Вот неплохое описание у baeldung
Если вкратце - ответ при ошибке будет иметь стандартизированный вид похожий на такой:
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "Invalid request content",
"instance": "/sales/calculate"
}

Библиотеки, решающие подобную задачу в Java, уже были:

  1. уже упомянутый jdoctor

  2. error-handling-spring-boot-starter

    Но думаю, что именно данное решение - от Spring, да еще по стандарту - имеет шансы популяризовать данную практику.

Что еще хочется отметить:

  1. стандартизация рулит) Каждый поставщик API разрабатывает формат для ответа при ошибке, каждый потребитель - специфический код для его обработки. А при этом понятно, что формат информации об ошибке мало зависит от бизнес-процесса

  2. еще в 2018 году в Сбере формат ответа для REST был стандартизирован. Но, увы, формат отличается от RFC, а область применения ограничена взаимодействием с фронтом.

Tags:
Total votes 1: ↑1 and ↓0+1
Comments2

Всем привет!

Ну что, началось)
https://www.piter.com/collection/all/product/programmirovanie-na-python-s-pomoschyu-github-copilot-i-chatgpt

Ок, ещё одна книжка про ChatGPT. Смотрим аннотацию: «Используя GitHub Copilot, можно простым языком описать, что должна делать программа, а искусственный интеллект тут же сгенерирует ее. Узнайте, как создавать и улучшать программы на Python с помощью ИИ, даже если прежде вы не написали ни строчки компьютерного кода.».

И ещё: « Глава 4 — первая из двух глав, в которых вы научитесь читать код на языке Python. Действительно, Copilot будет писать код за вас, но вам нужно уметь читать его, чтобы определить, будет ли он делать то, что вы хотите. И не волнуйтесь: Copilot поможет вам читать код!»

И это не ролик, не статья, целая книга... Войти в IT, если с первого раза не получилось) Интересно, на собесах Copylot уже используют?)

Меня только один вопрос мучает: если человек не захотел или не смог освоить язык программирования или фреймворк - как хорошо он сможет спроектировать сервис или алгоритм?

Tags:
Total votes 2: ↑2 and ↓0+4
Comments4

Всем привет!

Я иногда даю ссылки в своих постах на википедию. Ясное дело, что 100% гарантии достоверности статей в вики никто не даст. Народное творчество. Но в большинстве своем техническая (!) информация верна. Но есть забавные нюансы.

Ищу информацию по алгоритмам, используемым в Rate Limiters. Есть такой алгоритм - Token Bucket. Есть статья по нему https://ru.wikipedia.org/wiki/Алгоритм_текущего_ведра Алгоритм статья описывает в целом верно, хотя и добавляет туда сетевой специфики, видимо автор создал ее разбираясь в работе сетей, например QoS. Но посмотрим на название. Алгоритм текущего ведра. Токен = текущее? Причем проблема не в творческом переводе. У меня уже была ссылка на статью с описанием основных алгоритмов https://habr.com/ru/articles/448438/ Смотрим туда Leaky Bucket - протекающее ведро. Вполне логичный перевод. Но у нас же Token bucket. Или алгоритм маркерной корзины, что собственно мы и видим в первой же строчке статьи вики. Это два разных алгоритма. А статья создана в 2008 году, сразу с неправильным заголовком.

Что в итоге - в итоге путаница. Если "загуглить" заголовок - https://yandex.ru/search/?text=Алгоритм+текущего+ведра то мы увидим условно 5 ссылок на Leaky Bucket и 5 ссылок на Token Bucket, причем последние - это копии статьи с русскоязычной вики в других вики.

Второй вывод - мало просто скопировать википедию...)

Tags:
Total votes 1: ↑1 and ↓0+3
Comments0

Всем привет!

В продолжение предыдущего поста попробую сам себе возразить.
Предположим, что наши DevOps инженеры круто настроили pipeline: все атрибуты, которые должен настроить разработчик, параметризованы. Например, с помощью чартов Helm.
Значит ли это, что разработчик может расслабиться и не изучать все эти ваши Deployment, EnvoyFilter, VirtualService ...? Мой ответ - нет. И вот почему.

  1. если рассуждать дальше, то и Docker разработчику не нужен. Пусть его же DevOps-ы настраивают. А я на Tomcat встроенном запущу. Но вспомним в чем суть Docker - единая среда у разработчиков, тестировщиков и ПРОМа. Что позволяет избежать большой части ошибок, возникающих из-за разницы настроек окружения. Не всех, но большого числа

  2. окей, Docker пусть будет. А k8s? Но идея та же. Приложение в облаке ведёт себя по другому, чем в standalone. Его может в любой момент прибить k8s и поднять на другой node. А это ограничивает возможности локального кэширования. В облаке несколько приложений может работать параллельно. Это нужно учитывать, например, при чтении из топика Kafka. Более того число подов может меняться - см. HorizontalPodAutoscaler. Еще момент - по умолчанию у нас ephemeral storage и надеяться на сохранение логов после перезапуска нельзя. А ещё одно из Cloud Native требований - быстрый старт приложения, опять же из-за потенциального перезапуска в любой момент. На этот момент не всегда обращают внимание, хотя варианты улучшения времени запуска есть.

    Надеюсь, я вас убедил. Если нет - жду в комментах

Tags:
Total votes 1: ↑1 and ↓0+3
Comments0

Всем привет!

Когда заходит речь о разделении обязанностей между разработчиками и DevOps инженерами, споры обычно возникают в двух моментах - манифесты k8s\Openshift и CI джобы - они же джобы сборки. Поговорим про первые.
Мое мнение - за манифесты k8s\Openshift должны отвечать разработчики. Почему? А вот почему:

  1. liveness\readiness probes - только разработчики знают, по каким url они находятся. Конечно в мире Spring Boot и Actuator есть некая стандартизация, но не везде и не всегда. И не всегда actuator подходит для healthcheck, но это отдельная тема

  2. liveness\readiness timeouts - разработчики точно знают сколько времени старт пода. DevOps-ы могут это время эмпирически определить, но это требует времени)

  3. timeouts, circuit breaker, retry - опять же только разработчики могут сказать, реализовали они их на прикладном уровне или требуется настройка на уровне Service Mesh. Могут быть требования корпоративной архитектуры\сопровождения ПРОМ, их определяющие, но опять же не везде и не всегда.

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

  5. любые другие тонкие облачные настройки - переменные среды, значение параметров в ConfigMap, поддержка graceful shutdown .... Наверняка DevOps или сопровождение со всем этим разберется. Но будет ли это эффективно?

Tags:
Total votes 5: ↑2 and ↓3+3
Comments0

Всем привет!

Хочется сказать пару слов о практике T-Shape. Это когда помимо основной специальности - например, разработки, ты развиваешься в чем-то еще. Если рассмотреть состав типовой команды, то это аналитик или тестировщик. Может быть DevOps или НТ. Или даже сопровождение ПРОМ. Насколько я знаю, такая практика есть в Яндексе. Рассмотрим плюсы и минусы на примере разработчика-тестировщика.

Плюсы очевидны:

  1. взаимозаменяемость членов команды

  2. упрощение найма за счет унификации

Но есть и минусы.

  1. суть работы тестировщика - найти проблемы в коде, рассматривая его как черный ящик. Именно потому, что тестировщик не знает, что внутри, но знает, как должно работать, ему удается найти "новые" баги. Конечно, можно ввести практику: код пишет один разраб, а тестирует другой. Но это усложнение и человеческий фактор.

  2. развитие ИТ идет в сторону более узкой специализации. Да, любую технологию можно изучить. Проблема в том, что их очень много. Много и в разработке, и в тестировании. И распыляя свои усилия на 2 направления есть риск полноценно не научится ни тому, ни другому.

  3. пункт субъективный т.к. я разработчик. Сравнивая разработку и тестирование как две области деятельности я бы всегда выбирал разработку. IMHO, она сложнее и поэтому интереснее. Отсюда риск, что на тестирование будет выделяться меньше времени. Вопрос в уровне инженерной культуры и дисциплине, но это снова человеческий фактор.

    Итог - практика интересная, но требует высокой инженерной культуры и подвержена влиянию человеческого фактора

Tags:
Total votes 1: ↑1 and ↓0+1
Comments4

Всем привет!

Как приучить себя писать модульные, они же unit тесты?

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

  2. изначально определить, что обязательно должно быть покрыто тестами, остальное исключить из контроля покрытия. Если конечно у вас подключен контроль покрытия) Ничто так не демотивирует, как написание ненужных тестов на тривиальный код

  3. заставить себя написать первые скажем 100 тестов. Или 200. После того, как ключевые классы с бизнес-логикой будут покрыты тестами, появляется уверенность при рефакторинге кода. Правишь что-то, запускаешь тесты, убеждаешься, что ничего не сломал. Возвращаешься к коду спустя полгода, что-то правишь и снова все ок. Это одно из самых крутых свойств нормального покрытия кода тестами. Но для начала этого уровня покрытия нужно достичь, т.е. первое время видимого эффекта от тестов не будет.

  4. переписать медленные тесты, разделить быстрые и медленные. Как правило это разделение совпадет с модульные-интеграционные. Модульные запускать как можно чаще. Причина - ожидание 5 минут ну когда же закончатся тесты - бесит

  5. самый смешной пункт - включить в IDEA отображение успешно пройденных тестов. Сотня зеленых галочек... успокаивает что ли))))

Tags:
Total votes 2: ↑2 and ↓0+4
Comments0

Всем привет!

Какие компиляторы есть в Java?
Простой ответ - javac. Компилирует исходники в байт-код, который исполняет JVM. Исполняет и оптимизирует. И основные оптимизации происходят именно runtime, а javac является "примитивным". Идея в том, что собирается статистика использования кода, часто используемый код компилируется в "нативный" для конкретного процессора, а неиспользуемый удаляется. Получаем плюс один компилятор - JIT (Just in Time). Только исторически компиляторов два: С1 - быстрый, но оптимизирующий не оптимально))), второй C2 - медленный и хорошо оптимизирующий. Сейчас они используются в паре, см. https://for-each.dev/lessons/b/-jvm-tiered-compilation

А можно без байт-кода? Да, есть AOT (Ahead of Time) компилятор, поставляется в GraalVM https://graalvm.org/latest/reference-manual/native-image Он сразу компилирует в требуемый "нативный" код. А если поддержки требуемой процессорной архитектуры нет? Растет популярность ARM архитектур, а там тот еще зоопарк. А для этого уже существует промежуточный язык и набор компиляторов LLVM https://llvm.org/. Что-то типа Java байт-кода, только не привязанный к Java. GraalVM его поддерживает https://graalvm.org/latest/reference-manual/native-image/LLVMBackend
А можно его использовать и как runtime компилятор? Почему нет, в Azul JDK отказались от C1\C2 и сделали свой компилятор с LLVM - https://azul.com/products/components/falcon-jit-compiler

А еще есть компиляторы Kotlin, Scala, Groovy, Jython, JRuby... В общем я сбился со счета)

Tags:
Total votes 4: ↑3 and ↓1+3
Comments0

Всем привет!

Продолжаю серию полезных видео - https://youtu.be/j-i3NQiKbccТут по полочкам расписывает как работает логирование в Java.

Краткий конспект по архитектуре логирования:

  • адаптер - предоставляет API, которое вызывается из кода. Их всего 3 - SL4J, JCL (Apache Common Logging) и JBoss Logging. Самый распространенный и рекомендуемый - SLF4J

  • bridge - нужен, когда какая-то библиотека использует не тот адаптер, что мы хотим. По сути адаптер на адаптер, который эмулирует API, вызываемое из кода, и пробрасывает вызовы в нужный адаптер, как правило SLF4J. Понятно, что когда у нас есть адаптер на адаптер, есть риск бесконечной рекурсии. Про это надо помнить)

  • движок логгера - компонента, которая пишет логи. Примеры: log4j, log4j2, logback, JUL\JDK (встроенный в JDK)

  • appender - компонент, определяющий физическое место, куда пишутся логи: консоль, диск, БД, MQ... Вот полный список для log4j2 https://logging.apache.org/log4j/2.x/manual/appenders.html

  • фильтры и конверторы - позволяют отфильтровать или преобразовать сообщения на клиенте

Плюс 3 хороших совета:

  • соблюдать гигиену classpath - чистить его от лишних библиотек

  • логи могут стать основой мониторинга. Мы отбрасываем специальным образом размеченную запись в лог, которая после обработки становится событием мониторинга

  • не добавлять в свои библиотеки как зависимость движок логгера. Пусть его выберет потребитель, а не разбирается с транзитивными зависимостями

И 2 полезные утилиты - миграторы на logback и SLF4J с альтернативных библиотек.

Tags:
Total votes 1: ↑1 and ↓0+3
Comments0
1

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity

Specialization

Backend Developer, Chief Technology Officer (CTO)
Lead
Git
SQL
OOP
Java
Docker
Kubernetes
Java Spring Framework
High-loaded systems
Designing application architecture
DevOps