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
Релиз нового курса - первое видео уже на YouTube!

PS. Будет доступен по подписке Lead и со временем на других платформах (Udemy, GetCourse).
🔥108👍14🤩3💋3🏆2❤‍🔥11🎉1
🗄 DMdev talks: перезагрузка

С ужасом заметил, что последний пост я написал тут больше месяца назад.

Как так вышло?

На самом деле все просто:
Был фокус и четкий план на телеграм = были посты
Нет фокуса = нет постов

Хочу вдохнуть новую жизнь сюда, ибо формат телеграма мне очень нравится!

Для этого нужна ваша помощь🙏

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

На основании этого составлю себе план к действию и буду радовать вас почаще, чем раз в месяц😁
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥54👍8🫡4❤‍🔥1👨‍💻1
Часто мне задают вопросы такого плана - когда не понятно как реализовать или упростить уже существующий функционал.

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

Как можно было бы изменить код, чтобы автоматически при добавлении нового обработчика для определенного типа - не требовалось менять основную логику с добавлением еще одного if-else?

Можно словами в комментариях, можно прям скринами с кодом.

Если наберем несколько интересных вариантов, то я напишу свои мысли по этому поводу 😎
#dmdev_qa
👍25❤‍🔥4🔥3
Общими усилиями в комментариях мы пришли к гибкому решению!
Его я отобразил на картинке.

Единственное что я изменил - это тип процесса, сделав его Class<T> вместо enum для демонстрации альтернативного подхода.
В этом есть свои плюсы и минусы, как и в любом решении.

Плюсы:
- не нужно заводить перечисления (enum) и делать соответствия между ним и процессом
- не нужно передавать в ProcessService дополнительно этот enum, когда мы хотим получить обработчик процесса (или добавлять доп поле в каждый процесс)
- во время выполнения мы не получим ошибки, что получили из Map не тот обработчик (класс процесса сам же является и ключом)

Минусы:
- без enum не виден весь список возможных процессов
- не напишешь хороший тест, что на каждый процесс есть свой обработчик
- пришлось в ProcessService сделать явное приведение типов, потому что метод getClass в классе Object возвращает Class<?>

Что бы ты выбрал все-таки: enum vs Class<T>?
#dmdev_qa
🔥16👍91🤔1
Backwards compatibility

При создании любого открытого API, будь то HTTP, gRPC endpoint, public метод в Java - необходимо помнить про обратную совместимость.

А суть его в следующем:
код существующих клиентов открытого API не должен сломаться при обновлении этого API. Старые клиенты должны уметь работать с новой версией API.

К сожалении, не всегда очевидно - обратно совместимо ли какое-то изменении в API или нет.

Но есть несколько правил, которых можно придерживаться для этого:

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

2. Не делать поля обязательными в существующих сообщениях (в новых сообщениях тоже стараться делать поля optional)

3. Не удалять или переименовать уже существующие компоненты (переименование - это аналог “удалить + добавить поле”). Более того, придется продолжать заполнять старые поля, даже если они стали избыточными (redundant)

4. Не менять типы существующих полей

5. Осторожно работать с enum: если используется только в запросах - то добавить новое значение безболезненно, чего нельзя сказать про новые значения в ответах от сервера, где уже нужно писать клиент соответствующим образом

Вывод
Не так-то просто писать открытый API, особенно если им пользуется большое количество клиентов.
Да и становится понятно, почему в Java Core столько старых классов и методов 🙂
👍34🔥6❤‍🔥3💩1
Сode review н-нада?

Многие поддержали данное предложение, что ж, давайте попробуем реализовать его!

Кто хочет, чтобы я провел code review вашего кода - присылайте ссылку на github в комменты под этим постом.
Я рандомно выберу один проект и в следующем посте опубликаю краткое резюме по коду с ссылкой на код с моими комментариями

Условия участия:
- Проект опубликован на github
- Весь код в виде одного пул реквеста или коммита
- Чем больше кода - тем больше добавить описания о нем в README файле (чтобы я понимал о чем проект)
- Не удалять пул реквест или коммит после code review
- Согласие на то, что ваш разбор попадет в этот канал
- Ссылки жду до 6 мая включительно

P.S. Если зайдет рубрика, то можем ввести ее на постоянной основе, например, каждое первое число
#dmdev_code_review
👍47🔥16👏2❤‍🔥1
15.000 подписчиков на YouTube!
Это в 1,5 раза больше людей, чем в городе, котором я вырос.

И всех этих людей связывает один общий интерес - Java.

3 года прошло, как я создал канал DMdev.
И он совсем не похож на среднестатистический канал ютуба.

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

За это время:
- уже более 1.000.000 просмотров
- 666 видео
- 12 курсов (пройдя которые - действительно можно стать разработчиком)

Благодарю каждого за доверие и активное участие!
Без вас - ничего этого не было бы🙌🏻

P.S. 🔔 Напоминаю, что сегодня последний день, как я жду ваши ссылки на гитхаб для code review (подробнее в посте выше)
🔥82👍16🎉8❤‍🔥2😈1
#dmdev_code_review
Как и обещал, выбрал одного из участников, чтобы провести code review.

