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

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

P.S. Когда не программирую - я бегаю:
https://t.me/dmdev_pro_run
Download Telegram
Interruption

Остановить поток выполнения - не совсем тривиальная задача. Мы не знаем, какие ресурсы были заняты, а значит и не знаем, как их освободить. Поэтому еще во 2 версии Java метод stop был deprecated. Теперь мы можем только послать "сигнал" потоку, чтобы он увидел, что мы хотим "прервать" его выполнение. Тогда он сможет спокойно завершиться и почистить все необходимые ресурсы.

Когда в принципе может понадобится это прерывание? На самом деле основных вариантов немного (но встречаются очень часто в приложениях):
- graceful shutdown (всего приложения или его части)
- cancel (пользователь хочет отменить выполнение задачи)
- timeouts (задача/запрос выполняется дольше, чем отведено на это время)
- остановить ненужные параллельные задачи

Раньше я пытался реализовывать свой механизм отмены выполнения задачи, чтобы не мучиться с InterruptedException. Но в итоге код сводился к тому, что мне приходилось и проверять свой велосипед, и стандартный механизм interrupt, потому что он никуда не уходит.

Поэтому я выработал для себя несколько основных правил, которым всегда следую:
1. Когда это только возможно в логике (чаще всего перед каждой итерацией цикла) - проверяй Thread.isInterrupted()
2. Если ты увидел, что нужно прервать выполнение - то делаешь весь необходимый cleanup и пробрасываешь дальше InterruptedException
3. Если пробросить InterruptedException не получается (например, нужно свое кастомное исключение), то обязательно вызови Thread.currentThread().interrupt(), чтобы восстановить interrupted status


try {
logicThatCanBeTimeOutOrCancelled();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Restore the interrupted status
throw new MyCheckedException("describe what task was interrupted", e);
}




for (Path file : files) {
if (Thread.isInterrupted()) { // Check interruption before each iteration
// do cleanup and throw an InterruptedException
throw new InterruptedException();
}
doExpensiveTask(file);
}


#dmdev_best_practices
🔥72👍23❤‍🔥3🎉3
🥰4
Избегай длительного выполнения задач

Довольно часто на практике необходимо реализовывать задачи или scheduled jobs, которые должны долго выполнять какую-то работу. Например:
- рассылка недельных отчетов (статистика) для миллионов пользователей в системе
- обновление статуса всех expired подписок
- обработка файлов/фото/видео

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

Но какие проблемы мы получаем в таком случае?
1️⃣ Мы даже примерно не знаем, когда закончит выполнение задача. А в это время мы хотели бы рестартовать приложение, выкатывать новые версии его и т.д. - что означает прерывание задачи (что мы писали в предыдущем посте) и последующий запуск с того момента, на котором мы остановились.
2️⃣ Сложно распределить нагрузку между несколькими инстансами сервиса. Чаще всего такие задачи можно запустить только на одном, иначе возникает конфликт (который еще нужно избежать, потратив время на соответствующую реализацию!).
3️⃣ Трудоемкие долго живущие задачи могут замедлять оставшийся функционал сервиса, что негативно скажется на пользователях, а мы не сможем даже это исправить.
4️⃣ Такие задачи сложны в поддержке и обслуживании (как остановить ее? как поставить на паузу? как перезапустить? на все эти операции писать отдельный API?). Они более подвержены ошибкам и требуют больше усилий для исправления и оптимизации.

Поэтому предпочтительнее разбивать сложные задачи на более мелкие, более управляемые подзадачи
Например:
- запускать задачу гораздо чаще и обрабатывать только batch пользователей (например, по 1000)
- ограничивать по времени (например, отсылать emails не более минуты - после чего завершать работу).


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

#dmdev_best_practices
🔥68👍19❤‍🔥4💯1
👍3
Не следует сохранять лямбда-выражения в переменных/константах

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

Function<String, CsvRow> CONVERT_TO_CSV_ROW_FUNCTION =
line -> new CsvRow(line.split(","));

Predicate<CsvRow> VALIDATE_CSV_ROW_PREDICATE =
csvRow -> !csvRow.hasEmptyColumns();

return lines.stream()
.map(CONVERT_TO_CSV_ROW_FUNCTION)
.filter(VALIDATE_CSV_ROW_PREDICATE)
.toList();


