Чем отличается throw от throws? 🤓
Ответ:
Оба ключевых слова связаны с обработкой исключений, но выполняют разные функции.
throws используется в сигнатуре метода, чтобы объявить, что метод может выбросить указанные исключения (обычно проверяемые). Это предупреждение для вызывающего кода.
throw — это оператор, который фактически создает и выбрасывает объект исключения (например, throw new IOException("Ошибка")).
throw используется внутри тела метода.
#собеседование
Ответ:
throws используется в сигнатуре метода, чтобы объявить, что метод может выбросить указанные исключения (обычно проверяемые). Это предупреждение для вызывающего кода.
throw — это оператор, который фактически создает и выбрасывает объект исключения (например, throw new IOException("Ошибка")).
throw используется внутри тела метода.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
История технологий сегодня — 21 Февраля
ℹ️ Кто родился в этот день
Михаи́л Алекса́ндрович Бонч-Бруе́вич (9 (21) февраля 1888, Орёл — 7 марта 1940, Ленинград) — русский и советский радиотехник, основатель российской радиоламповой промышленности. Член-корреспондент АН СССР (1931). Профессор Московского высшего технического училища (1922), Ленинградского института инженеров связи (1932), доктор технических наук, один из основателей и руководителей Нижегородской радиолаборатории. Внёс значительный вклад в развитие советской радиофизики, разработку новых типов радиоламп, аппаратуры радиовещания и радиосвязи. Автор учебников, научных работ, а также около 60 патентов на изобретения в области радиотехники.
🌐 Знаковые события
2006 — космическим телескопом «Хаббл» открыт астрономический объект неизвестного типа SCP 06F6, природу которого астрономы не могут объяснить до сих пор.
#Biography #Birth_Date #Events #21февраля
Михаи́л Алекса́ндрович Бонч-Бруе́вич (9 (21) февраля 1888, Орёл — 7 марта 1940, Ленинград) — русский и советский радиотехник, основатель российской радиоламповой промышленности. Член-корреспондент АН СССР (1931). Профессор Московского высшего технического училища (1922), Ленинградского института инженеров связи (1932), доктор технических наук, один из основателей и руководителей Нижегородской радиолаборатории. Внёс значительный вклад в развитие советской радиофизики, разработку новых типов радиоламп, аппаратуры радиовещания и радиосвязи. Автор учебников, научных работ, а также около 60 патентов на изобретения в области радиотехники.
2006 — космическим телескопом «Хаббл» открыт астрономический объект неизвестного типа SCP 06F6, природу которого астрономы не могут объяснить до сих пор.
#Biography #Birth_Date #Events #21февраля
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
С 14.02 по 20.02
Предыдущий пост(с 07.02 по 13.02)
Воскресный мотивационный пост:
Не было мотивации
Запись встреч/видео:
6. От сырых метрик к production-мониторингу: Prometheus и Grafana
Обучающие статьи:
Раздел 8. Stream API и функциональный стиль
Глава 2: Анатомия Stream API. Ленивость и стоимость операций
Ленивость и Short-Circuit — ключ к эффективности
(Практика): Диссекция конвейера в «Библиотеке»
Глава 3: Чистые преобразования и борьба с исключениями
filter, map, flatMap — кирпичи декларативности
Советы по Java:
[Совет по Java #006]
Используйте Enum вместо строковых констант для ограниченного набора значений
[Совет по Java #007]
System.currentTimeMillis() для замеров производительности ненадежен. Всегда используйте System.nanoTime().
Полезные статьи и видео:
Hot reload секретов под нагрузкой в Java-сервисах на Spring
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Предыдущий пост(с 07.02 по 13.02)
Воскресный мотивационный пост:
Не было мотивации
Запись встреч/видео:
6. От сырых метрик к production-мониторингу: Prometheus и Grafana
Обучающие статьи:
Раздел 8. Stream API и функциональный стиль
Глава 2: Анатомия Stream API. Ленивость и стоимость операций
Ленивость и Short-Circuit — ключ к эффективности
(Практика): Диссекция конвейера в «Библиотеке»
Глава 3: Чистые преобразования и борьба с исключениями
filter, map, flatMap — кирпичи декларативности
Советы по Java:
[Совет по Java #006]
Используйте Enum вместо строковых констант для ограниченного набора значений
[Совет по Java #007]
System.currentTimeMillis() для замеров производительности ненадежен. Всегда используйте System.nanoTime().
Полезные статьи и видео:
Hot reload секретов под нагрузкой в Java-сервисах на Spring
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍3🔥2 2
А давайте сегодня, часиков в 17 по мск встретимся и поболтаем? ☺️
Что-то давно Вас всех не видел)))
Расскажете как у вас дела😉
Придете?📞
Что-то давно Вас всех не видел)))
Расскажете как у вас дела
Придете?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
История технологий сегодня — 22 Февраля
ℹ️ Кто родился в этот день
Томас Курц (англ. Thomas Eugene Kurtz; 22 февраля 1928, Ок-Парк — 12 ноября 2024, Лебанон[англ.]) — американский учёный в области информатики, один из разработчиков языка программирования Бейсик. В начале — середине 1960-х годов совместно с Джоном Кемени разработал Бейсик и DTTS (англ. Dartmouth Time Sharing System) — операционную систему для PDP-1, отмечаемую как первую успешную крупномасштабную реализацию концепции разделения времени.
Ирвинг «Эл» Гросс (/ɡroʊs/; 22 февраля 1918 — 21 декабря 2000) — был пионером мобильной беспроводной связи. Он создал и запатентовал множество коммуникационных устройств, в частности, раннюю версию рации, радиостанции гражданского диапазона, пейджер и беспроводной телефон.
🌐 Знаковые события
1966 — запущен спутник «Космос-110» с собаками Ветерком и Угольком на борту.
#Biography #Birth_Date #Events #22февраля
Томас Курц (англ. Thomas Eugene Kurtz; 22 февраля 1928, Ок-Парк — 12 ноября 2024, Лебанон[англ.]) — американский учёный в области информатики, один из разработчиков языка программирования Бейсик. В начале — середине 1960-х годов совместно с Джоном Кемени разработал Бейсик и DTTS (англ. Dartmouth Time Sharing System) — операционную систему для PDP-1, отмечаемую как первую успешную крупномасштабную реализацию концепции разделения времени.
Ирвинг «Эл» Гросс (/ɡroʊs/; 22 февраля 1918 — 21 декабря 2000) — был пионером мобильной беспроводной связи. Он создал и запатентовал множество коммуникационных устройств, в частности, раннюю версию рации, радиостанции гражданского диапазона, пейджер и беспроводной телефон.
1966 — запущен спутник «Космос-110» с собаками Ветерком и Угольком на борту.
#Biography #Birth_Date #Events #22февраля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
ГЛОБАЛИЗАЦИЯ ЗАКАНЧИВАЕТСЯ
Помните эту картинку, нарисованную влажной рекламой?
Айтишник на лежаке у океана. В одной руке — «Пина колада». А другой — пуш в гит. Проект в России. Жизнь в Таиланде. Зарплата в долларах.
Многие пошли в айти из-за этого. Многие сорвались в далёкие страны за убегающей картинкой-мечтой.
И да, некоторые добились желаемого.
Но мне всегда хотелось понять: ценой чего?
Жить там, где тебя терпят, пока есть деньги?
Бросить родных, друзей, свой двор — чтобы пожить красиво?
Быть вечным чужим и никогда не почувствовать, что ты на своей земле?
ЭТО НЕ КРИЗИС. ЭТО ЗАКАТ ГЛОБАЛИЗАЦИИ.
Если вы следите за миром, вы уже видели: торговые войны, санкции, запреты на чипы и облака, требования локализовать данные. Каждая страна строит свои цифровые стены.
Но многие всё ещё думают: потерпим, переждём, все вернётся к прежнему и привычному.
Нифига ребят.
Санкционные режимы — не временные проблемы. Это новые правила. Тем более в России, где большинство из нас родилось и живет. И даже в соседних странах, которые подмахивают в сторону запада - ничего не останется прежним.
Ограничения на полупроводники, ИИ, облака — долгосрочная политика ведущих держав. Данные больше не текут свободно — они стали стратегическим ресурсом, как нефть или уран.
И речь не о паре проблемных лет. Речь о том, что мир перестраивается навсегда.
IT ВНЕ ПОЛИТИКИ? ЗАБУДЬТЕ.
Раньше можно было прятаться за мантру: код — вне политики. GitHub — глобален. Мы — граждане интернета.
Как же сейчас это звучит смешно. Китай и США, Россия и Европейский союз - полностью расходятся бортами.
Код — теперь инфраструктура государства. Облака — суверенитет. Чипы — оборона. Разработчик больше не "фрилансер". Он встроен в геоэкономическую систему конкретной страны.
И выбраться из этого нельзя — можно только осознать и принять или начать бороться с ветряной мельницей.
Вы думаете, вас не коснётся? Посмотрите на карту, компании разделяются на региональные экосистемы. Доступы к сервисам обрываются.
Вчерашние «глобальные» инструменты завтра потребуют лицензию, которой у вас нет и не будет потому что цифровая стена отгородила Вас.
ПОЧЕМУ ЭТО ПРОИСХОДИТ ИМЕННО СЕЙЧАС?
Раньше границы были физическими. Теперь они стали цифровыми. И конфликты уходят туда же — в кремний, в протоколы, в исходный код. Борьба идёт не за территории, а за данные и контроль над ними.
Кто первым станет владеть цифрой - будет у руля будущего.
Поэтому сейчас вкладывают триллионы в ИИ, в надежде, что он решит все проблемы своих создателей.
Поэтому мир меняется. И не только в нашей стране.
ЧТО ЭТО ЗНАЧИТ ДЛЯ НАС?
Мир меняется. И вместе с ним меняются правила игры.
Раньше наши ребята писали код для стартапов из Кремниевой долины, делали фичи для европейских финтех-проектов, грезили офферами в FAANG. И успех измерялся тем, как далеко они уехали от дома.
Это была эпоха потребителей глобализации.
Теперь наступает эпоха строителей.
Посмотрите на карту: огромные рынки — Россия, Китай, Иран, многие страны Африки и Латинской Америки — выпадают из западной цифровой орбиты. Но люди там не перестали пользоваться приложениями, не перестали платить, не перестали общаться.
Кто закроет эти потребности?
Вспомните историю: когда Америка ввела эмбарго на технологии для СССР, мы не перестали летать в космос. Мы построили свою космонавтику.
Сейчас перед нами стоит точно такая же задача: построить свой цифровой мир. Не догоняющий и не копирующий, а свой.
Да, это сложно. Да, придется переучиваться. Придется забыть про "просто вставить готовую библиотеку с гитхаба" — потому что завтра её могут отозвать. Да и гитхаб заблокировать для пользователей "недружественной страны".
Придется научиться делать глубокие, безопасные, суверенные продукты с нуля.
И да, нас ждут горы ошибок и тонны недальновидных, "топорных" решений. Но без этого, в мире гигантов мы останемся карликами.
Глобализация заканчивается. Начинается эра мастеров. И она уже идёт, прямо здесь и сейчас.
😎 @Oleborn
Помните эту картинку, нарисованную влажной рекламой?
Айтишник на лежаке у океана. В одной руке — «Пина колада». А другой — пуш в гит. Проект в России. Жизнь в Таиланде. Зарплата в долларах.
Многие пошли в айти из-за этого. Многие сорвались в далёкие страны за убегающей картинкой-мечтой.
И да, некоторые добились желаемого.
Но мне всегда хотелось понять: ценой чего?
Жить там, где тебя терпят, пока есть деньги?
Бросить родных, друзей, свой двор — чтобы пожить красиво?
Быть вечным чужим и никогда не почувствовать, что ты на своей земле?
ЭТО НЕ КРИЗИС. ЭТО ЗАКАТ ГЛОБАЛИЗАЦИИ.
Если вы следите за миром, вы уже видели: торговые войны, санкции, запреты на чипы и облака, требования локализовать данные. Каждая страна строит свои цифровые стены.
Но многие всё ещё думают: потерпим, переждём, все вернётся к прежнему и привычному.
Нифига ребят.
Санкционные режимы — не временные проблемы. Это новые правила. Тем более в России, где большинство из нас родилось и живет. И даже в соседних странах, которые подмахивают в сторону запада - ничего не останется прежним.
Ограничения на полупроводники, ИИ, облака — долгосрочная политика ведущих держав. Данные больше не текут свободно — они стали стратегическим ресурсом, как нефть или уран.
И речь не о паре проблемных лет. Речь о том, что мир перестраивается навсегда.
IT ВНЕ ПОЛИТИКИ? ЗАБУДЬТЕ.
Раньше можно было прятаться за мантру: код — вне политики. GitHub — глобален. Мы — граждане интернета.
Как же сейчас это звучит смешно. Китай и США, Россия и Европейский союз - полностью расходятся бортами.
Код — теперь инфраструктура государства. Облака — суверенитет. Чипы — оборона. Разработчик больше не "фрилансер". Он встроен в геоэкономическую систему конкретной страны.
И выбраться из этого нельзя — можно только осознать и принять или начать бороться с ветряной мельницей.
Вы думаете, вас не коснётся? Посмотрите на карту, компании разделяются на региональные экосистемы. Доступы к сервисам обрываются.
Вчерашние «глобальные» инструменты завтра потребуют лицензию, которой у вас нет и не будет потому что цифровая стена отгородила Вас.
ПОЧЕМУ ЭТО ПРОИСХОДИТ ИМЕННО СЕЙЧАС?
Раньше границы были физическими. Теперь они стали цифровыми. И конфликты уходят туда же — в кремний, в протоколы, в исходный код. Борьба идёт не за территории, а за данные и контроль над ними.
Кто первым станет владеть цифрой - будет у руля будущего.
Поэтому сейчас вкладывают триллионы в ИИ, в надежде, что он решит все проблемы своих создателей.
Поэтому мир меняется. И не только в нашей стране.
ЧТО ЭТО ЗНАЧИТ ДЛЯ НАС?
Мир меняется. И вместе с ним меняются правила игры.
Раньше наши ребята писали код для стартапов из Кремниевой долины, делали фичи для европейских финтех-проектов, грезили офферами в FAANG. И успех измерялся тем, как далеко они уехали от дома.
Это была эпоха потребителей глобализации.
Теперь наступает эпоха строителей.
Посмотрите на карту: огромные рынки — Россия, Китай, Иран, многие страны Африки и Латинской Америки — выпадают из западной цифровой орбиты. Но люди там не перестали пользоваться приложениями, не перестали платить, не перестали общаться.
Кто закроет эти потребности?
Вспомните историю: когда Америка ввела эмбарго на технологии для СССР, мы не перестали летать в космос. Мы построили свою космонавтику.
Сейчас перед нами стоит точно такая же задача: построить свой цифровой мир. Не догоняющий и не копирующий, а свой.
Да, это сложно. Да, придется переучиваться. Придется забыть про "просто вставить готовую библиотеку с гитхаба" — потому что завтра её могут отозвать. Да и гитхаб заблокировать для пользователей "недружественной страны".
Придется научиться делать глубокие, безопасные, суверенные продукты с нуля.
И да, нас ждут горы ошибок и тонны недальновидных, "топорных" решений. Но без этого, в мире гигантов мы останемся карликами.
Глобализация заканчивается. Начинается эра мастеров. И она уже идёт, прямо здесь и сейчас.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3
История технологий сегодня — 23 Февраля
🇷🇺Россия — День защитника Отечества🫡
День защитника Отечества — праздник, отмечаемый ежегодно 23 февраля в России, Беларуси, Казахстане, Кыргызстане, Таджикистане, а также в частично признанных Абхазии, Южной Осетии и непризнанной Приднестровской Молдавской Республике (ПМР).
23 февраля (н. ст.) 1918 года было опубликовано воззвание СНК от 21 февраля «Социалистическое отечество в опасности!», а также «Воззвание Военного главнокомандующего» Н. В. Крыленко.
Этот день был объявлен праздником в РСФСР 27 января 1922 года, когда Президиум ВЦИК РСФСР опубликовал постановление о четвёртой годовщине Красной армии, в котором говорилось: «В соответствии с постановлением IX Всероссийского съезда Советов о Красной армии Президиум ВЦИК обращает внимание исполкомов на наступающую годовщину создания Красной армии (23 февраля)».
С 1922 года в СССР эта дата ежегодно традиционно отмечалась как «День Красной армии», с 1946 года — «День Советской армии», с 1949 по 1992 годы — «День Советской армии и Военно-морского флота».
ℹ️ Кто родился в этот день
Деррик Генри «Дик» Лемер (англ. Derrick Henry Lehmer; 23 февраля 1905, Беркли (Калифорния) — 22 мая 1991, Беркли (Калифорния)) — американский математик, усовершенствовавший работу Эдуарда Люка в 1930-е годы и разработавший Тест Люка — Лемера для простых чисел Мерсенна. Карьера Лемера развивалась в области теории чисел. Во время Великой Депрессии он со своей женой был вынужден сменить множество профессий как в Соединённых Штатах, так и за рубежом, что в конечном итоге случайно привело его в центр исследований в области ранней электронной вычислительной техники.
Роберт Николас Кристиан Топала (англ. Robert Nicholas Christian Topala; род. 23 февраля 1987, Уппландс Весбю, Швеция), более известный как RobTop, — независимый шведский разработчик видеоигр, аниматор и музыкант, прославившийся платформером Geometry Dash.
Аллан Маклауд Кормак (англ. Allan McLeod Cormack; 23 февраля 1924, Йоханнесбург, Южная Африка — 7 мая 1998, Уинчестер, штат Массачусетс, США) — южноафриканский и американский физик, лауреат Нобелевской премии по физиологии и медицине 1979 года «за разработку компьютерной томографии», которую он получил с Годфри Хаунсфилдом.
🌐 Знаковые события
1987 — вспышка сверхновой SN 1987A достигла Земли. Это самая близкая сверхновая со времён изобретения телескопа.
1993 — создан язык программирования Ruby.
#Biography #Birth_Date #Events #23февраля
🇷🇺Россия — День защитника Отечества
День защитника Отечества — праздник, отмечаемый ежегодно 23 февраля в России, Беларуси, Казахстане, Кыргызстане, Таджикистане, а также в частично признанных Абхазии, Южной Осетии и непризнанной Приднестровской Молдавской Республике (ПМР).
23 февраля (н. ст.) 1918 года было опубликовано воззвание СНК от 21 февраля «Социалистическое отечество в опасности!», а также «Воззвание Военного главнокомандующего» Н. В. Крыленко.
Этот день был объявлен праздником в РСФСР 27 января 1922 года, когда Президиум ВЦИК РСФСР опубликовал постановление о четвёртой годовщине Красной армии, в котором говорилось: «В соответствии с постановлением IX Всероссийского съезда Советов о Красной армии Президиум ВЦИК обращает внимание исполкомов на наступающую годовщину создания Красной армии (23 февраля)».
С 1922 года в СССР эта дата ежегодно традиционно отмечалась как «День Красной армии», с 1946 года — «День Советской армии», с 1949 по 1992 годы — «День Советской армии и Военно-морского флота».
Деррик Генри «Дик» Лемер (англ. Derrick Henry Lehmer; 23 февраля 1905, Беркли (Калифорния) — 22 мая 1991, Беркли (Калифорния)) — американский математик, усовершенствовавший работу Эдуарда Люка в 1930-е годы и разработавший Тест Люка — Лемера для простых чисел Мерсенна. Карьера Лемера развивалась в области теории чисел. Во время Великой Депрессии он со своей женой был вынужден сменить множество профессий как в Соединённых Штатах, так и за рубежом, что в конечном итоге случайно привело его в центр исследований в области ранней электронной вычислительной техники.
Роберт Николас Кристиан Топала (англ. Robert Nicholas Christian Topala; род. 23 февраля 1987, Уппландс Весбю, Швеция), более известный как RobTop, — независимый шведский разработчик видеоигр, аниматор и музыкант, прославившийся платформером Geometry Dash.
Аллан Маклауд Кормак (англ. Allan McLeod Cormack; 23 февраля 1924, Йоханнесбург, Южная Африка — 7 мая 1998, Уинчестер, штат Массачусетс, США) — южноафриканский и американский физик, лауреат Нобелевской премии по физиологии и медицине 1979 года «за разработку компьютерной томографии», которую он получил с Годфри Хаунсфилдом.
1987 — вспышка сверхновой SN 1987A достигла Земли. Это самая близкая сверхновая со времён изобретения телескопа.
1993 — создан язык программирования Ruby.
#Biography #Birth_Date #Events #23февраля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
[Совет по Java #008]
Тема: Не ловите Exception или Throwable без крайней необходимости. Ловите максимально конкретные исключения.
Проблема: Перехват общих типов исключений, таких как Exception или Throwable, является грубой ошибкой, нарушающей принцип обработки исключений.
Это приводит к тому, что блок catch обрабатывает не только ожидаемые исключения (например, IOException, SQLException), но и непредвиденные, фатальные ошибки, которые сигнализируют о серьезных сбоях в работе JVM. К таким ошибкам относятся NullPointerException, ArrayIndexOutOfBoundsException (программные ошибки), а также OutOfMemoryError, StackOverflowError (ошибки виртуальной машины).
Перехватывая Exception, разработчик маскирует баги, которые должны были привести к аварийному завершению программы и последующей диагностике. Вместо этого программа продолжает работу в некорректном состоянии, что может привести к повреждению данных, неконсистентности состояния и крайне сложной отладке.
Решение: Всегда перехватывайте максимально конкретные типы исключений, которые вы ожидаете и способны корректно обработать.
Используйте несколько блоков catch для разных типов исключений, располагая их от наиболее конкретных к наиболее общим. Если необходимо выполнить общие действия (например, логирование), используйте multi-catch (Java 7+) для объединения родственных типов исключений. Никогда не перехватывайте Throwable, если только вы не пишете код на самом верхнем уровне (например, пул потоков), где требуется гарантированно избежать "проглатывания" ошибок и обеспечить логирование фатальных сбоев перед завершением потока.
Объяснение: Иерархия исключений делится на проверяемые (восстановимые) и непроверяемые (ошибки программирования и JVM).
Перехватывая Exception, вы стираете эту границу. Правило простое: лови только то, что можешь обработать. FileNotFoundException можно обработать — запросить другой файл. NullPointerException обрабатывать нельзя — нужно исправлять код. OutOfMemoryError тем более не для catch — JVM в критическом состоянии.
Разработчик всегда задает вопрос: "Я могу это исправить?" — и если нет, не ловит.
#Java #советы
Тема: Не ловите Exception или Throwable без крайней необходимости. Ловите максимально конкретные исключения.
Проблема: Перехват общих типов исключений, таких как Exception или Throwable, является грубой ошибкой, нарушающей принцип обработки исключений.
Это приводит к тому, что блок catch обрабатывает не только ожидаемые исключения (например, IOException, SQLException), но и непредвиденные, фатальные ошибки, которые сигнализируют о серьезных сбоях в работе JVM. К таким ошибкам относятся NullPointerException, ArrayIndexOutOfBoundsException (программные ошибки), а также OutOfMemoryError, StackOverflowError (ошибки виртуальной машины).
Перехватывая Exception, разработчик маскирует баги, которые должны были привести к аварийному завершению программы и последующей диагностике. Вместо этого программа продолжает работу в некорректном состоянии, что может привести к повреждению данных, неконсистентности состояния и крайне сложной отладке.
Решение: Всегда перехватывайте максимально конкретные типы исключений, которые вы ожидаете и способны корректно обработать.
Используйте несколько блоков catch для разных типов исключений, располагая их от наиболее конкретных к наиболее общим. Если необходимо выполнить общие действия (например, логирование), используйте multi-catch (Java 7+) для объединения родственных типов исключений. Никогда не перехватывайте Throwable, если только вы не пишете код на самом верхнем уровне (например, пул потоков), где требуется гарантированно избежать "проглатывания" ошибок и обеспечить логирование фатальных сбоев перед завершением потока.
import java.io.*;
import java.sql.*;
public class ExceptionHandling {
//Антипаттерн
public void bad(String path) {
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
} catch (Exception e) { // Ловит IOException, NPE, OOM
e.printStackTrace(); // Фатальные ошибки "проглочены"
}
}
//Правильно
public void good(String path) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
String line = reader.readLine();
} catch (FileNotFoundException e) {
System.err.println("Файл не найден: " + path);
// Это восстановимая ситуация
}
// IOException пробрасывается выше
// NPE, OOM не ловятся — пусть падают
}
//Multi-catch
public void multi(String path) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
} catch (FileNotFoundException | ClassNotFoundException e) {
System.err.println("Ресурс не найден: " + e.getMessage());
} catch (IOException e) {
throw new RuntimeException("Ошибка ввода-вывода", e);
}
}
//Единственный случай для Throwable
public void thread(Runnable task) {
new Thread(() -> {
try {
task.run();
} catch (Throwable t) { // Только для логирования на верхнем уровне
System.err.println("Критическая ошибка: " + t);
}
}).start();
}
}
Объяснение: Иерархия исключений делится на проверяемые (восстановимые) и непроверяемые (ошибки программирования и JVM).
Перехватывая Exception, вы стираете эту границу. Правило простое: лови только то, что можешь обработать. FileNotFoundException можно обработать — запросить другой файл. NullPointerException обрабатывать нельзя — нужно исправлять код. OutOfMemoryError тем более не для catch — JVM в критическом состоянии.
Разработчик всегда задает вопрос: "Я могу это исправить?" — и если нет, не ловит.
#Java #советы
👍5🤯1
Что выведет код?
#Tasks
public class Task230226 {
public static void main(String[] args) {
try {
throw new StackOverflowError();
} catch (Error e) {
System.out.println("Error caught");
} catch (Exception e) {
System.out.println("Exception caught");
} catch (Throwable e) {
System.out.println("Throwable caught");
}
}
}#Tasks
👍1
Варианты ответа:
Anonymous Quiz
13%
Exception caught
57%
Error caught
3%
Throwable caught
27%
Ничего, программа упадет
👍2
7. Введение в распределённую трассировку. OpenTelemetry & Jaeger.
Когда у вас один сервис — всё просто. Но как только появляется второй, вы слепнете.
Почему запрос тормозит? Кто виноват: ваш код или внешний сервис?
Метрики врут, логи разрозненны. Нужна распределённая трассировка.🤓
В этом видео мы шаг за шагом разберём, как работает трассировка на реальном примере:
два микросервиса (order-service и notification-service), HTTP-вызовы, OpenTelemetry и Jaeger.
Что вы узнаете:
- Как устроена распределённая трассировка: trace, span, traceId, propagation
- Как настроить OpenTelemetry в Spring Boot 3 с Micrometer Tracing
- Как поднять Jaeger в Docker и отправлять в него трассы
- Как анализировать трассу: parent-child связи, длительность, теги
- Почему в трассе три спана, хотя сервисов два
- Как добавить бизнес-атрибуты (order.id) и искать по ним в Jaeger
Исходный код проекта на GitHub очень ждет Ваших звезд☺️
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!✌️
Когда у вас один сервис — всё просто. Но как только появляется второй, вы слепнете.
Почему запрос тормозит? Кто виноват: ваш код или внешний сервис?
Метрики врут, логи разрозненны. Нужна распределённая трассировка.
В этом видео мы шаг за шагом разберём, как работает трассировка на реальном примере:
два микросервиса (order-service и notification-service), HTTP-вызовы, OpenTelemetry и Jaeger.
Что вы узнаете:
- Как устроена распределённая трассировка: trace, span, traceId, propagation
- Как настроить OpenTelemetry в Spring Boot 3 с Micrometer Tracing
- Как поднять Jaeger в Docker и отправлять в него трассы
- Как анализировать трассу: parent-child связи, длительность, теги
- Почему в трассе три спана, хотя сервисов два
- Как добавить бизнес-атрибуты (order.id) и искать по ним в Jaeger
Исходный код проекта на GitHub очень ждет Ваших звезд
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1 1
Как работает цикл for-each? 🤓
Ответ:
for-each (или enhanced for loop) — это упрощенная форма цикла for для итерации по массивам и коллекциям, реализующим интерфейс Iterable.
Синтаксис: for (Тип переменная : коллекция) { ... }.
На каждой итерации в переменную автоматически помещается следующий элемент. Преимущество — краткость и отсутствие ошибок с индексами. Недостатки — нет доступа к индексу элемента, нельзя удалять элементы коллекции (вызовет ConcurrentModificationException) и изменять структуру коллекции во время итерации.
#собеседование
Ответ:
Синтаксис: for (Тип переменная : коллекция) { ... }.
На каждой итерации в переменную автоматически помещается следующий элемент. Преимущество — краткость и отсутствие ошибок с индексами. Недостатки — нет доступа к индексу элемента, нельзя удалять элементы коллекции (вызовет ConcurrentModificationException) и изменять структуру коллекции во время итерации.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологий сегодня — 24 Февраля
ℹ️ Кто родился в этот день
Сти́вен Пол (Стив) Джобс (англ. Steven Paul «Steve» Jobs; имя при рождении — Абдул Латиф Джандали; 24 февраля 1955, Сан-Франциско, Калифорния — 5 октября 2011, Пало-Алто, Санта-Клара, Калифорния) — американский предприниматель, изобретатель и промышленный дизайнер, получивший широкое признание в качестве пионера эры информационных технологий. Один из основателей, председатель совета директоров и CEO корпорации Apple. Один из основателей и CEO киностудии Pixar.
Ян Борисович Кум (род. 24 февраля 1976, Киев) — американский предприниматель и программист, сооснователь и CEO мессенджера WhatsApp.
Григо́рий Алекса́ндрович Маргу́лис (род. 24 февраля 1946, Москва) — советский и американский математик, доктор физико-математических наук (1978), научный сотрудник Института проблем передачи информации РАН, профессор Йельского университета (США), лауреат Филдсовской (1978), Абелевской (2020) премий и премии Вольфа (2004/05).
🌐 Знаковые события
Не нашел(
#Biography #Birth_Date #Events #24февраля
Сти́вен Пол (Стив) Джобс (англ. Steven Paul «Steve» Jobs; имя при рождении — Абдул Латиф Джандали; 24 февраля 1955, Сан-Франциско, Калифорния — 5 октября 2011, Пало-Алто, Санта-Клара, Калифорния) — американский предприниматель, изобретатель и промышленный дизайнер, получивший широкое признание в качестве пионера эры информационных технологий. Один из основателей, председатель совета директоров и CEO корпорации Apple. Один из основателей и CEO киностудии Pixar.
Ян Борисович Кум (род. 24 февраля 1976, Киев) — американский предприниматель и программист, сооснователь и CEO мессенджера WhatsApp.
Григо́рий Алекса́ндрович Маргу́лис (род. 24 февраля 1946, Москва) — советский и американский математик, доктор физико-математических наук (1978), научный сотрудник Института проблем передачи информации РАН, профессор Йельского университета (США), лауреат Филдсовской (1978), Абелевской (2020) премий и премии Вольфа (2004/05).
Не нашел(
#Biography #Birth_Date #Events #24февраля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Раздел 8. Stream API и функциональный стиль в Java
Глава 3: Чистые преобразования и борьба с исключениями
Side Effects — главный враг предсказуемости
Самый соблазнительный и опасный антипаттерн при работе со Stream API — использование forEach для накопления результатов во внешнюю коллекцию. Код выглядит лаконично, интуитивно понятен разработчикам с императивным бэкграундом, но несёт в себе фундаментальные архитектурные дефекты.
На первый взгляд, это работает. В тестовом окружении с небольшими данными результат будет корректным. Но этот код нарушает базовый контракт функционального программирования: операции над потоком должны быть чистыми функциями без побочных эффектов.
Побочный эффект (side effect) — любое изменение состояния, наблюдаемое за пределами операции. В данном случае names.add() модифицирует состояние объекта names, созданного вне лямбды. Лямбда захватывает ссылку на внешний список и мутирует его.
Три уровня проблемы
Проблема первая: некорректность при параллелизме
Главное преимущество Stream API — возможность прозрачного распараллеливания вычислений вызовом .parallel().
Но код с побочными эффектами ломается при этом:
ArrayList не потокобезопасен. При одновременном доступе из нескольких потоков происходит состояние гонки (race condition): два потока читают текущий размер, вычисляют индекс вставки, один записывает, второй перезаписывает ту же позицию. Результат недетерминирован: часть элементов пропадает, часть дублируется, возможны исключения при расширении внутреннего массива.
Синхронизация вручную решает проблему, но уничтожает производительность:
CopyOnWriteArrayList создаёт копию всего массива при каждой записи — для потоковой обработки это катастрофа.
Проблема вторая: скрытая зависимость и невозможность тестирования
Код с побочными эффектами тесно связывает логику обработки с механизмом накопления. Функцию u -> names.add(u.getName()) невозможно протестировать изолированно: она требует существования внешнего names, модифицирует его, не возвращает значения.
Чистая функция User::getName тестируется просто: дали пользователя, получили строку. Лямбда с побочным эффектом требует подготовки окружения, проверки состояния после выполнения, очистки между тестами. Сложность тестирования растёт экспоненциально с количеством захваченных переменных.
Проблема третья: утрата композиционности
Потоковые операции предназначены для композиции. Результат одной операции — вход другой. Но forEach — терминальная операция, возвращающая void.
Она разрывает цепочку, превращая поток в императивный блок:
Если позже потребуется дополнительная обработка (привести к верхнему регистру, отсортировать, убрать дубликаты), придётся либо модифицировать лямбду в forEach (нарушая единственную ответственность), либо создавать новый поток из names (лишние аллокации, потеря ленивости).
#Java #для_новичков #beginner #stream_api #side_effects
Глава 3: Чистые преобразования и борьба с исключениями
Side Effects — главный враг предсказуемости
Самый соблазнительный и опасный антипаттерн при работе со Stream API — использование forEach для накопления результатов во внешнюю коллекцию. Код выглядит лаконично, интуитивно понятен разработчикам с императивным бэкграундом, но несёт в себе фундаментальные архитектурные дефекты.
// Антипаттерн: мутация внешнего списка из потока
List<String> names = new ArrayList<>();
users.stream()
.filter(User::isActive)
.forEach(u -> names.add(u.getName())); // Побочный эффект
На первый взгляд, это работает. В тестовом окружении с небольшими данными результат будет корректным. Но этот код нарушает базовый контракт функционального программирования: операции над потоком должны быть чистыми функциями без побочных эффектов.
Побочный эффект (side effect) — любое изменение состояния, наблюдаемое за пределами операции. В данном случае names.add() модифицирует состояние объекта names, созданного вне лямбды. Лямбда захватывает ссылку на внешний список и мутирует его.
Три уровня проблемы
Проблема первая: некорректность при параллелизме
Главное преимущество Stream API — возможность прозрачного распараллеливания вычислений вызовом .parallel().
Но код с побочными эффектами ломается при этом:
List<String> names = new ArrayList<>();
users.parallelStream() // Добавили параллелизм
.filter(User::isActive)
.forEach(u -> names.add(u.getName())); // Race condition!
// Результат: потерянные элементы, дублирование, ArrayIndexOutOfBoundsException
ArrayList не потокобезопасен. При одновременном доступе из нескольких потоков происходит состояние гонки (race condition): два потока читают текущий размер, вычисляют индекс вставки, один записывает, второй перезаписывает ту же позицию. Результат недетерминирован: часть элементов пропадает, часть дублируется, возможны исключения при расширении внутреннего массива.
Синхронизация вручную решает проблему, но уничтожает производительность:
List<String> names = Collections.synchronizedList(new ArrayList<>());
// или names = new CopyOnWriteArrayList<>(); // ещё хуже по производительности
CopyOnWriteArrayList создаёт копию всего массива при каждой записи — для потоковой обработки это катастрофа.
Проблема вторая: скрытая зависимость и невозможность тестирования
Код с побочными эффектами тесно связывает логику обработки с механизмом накопления. Функцию u -> names.add(u.getName()) невозможно протестировать изолированно: она требует существования внешнего names, модифицирует его, не возвращает значения.
Чистая функция User::getName тестируется просто: дали пользователя, получили строку. Лямбда с побочным эффектом требует подготовки окружения, проверки состояния после выполнения, очистки между тестами. Сложность тестирования растёт экспоненциально с количеством захваченных переменных.
Проблема третья: утрата композиционности
Потоковые операции предназначены для композиции. Результат одной операции — вход другой. Но forEach — терминальная операция, возвращающая void.
Она разрывает цепочку, превращая поток в императивный блок:
// Не компонуется: forEach возвращает void
users.stream()
.filter(User::isActive)
.forEach(u -> names.add(u.getName())); // Конец цепочки
// .map(String::toUpperCase) // Невозможно: forEach уже выполнен
Если позже потребуется дополнительная обработка (привести к верхнему регистру, отсортировать, убрать дубликаты), придётся либо модифицировать лямбду в forEach (нарушая единственную ответственность), либо создавать новый поток из names (лишние аллокации, потеря ленивости).
#Java #для_новичков #beginner #stream_api #side_effects
👍4
forEach: последнее средство, не первое
Метод forEach предназначен для конечных действий (terminal side effects), не для агрегации данных. Его корректное применение — операции, которые по своей природе требуют побочных эффектов и уже учитывают многопоточность:
В этих случаях побочный эффект — сама цель операции. Мы не накапливаем данные для дальнейшей обработки, а выполняем окончательное действие над каждым элементом.
collect: правильный путь агрегации
Для накопления результатов Stream API предоставляет collect — мощную и гибкую терминальную операцию, инкапсулирующую стратегию свёртки потока в конкретную структуру данных.
Здесь мутация происходит внутри Collector, не видима снаружи, потокобезопасна при параллельном выполнении (через механизм комбайнеров), композиционна — результат можно передать дальше.
Как работает безопасность collect в параллельном потоке:
Коллектор toList() использует стратегию "разделяй и властвуй": поток делится на сегменты, каждый обрабатывается в своём потоке с локальным ArrayList (аккумулятор), затем локальные списки комбинируются в один результат. Никакой совместной мутации, никаких блокировок — только локальные изменения и финальное слияние.
Мутация внутри map и filter: скрытая бомба
Побочные эффекты опасны не только в forEach.
Любая промежуточная операция с мутацией внешнего состояния создаёт непредсказуемое поведение:
Здесь map используется не для преобразования элемента, а для генерации глобального счётчика. Это нарушает чистоту функции: результат зависит не только от входа, но от внешнего состояния и порядка выполнения.
Решение — встроить нумерацию в структуру данных или использовать специализированные операции:
Идентификация побочных эффектов
Признаки, что код содержит опасные побочные эффекты:
- Лямбда не возвращает значение, но делает что-то "полезное": x -> list.add(x), x -> map.put(x.getKey(), x)
- Захват изменяемых внешних переменных: лямбда использует переменные, объявленные до неё, и вызывает на них модифицирующие методы
- Необходимость очистки состояния между запусками: тесты требуют list.clear() или создания новых объектов
- Недетерминированные результаты при параллельном выполнении: одинаковый вход даёт разный выход
- Рефакторинг от побочных эффектов к чистым функциям следует шаблону: вынести мутацию в collect, преобразования в map, фильтрацию в filter, а forEach оставить только для истинно терминальных действий.
#Java #для_новичков #beginner #stream_api #side_effects
Метод forEach предназначен для конечных действий (terminal side effects), не для агрегации данных. Его корректное применение — операции, которые по своей природе требуют побочных эффектов и уже учитывают многопоточность:
// Корректное использование: логирование
orders.stream()
.filter(Order::isUrgent)
.forEach(o -> logger.info("Срочный заказ: {}", o.getId()));
// Корректное использование: запись в потокобезопасный sink
processedItems.parallelStream()
.forEach(database::save); // database.save потокобезопасен
// Корректное использование: отправка сообщений в брокер
events.stream()
.forEach(kafkaTemplate::send);
В этих случаях побочный эффект — сама цель операции. Мы не накапливаем данные для дальнейшей обработки, а выполняем окончательное действие над каждым элементом.
collect: правильный путь агрегации
Для накопления результатов Stream API предоставляет collect — мощную и гибкую терминальную операцию, инкапсулирующую стратегию свёртки потока в конкретную структуру данных.
// Правильно: агрегация через collect
List<String> names = users.stream()
.filter(User::isActive)
.map(User::getName) // Чистая трансформация
.collect(Collectors.toList()); // Инкапсулированная мутация внутри коллектора
Здесь мутация происходит внутри Collector, не видима снаружи, потокобезопасна при параллельном выполнении (через механизм комбайнеров), композиционна — результат можно передать дальше.
Как работает безопасность collect в параллельном потоке:
List<String> names = users.parallelStream()
.filter(User::isActive)
.map(User::getName)
.collect(Collectors.toList()); // Корректно при parallel!
Коллектор toList() использует стратегию "разделяй и властвуй": поток делится на сегменты, каждый обрабатывается в своём потоке с локальным ArrayList (аккумулятор), затем локальные списки комбинируются в один результат. Никакой совместной мутации, никаких блокировок — только локальные изменения и финальное слияние.
Мутация внутри map и filter: скрытая бомба
Побочные эффекты опасны не только в forEach.
Любая промежуточная операция с мутацией внешнего состояния создаёт непредсказуемое поведение:
// Антипаттерн: мутация в map
AtomicInteger counter = new AtomicInteger(0);
List<Integer> numbered = items.stream()
.map(item -> {
int num = counter.incrementAndGet(); // Побочный эффект!
return num + ": " + item;
})
.collect(toList());
// При parallelStream() нумерация будет хаотичной и пропущенной
Здесь map используется не для преобразования элемента, а для генерации глобального счётчика. Это нарушает чистоту функции: результат зависит не только от входа, но от внешнего состояния и порядка выполнения.
Решение — встроить нумерацию в структуру данных или использовать специализированные операции:
// Правильно: явная нумерация через индекс
List<String> numbered = IntStream.range(0, items.size())
.mapToObj(i -> (i + 1) + ": " + items.get(i))
.collect(toList());
// Или через StreamUtils сторонних библиотек с zipWithIndex
Идентификация побочных эффектов
Признаки, что код содержит опасные побочные эффекты:
- Лямбда не возвращает значение, но делает что-то "полезное": x -> list.add(x), x -> map.put(x.getKey(), x)
- Захват изменяемых внешних переменных: лямбда использует переменные, объявленные до неё, и вызывает на них модифицирующие методы
- Необходимость очистки состояния между запусками: тесты требуют list.clear() или создания новых объектов
- Недетерминированные результаты при параллельном выполнении: одинаковый вход даёт разный выход
- Рефакторинг от побочных эффектов к чистым функциям следует шаблону: вынести мутацию в collect, преобразования в map, фильтрацию в filter, а forEach оставить только для истинно терминальных действий.
#Java #для_новичков #beginner #stream_api #side_effects
🔥3👍2
Что выведет код?
#Tasks
import java.util.*;
import java.util.concurrent.*;
public class Task240226 {
public static void main(String[] args) {
List<Integer> source = Arrays.asList(1, 2, 3, 4, 5);
CopyOnWriteArrayList<Integer> target = new CopyOnWriteArrayList<>();
long count = source.parallelStream()
.filter(n -> {
target.add(n);
return n % 2 == 0;
})
.count();
System.out.println(target.size() + ":" + count);
}
}
#Tasks
👍2
👍4
Какие виды ссылок в Java вы знаете? 🤓
Ответ:
В Java существует 4 типа ссылок:
Strong Reference (сильная) — обычные ссылки (Object obj = new Object()), объект не будет собран GC, пока на него есть сильная ссылка.
Soft Reference (мягкая) — объект будет собран только перед OutOfMemoryError, если памяти не хватает (используется для кэшей).
Weak Reference (слабая) — объект будет собран при ближайшей сборке мусора, если на него нет сильных или мягких ссылок (используется в WeakHashMap).
Phantom Reference (фантомная) — позволяет узнать, что объект физически удален из памяти (используется для post-mortem cleanup).
#собеседование
Ответ:
Strong Reference (сильная) — обычные ссылки (Object obj = new Object()), объект не будет собран GC, пока на него есть сильная ссылка.
Soft Reference (мягкая) — объект будет собран только перед OutOfMemoryError, если памяти не хватает (используется для кэшей).
Weak Reference (слабая) — объект будет собран при ближайшей сборке мусора, если на него нет сильных или мягких ссылок (используется в WeakHashMap).
Phantom Reference (фантомная) — позволяет узнать, что объект физически удален из памяти (используется для post-mortem cleanup).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5