Хотелось бы отметить общие частовстречаемые ошибки, которые в то же самое время очень важны:

1. Не следует изменять статические поля в нестатическом контексте. Чаще всего это приводит к ошибкам в многопоточности или попросту неверно работает код.

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

3. Не стоит писать код на исключениях - клиентский код потом становится громоздким с кучей try/catch блоков. Пробрасывать исключения следует тогда, когда действительно произошла ИСКЛЮЧИТЕЛЬНАЯ ситуация, которую никак не избежать. Например, гораздо приятнее возвращать true/false в методе delete вместо пробрасывания исключения, если такой сущности не оказалось по переданному id.

4. Связанно с предыдущим пунктом: не нужно проглатывать исключение, пробрасывая свое кастомное - иначе теряется stacktrace рутовой ошибки и будет очень сложно понять что произошло. Если нужно обернуть одно исключение в другое - просто передавайте его как параметр в конструктор: new DatabaseException(sqlException)

5. Разумно подходить к использованию Optional & Streams. Какой-то код лучше писать в функциональном стиле, какой-то в императивном, какой-то в комбинации двух предыдущих. Но в любом случае стоит граммотно использовать все подходы. Возьмем простой случай: возвращать Optional из метода, который может вернуть null. И, наоборот, если метод всегда возвращает объект - то не стоит оборачивать его в Optional, ибо это доставляет неудобства клиенту.

6. Давать хорошие имена переменным, методам, классам - всему в коде. Иначе очень сильно усложняется чтение кода, на которое программист тратит большую часть своего рабочего времени. Особенно избегать таких имен, которые подразумевают только ЧТЕНИЕ, а по факту там происходит изменения состояния объектов - т.е. ЗАПИСЬ. Например, findProduct(productId) - а внутри изменение состояния объекта Product.

P.S. Весь список комментариев по code review можно найти в пул реквесте по ссылке

P.P.S. Если есть вопросы по коду/моим замечаниям, что я оставил - то можете задавать их прям здесь под постом в комментариях
🔥49👍11❤‍🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Ребят, в конце июня стартую последнюю 2-ую ступень менторства в этом году

Осталось 4 места 0 мест.
Так что, кто желает окунуться в интенсивное обучение Java со мной - welcome.

Записаться и почитать подробнее можно по ссылке:
https://dmdev.tilda.ws/second-level
😁20❤‍🔥3🔥3
Попросил ответить на три вопроса ребят, которые на этой неделе окончили 2 ступень:

1. Если описать тремя словами, как для тебя прошло менторство?

2. С позиции уже выпускника, как считаешь, кому будет полезно идти на менторство?
К чему нужно быть готовым/чего ожидать?

3. И какой совет дашь для тех, кто думает/сомневается - идти или не идти

Ответы на фото👆
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍8❤‍🔥5
#dmdev_qa - под этим хештегом отвечаю на ваши вопросы.
Вопрос на фото, ответ ниже👇

Этот подход зародился очень давно, можно сказать, исторически так сложилось. Даже в книгах писалось, что так нужно делать. Раньше это считалось best practices.

Потому что:
1️⃣ Ты легко можешь создать Dynamic Proxy, не прибегая к сторонним библиотекам и делая прокси через наследование, ибо у тебя есть интерфейс со всеми методами. Но сейчас по умолчанию даже Spring делает cglib прокси через наследование, ибо этот подход оказался более жизнеспособным.

2️⃣ Ты можешь описывать документацию над методами в интерфейсах или выносить туда константы (например, длинные SQL запросы для Repository), чтобы не делать этого в классах. Но сейчас тоже не актуально, ибо интерфейсы созданы именно для функционала, а не как хранилище констант, и второе - современные среды разработки и так умеют сворачивать документацию над методами, чтобы не смущать программистов.

3️⃣ Удобно было раньше создавать всякие заглушки в тестах или тестовых окружениях - просто создавая еще одну реализацию от интерфейса и ее подставлять вместо реального объекта. Но Mockito и без этого справляется и опять же через наследование.
👍264🔥4❤‍🔥2
🗓️ 1-ое число месяца, а это значит «время code review»

Кто хочет получить code review своего кода ➡️ присылайте ссылку на github в комменты под этим постом.

Я рандомно выберу один проект и в следующем посте опубликаю краткое резюме по коду с ссылкой на код с моими комментариями

Условия участия:
Проект опубликован на github

Весь код в виде одного пул реквеста или коммита

Чем больше кода - тем больше добавить описания о нем в README файле (чтобы я понимал о чем проект)

Не удалять пул реквест или коммит после code review

Согласие на то, что ваш разбор попадет в этот канал

Ссылки жду до 5 июня включительно

#dmdev_code_review
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥95
Теория бесполезна без практики

Сейчас сел перечитывать книгу “От 800 метров до марафона” Джека Дэниелса, которую прочел еще в прошлом году, когда только начал заниматься бегом. Только в этот раз я осознал, на сколько возросло мое понимание написанного в этой книге. Каждое предложение просто отпечатывалось в моем мозгу (наверное, даже на всю жизнь). Тогда как в прошлый раз - все просто выветривалось и очень быстро.