На самом деле, тут не все так плохо, но все-таки лучше рассматривать другой более читабельный вариант, где лямбда-выражения остаются внутри Stream API/Optional или вообще выносятся в отдельные методы:

return lines.stream()
.map(line -> new CsvRow(line.split(",")))
.filter(csvRow -> !csvRow.hasEmptyColumns())
.toList();


Здесь также есть другие преимущества:
- код будет разрастаться, и естественнее это будет выглядеть в методах, а не переменной
- намного проще именовать методы, чем переменные
- более естественно тестировать в последующем методы, а не переменные
- если поведение не совсем очевидно и хитро, то проще будет написать javadoc для метода

И последнее:
Нет необходимости сохранять лямбда-выражения в константы, чтобы "улучшить производительность" приложения. JVM оптимизирует те участки кода, где это необходимо. И делает это очень даже умно! Лучше обратить свое внимание на IO операции: там 90%+ проблемных по перфомансу мест.


#dmdev_best_practices
👍72🔥227❤‍🔥2
Заключительная заметка best practices от DMdev 🏁
Надеюсь, эта рубрика была полезной и интересной!

Ставь реакцию 💯, если хочешь оставить ее (естественно не на ежедневной основе, ибо чайник закипает мой уже 🤯).

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

Всех с Наступающим Новым Годом!!! 🎄

P.S. А кто хочет применить на практике все best practices - приглашаю ко мне на менторство 2 ступени (осталось 4 места). Будет отличным новогодним подарком для себя!
Please open Telegram to view this post
VIEW IN TELEGRAM
💯226🔥6👍43
Используй deadline propagation

Обычно, каждый RPC запрос должен выполняться с установленным deadline, который означает максимальное количество времени, отведенное на выполнение этого запроса. Если время превышает максимально допустимое - прерывается выполнение запроса и пробрасывается timout exception. Более того, сервер может пробросить это исключение сразу же, если видит, что deadline короче, чем требуется для выполнения запроса.

Но зачем в принципе использовать deadlines?
- чтобы не допускать запросов, которые выполняются бесконечно (особенно критично для user-facing)
- чтобы не тратить ресурсы сервера на поддержание долгих/бесконечных запросов

Зачем тогда deadline propagation?
Дело в том, что зачастую сервер не обрабатывает запрос полностью сам, а делает дополнительно другие downstream RPC запросы. И тогда становится вопрос - какой deadline устанавливать для них? Устанавливать какой-то дефолтный - плохо, он может быть меньше или больше необходимого. Поэтому deadline высчитывается из оставшегося времени, которое отвел на выполнение инициатор запроса (например, frondend).

Например, как на картинке:
- Client (инициатор) отправляет запрос с deadline = 10 секундам
- Server A обрабатывает запрос сам за 5 секунд и делает 2 асинхронных RPCs в Server B и D, установив каждому deadline = 5 секунд (10 - 5)
- Server B обрабывает запрос сам за 3 секунды и делает 1 RPC запрос в Server C, установив deadline = 2 секунды (5 - 3)

Как это работает?
- в случае синхронных серверов, вроде Apache Tomcat, то можно просто хранить значение deadline в ThreadLocal и при выполнении любой IO операции - получать ее оттуда (иначе использовать дефолтный или не ограничивать вовсе)
- в случае асинхронных серверов, вроде Netty, использовать аналог ThreadLocal - это Local Context.

#dmdev_best_practices
🔥56👍14❤‍🔥3🥰21
На YouTube вышла презентация проекта "Magic: The Gathering" по окончании 2-ой ступени менторства DMdev

С такими навыками каждого будут рады видеть в достойной компании на позиции сильного Junior Java Developer.

💻 В проекте использовались:
- Apache Maven для автоматизированной сборки
- JUnit 5 для покрытия кода unit и integration тестами
- Hibernate как основной ORM framework
- Liquibase для миграции SQL скриптов
- Spring Boot с Embedded Tomcat
- Множество различных Spring Starters (data-jpa, web, security, validation, thymeleaf, test, etc)

Более детальное описание можно найти в техническом задании

Смотри видео, задавай вопросы по проекту в комментариях.

А для тех, кто хочет стать участником менторства 2 ступени
👉 ссылка для записи с подробной информацией.

