Обновить
11
Станислав@SimSonic

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

0,1
Рейтинг
3
Подписчики
Хабр Карьера
Отправить сообщение

Терминатор, Чужой, Нечто ... какие классные статьи про съёмки фильмов выходят последнее время, не нарадоваться! Я только на днях пересмотрел после прочтения статьи все 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 один релиз, критичного ничего не добавляли, зато отношение было бы куда лучше. ИМХО.

Ломбок прекрасная вещь :)

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

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

При желании, вы можете сходить на такой фильм и написать заявление на незаконность происходящего.

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

Про "стандартное": скорее не так. Я не советую воровать. Меня тоже не очень радует ситуация, куда всё идёт. Но, оказавшись в какой-то не очень комфортной ситуации (или находясь в ней долгое время) не имеет смысла её отрицать, пытаться не видеть. А попытки указать на объективное её наличие -- её поддержкой.

Применительно к кинотеатрам. Год назад кинотеатры процветали, было много фильмов, зрителей, стало много и самих кинотеатров, и каких-то сопутствующих им вещей, та же продажа попкорна, условно. Рынок вырос и на нём были трудовые места. Сейчас всё упало, а людям надо платить зарплату. Или увольнять, увеличивая безработицу. Вот можем мы с вами гарантировано сказать, что все кинотеатры наживаются на пиратских показах, или все они делают это, чтобы поддержать оборот и людей на рабочих местах? Истина будет где-то посередине, но в обсуждениях обычно рассматриваются только крайности.

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

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

Имхо :)

Добавлю, что читать длинные строки трудно. Вместо того, чтобы читать код в плоскости высота+ширина (и тем более листать вправо), легче воспринимаются более вертикальные, одноразмерные конструкции. IMHO, в примере выше разбиение по строкам несколько помогает.

avgDeliveryOrderFulfillmentTime = superLongVarNameWithAdditionalInfo
                                  + anotherOneLongVarName / 2;

А вообще, тут ещё режет не длина, а отсутствие смысла. Смесь смысла и не-смысла. Если вместо абстрактных superLongVarNameWithAdditionalInfo и anotherOneLongVarName подставить бизнесовые смыслы, внезапно формула становится эмоционально приятнее.

avgDeliveryOrderFulfillmentTime = avgOrderCookingAndPackagingTime
                                  + maxOrderCourierDeliveryTime / 2;

Но в целом, конечно, да. Короткие скоупы -- очень хорошо. Иногда и i имеет право на жизнь, хотя я стараюсь всё-таки писать orderId :)

Информация

В рейтинге
4 663-й
Откуда
Новосибирск, Новосибирская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

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