DMdev talks
3.24K subscribers
156 photos
13 videos
89 links
Авторский канал Дениса Матвеенко, создателя DMdev - обучение Java программированию

То, что все ищут по Java:
https://taplink.cc/denis.dmdev

P.S. Когда не программирую - я бегаю:
https://t.iss.one/dmdev_pro_run
Download Telegram
P.S. Для тех, кто не в теме, оставляю ссылку на предыдущие выпуски "Code Review"
DMdev Code Review!

Всем спасибо за участие в опросе. Code Review быть!

Когда: 20.08.22 (суббота) в 10:00 по Москве
Где: прямая трансляция в Google Meet
Продолжительность: 1-1.5 часа
Количество человек: до 100

Кто хочет стать участником code review - подготовьте ссылку на github с кодом своего небольшого проекта.
В начале стрима я выберу рандомную ссылку. Из практики успеваю разобрать 2-3 человека.

P.S. Не стесняйтесь, это отличный шанс получить обратную связь по своему коду и помочь улучшить свои навыки!

До встречи в эфире👇
🔥31👍8🎉7
Best practices in Code Review

Ни один merge своего кода в main ветку не обходится без code review.
А значит каждый разработчик с этим сталкивается при ежедневной работе.

Для хорошего code review, нужно придерживаться определенных правил “на что обратить внимание”.
Эти правила не только разительно улучшают качество его проведения,
но и делают процесс действительно полезным для обоих сторон (owner & reviewer).

Тогда code review не будет сводится к принципу “лишь бы оставить комментарий”.
Все комментарии будут только по делу и не тратят впустую время разработчиков.

1. Код хорошо спроектирован
2. Функциональность легко читать, а значит использовать и поддерживать другим разработчикам
3. Код и его форматирование придерживаются общего стиля всего проекта
4. Нет привнесенной сложности. Код не сложнее, чем требует от того задача
5. Важен не только сам код, но и его контекст
6. Код безопасно работает в многопоточности
7. Код качественно покрыт тестами, которые точно также легко читаются
8. Если и есть комментарии, то они полезны и отвечают на вопрос “почему”, а не “как”

Делись в комментариях о каком пункте было бы интересно узнать более подробно - расскажу в отдельных постах

#dmdev_ликбез
👍39🔥91
На канале уже опубликовано первое видео нового курса Bash!

В первом уроке:
- Что нужно знать для прохождения курса
- GUI & CLI
- Командная оболочка shell
- Командная оболочка bash & zsh
- Что будет разбираться в курсе
- Зачем знать bash

Готов подружиться с Bash?
Переходи по ссылке, заваривай чашечку горячего чая и приятного просмотра 😊
🔥37👍11🎉7
Сейчас появилось свободное время из-за того, что заболел Covid.
К сожалению, это время приходится тратить по большей части на сон и отдых.
Тем не менее, удалось дочитать книгу “Не про бег”, которую как раз-таки мне и посоветовал друг, когда я начал заниматься пробежками.

На удивление, кроме большого потока полезной информации о беге, я записал себе две более глубокие мысли из нее:

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

2. Торопиться жить - это как брать в долг. Если не угадал с темпом в начале дистанции, то вторую половину придётся идти пешком.

Оба пункта на самом деле далеко не только про бег…
👍35🔥10👏3
DMdev talks
DMdev Code Review! Всем спасибо за участие в опросе. Code Review быть! Когда: 20.08.22 (суббота) в 10:00 по Москве Где: прямая трансляция в Google Meet Продолжительность: 1-1.5 часа Количество человек: до 100 Кто хочет стать участником code review - подготовьте…
В связи с тем, что я заболел Covid, решил перенести Code Review на неделю вперед.
Так мы сможем провести его более продуктивно для всех участников, ибо сейчас я не в своей лучшей форме 😁

Новое когда: 27.08.22 (суббота) в 10:00 по Москве

PS. Ссылка на митинг остается та же самая (кнопка в верхнем правом углу чата)
👍24
#dmdev_code_review
Недавно наткнулся на примерно вот такой код.
Здесь происходит сериализация Java объекта в xml (обычная строка) с помощью библиотеки jaxb.

Как думаешь, что не так с методом serialize? Или все так?
PS. Предположения/идеи пиши в комментариях
👍1
DMdev talks
#dmdev_code_review Недавно наткнулся на примерно вот такой код. Здесь происходит сериализация Java объекта в xml (обычная строка) с помощью библиотеки jaxb. Как думаешь, что не так с методом serialize? Или все так? PS. Предположения/идеи пиши в комментариях
1. Параметр marshaller изменяется внутри метода.
Best practices:
- clean code (всегда есть доступ к исходным параметрам функции)
- pure function/immutable (не изменяешь входные параметры, а значит безопасно вызывать такие функции извне)