- старт 22 января - осталось 3 места (ко мне)

P.S. Дай знать 🔥, если видео было интересным
🔥40👍11❤‍🔥52😁2🤯1
#15 Мой путь

Осенний призыв в армию 2014 года. Последние пару месяцев мне довольно часто приходилось ездить из Минска в военкомат своего родного города Мстиславль, чтобы относить различные справки, документы и проходить медкомиссии. Я даже встретился с тем самым офицером, у которого я забирал документы на поступление на военный факультет в далеком 2009 году. Он так и сказал: “я ведь говорил, что мы тебя все равно дождемся”.

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

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

Я понял одно - что одного месяца такой службы мне более чем хватило, чтобы осознать всю суть вещей и полюбить с двойной силой мою настоящую жизнь программистом. По возвращении я даже получал удовольствие от того, что могу сидеть в нормальном туалете, принимать душ когда захочу и сколько захочу. Да какой там душ… в принципе мыться чаще раза в неделю - это просто нечто невероятное. А удобная обувь чего стоит? Мои ноги только месяц приходили в порядок и заживали мозоли, что натерли пятки до кости.

Наверное, описывать службу в армии нет смысла, потому что она оказалась в действительности такой, какой ее мы все слышали из уст других людей: унижение нижестоящего по званию, грубость и маты, уборка луж с помощью лопат для снега (декабрь же на дворе!), 8-часовой сон с 10 вечера до 6 утра в одном помещении с 70-тью другими храпящими ребятами, еда вообще оставляла желать лучшего (я похудел до 55 кг).

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

#my_little_story
👍70🔥21❤‍🔥10😁32
Для тех, кто ждет «последний звонок» как в театре 🎭
Это он!

Присоединиться:

Первая ступень менторства:
https://dmdev.tilda.ws/first-level

Вторая ступень менторства:
https://dmdev.tilda.ws/second-level
🥰65🤔5🔥3😱2🤯1
Мне лень

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

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

Это намного лучше, чем начать листать reels, shorts, tiktok... что мы обычно, к сожалению, и делаем, когда нам лень.

Поэтому нужно этим очень полезным чувством научиться управлять умело, а не во вред себе!
👍93🔥23💯137
Лондон или Детройт?

При написании unit тестов нам приходится использовать mock объекты, которые являются зависимостями у тестируемого класса, и имитировать поведение реальных методов. Если мы этого не будем делать, то вместо имитации будет вызван реальный функционал.

К сожалению, этот реальный функционал часто делает IO операции, будь то это запросы в базу данных или отправка RPCs в другие сервисы. И этот функционал будет нерабочий, потому что в противном случае нам пришлось бы поднять базу данных или другой сервис во время работы unit (или уже integration?) тестов. А у этого сервиса могут быть свои транзитивные зависимости на другие сервисы и т.д.

Отсюда вытекают два основных направления в тестировании:
- тех, кто предпочитает использовать везде в тестах реальные реализации (классический, Detroit style)
- и тех, кто предпочитает использовать везде в тестах моки (mockist, London style)

Но как обычно - правда где-то посередине


Лично я предпочитаю использовать реальные реализации, если это не усложняет написание, чтение и поддержку тестов. Если же для использования реальной реализации мне приходится создавать еще больше mocks и программировать их поведение (а моки потом и поддерживать сложнее, и читать!), потому что эта реальная реализация содержит много транзитивных зависимостей - то я лучше буду использовать mocks (или любой другой test doubles).

Второй случай использовать моки - это тестирование различных corner cases. Для этого мне не нужно подсовывать настоящие реализации, которые усложнят или даже сделают невозможным достижение конкретного варианта ветвления в методе.

PS. Подробнее можно почитать в статье от Мартина Фаулера
https://martinfowler.com/articles/mocksArentStubs.html
👍37🔥85🎉1
Ты делаешь что-то действительно ВАЖНОЕ?

Как понять, что ты занимаешься действительно важными вещами? Особенно это относится к поставленным целям.

