senior junior developer
125 subscribers
89 photos
4 videos
70 links
Привет! Меня зовут Максим @senior_junior_dev, я Java-разработчик. Делюсь здесь своим опытом в индустрии.
Download Telegram
Постепенно выхожу из зимней спячки. Мысли пришли в движение, и я наконец понял для себя, за что люблю Новый год.

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

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

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

Вообще-то этим можно заниматься не привязываясь к конкретной дате, которая наступает неизменно, но всего раз в году. Просто так принято. И это, как по мне, уже неплохо.

А Новый год я люблю за длинные выходные 😃
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4😁1
Как вам этот интерфейс?
public interface NewsletterSender {
void setSmtpServer(String smtpServer);
String getSmtpServer();
void setFromAddress(String fromAddress);
String getFromAddress();
void send();
}

Авторы книги Pro Spring 6, An In-Depth Guide to the Spring Framework утверждают, что:
Thus, placing setters and getters for configuration parameters in the business interface is a good idea and makes setter injection a valuable tool.

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

1️⃣ Configuration parameters are passive

Параметр smtpServer — пример пассивной зависимости, он сам не выполняет никаких действий, а лишь используется под капотом, в том числе другими (активными) зависимостями.

2️⃣ Configuration parameters are usually information, not other components

Здесь упор на то, что адрес smtpServer не является частью нашей системы/архитектуры. Условный набор эвристик (правил поведения) List<Rule> rules(), разрешающий/запрещающий отправку письма является контрпримером этого правила.

3️⃣ Configuration parameters are usually simple values or collections of simple values

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

Написано всё вполне логично! Однако обратимся к типичному использованию такого интерфейса в Spring-приложении:
@Service
public Service NewsletterService {
private final NewsletterSender newsletterSender;

...
}


Очевидно, что из всего многообразия методов в NewsletterService будет использоваться только void send(). А теперь, как бы это пошло ни звучало, обратимся к принципам SOLID, а именно к interface segregation principle (ISP), который гласит, что код не должен зависеть от методов, которые он не использует. Лишние методы еще и раскрывают детали реализации, указывая протокол в сигнатуре метода. Вишенкой на торте является передача параметров в "сыром" типе String, вместо специализированных классов, где не будет возможности ошибиться, передав адрес, например, в некорректном формате.

Авторы, простите, но такой код на Spring'е нам не нужóн!
👍21💯1
😁11
Почему каждый раз не делают собственное (простое / понятное / маленькое) решение, а берут Open Source?

Мы в банке часто пишем свои стартеры, библиотеки, боты и т.д. Хорошо ли это? Предлагаю обсудить.

1️⃣ Нет универсальности

Универсальность — обоюдоострый клинок. С одной стороны заточенное под решение нашей задачи ПО будет лучше справляться (по крайней мере после нескольких итераций разработки 😃) с этой самой задачей. С другой стороны любой шаг в сторону от исходной проблемы, о которой мы ранее даже не могли подумать, может потребовать значительной переработки архитектуры / кодовой базы исходного решения. Взрослый Open Source уже прошёл через все эти грабли, так как используется многими командами для решения разных задач со своими ограничениями.

2️⃣ Нет "бесплатных" мейнтейнеров

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

Разработчики обычно не любят вникать в очень специфичные решения, которые более нигде, кроме как в вашей компании не используются. Будет проще, если это библиотека, которая решает распространенные задачи по типу кэширования / логирования / работы с БД и т.п.

3️⃣ Ограниченное коммьюнити

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

4️⃣ Вы всегда альфа- или бета-тестер

Обычно новые внутренние решения проходят процедуру "пилота", когда на нескольких командах-добровольцах отлавливаются детские проблемы. Моя команда много раз в числе первых подключала новые библиотеки, сервисы, процессы и т.д. И каждый раз это была боль, которую нам приходилось перетерпеть: это и падающие тесты, и несостыковки контрактов, и баги, из-за которых съезжал релизный цикл. Радует то, что мы до сих пор используем все те решения, они показали свою состоятельность. Но и флэшбэки одолевают нас до сих пор 😢 А прямо сейчас правлю баг в библиотеке кэширования на стыке near-cache и синхронизации записи несколькими потоками по одному ключу... Кстати, этому багу год, но нарвались в проде на него почему-то только сейчас.

