Pull to refresh
12
Станислав@SimSonic

Душный погромист

Send message

Никто не запрещает попробовать EAP / триалка ;)

Аналогично, не смог победить. Особенно проблема, если корневая помка в подпапке. Issue открыт несколько лет.

Вроде это обошёл новой фейковой помкой в корне, но столкнулся с отсутствием поддержки --enable-preview фич. Завел Issue.

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

Мы на проекте, чтобы избежать всего этого, включили sping-hibernate-query-utils в режиме exception, чтобы никаких N+1 не прошло. Сейчас надежда на тесты и QA, чтобы исключение не дошло до боя.

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

Пока наше решение это одновременно и включённые батчи в пропертях глобально в режиме PADDING, и 2х запросы.

Эх, жаль, что для моего Asus wl-520gc нет новой прошивки :)

Проектов на Kotlin и Spring Data JPA не существует?!?

Терминатор, Чужой, Нечто ... какие классные статьи про съёмки фильмов выходят последнее время, не нарадоваться! Я только на днях пересмотрел после прочтения статьи все 4 части Чужих, видимо, сегодня перед сном накрываюсь одеялкой и включаю Нечто ))

Кстати, а мне и 2 часть понравилась. Снято вполне аутентично. Правда смотрел только один раз, когда вышла, сейчас гляну обе вместе.

Спасибо, продолжайте =)

О, господи, сколько всего собрано в одном месте! Я попробую самые крупные огрехи хотя бы указать:

  • Банальный вывод статьи. Делать много запросов дороже, чем один - это очень важное сообщение от КО.

  • Использовать System.out.println, когда уже есть логгер (@Slf4j висит над классом).

  • Логирование 10к запросов в консоль, к слову, тоже влияет на результат ;)

  • Сразу же в application.yaml отключит OSiV.

  • На сущности висит Data, читать классическую статью https://thorben-janssen.com/lombok-hibernate-how-to-avoid-common-pitfalls/.

  • Можно побенчмаркать хотя бы JMeter-ом.

  • "Ребят, ревьюю ваш код, у вас тут поиск по email, а на нём индекса нет..."

Похвалить автора, конечно, тоже есть за что, например, что юзает StopWatch, а не сам мерит nanoTime., докер использует. В каждом ревью должно быть что-то позитивное =)

Если кому-то интересно, отчитываюсь за прошедшую зиму:

  • Ни единой проблемы с эксплуатацией не возникло.

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

  • Внизу под палетой скапливалась влага. Есть желание в будущем под неё насыпать кошачий силиконовый наполнитель, чтобы впитывал.

  • Картошка сохранилась прекрасно за всё время, а морковка и свёкла после НГ начали подсыхать. Отдам этот садоводческий вопрос в будущем на аутсорс.

  • Ни одна лампочка не перегорела, ни один рептилический нагреватель не вышел из строя. Даже самый дешёвый USB вентилятор из DNS открутил всю зиму без остановки и вышел из ящика как новенький (так и напишу у него в отзыве).

Данные за всю осень-зиму-весну
Данные за всю осень-зиму-весну

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

Тоже за 2 недели раза три помог мне найти решение, над которым не хотелось ломать голову.

Поддерживаю написанное выше, на нашем проекте со временем пришли к тем же выводам. Дополню несколько интересных моментов.

Использовать Spring-контекст гарантированно один раз за прогон всех тестов помогает вот такая простая штука:

@Slf4j
public class FailFastContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private static final AtomicBoolean flag = new AtomicBoolean();

    @SuppressFBWarnings("DM_EXIT")
    @Override
    public void initialize(@NonNull ConfigurableApplicationContext applicationContext) {
        boolean error = flag.getAndSet(true);
        if (error) {
            // throw new IllegalStateException("Second application context start attempt.");
            log.error("""
                              Second application context start attempt.
                              ####################################################
                              #     SECOND APPLICATION CONTEXT START ATTEMPT.    #
                              #     -----------------------------------------    #
                              #  Please look upper for the reason why Spring is  #
                              #  trying to recreate test context.  This can be   #
                              #  caused by adding an @Import/@MockBean and some  #
                              #  other annotations to the test class.            #
                              #                                                  #
                              #  This process will now exit immediately.         #
                              ####################################################
                              """);
            System.exit(-1);
        }
    }
}

Нужно только подложить его в @ContextConfiguration(initializers={...}) на главном тестовом классе приложения BaseApplicationTest (от которого удобно наследовать все непосредственно тестовые классы).

Вызовы своего боевого API совершаем через честный http-клиент. Это даёт небольшие накладные расходы на сериализацию/десериализацию, зато дополнительно покрывает: конфигурацию Jackson (кто не ловил, что Instant сериализуется в массив чисел?), цепочку фильтров (особенно если подложены свои фильтры), настройки приложения (вкл/выкл OSiV?) и т.п. В общем, успешно пройденный тест даёт ещё больше гарантий, чем вызов напрямую контроллеров.

Иногда (в полной мере этого слова) — всё-таки приходится искать способы внедрить какие-то ассерты в кишки боевого кода. Для этого можно придумать отдельный интерфейс, похожий на обычные функциональные (Function, Consumer, Supplier, в зависимости от вашей ситуации), и инжектить в боевой код Optional<ThisInterface> и дёргать в нужном месте. Естественно, в боевом контексте не будет реализации и ничего выполняться не будет. В тестах подкладывать собственную реализацию этого интерфейса, инжектить в свой тестовый класс, использовать. Обычно внутри реализации прячется какой-нибудь Exchange, AtomicReference или какой-то такой примитив для обмена данными.

Не стесняйтесь в тестовом коде писать свои контроллеры, сервисы и даже репозитории. Все они могут помочь не строить костыли. Или можно написать просто класс-accessor для package-private данных в каком-то боевом пакете, просто расположив его в нём же и сделав публичным. Сделать какой-то боевой код (классы, методы) package-private вместо private — может быть приемлемым компромиссом в ряде случаев. Я тогда в комментариях так и пишу "Является package-private для целей тестирования".

Ну и самая пушка в нашем проекте — гарантия от тестовой инфраструктуры в сторону теста, что БД всегда чиста. Требует некоторое время для реализации, даёт некоторые накладные расходы, зато как приятно ощущать, что тест действительно изолирован от остальных. Очень радует и при написании новых, и при исправлении имеющихся.

В заключении хочется повторить Uncle Боба — относитесь к коду своих тестов также, как к боевому, и ни в коем случае не как к коду второго сорта.

Тут есть некий замкнутый круг, что бы понять, что best practice — вот он, нужно сначала узнать основы, в какой-то мере и плохие практики тоже нужно сначала увидеть.

Джава ускорилась, и JebBrains приходится больше сил тратить на её поддержку в IDEA, чем развивать Котлин :)

Здесь так много тех, кто любит минусовать и не аргументировать :)

Ждём, пока ломбок подтянется, и в прод!

Все эти номера версий с уже давно почившим временем жизни оставляют какую-то неприятную нотку. От 16 до 17 один релиз, критичного ничего не добавляли, зато отношение было бы куда лучше. ИМХО.

Information

Rating
5,706-th
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity

Specialization

Бэкенд разработчик
Ведущий
From 500,000 ₽
Java
Spring Boot
PostgreSQL
MySQL
Docker
Kubernetes
CI/CD