Действительно важные цели - это не одномоментные события. Ты идешь к ним многими месяцами и даже годами. Ты скорее всего не получаешь удовольствия на пути к этим целям, а, наоборот, превозмогаешь трудности. Но сам этот путь подпитывает тебя, мотивирует, ты чувствуешь приятные ощущения в организме от того, что стал лучше/сильнее, что чуточку стал ближе к этой цели. Например:
- ты хочешь построить свой дом
- создать свою собственную компанию
- получить разряд в каком-то виде спорта
- набрать 100.000 подписчиков на своем YouTube канале

С другой стороны, НЕ важные вещи или цели достичь легко, ты быстро насыщаешься ими, и они тебе надоедают также очень быстро. Как итог - удовольствие только падает, и ты скорее демотивируешь себя что-то делать вообще. Например:
- еда (попробуй недельку поесть красную игру!)
- компьютерные игры
- в большинстве своем соц. сети (особенно reals, shorts, stories и прочие секундные видео)

В общем все то, что не требует усилий от тебя и что получить очень легко. Если еще конкретнее: ты не ПРЕОДОЛЕВАЕШЬ никакие препятствия на пути к желаемому.

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

Осталось только понять, как научиться не останавливаться на первых самых сложных этапах в достижении действительно ВАЖНЫХ целей, ведь удовольствия от этого мы не получаем. Скорее мы испытываем сложности, превозмогаем себя, нам действительно может быть тяжело. Но про один очень действенный способ, что использую лично я, расскажу в следующем посте 🙂
💯56👍19🔥114🤔2
Как научиться достигать действительно ВАЖНЫХ целей?

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

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

Другими словами, чтобы достичь той самой ВАЖНОЙ цели в жизни, нужно совершать действия без получения мгновенной награды, превозмогая трудности. Результат так отсрочен от действий, что тебе просто необходимо найти радость и хоть какое-то удовольствие от выполнения этих ДИСЦИПЛИНИРОВАННЫХ действий.

Потом в других сферах ты будешь пробовать, оступаться, у тебя будет постоянно что-то не получаться вновь и вновь - но это абсолютно спортивный путь, к которому твое тело уже и так привыкло. Достигать действительно ВАЖНЫХ целей - это такой же спорт, те же тренировки и такие же соревнования.

PS. Например, если брать DMdev, прежде чем мои видео на YouTube принесли хоть какие дивиденды - ушло 9 месяцев (или около 200 созданных видео). И эти дивиденды составили $6.71 🙂
👍74🔥26💯8🤔31
Отличный вопрос!
Как научиться систематически заниматься спортом?


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

Лучше выбрать тот вид спорта, который ХОТЬ КАК-ТО тебе нравится и привлекает (хотя, порой, нужно попробовать все подряд, чтобы определиться со своими предпочтениями). И желательно, чтобы ты не совершал слишком больших усилий, чтобы прийти в то место, где ты можешь делать это.

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

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

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


Далее останется лишь подкреплять тренировки каким-то целями. Например, пробежать 5км за 20 минут, пробежать свой первый марафон, получить разряд и т.д.

Также, ты начнешь замечать физические изменения в своем организме, которые не могут не радовать. Это тоже дополнительно будет мотивировать тебя.
🔥37👍16❤‍🔥7💯2
Docker возвращается...

Прошло 8 месяцев с момента публикации последнего 16-го видео по курсу Docker. Перерыв был таким большим, что я весь вечер только вспоминал, что уже заснял и на чем остановился. Для этого пришлось даже свои же видео пересматривать. Да что там пересматривать, даже моему сыну уже полгода исполнилось за это время!

Вот почему так плохо останавливаться на пол пути - мозг все быстро забывает. Особенно это касается изучения Java или чего-либо еще. Поэтому не стоит останавливаться на достигнутом!

Тем временем, я уже наметил план на следующие 10 уроков! Как говорится, главное начать и сделать первый шаг? 🙂

17 видео уже опубликовано на YouTube, которые доступны по Lead подписке за 14.99$. В которую включены все существующие на данный момент курсы.

Приятного просмотра!
🔥80👍148🎉5❤‍🔥1
JUnit assertions

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

// Только заглянув в название параметров, можно понять где что
public static void assertEquals(Object expected, Object actual) {
AssertEquals.assertEquals(expected, actual);
}


Именно поэтому я предпочитаю использовать дополнительные библиотеки, такие как AssertJ или Truth. Потому что я всегда знаю, что на вход каждый метод assertThat принимает именно актуальное значение. Кстати, в своем курсе JUnit 5 я более подробно рассказывал про это.