5️⃣ Вопросы безопасности

Безопасная разработка — по сути отдельная высокооплачиваемая профессия профессия, которую надо бы иметь всем, но большинство разработчиков имеют слабое (ограниченное) представление. Почему? Это сложно → таких людей мало (а задач много) → они занимаются своими узкоспециализированными вопросами, на всех их не хватает.

Понятное дело, что Open Source тоже дырявый, но он больше челенджится энтузиастами и становится лучше. Внутренние решения могут игнорировать этот аспект вовсе. И уж точно сложно представить, что кто-то пойдет пилить свой легковесный аналог Keycloak'а.

———

Тем не менее внутренние разработки должны быть. Мы упростили множество процессов и рутины благодаря им. Со временем плохие / невостребованные решения отмирают, а хорошие — приживаются и эффективно решают поставленные задачи, часто сами перерастая в Open Source решения.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤔1🌚1
На работе прилетело несколько интересных задач. Сегодня поделюсь одной из них.

Саппорт (функциональное сопровождение) прода пришел с жалобой на то, что алертинг, настроенный на логи, не может нормально работать. Причина простая: у большинства документов в Elasticsearch (ES), который мы используем как хранилище логов, по одной и той же ошибке (один и тот же logger.error(...) в коде) разное значение поля message.

Почему так происходит? В поле message кроме непосредственно описания происходящего мы часто фиксируем уникальные идентификаторы / параметры / свойства (и т.п.) важные для последующего анализа. И именно по этому полю не😃 происходит группировка сообщений с последующим не😃 срабатыванием настроенных алертов. С причиной разобрались: сообщения разные, а значит в одну группу они не попадут.

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

Как решить проблему? Убрать лишнее из message. Совсем? Потеряем в информативности. Тогда вынесем "лишнее" в отдельное новое поле документа по аналогии с тем, как это делают с userId и traceId и другими. Как его назвать? Мне пока нравится универсальное context, так как содержимое от лога к логу в среднем будет абсолютно разное.

Раз уж придется лезть в эту историю, то как будто хочется заиметь еще одно поле, которое будет отвечать за категорию (идентификатор) проблемы. Каждая категория — отдельный код. Мы заранее составляем справочник таких кодов и в логах используем их. Один и тот же код может использоваться сразу во многих местах для однотипных ситуаций. Кажется, что это должно быть удобно как для алертинга, так и для анализа, в т. ч. построения дашбордов. Надо подумать 🎹
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
Соскучились? Я тоже 👋

Только вернулся с тура по Байкалу! Отпраздновали день рождения и проводили на топовую позицию в международной компании нашего дорогого друга!

Красивая, вкусная и насыщенная на эмоции поездка. Мы ни в чём себе не отказывали и за неделю уложились в скромные ~250 т.р. на человека с учётом проживания и дороги 😕

А ещё нам два раза несказанно повезло!

Мы не утонули. В последние дни было особенно тепло и лёд активно расходился. К сожалению, одна буханка с группой китайских туристов ушла на дно озера.

Не пересеклись с Шаманом. Без комментариев.

Всем прекрасных длинных выходных!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥65👍2
Всё! Больше никаких Merge Request! Как собственно и Pull Request... Шутка! Пока что...

Давече прочитал уморительную статью "Законъ о запрете иностранных словъ… в разработке". Причиной появления оной послужила новость:

С 1 марта 2026 вся публичная информация для потребителя должна быть на русском — № 168-ФЗ.


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

Предлагаю план из двух пунктов:
1. начать активно читать переведенные иностранные издания (для меня они абсолютно нечитабельные, вспомнить хотя бы Java Concurrency In Practice под авторством Brian Goetz)
2. запастись словарём иностранных слов. Почему им? Читай нормативы!

А знаете, что-то в этом есть. Не грубое legacy, а национальное достояние культурное наследие 😃.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5
Пример из резюме того, как надо любить себя 🧠

Сколько у вас получилось?
Please open Telegram to view this post
VIEW IN TELEGRAM
3😁3