2. Объект класса Marshaller - не потокобезопасный. Как и говорил в посте по code review выше - нужно всегда обращать внимание на работу кода в многопоточности. Поэтому лучше сделать вместо параметра - локальную переменную через jaxbContext (локальные переменные и jaxbContext точно потокобезопасны).

3. Многие писали про закрытие потока StringWriter. Но это не обязательно для данной реализации Writer, потому он что содержит внутри обычный объект типа StringBuffer.

4. <T extends Serializable> - тоже не следует делать для объекта сериализации, ибо ограничений у jaxb библиотеки на реализацию этого интерфейса тоже нет.

5. На null все параметры проверять и пробрасывать исключение тоже не имеет смысла - все методы будут громоздкие и неуклюжие. Используй Optional или обычные @NonNull аннотации, которые генерируют подобные проверки автоматически согласно fail fast principle

#dmdev_code_review
👍18🔥11
В который раз убеждаюсь, что как только ты пытаешься объяснить совершенно любую тему другому человеку, то намного глубже начинаешь понимать ее. Я бы даже сказал, что порой приходит какое-то озарение и складывается пазл в единую картину.

Как и сейчас при подготовке очередного видео по курсу Bash я пытался схематично показать разницу между soft и hard links в Unix operating systems, и сам понял, как это работает на самом деле 😅

Как же я люблю визуализировать!

А ты знал про inode number, который дополнительно хранится с именем любого файла, и для чего он нужен?
🔥32👍9
Как и обещал, выложил вчерашний уже третий выпуск live code review, где были разобраны 2 проекта, написанные на стандартном стэке технологий: Apache Maven, JUnit 5, Hibernate, Spring.

Также использовалось множество различных дополнительных библиотек:
- lombok для генерации boilerplate кода
- quierydsl для более удобного написания sql запросов с фильтрацией
- testcontainers для поднятия PostgreSQL в docker контейнере в интеграционных тестах
- liquibase для миграции баз данных
И многие другие, что были разобраны и объяснены на курсах dmdev.

Так что кто не смог участвовать, но очень хотел посмотреть - вот ссылка

#dmdev_code_review
👍39❤‍🔥4🤩3👏1
This media is not supported in your browser
VIEW IN TELEGRAM
Когда спрятал свой баг глубоко в код, и он прошел все тесты 😁

Наверное, это тот самый момент, когда можно сказать: "Это не баг, а фича!".

PS. Что-то все никак не могу успокоиться от этого видоса 😅

#dmdev_mems
😁60🔥11👍91
Ставишь final над параметрами и локальными переменными?

Многие разработчики предпочитают помечать параметры методов и локальные переменные ключевым словом final где это только возможно.
Лично я не поощряю такую практику за исключением единичных случаев.

В свою очередь я использую другой подход: по умолчанию нужно воспринимать ВСЕ параметры и локальные переменные как effectively-final (как в замыканиях).

Благодаря такой практике, вместо нагромождения кода ненужными ключевыми словами (которые отбирают драгоценное внимание программиста во время его прочтения), ты будешь:
- стараться делать методы более лаконичным и чистыми
- избегать изменения параметров (immutable)
- комбинировать или даже заменять императивный подход на функциональный (где не указываются вовсе final и даже типы данных).

#dmdev_ликбез
👍31🔥13
Ребят, кто пропустил информацию, то сейчас идет набор группы на менторство 1 ступени.
Старт: 19 сентября
Продолжительность: ~3,5 месяца
Свободно: 6 мест мест нет

Вся подробная информация о менторстве DMdev и запись тут:
https://dmdev.tilda.ws/first-level

PS. Вопросы можно также задавать здесь в комментариях
PPS. Пример финального проекта по окончании менторства есть на YouTube
👍19
Зачем инициализировать Prometheus Counter явно?

На практике при работе с метриками часто забывается, что только counters без labels инициализируются сразу же при их объявлении (по сути выставляются в 0).
Если же counter содержит хотя бы одну label, он будет проинициализирован только при первом инкременте c этой label.

И все бы ничего, но в таком случае написание alerts такого вида становятся некорректными:
sum(rate(validated_tokens_total[15m])) < 0.01

Потому что в случае отсутствия траффика на наш сервис (о чем собственно мы и хотим узнать, написав данный alert), мы получим no data, но никак не число, которое Prometheus потом сможет сравнить.

В таком случае, мы можем упустить инцидент: пользователям не отвечает наше приложение, а мы об этом даже не знаем!

Решений здесь 2:
1. Обязательно добавлять второе условие c absent в подобные alerts: OR absent(rate(validated_tokens_total[15m]))
2. Просто инициализировать все возможные labels сразу же (как на картинке в static block)

Лично я предпочитаю второй вариант, потому что не могу надеяться, что все разработчики знают и помнят такие нюансы при написании alerts 😅

PS. Более подробно можно почитать здесь

