Почему конспекты не работают
Я помню, что в студенческие годы нам говорили и даже заставляли вести конспекты, без которого даже некоторые преподаватели не пускали на экзамен. Отчасти, я понимаю, почему… только, к сожалению, написание конспектов на парах не работало, по крайней мере для меня. И сейчас объясню почему.
Как я уже писал в предыдущем посте, для закрепления информации нужно подключать как можно больше СЕНСОРНЫХ, МОТОРНЫХ и УМСТВЕННЫХ трудов.
Начнем по порядку.
Сенсорная система человека - это то, как наша нервная система с помощью всех пяти органов чувств получает информацию извне. Другими словами говоря - это наш самый, что ни на есть, природный Input Stream. На примере написания конспекта - мы слышим преподавателя, ощущаем ручку и бумагу, видим написанное, и даже чувствуем запах чернил.
Моторика - это произвольные движения нашего тела, для которых необходимо использовать сразу несколько систем: нервную, костную и мышечную. В нашем примере с конспектами - используются ТОЧНЫЕ движения ручкой. Эта уже даже мелкая моторика, которая подключает отделы нашего головного мозга еще эффективнее (потому так полезна для детей).
Это наш природный Output Stream. И как можно догадаться, он разительно менее эффективен, чем InputStream: все-таки получать информацию мы научились в гораздо больших объемах, нежели выводить ее из себя.
К сожалению, у большинства животных моторика и сенсорные системы развиты в разы лучше, чем у человека. Но человек все-таки превосходит животных благодаря третьей составляющей - осмысливанию информации! Благодаря чему прокладываются прочные нейронные сети и выстраиваются ассоциативные связи между различной информацией.
И именно этой третьей части мне всегда не хватало на лекциях, когда я писал конспекты. Потому что времени на осмысливание информации попросту не было. Я пытался законспектировать услышанное и все. Т.е. преобразовывал Input Stream полученный из слуховой системы (СЕНСОРИКА) - напрямую в записи в тетради (МОТОРИКА) с минимально обработкой, чтобы этого было достаточно для конспектирования.
Именно по этой причине мне никогда не нравились занятия в группах и посещения лекций в универе, я всегда любил заниматься самостоятельно. Для этого я могу использовать, например, видео уроки - их всегда можно пересмотреть с нужного тебе момента, если ты не успел ОСМЫСЛИТЬ услышанное.
Поэтому если правильно использоватьэто оружие конспекты - то можно получить неплохую пользу 🙂
Я помню, что в студенческие годы нам говорили и даже заставляли вести конспекты, без которого даже некоторые преподаватели не пускали на экзамен. Отчасти, я понимаю, почему… только, к сожалению, написание конспектов на парах не работало, по крайней мере для меня. И сейчас объясню почему.
Как я уже писал в предыдущем посте, для закрепления информации нужно подключать как можно больше СЕНСОРНЫХ, МОТОРНЫХ и УМСТВЕННЫХ трудов.
Начнем по порядку.
Сенсорная система человека - это то, как наша нервная система с помощью всех пяти органов чувств получает информацию извне. Другими словами говоря - это наш самый, что ни на есть, природный Input Stream. На примере написания конспекта - мы слышим преподавателя, ощущаем ручку и бумагу, видим написанное, и даже чувствуем запах чернил.
Моторика - это произвольные движения нашего тела, для которых необходимо использовать сразу несколько систем: нервную, костную и мышечную. В нашем примере с конспектами - используются ТОЧНЫЕ движения ручкой. Эта уже даже мелкая моторика, которая подключает отделы нашего головного мозга еще эффективнее (потому так полезна для детей).
Это наш природный Output Stream. И как можно догадаться, он разительно менее эффективен, чем InputStream: все-таки получать информацию мы научились в гораздо больших объемах, нежели выводить ее из себя.
К сожалению, у большинства животных моторика и сенсорные системы развиты в разы лучше, чем у человека. Но человек все-таки превосходит животных благодаря третьей составляющей - осмысливанию информации! Благодаря чему прокладываются прочные нейронные сети и выстраиваются ассоциативные связи между различной информацией.
И именно этой третьей части мне всегда не хватало на лекциях, когда я писал конспекты. Потому что времени на осмысливание информации попросту не было. Я пытался законспектировать услышанное и все. Т.е. преобразовывал Input Stream полученный из слуховой системы (СЕНСОРИКА) - напрямую в записи в тетради (МОТОРИКА) с минимально обработкой, чтобы этого было достаточно для конспектирования.
Именно по этой причине мне никогда не нравились занятия в группах и посещения лекций в универе, я всегда любил заниматься самостоятельно. Для этого я могу использовать, например, видео уроки - их всегда можно пересмотреть с нужного тебе момента, если ты не успел ОСМЫСЛИТЬ услышанное.
Поэтому если правильно использовать
👍33🤔12🔥9❤1
Мое наблюдение о преподавании Java онлайн и оффлайн
В январе 2018 года, когда я только начал преподавать - я очень тщательно готовился перед каждой лекцией, чтобы понятно и доходчиво объяснить тему. А главное - ничего важного не упустить.
Конечно же я использовал для этого конспекты: память человека всегда может подвести, а вот то, что записал на листок (а значит сохранил на внешний носитель) - нет. И мне такой подход действительно очень нравился поначалу.
Как-то раз, уже во второй половине курса, одна беременная ученица не смогла прийти на мои лекции в виду того, что родился малыш. И попросила методистов it-academy записывать видео.
💭 Я еще тогда подумал: “хм, прикольно, можно же записывать лекции, чтобы даже в таких ситуациях можно было ничего не пропустить и пересмотреть”. Но на этом мысль и закончилась и никуда дальше не продвинулась.
Еще через некоторое время я начал замечать, что ребята начали снимать на камеру то, что я говорю. Видать, мысль про постоянную запись лекций пришла не только ко мне, что в принципе и не удивительно. Один парень просто приносил ноут, поворачивали камерой ко мне - и все 4 академических часа шла съемка. Далее выкладывал на YouTube и шарил ссылку в общем чате нашей группы.
Тогда я понял первый недостаток своего подхода - он все еще неудобен тем, кто слушает меня, потому что невозможно запомнить большой объем информации сразу. А мой краткий конспект удобен только мне - потому что он содержит лишь ключевые фразы, которые мне нужны, чтобы извлечь из своей памяти еще больше информации и не забыть ее рассказать.
Следующие группы с первой же лекции начинали снимать меня и выкладывать видео на YouTube. Более того, все записанные видео бывало пересматривал и я, т.к. было познавательно смотреть на себя со стороны и подмечать моменты, которые мог исправить или улучшить в будущем. Это как взгляд со стороны, обратная связь самому себе. Более того, я мог поделиться ссылкой на записанный playlist с теми, кто самостоятельно изучал Java.
Спустя годы я уже подустал повторять одно и то же. Как и любой программист - хотелось автоматизировать этот процесс. Потом еще начался covid и обучение перешло в online, где ведение живых лекций еще более исказилось и польза от online общения казалась еще менее эффективна. В тот момент и вернулась та самая идея записывать видео, тем самым вывести процесс обучения на новый уровень.
🎥 В принципе, тогда, 30 мая 2020 года, и зародился канал dmdev на YouTube и его самое первое видео.
Из очевидных плюсов записанных видео:
- возможность смотреть видео в удобнее тебе время. Не надо ехать куда-то сразу после работы, экономя время на логистику
- возможность останавливать, проматывать, пересматривать видео сколько угодно раз, чтобы ОСМЫСЛИТЬ информацию
- лектор запишет точно все, что хотел сказать, и ничего не забудет
Из минусов:
- нет возможности задать уточняющие вопросы лектору сразу по ходу видео
- нет обратной связи
Но эти минусы практически полностью решаются с помощью дополнительных созвонов с ментором (которые гораздо эффективнее проходят, ибо понятен контекст обоим сторонам) и телеграм чатов.
Присоединиться на менторство DMdev, оставив заявку по ссылке:
👉Первая ступень менторства
👉Вторая ступень менторства
Старт: конец января 2024г.
P.S. Количество мест ограничено, группы по 10-12 человек.
В январе 2018 года, когда я только начал преподавать - я очень тщательно готовился перед каждой лекцией, чтобы понятно и доходчиво объяснить тему. А главное - ничего важного не упустить.
Конечно же я использовал для этого конспекты: память человека всегда может подвести, а вот то, что записал на листок (а значит сохранил на внешний носитель) - нет. И мне такой подход действительно очень нравился поначалу.
Как-то раз, уже во второй половине курса, одна беременная ученица не смогла прийти на мои лекции в виду того, что родился малыш. И попросила методистов it-academy записывать видео.
💭 Я еще тогда подумал: “хм, прикольно, можно же записывать лекции, чтобы даже в таких ситуациях можно было ничего не пропустить и пересмотреть”. Но на этом мысль и закончилась и никуда дальше не продвинулась.
Еще через некоторое время я начал замечать, что ребята начали снимать на камеру то, что я говорю. Видать, мысль про постоянную запись лекций пришла не только ко мне, что в принципе и не удивительно. Один парень просто приносил ноут, поворачивали камерой ко мне - и все 4 академических часа шла съемка. Далее выкладывал на YouTube и шарил ссылку в общем чате нашей группы.
Тогда я понял первый недостаток своего подхода - он все еще неудобен тем, кто слушает меня, потому что невозможно запомнить большой объем информации сразу. А мой краткий конспект удобен только мне - потому что он содержит лишь ключевые фразы, которые мне нужны, чтобы извлечь из своей памяти еще больше информации и не забыть ее рассказать.
Следующие группы с первой же лекции начинали снимать меня и выкладывать видео на YouTube. Более того, все записанные видео бывало пересматривал и я, т.к. было познавательно смотреть на себя со стороны и подмечать моменты, которые мог исправить или улучшить в будущем. Это как взгляд со стороны, обратная связь самому себе. Более того, я мог поделиться ссылкой на записанный playlist с теми, кто самостоятельно изучал Java.
Спустя годы я уже подустал повторять одно и то же. Как и любой программист - хотелось автоматизировать этот процесс. Потом еще начался covid и обучение перешло в online, где ведение живых лекций еще более исказилось и польза от online общения казалась еще менее эффективна. В тот момент и вернулась та самая идея записывать видео, тем самым вывести процесс обучения на новый уровень.
🎥 В принципе, тогда, 30 мая 2020 года, и зародился канал dmdev на YouTube и его самое первое видео.
Из очевидных плюсов записанных видео:
- возможность смотреть видео в удобнее тебе время. Не надо ехать куда-то сразу после работы, экономя время на логистику
- возможность останавливать, проматывать, пересматривать видео сколько угодно раз, чтобы ОСМЫСЛИТЬ информацию
- лектор запишет точно все, что хотел сказать, и ничего не забудет
Из минусов:
- нет возможности задать уточняющие вопросы лектору сразу по ходу видео
- нет обратной связи
Но эти минусы практически полностью решаются с помощью дополнительных созвонов с ментором (которые гораздо эффективнее проходят, ибо понятен контекст обоим сторонам) и телеграм чатов.
Присоединиться на менторство DMdev, оставив заявку по ссылке:
👉Первая ступень менторства
👉Вторая ступень менторства
Старт: конец января 2024г.
👍24🔥9❤🔥5
Вопрос 👆 - Ответ 👇
Довольно часто задают мне этот вопрос. И в основном, как не удивительно, его задают те, кто математику не очень хорошо понимает, но хочет стать программистом.
Давайте разбираться…
По сути задача программиста - преобразовывать логику в машинный код, который автоматизирует ее и сможет выполнять для миллионов пользователей. Поэтому каждая строчка кода приложения - это логика! Каждая инструкция, каждая операция ветвления, каждый цикл, каждый созданный массив, по которому далее ты будешь проходиться циклом и отфильтровать значения по каким-либо условиям - это все логика.
Теперь самое интересное: математика целиком и полностью построена на логике. Это как следующий уровень после логики. Математика развивает мышление, учит анализировать и систематизировать знания, учит мыслить абстрактно и конечно же ЛОГИЧЕСКИ!
По сути я в предыдущем предложении перечислил все то, что использует программист во время написания приложений.
Надо понять одну простую истину:
И в случае программирования - это в первую очередь логика.
❓Поэтому, отвечая на вопрос нужно ли знать программисту математику?
Ответ нет. Программирование не строится на ней.
❓Хорошо бы знать программисту математику?
Ответ да. Ибо транзитивно математика прокачает ключевые навыки для программиста.
#dmdev_qa
Довольно часто задают мне этот вопрос. И в основном, как не удивительно, его задают те, кто математику не очень хорошо понимает, но хочет стать программистом.
Давайте разбираться…
Что самое важное в любом приложении? Конечно же это логика его работы.
По сути задача программиста - преобразовывать логику в машинный код, который автоматизирует ее и сможет выполнять для миллионов пользователей. Поэтому каждая строчка кода приложения - это логика! Каждая инструкция, каждая операция ветвления, каждый цикл, каждый созданный массив, по которому далее ты будешь проходиться циклом и отфильтровать значения по каким-либо условиям - это все логика.
Теперь самое интересное: математика целиком и полностью построена на логике. Это как следующий уровень после логики. Математика развивает мышление, учит анализировать и систематизировать знания, учит мыслить абстрактно и конечно же ЛОГИЧЕСКИ!
По сути я в предыдущем предложении перечислил все то, что использует программист во время написания приложений.
Надо понять одну простую истину:
знание не бывает в вакууме, оно обязательно цепляет другие сферы, которые жизненно необходимы для усвоения этого нового знания
И в случае программирования - это в первую очередь логика.
❓Поэтому, отвечая на вопрос нужно ли знать программисту математику?
Ответ нет. Программирование не строится на ней.
❓Хорошо бы знать программисту математику?
Ответ да. Ибо транзитивно математика прокачает ключевые навыки для программиста.
#dmdev_qa
🔥33👍11❤🔥3❤1
Не будь излишне терпим к null
Если ты излишне терпим к null вместо того, чтобы обрывать ход выполнения приложения с NullPointerException в тех местах, где null НЕ ожидается - это делает твой код более сложным в понимании и более хрупким.
Поэтому:
- если ты НЕ ожидаешь, что object может быть null,
- если ты ожидаешь, что object может быть null, то лучше использовать
- для параметров метода, которые не должны быть null, вообще лучше использовать fail-fast принцип
#dmdev_best_practices
Если ты излишне терпим к null вместо того, чтобы обрывать ход выполнения приложения с NullPointerException в тех местах, где null НЕ ожидается - это делает твой код более сложным в понимании и более хрупким.
Например, когда сравниваешь объекты
object.equals(CONSTANT)
- тебе необходимо учитывать, что object может быть null.
Yoda notation
CONSTANT.equals(object)
- обычно является той самой попыткой быть терпимым к null. Но зачастную такое сложнее читается, ибо выглядят не "естественно".
Поэтому:
- если ты НЕ ожидаешь, что object может быть null,
object.equals(CONSTANT)
- это отличный вариант написания. - если ты ожидаешь, что object может быть null, то лучше использовать
Objects.equals(object, CONSTANT)
- это сделает код более чистым и понятным. Более того, он говорит, что object может принимать null значения.- для параметров метода, которые не должны быть null, вообще лучше использовать fail-fast принцип
Objects.requireNonNull
(обычно генерируется автоматически с помощью тех же аннотаций Lombok)#dmdev_best_practices
🔥85👍18❤🔥6❤2👏2
Используй @Nullable в своем коде
Эта аннотация говорит о том, что значение может быть null, и зачастую используется в трех местах: полях класса, параметрах метода или даже возвращаемого значения (для локальных переменных не следует, да и смысла особого нет).
Ее не обязательно использовать в коде, но если начал - то продолжай расставлять ее во всем своем проекте или модуле:
В противном случае, другие программисты будут считать, что если что-то не аннотировано @Nullable - то оно не может быть null.
Подытожим:
- используй @Nullable везде, если это возможно
- если не можешь поддерживать consistency во всем коде - то лучше избегай @Nullable (или везде, или нигде!)
- если используешь @Nullable, то смысла в @NotNull аннотации нет - ибо все и так по умолчанию будет восприниматься not null
#dmdev_best_practices
Эта аннотация говорит о том, что значение может быть null, и зачастую используется в трех местах: полях класса, параметрах метода или даже возвращаемого значения (для локальных переменных не следует, да и смысла особого нет).
Ее не обязательно использовать в коде, но если начал - то продолжай расставлять ее во всем своем проекте или модуле:
consistency превыше всего!
В противном случае, другие программисты будут считать, что если что-то не аннотировано @Nullable - то оно не может быть null.
Подытожим:
- используй @Nullable везде, если это возможно
- если не можешь поддерживать consistency во всем коде - то лучше избегай @Nullable (или везде, или нигде!)
- если используешь @Nullable, то смысла в @NotNull аннотации нет - ибо все и так по умолчанию будет восприниматься not null
#dmdev_best_practices
🔥60👍20❤🔥7❤3😁1
Предпочитай кастомные аннотации, нежели использование @Named
Аннотации @Named и @Qualifier (Spring annotation) - очень мощный инструмент, позволяющий определять и использовать несколько бинов одного и того же типа. Вообще, спецификация JSR 330 Dependency Inject предоставляет два варианта: использование стандартных аннотаций вроде @Named, либо создавать свои кастомные. И именно второй вариант должен быть предпочтительным.
Основной недостаток стандартных аннотаций - это использование строкового значения в качестве идентификатора бина @Qualifier("primaryHttpClient")
Это неудобно и довольно легко допустить ошибку в написании, тем более что эти строки проверяются не во время компиляции, а только в момент уже создания бина (runtime). А если бин lazy - то это как бомба замедленного действия.
Конечно, существуют всякие статические анализаторы и подсказки от мощных IDEA, но они минимальны и не всегда помогают. Поэтому именно кастомная аннотация обеспечивает все необходимые проверки и помогает избегать типичных опечаток:
#dmdev_best_practices
Аннотации @Named и @Qualifier (Spring annotation) - очень мощный инструмент, позволяющий определять и использовать несколько бинов одного и того же типа. Вообще, спецификация JSR 330 Dependency Inject предоставляет два варианта: использование стандартных аннотаций вроде @Named, либо создавать свои кастомные. И именно второй вариант должен быть предпочтительным.
Основной недостаток стандартных аннотаций - это использование строкового значения в качестве идентификатора бина @Qualifier("primaryHttpClient")
Это неудобно и довольно легко допустить ошибку в написании, тем более что эти строки проверяются не во время компиляции, а только в момент уже создания бина (runtime). А если бин lazy - то это как бомба замедленного действия.
Конечно, существуют всякие статические анализаторы и подсказки от мощных IDEA, но они минимальны и не всегда помогают. Поэтому именно кастомная аннотация обеспечивает все необходимые проверки и помогает избегать типичных опечаток:
@Documented
@Retention(RUNTIME)
@Qualifier
@interface PrimaryHttpClient {}
#dmdev_best_practices
👍52🔥21❤9❤🔥5💯1
Когда использовать Stream API
Императивный цикл for конечно же намного мощнее, чем обычная цепочка вызовов в Stream API.
Ты можешь:
- вернуться из цикла любой вложенности в любой момент времени
- изменять данные как угодно и где угодно (а не только affectively final)
- создавать несколько выходных результатов из цикла (а не только один)
- гибко обрабатывать и пробрасывать исключения
- использовать if, else и как угодно еще изменять ход выполнения программы
В свою очередь Stream API навязывает множество ограничений на то, что ты можешь делать:
- ты можешь определить только последовательный список шагов без использования сложных структур данных и операций ветвлений.
Такие ограничения означают, что практически невозможно написать сложный алгоритм, используя Stream API. Либо этот алгоритм будет выглядить очень громоздко, что его проще будет переписать на императивный цикл for.
С другой стороны, благодаря таким ограничениям более простые алгоритмы читаются намного лучше и приятнее программистами.
Если программист знаком со Stream API - то по такому коду невероятно быстро схатываешь его суть, что он делает.
P.S. А вот как представить многие задачи в виде последовательной цепочки шагов - еще надо научиться!
#dmdev_best_practices
Императивный цикл for конечно же намного мощнее, чем обычная цепочка вызовов в Stream API.
Ты можешь:
- вернуться из цикла любой вложенности в любой момент времени
- изменять данные как угодно и где угодно (а не только affectively final)
- создавать несколько выходных результатов из цикла (а не только один)
- гибко обрабатывать и пробрасывать исключения
- использовать if, else и как угодно еще изменять ход выполнения программы
В свою очередь Stream API навязывает множество ограничений на то, что ты можешь делать:
- ты можешь определить только последовательный список шагов без использования сложных структур данных и операций ветвлений.
Такие ограничения означают, что практически невозможно написать сложный алгоритм, используя Stream API. Либо этот алгоритм будет выглядить очень громоздко, что его проще будет переписать на императивный цикл for.
С другой стороны, благодаря таким ограничениям более простые алгоритмы читаются намного лучше и приятнее программистами.
Если программист знаком со Stream API - то по такому коду невероятно быстро схатываешь его суть, что он делает.
Поэтому правила просты:
- если задача может быть представлена в виде последовательной цепочки шагов, то обязательно используй Stream API
P.S. А вот как представить многие задачи в виде последовательной цепочки шагов - еще надо научиться!
#dmdev_best_practices
❤🔥46👍33🔥24❤2
Когда избегать Stream API
Если комплексный императивный цикл for сложно преобразовать в Stream (особенно если алгоритм этого цикла делает кучу “side effects”) - ничего страшного, продолжай использовать императивный стиль.
Я много раз замечал, что программисты впадают в две крайности - либо пытаются все представить в виде стримов, либо не используют их вовсе.
Но как обычно это и бывает - правда где-то по середине. Другими словами говоря,
Кстати, что заметил очень полезного, когда начал использовать стримы - это прокачивание навыка декомпозировать задачи на более мелкие составляющие, что в последующем повлияло на декомпозицию задач любой сложности и любого уровня. Ибо в противном случае не получится компактно и понятно представить логику в виде стримов.
Также на своем опыте скажу, что API более высокого уровня я практически всегда определяю с помощью стримов, и только уходя вглубь - я могу прибегать к императивному стилю, если потребуется. Все потому что это очень сильно облегчает чтение программного кода, ибо я начинаю изучение всего “сверху вниз”.
#dmdev_best_practices
Если комплексный императивный цикл for сложно преобразовать в Stream (особенно если алгоритм этого цикла делает кучу “side effects”) - ничего страшного, продолжай использовать императивный стиль.
Я много раз замечал, что программисты впадают в две крайности - либо пытаются все представить в виде стримов, либо не используют их вовсе.
Но как обычно это и бывает - правда где-то по середине. Другими словами говоря,
сила в балансе между двумя подходами и умении их комбинировать. Какие-то задачи лучше решить через Stream API, какие-то в императивном стиле.
Кстати, что заметил очень полезного, когда начал использовать стримы - это прокачивание навыка декомпозировать задачи на более мелкие составляющие, что в последующем повлияло на декомпозицию задач любой сложности и любого уровня. Ибо в противном случае не получится компактно и понятно представить логику в виде стримов.
Также на своем опыте скажу, что API более высокого уровня я практически всегда определяю с помощью стримов, и только уходя вглубь - я могу прибегать к императивному стилю, если потребуется. Все потому что это очень сильно облегчает чтение программного кода, ибо я начинаю изучение всего “сверху вниз”.
#dmdev_best_practices
👍61🔥46❤8❤🔥1
Создавай короткие lambda выражения
Когда ты используешь Stream API или Optional с его приятными методами map(), filter(), etc - избегай длинных и сложных lambda выражений в них.
Их не только становится сложно читать, но такой подход убивает всю суть стримов: их компактность и быстрое понимание общей логики кода. Благодаря компактности у программиста появляется возможность смотреть на код с высоты птичьего полета. А если нужны более подробные детали - то уже опускаешься глубже в каждый конкретный метод map(), filter(), etc.
Поэтому, если lambda выражение становится сложным:
- вынеси ее в отдельный метод или даже разбей на несколько
- давай хорошие названия параметрам, если они помогают чтению lambda выражений
Например, вряд ли кому-то понравится код, который выглядит примерно так:
Здесь не все так плохо еще, потому что хотя бы вынесена логика по чтению файла в отдельный метод readFile.
Но гораздо приятнее видеть такое:
Здесь мне каждая деталь помогает понять логику
- и название fileDescriptor
- и что я буду считывать файл на основании id из fileDescriptor
- и даже результат этого чтения: стрим байт
P.S. Заметил, что с каждым постом реакций все меньше.
Дай огня, если хочешь продолжение этого адвента.
#dmdev_best_practices
Когда ты используешь Stream API или Optional с его приятными методами map(), filter(), etc - избегай длинных и сложных lambda выражений в них.
Их не только становится сложно читать, но такой подход убивает всю суть стримов: их компактность и быстрое понимание общей логики кода. Благодаря компактности у программиста появляется возможность смотреть на код с высоты птичьего полета. А если нужны более подробные детали - то уже опускаешься глубже в каждый конкретный метод map(), filter(), etc.
Поэтому, если lambda выражение становится сложным:
- вынеси ее в отдельный метод или даже разбей на несколько
- давай хорошие названия параметрам, если они помогают чтению lambda выражений
Например, вряд ли кому-то понравится код, который выглядит примерно так:
.flatMap(
it -> {
try {
return readFile(it.getId()).stream();
} catch (IOException e) {
return Stream.empty();
}
})
Здесь не все так плохо еще, потому что хотя бы вынесена логика по чтению файла в отдельный метод readFile.
Но гораздо приятнее видеть такое:
.flatMap(fileDescriptor -> readFileAsByteStream(fileDescriptor.getId()))
Здесь мне каждая деталь помогает понять логику
- и название fileDescriptor
- и что я буду считывать файл на основании id из fileDescriptor
- и даже результат этого чтения: стрим байт
P.S. Заметил, что с каждым постом реакций все меньше.
Дай огня, если хочешь продолжение этого адвента.
#dmdev_best_practices
🔥366👍27❤10💯4❤🔥2🙏2
Ну вот как после такого не замотивироваться! Можете же порадовать старика 😅
Все, пошел писать следующий best practice на завтра💬
Все, пошел писать следующий best practice на завтра
Please open Telegram to view this post
VIEW IN TELEGRAM
👍78❤22🔥14🤩7😁6❤🔥1
В которой раз убедился и практическим путем доказал даже на примере сегодняшних лайков - человек просто невероятно ленив
1️⃣ Если нет лайков под постом, то процент того, что человек поставит под ним свой - меньше, ибо нужно совершить больше действий (целых два клика! вместо одного)
2️⃣ Если не попросить реакции/комментариев, то их будет просто в разы меньше
Кстати, второй пункт работает со всем. Например, на YouTube, думаю, вы часто замечали, что автор просит поставить лайк/комментарий/поделиться видео и т.д. Все потому - что это действительно работает.
В своих видео я так не делал ни разу по многим причинам. Поэтому и лайков/комментариев тоже меньше, чем могло бы быть.
Поэтому знайте, даже если вас не просят реакций - автору очень приятно их видеть, и он очень благодарен за это.
Любая обратная связь невероятно важна человеку!
Думаю, это малая цена за создаваемый полезный контент 🙂
1️⃣ Если нет лайков под постом, то процент того, что человек поставит под ним свой - меньше, ибо нужно совершить больше действий (целых два клика! вместо одного)
2️⃣ Если не попросить реакции/комментариев, то их будет просто в разы меньше
Кстати, второй пункт работает со всем. Например, на YouTube, думаю, вы часто замечали, что автор просит поставить лайк/комментарий/поделиться видео и т.д. Все потому - что это действительно работает.
В своих видео я так не делал ни разу по многим причинам. Поэтому и лайков/комментариев тоже меньше, чем могло бы быть.
Поэтому знайте, даже если вас не просят реакций - автору очень приятно их видеть, и он очень благодарен за это.
Любая обратная связь невероятно важна человеку!
Думаю, это малая цена за создаваемый полезный контент 🙂
❤142👍65🔥21💯14❤🔥7🤔3🤩3🙏2🥰1👏1😱1
Optional.isPresent(), .isEmpty(), and .get() методы обычно не следует использовать
Вышеперечисленные методы можно заменять на более выразительные конструкции Optional API.
1️⃣ Представим такую "классическую" логическую конструкцию if-else, где нужно вернуть значение:
2️⃣ Порой нам надо сделать что-то со значением, если оно существует, и это действие void (в отличие от пункта 1). А если его нет - то ничего не делать. И такая конструкция:
3️⃣ Похоже на пункт 2, но нам нужно сделать else действие, которое тоже void, если значение в Optional не существует.
4️⃣ Очень похоже на пункт 2, только объем работы нужно выполнить больше, если значение в Optional существует, и порой приходится даже сохранять это значение в отдельную переменную. Это выглядит так:
#dmdev_best_practices
Вышеперечисленные методы можно заменять на более выразительные конструкции Optional API.
1️⃣ Представим такую "классическую" логическую конструкцию if-else, где нужно вернуть значение:
if (optionalObject.isPresent()) {
return doWork(optionalObject.get());
} else {
return "other";
}
// Она может легко быть представлена двумя другими в зависимости от надобности в "ленивой" инициализации значения в else:
return optionalObject.map(this::doWork)
.orElse("other");
return optionalObject.map(this::doWork)
.orElseGet(this::doOtherLazy);
2️⃣ Порой нам надо сделать что-то со значением, если оно существует, и это действие void (в отличие от пункта 1). А если его нет - то ничего не делать. И такая конструкция:
if (optionalObject.isPresent()) {
doWork(optionalObject.get());
}
// Заменяется на:
optionalObject.ifPresent(this::doWork);
3️⃣ Похоже на пункт 2, но нам нужно сделать else действие, которое тоже void, если значение в Optional не существует.
if (optionalObject.isPresent()) {
doWork(optionalObject.get());
} else {
doOtherWork();
}
// Это можно заменить на конструкцию .ifPresentOrElse, которого очень не хватало в Java 8, и которое добавили только в следующей Java 9:
optionalObject.ifPresentOrElse(this::doWork, this::doOtherWork);
4️⃣ Очень похоже на пункт 2, только объем работы нужно выполнить больше, если значение в Optional существует, и порой приходится даже сохранять это значение в отдельную переменную. Это выглядит так:
Optional<Object> optionalObject = getOptionalObject();
if (optionalObject.isEmpty()) {
return;
}
Object object = optionalObject.get();
doWork(object);
// code ...
doWorkAgain(object);
// Вместо этого мы можешь просто воспользоваться .orElse(null), чтобы сразу получить значение из Optional и далее работать только с ним:
Object object = getOptionalObject().orElse(null);
if (object == null) {
return;
}
doWork(object);
// code ...
doWorkAgain(object);
#dmdev_best_practices
🔥198👍39❤🔥9🤯2😍2❤1👏1
Названия тестов - очень важны!
Название теста должно описывать поведение (test case). Когда программист просто читает название теста - этого уже должно быть достаточно, чтобы понять, что тест пытается проверить и какой ожидаемый результат.
Другими словами говоря, название теста служит для своего рода самодокументации.
На своем примере:
Когда я хочу посмотреть возможные варианты использования какого-то API, то при хорошо написанных тестах - мне достаточно просто взглянуть на них. Хорошие тестовые имена очень здорово описывают поведение API при самых разных условиях/входных параметрах, которые ты, порой, даже не ожидал. Ибо у того, кто писал этот API, как правило было больше контекста, чем у тебя, и он больше понимал его логику и его нюансы.
Для интереса можно сравнить два примера одного и того же test case:
Лишь взглянув на второй вариант, мне будет достаточно понять его суть.
Поэтому я нашел для себя этот паттерн именования тестов наилучшим:
#dmdev_best_practices
Название теста должно описывать поведение (test case). Когда программист просто читает название теста - этого уже должно быть достаточно, чтобы понять, что тест пытается проверить и какой ожидаемый результат.
Другими словами говоря, название теста служит для своего рода самодокументации.
На своем примере:
Когда я хочу посмотреть возможные варианты использования какого-то API, то при хорошо написанных тестах - мне достаточно просто взглянуть на них. Хорошие тестовые имена очень здорово описывают поведение API при самых разных условиях/входных параметрах, которые ты, порой, даже не ожидал. Ибо у того, кто писал этот API, как правило было больше контекста, чем у тебя, и он больше понимал его логику и его нюансы.
Для интереса можно сравнить два примера одного и того же test case:
@Test
void processMessage_failed()
@Test
void processMessage_missingMessageId_throwsValidationException()
Лишь взглянув на второй вариант, мне будет достаточно понять его суть.
Поэтому я нашел для себя этот паттерн именования тестов наилучшим:
apiUnderTest_behavior_expectedResult
#dmdev_best_practices
🔥108👍38❤5❤🔥5
Избегай boolean параметров
Если это возможно, то лучше избегать boolean параметров в public методах (открытый API). Все потому, что такие структуры очень плохо и читаются в коде, и пишутся, да и тестировать тоже неприятно. А создавать целые переменные только для того, чтобы описывать true/false флаг, программисты попросту не будут (да и не поможет это).
Например, глядя на этот код, можно только гадать, что значит true, и что будет, если в метод передать false:
Как можно этого избежать?
1️⃣ Джошуа Блох в своей книге Effective Java (Item 51) советует создавать enum с двумя значениями. Что и легко читается, легко документируется, и в случае чего - можно добавлять третье/четвертое значение и т.д.
2️⃣ Заменить один метод на два других с более подходящими названиями.
3️⃣ Воспользоваться техникой уменьшения количества параметров в методах, т.е. просто создать объект, который будет содержать все параметры:
4️⃣ Если по каким-то стечениям обстоятельств не помогли три предыдущие пункта, то нужно хотя бы оставить комментарий, что означает boolean параметр:
#dmdev_best_practices
Если это возможно, то лучше избегать boolean параметров в public методах (открытый API). Все потому, что такие структуры очень плохо и читаются в коде, и пишутся, да и тестировать тоже неприятно. А создавать целые переменные только для того, чтобы описывать true/false флаг, программисты попросту не будут (да и не поможет это).
Например, глядя на этот код, можно только гадать, что значит true, и что будет, если в метод передать false:
Result result = processMessage(message, true);
Как можно этого избежать?
1️⃣ Джошуа Блох в своей книге Effective Java (Item 51) советует создавать enum с двумя значениями. Что и легко читается, легко документируется, и в случае чего - можно добавлять третье/четвертое значение и т.д.
Result result = processMessage(message, ProcessingType.DRY_RUN);
2️⃣ Заменить один метод на два других с более подходящими названиями.
Result result = processMessage(message);
Result result = processMessageDryRun(message);
3️⃣ Воспользоваться техникой уменьшения количества параметров в методах, т.е. просто создать объект, который будет содержать все параметры:
ProcessOptions options = ProcessOptions.builder().message(message).dryRun(true).build();
Result result = process(options);
4️⃣ Если по каким-то стечениям обстоятельств не помогли три предыдущие пункта, то нужно хотя бы оставить комментарий, что означает boolean параметр:
Result result = processMessage(message, /* dryRun= */ true);
#dmdev_best_practices
👍108🔥50❤🔥6
Открываю набор на менторство DMdev
Кто хочет в Новом Году наконец-то покорить Java и заложить крепкий фундамент на будущее в IT?
Стать конкурентоспособным разработчиком на этапе собеседований и/или внутри своей компании?
В связи с этим, приглашаю на менторство DMdev первой и второй ступени начинающих и практикующих джавистов!
Результат первой ступени менторства - готовый веб-проект в CV, написанный чисто на Java Core.
Результат второй ступени - веб-проект в CV, написанный на Java с использованием фреймворков (Hibernate, Spring)
❕ Проекты не шаблонные, можно выбрать по своему желанию, чего душа желает❕
Старт: 22 января
Продолжительность: 3,5 месяца
Количество участников: до 12 человек
Оставить заявку и узнать подробности можно по ссылкам ниже:
- первая ступень менторства
- вторая ступень менторства
P.S. Это может стать одним из лучших подарков для себя 🎁 🎄
Кто хочет в Новом Году наконец-то покорить Java и заложить крепкий фундамент на будущее в IT?
Стать конкурентоспособным разработчиком на этапе собеседований и/или внутри своей компании?
В связи с этим, приглашаю на менторство DMdev первой и второй ступени начинающих и практикующих джавистов!
Что внутри?
- недельные спринты с уроками и домашним заданием
- два раза в неделю живые созвоны с опытным ментором-разработчиком (на второй ступени со мной)
- еженедельное code review
- безлимитное общение в чате с ментором
Результат первой ступени менторства - готовый веб-проект в CV, написанный чисто на Java Core.
Результат второй ступени - веб-проект в CV, написанный на Java с использованием фреймворков (Hibernate, Spring)
Старт: 22 января
Продолжительность: 3,5 месяца
Количество участников: до 12 человек
Оставить заявку и узнать подробности можно по ссылкам ниже:
- первая ступень менторства
- вторая ступень менторства
P.S. Это может стать одним из лучших подарков для себя 🎁 🎄
Please open Telegram to view this post
VIEW IN TELEGRAM
👍33🔥16❤🔥3