Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса🎁 .
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🥰3
Как из Java приложения запустить другую программу?
Самый простой и базовый способ – с помощью метода Runtime.getRuntime().exec(). В качестве параметра ему передается строка системной команды. Опциональные можно передать рабочую директорию, и переменные окружения в виде массива строк "имя=значение". Если команде нужны аргументы, они передаются либо массивом, либо в той же строке команды через пробелы.
Рекомендуемый, и более управляемый способ – использование класса ProcessBuilder. Он же применяется внутри метода exec. Билдер дает, например, средства для использования в команде пайплайнов и редиректов ввода-вывода.
В результате запуска команды создается объект класса Process. Его можно сконвертировать в более современный (Java 9+) и функциональный ProcessHandle. Через эти объекты идет работа с вводом-выводом процесса, его характеристиками и статусом.
Команда запускается в отдельном подпроцессе операционной системы. Это значит, что лозунг «Write once, run anywhere» перестает здесь работать – ваша программа становится платформо-зависимой. Обращение к ОС, а тем более выделение нового процесса обычно занимает немало ресурсов компьютера. Запуск внешних программ не считается плохой практикой, но всё-таки при возможности стоит его избегать.
Самый простой и базовый способ – с помощью метода Runtime.getRuntime().exec(). В качестве параметра ему передается строка системной команды. Опциональные можно передать рабочую директорию, и переменные окружения в виде массива строк "имя=значение". Если команде нужны аргументы, они передаются либо массивом, либо в той же строке команды через пробелы.
Рекомендуемый, и более управляемый способ – использование класса ProcessBuilder. Он же применяется внутри метода exec. Билдер дает, например, средства для использования в команде пайплайнов и редиректов ввода-вывода.
В результате запуска команды создается объект класса Process. Его можно сконвертировать в более современный (Java 9+) и функциональный ProcessHandle. Через эти объекты идет работа с вводом-выводом процесса, его характеристиками и статусом.
Команда запускается в отдельном подпроцессе операционной системы. Это значит, что лозунг «Write once, run anywhere» перестает здесь работать – ваша программа становится платформо-зависимой. Обращение к ОС, а тем более выделение нового процесса обычно занимает немало ресурсов компьютера. Запуск внешних программ не считается плохой практикой, но всё-таки при возможности стоит его избегать.
👍13🥰2🎉1
Начинать путь в мобильной разработке непросто даже тем, кто уже работает в IT.
В своём канале Илья, android-разработчик с 9-летним стажем, даёт ценные советы о том, какой минимальный набор знаний библиотек и подходов нужен, чтобы устроиться на работу.
Важные плюсы android-разработки на Kotlin в том, что тут всегда много вакансий, а язык можно освоить за месяц, и пригодится он в том числе и в backend.
Подписывайтесь на канал Ильи и получите пошаговый план развития с нуля до Junior.
Также в канале вас ждут лучшие практики, лайфхаки и советы по рефакторингу.
В своём канале Илья, android-разработчик с 9-летним стажем, даёт ценные советы о том, какой минимальный набор знаний библиотек и подходов нужен, чтобы устроиться на работу.
Важные плюсы android-разработки на Kotlin в том, что тут всегда много вакансий, а язык можно освоить за месяц, и пригодится он в том числе и в backend.
Подписывайтесь на канал Ильи и получите пошаговый план развития с нуля до Junior.
Также в канале вас ждут лучшие практики, лайфхаки и советы по рефакторингу.
👍7
Как сгенерировать хорошее случайное число?
Этот вопрос глубже, чем кажется на первый взгляд. Для начала, нужно разобраться в двух понятиях: псевдослучайные, и истинно случайные числа.
Псевдослучайные числа – это последовательность случайных на вид чисел, на самом деле полученных в результате математического алгоритма. Последовательность таких чисел можно воспроизвести, зная начальные условия (seed, энтропия) и используемый алгоритм. Метод, который используется для генерации чисел в классе java.util.Random, дает криптографически ненадежные псевдослучайные числа – злоумышленник может достаточно легко их предугадывать.
Истинно случайные числа основываются на физических свойствах, которые трудно поддаются измерению. Это могут быть, например, доли секунд текущего системного времени. Алгоритм генерации истинно случайных чисел не позволяет с хорошей точностью угадать следующее число, даже зная предыдущие.
Класс SecureRandom предоставляет доступ к криптографически надежным генераторам случайных чисел. При том, это могут быть как достаточно сложные последовательности псевдослучайных, так и истинно случайные числа. Согласно стандартам безопасности, они будут достаточно непредсказуемы.
Не все случайные числа одинаково случайны. Шанс что рост случайного человека окажется ближе к среднему высок, тогда как у игральной кости одинакова вероятность выпадения любой из граней. В математике это называется распределением вероятностей.
Внутри SecureRandom использует SPI. Мы можем выбирать из различных алгоритмов генерации и их провайдеров, указав их названия в фабричном методе getInstance. Все перечисленные выше свойства определяются именно используемым алгоритмом.
Этот вопрос глубже, чем кажется на первый взгляд. Для начала, нужно разобраться в двух понятиях: псевдослучайные, и истинно случайные числа.
Псевдослучайные числа – это последовательность случайных на вид чисел, на самом деле полученных в результате математического алгоритма. Последовательность таких чисел можно воспроизвести, зная начальные условия (seed, энтропия) и используемый алгоритм. Метод, который используется для генерации чисел в классе java.util.Random, дает криптографически ненадежные псевдослучайные числа – злоумышленник может достаточно легко их предугадывать.
Истинно случайные числа основываются на физических свойствах, которые трудно поддаются измерению. Это могут быть, например, доли секунд текущего системного времени. Алгоритм генерации истинно случайных чисел не позволяет с хорошей точностью угадать следующее число, даже зная предыдущие.
Класс SecureRandom предоставляет доступ к криптографически надежным генераторам случайных чисел. При том, это могут быть как достаточно сложные последовательности псевдослучайных, так и истинно случайные числа. Согласно стандартам безопасности, они будут достаточно непредсказуемы.
Не все случайные числа одинаково случайны. Шанс что рост случайного человека окажется ближе к среднему высок, тогда как у игральной кости одинакова вероятность выпадения любой из граней. В математике это называется распределением вероятностей.
Внутри SecureRandom использует SPI. Мы можем выбирать из различных алгоритмов генерации и их провайдеров, указав их названия в фабричном методе getInstance. Все перечисленные выше свойства определяются именно используемым алгоритмом.
👍15🔥3
Пройди тест по Java и проверь свои знания.
Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса .
🎄 Новогодние скидки! Возможна оплата в рассрочку! Предложение ограничено.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Какой выбрать тип для даты/времени?
В пакете java.util расположены старые классы стандартной библиотеки Java: Date (дата+время), Calendar (конвертация и манипуляция), TimeZone (смещение часового пояса). Эти классы обладали рядом известных проблем. Экземпляры были изменяемыми, что делало их потоко-небезопасными. Работа с датами через календарь была неудобной, не было нормальной поддержки часовых поясов и интернационализации.
Постепенно стандартом де-факто стала сторонняя библиотека Joda-Time. Её разработчики решили все названные выше проблемы.
В Java 8 был добавлен пакет java.time, который взял решения из Joda-Time в стандарт, создатель библиотеки участвовал в разработке. Ключевые классы пакета:
• LocalDate, LocalTime и LocalDateTime – локальные для пользователя дата/время.
• ZonedDateTime – дата/время в определенной часовой зоне.
• Period и Duration – периоды дат и времени соответственно.
Отдельно существуют классы Date и Time пакета java.sql. Это представление даты и времени для обмена данными через JDBC. Не стоит пользоваться ими вне уровня доступа к данным, хотя бы потому, что это классы-наследники старого java.util.Date.
В пакете java.util расположены старые классы стандартной библиотеки Java: Date (дата+время), Calendar (конвертация и манипуляция), TimeZone (смещение часового пояса). Эти классы обладали рядом известных проблем. Экземпляры были изменяемыми, что делало их потоко-небезопасными. Работа с датами через календарь была неудобной, не было нормальной поддержки часовых поясов и интернационализации.
Постепенно стандартом де-факто стала сторонняя библиотека Joda-Time. Её разработчики решили все названные выше проблемы.
В Java 8 был добавлен пакет java.time, который взял решения из Joda-Time в стандарт, создатель библиотеки участвовал в разработке. Ключевые классы пакета:
• LocalDate, LocalTime и LocalDateTime – локальные для пользователя дата/время.
• ZonedDateTime – дата/время в определенной часовой зоне.
• Period и Duration – периоды дат и времени соответственно.
Отдельно существуют классы Date и Time пакета java.sql. Это представление даты и времени для обмена данными через JDBC. Не стоит пользоваться ими вне уровня доступа к данным, хотя бы потому, что это классы-наследники старого java.util.Date.
👍19❤2🔥2
Проверь насколько хорошо ты знаешь Java и готов освоить Spring!
Ответишь — пройдешь на продвинутый курс "Разработчик на Spring Framework" от OTUS по специальной цене.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ruPlease open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
Как сгенерировать уникальный идентификатор?
UUID (universally unique identifier) – стандарт, описывающий способ создания правильных уникальных идентификаторов. Значения генерируются на основании таких источников информации, как системное время и MAC-адрес, за счет чего они остаются с достаточной вероятностью уникальными, даже будучи сгенерированными независимо. Можно с разных машин добавлять в базу данных записи с UUID-идентификаторами, и не бояться конфликта.
UUID бывает пяти разных версий, версия определяет способ создания. Формат остается одинаковым: это строковое шестнадцатеричное представление 128-битного целого числа (два long-а), разделенное дефисами на группы фиксированного размера:
25b32eaa-3017-4ad7-9224-383f6bfa5212
В Java уникальный идентификатор представляется иммутабельным классом UUID из пакета java.util. В нём нет сложной логики, только getter-ы для описанных в стандарте составных частей, конструктор и статические фабричные методы.
Единственный конструктор позволяет создать экземпляр по двум указанным половинам значения (старшие и младшие 64 бита в виде long параметров). nameUUIDFromBytes строит из заданного массива байтов UUID версии 3. randomUUID генерирует случайный уникальный идентификатор версии 4, с применением SecureRandom.
UUID (universally unique identifier) – стандарт, описывающий способ создания правильных уникальных идентификаторов. Значения генерируются на основании таких источников информации, как системное время и MAC-адрес, за счет чего они остаются с достаточной вероятностью уникальными, даже будучи сгенерированными независимо. Можно с разных машин добавлять в базу данных записи с UUID-идентификаторами, и не бояться конфликта.
UUID бывает пяти разных версий, версия определяет способ создания. Формат остается одинаковым: это строковое шестнадцатеричное представление 128-битного целого числа (два long-а), разделенное дефисами на группы фиксированного размера:
25b32eaa-3017-4ad7-9224-383f6bfa5212
В Java уникальный идентификатор представляется иммутабельным классом UUID из пакета java.util. В нём нет сложной логики, только getter-ы для описанных в стандарте составных частей, конструктор и статические фабричные методы.
Единственный конструктор позволяет создать экземпляр по двум указанным половинам значения (старшие и младшие 64 бита в виде long параметров). nameUUIDFromBytes строит из заданного массива байтов UUID версии 3. randomUUID генерирует случайный уникальный идентификатор версии 4, с применением SecureRandom.
👍13🔥4🥰3
Получить все необходимые навыки до уровня Middle на комплексном онлайн-курсе «Специализация Java-разработчик» от OTUS.
После обучения вы сможете:
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ruPlease open Telegram to view this post
VIEW IN TELEGRAM
👍4😢3❤2🔥2
Чем IllegalArgumentException лучше чем NullPointerException?
Речь здесь идет о выборе подхода к обработке ошибки, когда пользователь передал в non-nullable параметр значение null.
Технически, оба этих исключения unchecked, оба из стандартной библиотеки, и особой разницы нет.
Однако семантически эти исключения отличаются. NullPointerException говорит пользователю о попытке обратиться к членам класса через null-ссылку. Это лишь техническое описание, без информации для пользователя о логике программы. IllegalArgumentException, напротив, явно говорит о недопустимом значении аргумента – это понятная для пользователя информация.
Семантическая разница иногда проявляется и технически. Например, в обработчиках исключений некоторых фреймворков именно IllegalArgumentException превращается в HTTP-ответ с кодом 400 Bad Request, в то время как NPE остается общим кодом «неизвестной ошибки» 500 Internal Server Error.
Кроме того, чтобы выбросить NullPointerException не требуется явного кода обработки null. Остается неизвестным, ожидаемо ли в этом случае исключение, или разработчик попросту забыл добавить корректную обработку.
Явная обработка null и выброс IllegalArgumentException для пользователя кода будет служить документацией, а сообщение об ошибке в аргументе его конструктора внесет еще больше ясности.
Речь здесь идет о выборе подхода к обработке ошибки, когда пользователь передал в non-nullable параметр значение null.
Технически, оба этих исключения unchecked, оба из стандартной библиотеки, и особой разницы нет.
Однако семантически эти исключения отличаются. NullPointerException говорит пользователю о попытке обратиться к членам класса через null-ссылку. Это лишь техническое описание, без информации для пользователя о логике программы. IllegalArgumentException, напротив, явно говорит о недопустимом значении аргумента – это понятная для пользователя информация.
Семантическая разница иногда проявляется и технически. Например, в обработчиках исключений некоторых фреймворков именно IllegalArgumentException превращается в HTTP-ответ с кодом 400 Bad Request, в то время как NPE остается общим кодом «неизвестной ошибки» 500 Internal Server Error.
Кроме того, чтобы выбросить NullPointerException не требуется явного кода обработки null. Остается неизвестным, ожидаемо ли в этом случае исключение, или разработчик попросту забыл добавить корректную обработку.
Явная обработка null и выброс IllegalArgumentException для пользователя кода будет служить документацией, а сообщение об ошибке в аргументе его конструктора внесет еще больше ясности.
👍34🔥6
Microservices | Вопросы с Собеседований
- Подборка вопросов по микросервисной архитектуре с реальных собеседований
- Авторские статьи по архитектуре, проектированию, базам данных
- Автор - Lead Developer с 8 лет опыта на Java/Kotlin
- Подборка вопросов по микросервисной архитектуре с реальных собеседований
- Авторские статьи по архитектуре, проектированию, базам данных
- Автор - Lead Developer с 8 лет опыта на Java/Kotlin
👍9🔥5
Сгенерируйте случайное число в интервале
Когда мы сталкиваемся со случайными числами, то всегда должны помнить о вопросе их распределения. Не будем здесь углубляться в теорию мат. статистики, а рассмотрим только практические следствия.
Самые стандартные классы-генераторы случайных чисел создают равномерно распределенные значения. Любое число возникает с одинаковой вероятностью – это ожидаемое поведение для большинства задач. Например, метод Random.nextInt(1) будет генерировать примерно одинаковое количество значений 0 и 1.
Однако, программист легко может "испортить" равномерность значений последующими операциями. Возьмем вместо предыдущего примера Random.nextInt(2)%2. Такая конструкция тоже будет возвращать 0 или 1. Однако, третье возможное значение из генератора, 2, будет тоже превращено в 0. Значит, ответ 0 будет возникать в два раза чаще чем 1.
Это та причина, по которой лучше не пользоваться общепринятым «школьным» арифметическим ограничением с помощью оператора %. Вместо этого следует оставить заботу о распределении разработчикам библиотеки, и пользоваться в прикладном коде готовыми методами с границами.
Если задача подразумевает более плотную работу с распределениями, стоит воспользоваться специализированной библиотекой вроде Apache Commons Math.
Когда мы сталкиваемся со случайными числами, то всегда должны помнить о вопросе их распределения. Не будем здесь углубляться в теорию мат. статистики, а рассмотрим только практические следствия.
Самые стандартные классы-генераторы случайных чисел создают равномерно распределенные значения. Любое число возникает с одинаковой вероятностью – это ожидаемое поведение для большинства задач. Например, метод Random.nextInt(1) будет генерировать примерно одинаковое количество значений 0 и 1.
Однако, программист легко может "испортить" равномерность значений последующими операциями. Возьмем вместо предыдущего примера Random.nextInt(2)%2. Такая конструкция тоже будет возвращать 0 или 1. Однако, третье возможное значение из генератора, 2, будет тоже превращено в 0. Значит, ответ 0 будет возникать в два раза чаще чем 1.
Это та причина, по которой лучше не пользоваться общепринятым «школьным» арифметическим ограничением с помощью оператора %. Вместо этого следует оставить заботу о распределении разработчикам библиотеки, и пользоваться в прикладном коде готовыми методами с границами.
Если задача подразумевает более плотную работу с распределениями, стоит воспользоваться специализированной библиотекой вроде Apache Commons Math.
👍12🔥2
Расскажем на бесплатном открытом уроке «Разбираемся с АОП в Spring» от OTUS.
На вебинаре разберём:
✔️ что такое аспекты;
✔️ как ими пользоваться и как они работают в Spring;
✔️ почему это важно для понимания работы самого фреймворка.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ruPlease open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🔥2
Когда стоит выбрать char[] вместо String?
Первая, очевидная причина – оптимизация. Если вам заранее известен размер строки, и он фиксирован, может быть полезно выбрать массив. Если программа работает с неизменяемыми подстроками, удобно представить их в виде offset-ов общего массива (как это было сделано раньше в самом String).
Следует помнить, что оптимизировать нужно осознанно и своевременно. JVM тоже прикладывает усилия по оптимизации строк (вроде интернирования), которые могут оказаться эффективнее ваших.
Вторая, менее очевидная причина – безопасность. Строки в Java иммутабельны. Это значит, что когда вы сохраняете пароль в объекте типа String, физически уничтожить его из памяти может только сборщик мусора.
Существует способ алгоритмической атаки на систему, когда хакер своими действиями вызывает переполнение памяти, и конфиденциальная информация попадает в heap dump.
Если пароль хранится в массиве, программист может самостоятельно «занулить» значение после использования.
Первая, очевидная причина – оптимизация. Если вам заранее известен размер строки, и он фиксирован, может быть полезно выбрать массив. Если программа работает с неизменяемыми подстроками, удобно представить их в виде offset-ов общего массива (как это было сделано раньше в самом String).
Следует помнить, что оптимизировать нужно осознанно и своевременно. JVM тоже прикладывает усилия по оптимизации строк (вроде интернирования), которые могут оказаться эффективнее ваших.
Вторая, менее очевидная причина – безопасность. Строки в Java иммутабельны. Это значит, что когда вы сохраняете пароль в объекте типа String, физически уничтожить его из памяти может только сборщик мусора.
Существует способ алгоритмической атаки на систему, когда хакер своими действиями вызывает переполнение памяти, и конфиденциальная информация попадает в heap dump.
Если пароль хранится в массиве, программист может самостоятельно «занулить» значение после использования.
👍24🔥8
«Обработка тысяч одновременных записей и обеспечение согласованности данных»
• Разберем уровни изоляции транзакций
• Физический состав работы с базой данных
• Locks: pessimistic, optimistic & advisory
Рассмотрим потенциальные проблемы при работе со связкой java->database. Выполним тысячи апдейтов над одними и теми же строками и покажем наиболее распространенные подходы для достижения согласованности и производительности.
Ведущий: Роман Оборин, Senior Software Engineer
Опыт программирования на Java — 6 лет (Tesco, BNP paribas, Natera)
Реклама. ООО "Платформа непрерывного обучения" ИНН 7839405924
erid: 2Vtzqvy3bJD
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Под каким типом хранить период времени?
В стандартной библиотеке современных версий Java для этих целей есть два класса:
Period – календарный период. Количество дней, месяцев и лет. Одним днем здесь считается день в терминах ZonedDateTime.
Duration – длительность времени. Количество наносекунд, секунд, минут, часов, и тоже дней. Здесь один день – ровно 24 часа.
Оба класса реализуют общий интерфейс TemporalAmount – период времени вообще. Оба иммутабельны, и как следствие, потокобезопасны. Любая модифицирующая операция вроде plusX() возвращает новый экземпляр с измененным значением.
Экземпляры обоих классов могут быть созданы из значений отдельных компонентов, из двух моментов времени методом between, или из строки. Строковое представление Duration: "P2DT3H4M", Period: "P1Y2M3D".
До Java 8 основным способом хранения периода были числовые примитивы. В этом подходе есть много недостатков, среди которых в первую очередь неограниченность значений и ненаглядность. Чтобы в Java 8+ получить период числом, используется метод between() нужного элемента енама ChronoUnit.
В стандартной библиотеке современных версий Java для этих целей есть два класса:
Period – календарный период. Количество дней, месяцев и лет. Одним днем здесь считается день в терминах ZonedDateTime.
Duration – длительность времени. Количество наносекунд, секунд, минут, часов, и тоже дней. Здесь один день – ровно 24 часа.
Оба класса реализуют общий интерфейс TemporalAmount – период времени вообще. Оба иммутабельны, и как следствие, потокобезопасны. Любая модифицирующая операция вроде plusX() возвращает новый экземпляр с измененным значением.
Экземпляры обоих классов могут быть созданы из значений отдельных компонентов, из двух моментов времени методом between, или из строки. Строковое представление Duration: "P2DT3H4M", Period: "P1Y2M3D".
До Java 8 основным способом хранения периода были числовые примитивы. В этом подходе есть много недостатков, среди которых в первую очередь неограниченность значений и ненаглядность. Чтобы в Java 8+ получить период числом, используется метод between() нужного элемента енама ChronoUnit.
👍12❤1
Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса🎁 .
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2☃1
Как работает инъекция прототипа в синглтон?
Раньше мы уже рассматривали различия скоупов singleton и prototype в Spring Framework. Допустим ситуацию, когда в singleton-компонент внедряется зависимость со скоупом prototype – когда будет создан её объект?
Если просто добавить к определению бина аннотацию @Scope(SCOPE_PROTOTYPE), и использовать этот бин в синглтоне через аннотацию @Autowired – будет создан только один объект. Потому что синглтон создается только однажды, и обращение к прототипу случится тоже однажды при его создании (при внедрении зависимости).
Примитивный способ получать новый объект при каждом обращении – отказаться от @Autowired, и доставать его из контекста вручную. Для этого нужно вызывать context.getBean(MyPrototype.class).
Воспользоваться автоматическим внедрением зависимостей можно через внедрение метода (паттерн «Команда»). Автовайрится не сам объект, а производящий его метод.
Более красивый декларативный способ – правильно настроить определение бина. В аннотации @Scope кроме самого scopeName доступен второй параметр – proxyMode. По умолчанию его значение NO – прокси не создается. Но если указать INTERFACES или TARGET_CLASS, то под @Autowired будет внедряться не сам объект, а сгенерированный фреймворком прокси. И когда проксируемый бин имеет скоуп prototype, то объект внутри прокси будет пересоздаваться при каждом обращении.
Лучший способ разобраться со скоупами – прочитать официальный гайд с иллюстрациями, и поэкспериментировать на практике. Для начала попробуйте пример с изображения выше.
Раньше мы уже рассматривали различия скоупов singleton и prototype в Spring Framework. Допустим ситуацию, когда в singleton-компонент внедряется зависимость со скоупом prototype – когда будет создан её объект?
Если просто добавить к определению бина аннотацию @Scope(SCOPE_PROTOTYPE), и использовать этот бин в синглтоне через аннотацию @Autowired – будет создан только один объект. Потому что синглтон создается только однажды, и обращение к прототипу случится тоже однажды при его создании (при внедрении зависимости).
Примитивный способ получать новый объект при каждом обращении – отказаться от @Autowired, и доставать его из контекста вручную. Для этого нужно вызывать context.getBean(MyPrototype.class).
Воспользоваться автоматическим внедрением зависимостей можно через внедрение метода (паттерн «Команда»). Автовайрится не сам объект, а производящий его метод.
Более красивый декларативный способ – правильно настроить определение бина. В аннотации @Scope кроме самого scopeName доступен второй параметр – proxyMode. По умолчанию его значение NO – прокси не создается. Но если указать INTERFACES или TARGET_CLASS, то под @Autowired будет внедряться не сам объект, а сгенерированный фреймворком прокси. И когда проксируемый бин имеет скоуп prototype, то объект внутри прокси будет пересоздаваться при каждом обращении.
Лучший способ разобраться со скоупами – прочитать официальный гайд с иллюстрациями, и поэкспериментировать на практике. Для начала попробуйте пример с изображения выше.
👍12🥰2😁1
Как инженеру и разработчику усилить резюме?
Изучить востребованный инструмент Apache Kafka! Начните знакомство с ним на бесплатном практическом уроке от Евгения Непомнящего – разработчика в IT Sense.
💻На вебинаре:
- узнаете про особенности Kafka и ее устройство;
- познакомитесь с основными утилитами;
- рассмотрите базовое API для работы с Kafka.
Занятие пройдёт 23 января в 20:00 мск и будет приурочено к старту курса «Apache Kafka». Программа доступна в рассрочку!
👉Регистрируйтесь прямо сейчас, чтобы принять участие в открытом уроке и получить запись: https://otus.pw/bBR4/
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Изучить востребованный инструмент Apache Kafka! Начните знакомство с ним на бесплатном практическом уроке от Евгения Непомнящего – разработчика в IT Sense.
💻На вебинаре:
- узнаете про особенности Kafka и ее устройство;
- познакомитесь с основными утилитами;
- рассмотрите базовое API для работы с Kafka.
Занятие пройдёт 23 января в 20:00 мск и будет приурочено к старту курса «Apache Kafka». Программа доступна в рассрочку!
👉Регистрируйтесь прямо сейчас, чтобы принять участие в открытом уроке и получить запись: https://otus.pw/bBR4/
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
👍2🔥2🍾1
Чем отличается final finally finalize?
Тем, что это даже синтаксически разные вещи. Как и вопрос о методах Object, это способ начать разговор.
finalize – метод-финализатор из Object.
final – модификатор, который применяется к переменным, полям, методам и классам. Переменная или поле становится неизменяемым и требует инициализации. Финальный метод нельзя переопределить в наследниках. Финальный класс не может иметь наследников вообще. Используется для создания хорошего API по принципу наименьших привилегий.
Когда в методе используется локальная переменная внешней области видимости, она обязана быть effectively final. В этом случае ключевое слово final необязательно, но значение всё равно не должно меняться.
finally – часть языковой конструкции try-catch-finally.
Любое исключение, выброшенное из блока try переводит исполнение в самый соответствующий ему catch (при наличии). Этим продиктована необходимость располагать блоки catch в строгом порядке, от типа исключения-наследника, к родителю. В случае multicatch тот же порядок должен соблюдаться и внутри одного catch. Больше примеров про порядок.
После выполнится блок finally. Выполняется он в любом случае, было исключение или нет. Типичное использование – освобождение ресурсов, обязательные завершающие действия.
Для требующих финализации классов («ресурсов») добавляется интерфейс AutoCloseable, повторяющийся код блока final выносится в метод close и вызывается неявно в конце try-with-resources. Если в этой конструкции присутствует и явный final, он будет выполнен после.
Тем, что это даже синтаксически разные вещи. Как и вопрос о методах Object, это способ начать разговор.
finalize – метод-финализатор из Object.
final – модификатор, который применяется к переменным, полям, методам и классам. Переменная или поле становится неизменяемым и требует инициализации. Финальный метод нельзя переопределить в наследниках. Финальный класс не может иметь наследников вообще. Используется для создания хорошего API по принципу наименьших привилегий.
Когда в методе используется локальная переменная внешней области видимости, она обязана быть effectively final. В этом случае ключевое слово final необязательно, но значение всё равно не должно меняться.
finally – часть языковой конструкции try-catch-finally.
Любое исключение, выброшенное из блока try переводит исполнение в самый соответствующий ему catch (при наличии). Этим продиктована необходимость располагать блоки catch в строгом порядке, от типа исключения-наследника, к родителю. В случае multicatch тот же порядок должен соблюдаться и внутри одного catch. Больше примеров про порядок.
После выполнится блок finally. Выполняется он в любом случае, было исключение или нет. Типичное использование – освобождение ресурсов, обязательные завершающие действия.
Для требующих финализации классов («ресурсов») добавляется интерфейс AutoCloseable, повторяющийся код блока final выносится в метод close и вызывается неявно в конце try-with-resources. Если в этой конструкции присутствует и явный final, он будет выполнен после.
👍6❤1