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
В который раз убеждаюсь, что как только ты пытаешься объяснить совершенно любую тему другому человеку, то намного глубже начинаешь понимать ее. Я бы даже сказал, что порой приходит какое-то озарение и складывается пазл в единую картину.

Как и сейчас при подготовке очередного видео по курсу 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
This media is not supported in your browser
VIEW IN TELEGRAM
☝️Путь к успеху

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

Хотел сначала написать более подробно об этом пути, но получилось слишком много текста для поста и больше стало походить на начало книги автобиографии 😅

🔥 - опубликовать набросок
😱 - оставь себе, не люблю много читать
🔥151😱62😈1
#1 Мой путь

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

Кто-то из знакомых рассказывал, что есть университет в Минске - БГУИР (Белорусский Государственный Университет Информатики и Радиоэлектроники), где всему научат, и где ты сможешь получить то, чего так хочешь. Как сейчас помню, это был 8 класс и первая осознанная цель в жизни - поступить в БГУИР.

К сожалению, твои цели не всегда соответствуют реальным происходящим событиям. Дело в том, что я учился по новой 12-летней программе обучения, которая, как оказалось, была неудачной. В конце 10 класса мы все узнали, что будем поступать уже в следующем году вместе с ребятами по 11-летней программе. Другими словами, двойной поток и искусственное увеличение конкурса в 2 раза на бюджетные места в учебных заведениях.

Проблема в том, что я из многодетной семьи, и рассматривались возможности поступать исключительно на бюджет. Следовательно, шанс был всего один, а стать программистом очень уж хотелось. Поэтому я разузнал, что есть военный факультет в БГУИРе, куда поступить чуть ли не в два раза проще. Как итог: заявление в военкомат, многоэтапные медкомиссии, сдача физических нормативов и подготовка к ЦТ (Централизованное Тестирование).

Но что-то мне подсказывало, что на военном факультете будет не совсем то, чего я хотел…

После сдачи ЦТ я подсчитал все свои баллы вместе с аттестатом и пошел читать книгу прошлых лет о проходных баллах на факультеты БГУИР. Я понимал, что два потока будущих студентов должны неплохо увеличить этот балл, следовательно брал с запасом. По моим меркам, я должен был без проблем пройти на бюджет и, конечно же, не на военный факультет. Осталось лишь уговорить родителей и забрать заявление в военкомате.

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

В тот момент я не осознавал, насколько здорово они умеют держать свои обещания…

#my_little_story
👍89🔥28👏42😱1😢1
#2 Мой путь

1 сентября 2009 года - я поступил в БГУИР на специальность ИТиУТС (Информационные Технологии и Управление в Технических Системах) и стою возле 5 корпуса университета на открытии учебного года. Переехав из маленького города Мстиславль, Минск казался тогда просто огромным и невероятным! Столько высотных зданий, большие улицы, миллионы людей, даже впервые на метро покатался!

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

К сожалению, а может и, наоборот, к счастью, процесс обучения очень отличался от того, что я себе представлял. На первой лабораторной работе на своем первом языке программирования С задание звучало (дословно): скачиваем методическое пособие с сайта, находим первую задачу и начинаем писать код. И нет тебе каких-либо наставлений или объяснений, только куча вопросов у меня: где писать? как писать? почему все что-то делают, а я не пойму даже с чего начать?

Отсюда я получил урок номер 1: обучение в университетах построено практически полностью на самообучении, начитке кучи лекций и отсутствием практики.

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

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

#my_little_story
👍75🔥11👏6🤯41
Зачем столько однотипных методов of в интерфейсе List?

Начинающие джависты часто спрашивают меня (и, думаю, многие не начинающие тоже задавались вопросом), зачем разработчики языка Java добавили с десяток методов of в интефейс List, которые отличаются лишь количеством параметров.

И правда, зачем? 🤔
И есть ли действительно смысл в этом?

#dmdev_ликбез
🤔23👍3😐3
DMdev talks
Зачем столько однотипных методов of в интерфейсе List? Начинающие джависты часто спрашивают меня (и, думаю, многие не начинающие тоже задавались вопросом), зачем разработчики языка Java добавили с десяток методов of в интефейс List, которые отличаются лишь…
📚 В топ-1 книге для Java разработчиков “Effective Java” by Joshua Bloch отлично описывается зачем приходится перегружать методы таким образом и как выбирается количество элементов без использования varargs.

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

На картинке тот самый кусочек информации из книги!
(3rd Edition, Item 53 “Use varargs judiciously”)

#dmdev_ликбез
#dmdev_top_books
👍31🔥101🤔1
#3 Мой путь

На своем стареньком компьютере я установил не менее старенькую среду разработки Visual Studio 2005 для того, чтобы писать свои программы на языке С уже там, а не на листке бумаги. Почему-то код не стал быть более понятным. Я уже мог отличать ключевые слова, такие как for, if, array[]. Я понимал, где ставить фигурные скобочки, что вот это циклы, это ветвления, а вот это массивы и функции, но не более. Я не мог осознать, как самому это написать и почему ключевое слово return еще и что-то куда-то возвращает.

В один прекрасный день я увидел, как мой одногруппник использует дивный функционал в той же самое среде разработки. Он как будто бы сам выполнял построчно код программы, а не компьютер. Ему отображались все значения переменных, индексы циклов, он даже мог переходить в функции и выходить их них - все! Тот первый переломный момент в моем становлении программистом был уже в конце декабря перед началом сессии - я узнал про отладку программ (Debug).

Я понял как работает процессор, как он выполняет мои инструкции в коде, я дебажил строчка за строчкой. Я стал запоем читать свою первую электронную книгу по С, что попалась под руку. Cделал все лабораторные работы за неделю и сдал перед самым началом экзамена, получив к нему доступ. Сам экзамен я тоже сдал на максимальный балл. Моей радости не было предела. Почти 4 месяца у меня ушло перед тем, как я осознанно стал писать строчки кода в своих программах.

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

#my_little_story
👍56🔥281🤔1
Какой же жизненный мем 😅
😁486👍1
Индекс DMdev: update

Количество видео DMdev уже давно перевалило за 500!

Хоть информация и подается в структурированном виде, но все равно порой необходимо возвращаться и искать какую-то конкретную тему, которую когда-то смотрел, но хочется освежить в памяти - что-то вроде конспекта.

Именно для таких целей и был создан индекс по курсам DMdev.
В обновленной версии присутствуют описания, таймкоды и даже ссылки на конкретное место в видео по следующим курсам: Java Core, SQL, JDBC, HTTP. Servlets, Maven, Junit5, Groovy, Gradle, Hibernate и Spring.

P.S. Сейчас идет работа по добавлению курса Bash и ссылок на GetCourse
👍44🔥26👏2