#dmdev_ликбез
👍14🐳9🔥41
This media is not supported in your browser
VIEW IN TELEGRAM
🗣 Недавно мне задали вопрос:
«Как я подхожу к изучению любой библиотеки или фреймворка, чтобы хорошо и глубоко их понимать?"

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

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

Это как инвестиции: сначала ты тратишь больше времени, чтобы лучше изучить инструмент, но на более длительный период выигрыш просто увеличивается по экспоненте!

🗝 А отвечая на вопрос: простого ответа здесь нет, но есть как минимум 3 вещи, которые действительно работают для меня и эффективно справляются с этой задачей.

1️⃣ Debug
Это как остановить время (или быть в моменте), когда ты видишь состояние потока и всех объектов лишь в одной точке выполнения!
Более того, ты еще и управляешь им, заглядывая в прошлое и будущее!
Именно Debug дал первый толчок для меня в понимании программирования в принципе.

2️⃣ Чтение исходного кода изучаемых инструментов
Только исходный код всегда говорит правду, и только он является single source of truth.

3️⃣ Преподавание
Эту простую истину уже открыли задолго до меня: если хочешь что-то понять - попробуй рассказать другому.
Пожалуй, этот пункт повлиял на меня сильнее всего почти 5 лет назад, когда я решил заняться преподаванием.

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

PS. Кстати, заняться преподаванием меня сподвигло прочтение книги "7 навыков высокоэффективных людей"
👍31🔥11🤔2
Программисты, настоящие и будущие, всех с праздником 🎉

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

Делитесь в комментах, как отмечаете и какие плюшки приготовила для вас компания? 😁

P.S. Я начну первым комментом, как я провожу этот день)
🎉50🔥5👍3👎2
Личная победа 🏆
И мои 7️⃣ выводов после первого забега на 10.000 метров

1. Любое новое начинание первое время приносит мало приятного. В основном только боль и разочарование. Нужно это просто принять.

2. Если 2 месяца с нуля заниматься каким-то делом, но постоянно - то точно можно добиться уже хороших результатов.

3. Даже в течение небольшого промежутка времени (2 месяца) могут случаться форс-мажоры. Главное - восстанавливаться и продолжать идти к своей цели (в моем случае заболел ковидом и выпал на 2 недели).

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

5. С опытным ментором можно ускорить процесс роста в разы!

6. Очень здорово иметь единомышленников: они вдохновляют и мотивируют не останавливаться!

7. Празднуй свои большие и маленькие успехи. Поощряй себя за труд, который ты действительно проделал!
👍55🏆24🔥11👏3🎉2
Static imports

Часто замечаю некорректное или даже неуместное использование статического импорта методов и констант в классах.
Либо, наоборот, когда его не используют вовсе.

Хотя на самом деле, правильное применение его:
1️⃣ Убирает ненужный контекст (less verbose)
2️⃣ Уменьшает количество boilerplate кода
3️⃣ Улучшает читабильность кода

Но сложность в использовании или не использовании статического импорта мне понятна:
потому что нет и вряд ли могут быть четкие правила для этого.

: Когда же использовать статический импорт, чтобы получать все эти плюсы?
🗝: Когда его применение ясно и без дополнительного контекста, т.е. того класса, в котором находятся статические методы и константы.

Обычно это общеизвестные классы, но лучше сразу на примерах!

Уместное использование:
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static java.util.stream.Collectors.toList;
import static java.util.Arrays.asList;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static java.util.function.Predicate.not;
import static java.time.ZoneOffset.UTC;
import static java.nio.charset.StandardCharsets.UTF_8;


Неуместное использование:
import static java.util.Optional.of;
import static org.junit.jupiter.params.provider.Arguments.of;
import static com.dmdev.spring.entity.User.builder;
import static com.dmdev.spring.converter.DateConverter.convert;

PS. В любом случае статический импорт остается на совести разработчика 😊

#dmdev_ликбез
👍23🔥8👌4
Logging and re-throwing an exception

Почему логирование ошибки и сразу ее пробрасывание дальше - является антипаттерном?

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

Поэтому есть два варианта решения:
🗝 Либо логирование И обработка ошибки
🗝 Либо пробрасывание ошибки дальше БЕЗ какого-либо логирования (что обычно является более предпочтительным)

#dmdev_ликбез
👍47🔥10🤔62
Готовность: 99%
Bash
на финишной прямой - наконец-то дошел до создания финального практического занятия!

Как обычно не получилось обойтись 20-25 видео.
Каждый раз хочется рассказать еще что-то и внести правки в изначальный Bash Roadmap.

В итоге весь курс занял:
📌 34 видео
📌 ~5.5 часов контента
📌 ~2.5 месяцев создания

PS. На картинке план практического занятия, по которому будет реализована утилитная программа (Bash Script), соблюдая все best practices.

Спойлер: Bash Script будет управлять жизненным циклом приложения из курса по Spring 😎
👍53🔥276😍2🎉1