// Пример метода assertThat из библиотеки AssertJ
public static <T> ObjectAssert<T> assertThat(T actual) {
return AssertionsForClassTypes.assertThat(actual);
}


Есть только несколько исключений, когда я могу воспользоваться классическими методами из JUnit 5, потому что они короче и проще/лучше читаются:

assertNull(Object actual);
assertNotNull(Object actual);
assertTrue(boolean condition);
assertFalse(boolean condition);


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

#dmdev_best_practices
👍4615🔥8
Заключительный базовый блок по Docker

Я наконец-то закончил создавать все базовые блоки по курсу Docker. Сегодня вышло видео по четвертому последнему, но не менее важному - Docker Networking (видео в открытом доступе).

Ведь без настройки сети все еще не получится добиться полной изолированности контейнера, поэтому нам и приходит на помощь следующий Linux Namespace - NET. На видео разберем суть Docker Networking и вкратце пройдемся по всем 4-м основным Network Drivers, которые более подробно будем разбирать в последующих видео.

Теперь мы сможем понять более сложные темы Docker, такие как создание своих собственных docker images, как работать с docker compose и другое. Т.е. все то, что мы будем проходить в последующем на этом курсе.
🔥67👍16🎉3❤‍🔥1
#16 Мой путь

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

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

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

В мае 2016 года я наконец-то получил свои лейтенантские погоны, а 30 июня у меня заканчивалось распределение, которое я терпеливо дождался. Как говорится, все долги “родине” я отдал, и теперь моя совесть была чиста - я мог делать то, что захочу. Ибо последние 2 года действительно ощущалось, что я был связан по рукам и ногам.

Первым делом я открыл LinkedIn и сразу же начал принимать предложения о прохождении собеседования от всех компаний подряд. Времени у меня было в обрез - на все про все чуть больше месяца до конца распределения. Поэтому я решил не медлить с этим. К счастью, я довольно быстро получил несколько офферов (чем больше попыток делаешь, тем больше шанс на получить нужный результат). Как говорится, не зря держал себя в тонусе последние несколько лет, особенно в теоретической части. Это придало мне еще большей уверенности для следующего шага…

А вторым шагом меня ждала неприятная беседа со своим руководством в IBA. Но опыт разговора об уходе из компании у меня уже был со времен Epam Systems: это будет быстро, но это надо пережить. К сожалению, расстаться на хорошей ноте не получилось. Я наотрез отказался задерживаться на текущем месте даже на несколько месяцев. В итоге, я просто не подписал продление контракта и 30 июня был уволен в связи с истечением срока действия срочного трудового договора. С облегчением и трудовой книжкой в рюкзаке - я потопал радостный домой.

#my_little_story
👍43🔥97❤‍🔥2👏2
Недавно смотрел видео "Психология и философия" от лектора МГУ Валерия Петухова. И казалось бы, что можно было там найти, связанное с программированием? Но как обычно это и бывает - все сферы жизни человека взаимосвязаны. И используя какие-то полезные принципы или приемы в одной сфере, можно перенимать это и использовать в другой с такой же эффективностью.

Так вот, одна фраза этого лектора у меня до сих пор не выходит из головы:
В ваших конспектах находятся записи с ответами, на которые вы еще не задали вопрос


Я давно догадывался итуитивно, что при изучении чего-то нового в программировании, например, чтение книги "Effective Java" - всегда остается непонятная информация. А когда вновь возвращаешься к этому материалу через неделю-месяц-год, то ты как будто заново открываешь для себя ее. Все вдруг становится очевидным. И ты лишь думаешь: как можно было сразу это не понять! Тут ведь все так доходчиво объяснено!

То же самое и при просмотре моих видео курсов. Не нужно пытаться понять сразу все. Нужно для начала просто ПОСЛЕДОВАТЕЛЬНО изучать, ибо любая новая информация основывается на предыдущей, уже пройденной.

А то, что было сразу не понятно - это лишь потому, что мы еще не можем даже сформировать и задать правильный вопрос по этому поводу. Все придет, главное продолжать развиваться в нужном направлении и время от времени возвращаться к конспектам моим видео за ответами!
👍82🔥23❤‍🔥62🤯1