Если раньше я мог пролистывать часть страниц, думая, что это “не важно”, или давая себе совсем другие смыслы написанному, нежели закладывал автор (пытаясь понять и запомнить по-своему) - то сейчас как будто мир заиграл новыми красками. В голове всплывал лишь один вопрос - как я не понимал этого 10 месяцев назад?

А ответ довольно прост - я все эти 10 месяцев просто практиковался в беге, постоянно и методично. Экспериментируя, анализируя все, что делаю “на практике”.

Как здорово, что один и тот же принцип “теория-практика” можно применять в любых сферах: как в программировании, так и в таких видах спорта как бег.

Практикуй то, что изучаешь!
👍588🔥3🤔2❤‍🔥1👏1
Может все-таки велосипед?

Каждый раз, когда приступаю к написанию какого-то функционала, руки так и рвутся создать что-то с “нуля”. Чтобы было в этот раз уж точно гибко, расширяемо, без багов, а главное - свое!

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

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

Например, если мне нужно создать endpoint, который возвращает список чего-либо, я просто посмотрю как его реализовывают такие компании как Google, Amazon и т.д. Крупные компании имеют свойство хорошо документировать свои решения и даже выкладывать его в public доступ.

Поэтому, я открываю API документацию (в нашем случае list endpoint) и начинаю читать ее. И практически всегда я точно нахожу для себя что-то полезное, о чем “не подумал“, и что могу переиспользовать для своего решения 🙂
👍51🔥6❤‍🔥4
Ребят, кто пропустил информацию, то сейчас идет набор группы на менторство 1 ступени.

Старт: 4 сентября
Продолжительность: ~3,5 месяца
Свободно: 5 мест 1 место

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

PS. Вопросы можно также задавать здесь в комментариях
PPS. Пример финального проекта по окончании менторства есть на YouTube (проект можно выбрать абсолютно любой)
🔥14👍54
Полнотекстовый поиск

Пожалуй, один из немногих инструментов, который остался, надёжно закрепился и активно используется у меня при решении многих проблем при разработке ПО - это полнотекстовый поиск!

Хочешь найти применение класса, метода, куска кода в каком-то репозитории, да даже любой интересующий тебя ключ в yaml файле? Используй полнотекстовый поиск (особенно когда нет возможности открыть проект в среде разработки или это заняло бы неоправданно много времени).

Из совсем недавних примеров…

1. На менторстве при старте интеграционных тестов происходило обращение к Postgres по урлу 192.168.0.150:5432, хотя должен был определяться порт динамически из библиотеки testcontainers. Полнотекстовый поиск по ip 192.168.0.150 - и оказывается этот урл указан в забытом файле hibernate.cfg.xml.

2. Точно помнишь, что в каком-то видео на каком-то курсе dmdev слышал/видел информацию об аннотации @DynamicPropertySource. Открываешь индекс dmdev, ctrl + F - и находишь то, что хотел.

Так что смело используй полнотекстовый поиск как одно из возможных и очень хороших решений твоей проблемы!

PS. И это я еще забыл упомянуть, как он меня выручает при поиске чего-либо в многотерабайтном монорепозитории гугла, который в принципе невозможно открыть и развернуть локально
👍203🔥3❤‍🔥1
Смогу ли я устроиться на работу?

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

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

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

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

Поэтому что бы я сделал:

1️⃣ Лучше формулировал бы вопрос. Хороший вопрос - это уже половина ответа. Добавил информацию в каком городе буду искать работу, сколько ресурсов денежных и временных у меня есть для обучения. Кто-то может позволить только самообучение, кто-то наставника. От чего зависит и скорость, и качество обучения.

2️⃣ На каком языке программирования я хочу сфокусироваться. За двумя зайцами погонишься - ни одного не поймаешь.

3️⃣ Предварительно пробил информацию о рынке труда. Сейчас в каждой локации/стране есть сайты-агрегаторы об открытых вакансиях. Лишь благодаря такому анализу я могу вообще передумать изучать программирование или увеличить в 4 раза свои шансы на получение работы, выбрав, например, язык Java, а не C#. Потому что в моем регионе вакансий на Java в 4 раза больше. Или даже запланировал смену места жительства, ибо в городе, где я живу - с программированием все обстоит не очень.

PS. В любом случае, большие цели - требуют больших усилий. Так что вопрос лишь в том, на сколько сильно хочется этого достичь и чем ты готов пожертвовать ради достижения этой цели.
🔥29👍133
DMdev talks
Ребят, кто пропустил информацию, то сейчас идет набор группы на менторство 1 ступени. Старт: 4 сентября Продолжительность: ~3,5 месяца Свободно: 5 мест 1 место Вся подробная информация о менторстве DMdev и запись тут: https://dmdev.tilda.ws/first-level PS.…
Напоминаю, что еще осталось 1 место на менторство 1 ступени, которое уже стартует через 2 недели!

Можно писать в личку, в комментариях к посту, или просто оставить заявку на сайте https://dmdev.tilda.ws/first-level (там же вся информация о процессе обучения)
DMdev talks pinned a photo