Продолжаем выбирать темы для разбора и голосовать за рассмотрение предложенных! 🤓
Голосуем за тему к рассмотрению в эти выходные!
Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)
Не стесняемся!✌️
Голосуем за тему к рассмотрению в эти выходные!
Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)
Не стесняемся!
Please open Telegram to view this post
VIEW IN TELEGRAM
Очень странно… 83 просмотра и 42 голоса
https://t.me/Java_for_beginner_dev/2477
Это реально столько активных пользователя?😭
Ау где остальные?👋
https://t.me/Java_for_beginner_dev/2477
Это реально столько активных пользователя?
Ау где остальные?
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Java for Beginner
Вы еще читаете этот канал? 🤨
Да! Каждый день, все интересно, стараюсь не пропускать 🙂 / Да, периодически встречается что-то интересное 🤷♀️ / Редко, но заглядываю 🤫 / Канал больше не интересен, практически не захожу 👎 / Я сам(а) не понимаю зачем нахожусь…
Да! Каждый день, все интересно, стараюсь не пропускать 🙂 / Да, периодически встречается что-то интересное 🤷♀️ / Редко, но заглядываю 🤫 / Канал больше не интересен, практически не захожу 👎 / Я сам(а) не понимаю зачем нахожусь…
Что такое лямбда-выражения в Java? 🤓
Ответ:
Лямбда-выражения в Java — это краткий способ записи анонимных функций, которые можно передавать как аргументы в методы или сохранять в переменные. Они появились в Java 8 и позволяют писать более компактный и читаемый код, особенно при работе с функциональными интерфейсами (интерфейсами с одним абстрактным методом, например, Runnable, Comparator, Predicate).
Синтаксис лямбда-выражения:
(параметры) -> { тело_лямбды }
Если параметр один, скобки () можно опустить.
Если тело состоит из одной строки, фигурные скобки {} и return можно не писать.
#собеседование
Ответ:
Синтаксис лямбда-выражения:
(параметры) -> { тело_лямбды }
Если параметр один, скобки () можно опустить.
Если тело состоит из одной строки, фигурные скобки {} и return можно не писать.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
С 31.05 по 06.06
Предыдущий пост(с 24.05 по 30.05)
Следующая неделя
Воскресный мотивационный пост:
«Ты не программируешь — ты притворяешься, что учишься»
Выбранная голосованием тема:
Архитектурный шаблон MVC в Java Spring: теория, правила, ошибки
Запись встреч:
Многопоточка во всей красе. Часть 1.
Обучающие статьи:
Типы changesets и стратегии развертывания в Liquibase
Откаты (Rollback) и теги в Liquibase
Интеграция Liquibase с другими инструментами
Глубокое изучение типа данных boolean в Java
Ссылочные типы данных в Java
Пост под которым нет поздравлений:
Сегодня каналу исполнился год!🥳
Авторская статья (которая кому-то не понравилась):
Пагинация, которую начинаешь ненавидеть😵
Полезные статьи и видео:
Создаём HTTP-сервер на Java NIO
Большой гайд. Пишем микросервисы на Java и Spring Boot, заворачиваем в Docker, запускаем на EKS, мониторим на Grafana
ИСТОРИЯ НЕЙРОСЕТЕЙ - ОТ ПЕРЦЕПТРОНА ДО CHATGPT
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
#memory
Предыдущий пост(с 24.05 по 30.05)
Следующая неделя
Воскресный мотивационный пост:
«Ты не программируешь — ты притворяешься, что учишься»
Выбранная голосованием тема:
Архитектурный шаблон MVC в Java Spring: теория, правила, ошибки
Запись встреч:
Многопоточка во всей красе. Часть 1.
Обучающие статьи:
Типы changesets и стратегии развертывания в Liquibase
Откаты (Rollback) и теги в Liquibase
Интеграция Liquibase с другими инструментами
Глубокое изучение типа данных boolean в Java
Ссылочные типы данных в Java
Пост под которым нет поздравлений:
Сегодня каналу исполнился год!
Авторская статья (которая кому-то не понравилась):
Пагинация, которую начинаешь ненавидеть
Полезные статьи и видео:
Создаём HTTP-сервер на Java NIO
Большой гайд. Пишем микросервисы на Java и Spring Boot, заворачиваем в Docker, запускаем на EKS, мониторим на Grafana
ИСТОРИЯ НЕЙРОСЕТЕЙ - ОТ ПЕРЦЕПТРОНА ДО CHATGPT
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
#memory
Please open Telegram to view this post
VIEW IN TELEGRAM
Настройка OAuth2 для Gmail
Для Gmail предпочтительно использовать OAuth2.
Пример конфигурации:
Примечание: Зарегистрируйте приложение в Google Cloud Console и используйте библиотеку google-auth-library-oauth2-http для получения accessToken.
Создание сервиса отправки почты
Создадим сервис EmailService для отправки писем.
Конфигурация асинхронности:
#Java #middle #on_request #JavaMailSender
Для Gmail предпочтительно использовать OAuth2.
Пример конфигурации:
@Configuration
public class MailConfig {
@Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername("your.email@gmail.com");
Properties props = mailSender.getJavaMailProperties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
// Настройка OAuth2 токена через Google API Client Library
// Подробности: https://developers.google.com/identity/protocols/oauth2
return mailSender;
}
}
Примечание: Зарегистрируйте приложение в Google Cloud Console и используйте библиотеку google-auth-library-oauth2-http для получения accessToken.
Создание сервиса отправки почты
Создадим сервис EmailService для отправки писем.
@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;
@Autowired
private TemplateEngine templateEngine;
private static final Logger logger = LoggerFactory.getLogger(EmailService.class);
public void sendSimpleEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
}
public void sendHtmlEmail(String to, String subject, String htmlBody) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(to);
helper.setSubject(MimeUtility.encodeText(subject, "UTF-8", null));
helper.setText(htmlBody, true);
mailSender.send(message);
}
public void sendEmailWithAttachment(String to, String subject, String text, File attachment) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(to);
helper.setSubject(MimeUtility.encodeText(subject, "UTF-8", null));
helper.setText(text);
FileSystemResource file = new FileSystemResource(attachment);
helper.addAttachment(attachment.getName(), file);
mailSender.send(message);
}
@Async
public CompletableFuture<Void> sendSimpleEmailAsync(String to, String subject, String text IMPORTANT: text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(MimeUtility.encodeText(subject, "UTF-8", null));
message.setText(text);
mailSender.send(message);
return CompletableFuture.completedFuture(null);
}
public void sendTemplatedEmail(String to, String subject, String username) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
Context context = new Context();
context.setVariable("username", username);
String htmlBody = templateEngine.process("email-template", context);
helper.setTo(to);
helper.setSubject(MimeUtility.encodeText(subject, "UTF-8", null));
helper.setText(htmlBody, true);
mailSender.send(message);
}
}
Конфигурация асинхронности:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.initialize();
return executor;
}
}
#Java #middle #on_request #JavaMailSender
Примеры кода
Простой текст:
HTML-письмо:
Вложение:
Обработка ошибок и логирование
JavaMailSender может выбрасывать исключения, которые нужно обрабатывать.
Основные исключения:
Пример отлова:
Повторные попытки
Используйте @Retryable из Spring Retry:
Зависимость:
Мониторинг и метрики
Для продакшен-приложений полезно отслеживать метрики отправки писем с помощью Spring Actuator:
Зависимость:
Безопасность и защита данных
Никогда не храните пароли в открытом виде в git-репозиториях.
Рекомендации:
Используйте переменные окружения или секреты (например, Kubernetes Secrets).
Применяйте Spring Cloud Vault или HashiCorp Vault.
Используйте шифрование с Jasypt.
Настройте OAuth2 для Gmail.
Пример с переменными окружения:
#Java #middle #on_request #JavaMailSender
Простой текст:
SimpleMailMessage message = new SimpleMailMessage();
message.setTo("user@example.com");
message.setSubject("Тестовое письмо");
message.setText("Привет из Spring Boot!");
mailSender.send(message);
HTML-письмо:
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo("user@example.com");
helper.setSubject(MimeUtility.encodeText("HTML письмо", "UTF-8", null));
helper.setText("<h1>Привет!</h1><p>Это HTML письмо.</p>", true);
mailSender.send(message);
Вложение:
File file = new File("/path/to/file.pdf");
FileSystemResource resource = new FileSystemResource(file);
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo("user@example.com");
helper.setSubject(MimeUtility.encodeText("Письмо с вложением", "UTF-8", null));
helper.setText("Смотри вложение!");
helper.addAttachment("file.pdf", resource);
mailSender.send(message);
Обработка ошибок и логирование
JavaMailSender может выбрасывать исключения, которые нужно обрабатывать.
Основные исключения:
MailAuthenticationException
MailSendException
MessagingException
Пример отлова:
try {
mailSender.send(message);
} catch (MailException e) {
logger.error("Ошибка отправки письма", e);
throw e;
}
Повторные попытки
Используйте @Retryable из Spring Retry:
@Retryable(value = MailException.class, maxAttempts = 3)
public void sendSimpleEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
}
Зависимость:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
Мониторинг и метрики
Для продакшен-приложений полезно отслеживать метрики отправки писем с помощью Spring Actuator:
@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;
@Autowired
private MeterRegistry meterRegistry;
public void sendSimpleEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
try {
mailSender.send(message);
meterRegistry.counter("email.sent.success").increment();
} catch (MailException e) {
meterRegistry.counter("email.sent.failure").increment();
throw e;
}
}
}
Зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Безопасность и защита данных
Никогда не храните пароли в открытом виде в git-репозиториях.
Рекомендации:
Используйте переменные окружения или секреты (например, Kubernetes Secrets).
Применяйте Spring Cloud Vault или HashiCorp Vault.
Используйте шифрование с Jasypt.
Настройте OAuth2 для Gmail.
Пример с переменными окружения:
spring.config.import=optional:configserver:http://config-server
spring.mail.password=${MAIL_PASSWORD}
#Java #middle #on_request #JavaMailSender
Тестирование отправки почты
Интеграционные тесты с Testcontainers:
Зависимость:
Unit-тестирование:
Интеграция с очередями
Для отложенной отправки используйте RabbitMQ(ну или другой брокер сообщений):
Зависимость:
Распространенные ошибки и подводные камни
Неверная конфигурация SMTP (порт, шифрование).
Проблемы с двухфакторной авторизацией (особенно Gmail).
Ограничения на массовую рассылку (например, Gmail: ~500 писем/день для бесплатных аккаунтов).
Проблемы с кодировкой (например, кириллица в теме письма).
Отсутствие MIME-типа у вложений.
Блокировка сервером (например, Mail.ru требует DKIM и SPF).
Решение для кодировки:
#Java #middle #on_request #JavaMailSender
Интеграционные тесты с Testcontainers:
@Testcontainers
@SpringBootTest
public class EmailServiceTest {
@Container
private static final GreenMailContainer greenMail = new GreenMailContainer();
@Autowired
private EmailService emailService;
@Test
void shouldSendEmail() {
emailService.sendSimpleEmail("test@example.com", "Test Subject", "Test Body");
assertEquals(1, greenMail.getReceivedMessages().length);
}
}
Зависимость:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>greenmail</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
Unit-тестирование:
@MockBean
private JavaMailSender mailSender;
@Test
void shouldSendMail() {
SimpleMailMessage message = new SimpleMailMessage();
emailService.sendSimpleEmail("to", "subject", "body");
verify(mailSender, times(1)).send(any(SimpleMailMessage.class));
}
Интеграция с очередями
Для отложенной отправки используйте RabbitMQ(ну или другой брокер сообщений):
@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendEmailToQueue(String to, String subject, String text) {
EmailMessage email = new EmailMessage(to, subject, text);
rabbitTemplate.convertAndSend("emailQueue", email);
}
@RabbitListener(queues = "emailQueue")
public void processEmail(EmailMessage email) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(email.getTo());
message.setSubject(email.getSubject());
message.setText(email.getText());
mailSender.send(message);
}
@Data
static class EmailMessage {
private String to;
private String subject;
private String text;
}
}
Зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
Распространенные ошибки и подводные камни
Неверная конфигурация SMTP (порт, шифрование).
Проблемы с двухфакторной авторизацией (особенно Gmail).
Ограничения на массовую рассылку (например, Gmail: ~500 писем/день для бесплатных аккаунтов).
Проблемы с кодировкой (например, кириллица в теме письма).
Отсутствие MIME-типа у вложений.
Блокировка сервером (например, Mail.ru требует DKIM и SPF).
Решение для кодировки:
helper.setSubject(MimeUtility.encodeText("Тема на кириллице", "UTF-8", null));
#Java #middle #on_request #JavaMailSender
Сегодня продолжаем изучение многопоточки
В связи с техническими нюансами, встречу по многопоточке пришлось отменить.
Но мы же не могли оставить Вас без продолжения?😏
Поэтому @rKiraLis39 записал (за что ему огромное спасибо) для Вас видео в котором мы узнали:
⏺ Что такое атомарные операции в потоках
⏺ Что такое волатильность и как ее использовать
⏺ Как взаимодействовать с Executor'ами и как их настраивать
⏺ И много еще интересного
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
В связи с техническими нюансами, встречу по многопоточке пришлось отменить.
Но мы же не могли оставить Вас без продолжения?
Поэтому @rKiraLis39 записал (за что ему огромное спасибо) для Вас видео в котором мы узнали:
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Please open Telegram to view this post
VIEW IN TELEGRAM
«Обучение Java — марафон, а не прыжок с трамплина»
Так вышло, что мое знакомство с Java и программированием в целом, началось еще в 2021 году.
Тогда, окрыленный надеждами на новую, интересную работу, я потратил приличное количество времени на изучение Java Core. Но как часто бывает, реальность продиктовала свои условия, я не смог осилить обучение и бросил его.
Периодически возвращаясь я понял, что придется начинать сначала.
И когда я смог подогнать жизненные условия к тому, чтобы бросить все и посвятить себя только обучению, которое в итоге привело меня сюда, я понял важную вещь - обучение программированию (да наверно любой другой сложной концепции) — это долгая, часто тяжелая дорога, где не будет "легко", но "результат" стоит того.
Вот, что важно понимать если ты только принял решение вступить на этот путь:
🟥 Начнем с массового, современного увлечения курсами, буткемпами, менторством, тренингами и подобной требухой.
Пойми простую вещь - кто обещает «легко и быстро» — 100% врет. Так практически не бывает, за исключением единичных примеров. Но ссылаясь на эти примеры, некоторые строят целые онлайн-школы и бизнес (на твоих деньгах).
И я не говорю, что ты не получишь ничего полезного на этих занятиях. НО! Ты не сможешь, к примеру за 3 месяца, стать конкурентным специалистом в Java, если ты обычный среднестатистический человек.
Ну никак, сорян, кто бы что не говорил🤷♀️
🟥 Ощущение «я тупой» — обязательный этап каждого.
Перед окунанием в "программирование", знай, что к примеру Java, уже отпраздновала 30-летие в этом году. А это, возможно больше чем ты живешь на свете.
А это значит, что изучение её (по крайней мере, как ощущаю это я) - это погружение в бесконечную кроличью нору.🐇
На каждую понятую тобой концепцию или алгоритм, за его спиной вырастут еще с десяток и ты постоянно будешь ощущать себя неполноценным😂
Не переживай - это нормально. Все проходят через это🙂
🟥 Медленный прогресс — это не глупость.
Пойми и прими, то, что порой в Java встречаются темы, которые не взять "с наскока". Ну никак.
И если ты вдруг, ловишь себя на мысли, что на какую-то тему ты тратишь неприлично долгое время - это не значит, что ты "не тянешь".
Просто это тоже нормально. Мы все разные, с разным бекграундом.
Важно не «как быстро», а как долго ты не сливаешься. Ведь в итоге самые стойкие — выигрывают, даже если тупят на старте.🏝
🟥 Ты просто обязан пройти через говнокод.
Знай, никто не пишет "красиво" и "правильно" с первого раза. Даже "гении".
А ты и я тем более.
Поэтому, как я писал в предыдущей статье - если первые месяцы ты будешь писать грязно, неэффективно и тупо — это тоже нормально и правильно.
Запомни: в начале пути, идеальный код — не твоя цель. Цель — живой и работающий код, а все остальное приложится.🧑💻
🟥 Ну и главное - обучение не должно быть "в кайф".
Если тебе в процессе обучения неприятно, неудобно и сложно — значит, ты делаешь правильно. (Особенно это актуально для тех кто за "30"👋 )
Твой мозг вышел из зоны комфорта, он испытывает стресс и пытается повлиять на тебя, вернув в теплые объятия неведения.
Твоя задача - ежедневно, ежеминутно, бороться с ленью, преодолевать алгоритмические и идейные трудности, выстраивая новые нейронные связи.
Комфорт — не показатель правильности выбранной методики обучения. Часто наоборот.
И вот когда ты преодолеешь себя, увидишь как на твою почту придет первый оффер, тогда ты как и я, поймешь, что и не стоило ждать удобств в обучении. (Тем более, что оно всегда будет продолжаться)
Ведь те трудности которые ты преодолел - сформировали из тебя того кто смог пройти собеседование и получить заветную работу.🥳
Главное вера в себя и свои силы💪
😎
Понравилась статья - поделись с другом и, будет тебе моя благодарность 👏
#motivation
Так вышло, что мое знакомство с Java и программированием в целом, началось еще в 2021 году.
Тогда, окрыленный надеждами на новую, интересную работу, я потратил приличное количество времени на изучение Java Core. Но как часто бывает, реальность продиктовала свои условия, я не смог осилить обучение и бросил его.
Периодически возвращаясь я понял, что придется начинать сначала.
И когда я смог подогнать жизненные условия к тому, чтобы бросить все и посвятить себя только обучению, которое в итоге привело меня сюда, я понял важную вещь - обучение программированию (да наверно любой другой сложной концепции) — это долгая, часто тяжелая дорога, где не будет "легко", но "результат" стоит того.
Вот, что важно понимать если ты только принял решение вступить на этот путь:
Пойми простую вещь - кто обещает «легко и быстро» — 100% врет. Так практически не бывает, за исключением единичных примеров. Но ссылаясь на эти примеры, некоторые строят целые онлайн-школы и бизнес (на твоих деньгах).
И я не говорю, что ты не получишь ничего полезного на этих занятиях. НО! Ты не сможешь, к примеру за 3 месяца, стать конкурентным специалистом в Java, если ты обычный среднестатистический человек.
Ну никак, сорян, кто бы что не говорил
Перед окунанием в "программирование", знай, что к примеру Java, уже отпраздновала 30-летие в этом году. А это, возможно больше чем ты живешь на свете.
А это значит, что изучение её (по крайней мере, как ощущаю это я) - это погружение в бесконечную кроличью нору.
На каждую понятую тобой концепцию или алгоритм, за его спиной вырастут еще с десяток и ты постоянно будешь ощущать себя неполноценным
Не переживай - это нормально. Все проходят через это
Пойми и прими, то, что порой в Java встречаются темы, которые не взять "с наскока". Ну никак.
И если ты вдруг, ловишь себя на мысли, что на какую-то тему ты тратишь неприлично долгое время - это не значит, что ты "не тянешь".
Просто это тоже нормально. Мы все разные, с разным бекграундом.
Важно не «как быстро», а как долго ты не сливаешься. Ведь в итоге самые стойкие — выигрывают, даже если тупят на старте.
Знай, никто не пишет "красиво" и "правильно" с первого раза. Даже "гении".
А ты и я тем более.
Поэтому, как я писал в предыдущей статье - если первые месяцы ты будешь писать грязно, неэффективно и тупо — это тоже нормально и правильно.
Запомни: в начале пути, идеальный код — не твоя цель. Цель — живой и работающий код, а все остальное приложится.
Если тебе в процессе обучения неприятно, неудобно и сложно — значит, ты делаешь правильно. (Особенно это актуально для тех кто за "30"
Твой мозг вышел из зоны комфорта, он испытывает стресс и пытается повлиять на тебя, вернув в теплые объятия неведения.
Твоя задача - ежедневно, ежеминутно, бороться с ленью, преодолевать алгоритмические и идейные трудности, выстраивая новые нейронные связи.
Комфорт — не показатель правильности выбранной методики обучения. Часто наоборот.
И вот когда ты преодолеешь себя, увидишь как на твою почту придет первый оффер, тогда ты как и я, поймешь, что и не стоило ждать удобств в обучении. (Тем более, что оно всегда будет продолжаться)
Ведь те трудности которые ты преодолел - сформировали из тебя того кто смог пройти собеседование и получить заветную работу.
Главное вера в себя и свои силы
#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
Предлагаем темы для разбора и публикации! 📖
В комментариях к данному посту предлагайте вопросы, которые вы хотели бы увидеть максимально подробно разобранными в постах, а если будет интересно то и на видео.
Голосование будет проводиться всю неделю, а статья или видео - выходить по выходным.
Примерные правила:
🟢 темы, не выше уровня middle, чтоб был интерес общим.
🟢 один человек - одна тема.
🟢 Тема должна быть отдельным теоретически-практическим вопросом. Готовый проект - это не тема!
Жду Ваших предложений!👏
В комментариях к данному посту предлагайте вопросы, которые вы хотели бы увидеть максимально подробно разобранными в постах, а если будет интересно то и на видео.
Голосование будет проводиться всю неделю, а статья или видео - выходить по выходным.
Примерные правила:
Жду Ваших предложений!
Please open Telegram to view this post
VIEW IN TELEGRAM
Голосуем за предложенные темы!
Anonymous Poll
54%
Stream API
15%
@Slf4j, логирование, кастомизация логов
13%
IO, NIO: работа с файловой системой
17%
Maven: жизненный цикл, фазы
Объекты в Java
Объекты являются фундаментальным понятием в Java и лежат в основе всей объектно-ориентированной парадигмы языка. Каждый объект представляет собой экземпляр класса и объединяет в себе состояние (поля) и поведение (методы).
1. Введение
В Java всё, что не является примитивным типом, относится к ссылочным типам, а основные единицы этих типов — это объекты.
Объект-ориентированная модель основана на трёх ключевых принципах:
Инкапсуляция: объединение данных и методов для управления ими.
Наследование: возможность создавать новые классы на основе уже существующих, унаследовав их состояние и поведение.
Полиморфизм: возможность работать с объектами через их общий (абстрактный) тип, подставляя разные конкретные реализации.
Вся динамика и гибкость Java-приложений строится на том, что объекты создаются во время выполнения программы, передаются по ссылке, могут образовывать сложные графы связей и автоматически удаляться сборщиком мусора.
2. Создание объектов
2.1. Ключевое слово new
Самый распространённый способ создания объекта — использование оператора new, который выполняет два основных действия:
Выделяет память в куче (heap) под новый объект.
Вызывает конструктор соответствующего класса, чтобы инициализировать поля объекта.
Здесь:
new Person("John", 25) — порождает новый объект класса Person, вызывая конструктор Person(String name, int age).
Полученная ссылка на вновь созданный объект присваивается переменной person1 типа Person.
Переменная person1 не содержит непосредственно самого объекта, а лишь указывает на область памяти, где объект расположен.
2.2. Фабричные методы и другие способы
Кроме new, объекты могут создаваться через:
Фабричные методы (static factory methods), например, List.of(...) или Optional.of(...).
Клонирование (когда класс поддерживает интерфейс Cloneable и реализует метод clone()).
Десериализация (с помощью API сериализации или при работе с JSON/XML).
Рефлексия (пересоздание экземпляра через Class.newInstance() или Constructor.newInstance()).
Однако в подавляющем большинстве случаев для явного создания объекта используется именно new.
2.3. Размещение ссылок и объектов
Объекты всегда размещаются в куче (heap).
Ссылочные переменные (person1 в примере) могут храниться:
В стеке вызовов (если это локальная переменная метода).
В полях других объектов (если объект содержится в качестве поля другого объекта).
В элементах массива (если это массив ссылок).
В статических полях классов (в специальной области памяти, связанной с загрузчиком классов).
3. Существование и удаление объектов
3.1. Существование объектов
Объект продолжает «жить» в памяти до тех пор, пока на него существует хотя бы одна активная ссылка.
Пример:
В момент создания объекта через new в куче появляется новый экземпляр Person.
Переменные person1 и person2 указывают на одну и ту же область памяти.
Когда мы присвоили person1 = null;, объект всё ещё существует, поскольку на него ссылается person2.
Как только все ссылки будут убраны (например, person2 = null; или метод, в котором была локальная ссылка, завершится и стек «очистится»), объект становится недостижимым.
Java применяет алгоритм mark-and-sweep для сборки мусора, поэтому даже если два объекта ссылаются друг на друга, но на них никто извне не ссылается, они будут помечены как недостижимые и удалены.
#Java #для_новичков #beginner #reference_types #Object
Объекты являются фундаментальным понятием в Java и лежат в основе всей объектно-ориентированной парадигмы языка. Каждый объект представляет собой экземпляр класса и объединяет в себе состояние (поля) и поведение (методы).
1. Введение
В Java всё, что не является примитивным типом, относится к ссылочным типам, а основные единицы этих типов — это объекты.
Объект-ориентированная модель основана на трёх ключевых принципах:
Инкапсуляция: объединение данных и методов для управления ими.
Наследование: возможность создавать новые классы на основе уже существующих, унаследовав их состояние и поведение.
Полиморфизм: возможность работать с объектами через их общий (абстрактный) тип, подставляя разные конкретные реализации.
Вся динамика и гибкость Java-приложений строится на том, что объекты создаются во время выполнения программы, передаются по ссылке, могут образовывать сложные графы связей и автоматически удаляться сборщиком мусора.
2. Создание объектов
2.1. Ключевое слово new
Самый распространённый способ создания объекта — использование оператора new, который выполняет два основных действия:
Выделяет память в куче (heap) под новый объект.
Вызывает конструктор соответствующего класса, чтобы инициализировать поля объекта.
Person person1 = new Person("John", 25);
Здесь:
new Person("John", 25) — порождает новый объект класса Person, вызывая конструктор Person(String name, int age).
Полученная ссылка на вновь созданный объект присваивается переменной person1 типа Person.
Переменная person1 не содержит непосредственно самого объекта, а лишь указывает на область памяти, где объект расположен.
2.2. Фабричные методы и другие способы
Кроме new, объекты могут создаваться через:
Фабричные методы (static factory methods), например, List.of(...) или Optional.of(...).
Клонирование (когда класс поддерживает интерфейс Cloneable и реализует метод clone()).
Десериализация (с помощью API сериализации или при работе с JSON/XML).
Рефлексия (пересоздание экземпляра через Class.newInstance() или Constructor.newInstance()).
Однако в подавляющем большинстве случаев для явного создания объекта используется именно new.
2.3. Размещение ссылок и объектов
Объекты всегда размещаются в куче (heap).
Ссылочные переменные (person1 в примере) могут храниться:
В стеке вызовов (если это локальная переменная метода).
В полях других объектов (если объект содержится в качестве поля другого объекта).
В элементах массива (если это массив ссылок).
В статических полях классов (в специальной области памяти, связанной с загрузчиком классов).
3. Существование и удаление объектов
3.1. Существование объектов
Объект продолжает «жить» в памяти до тех пор, пока на него существует хотя бы одна активная ссылка.
Пример:
Person person1 = new Person("John", 25);
Person person2 = person1; // person2 ссылается на тот же самый объект
person1 = null; // теперь единственная ссылка на объект — person2
В момент создания объекта через new в куче появляется новый экземпляр Person.
Переменные person1 и person2 указывают на одну и ту же область памяти.
Когда мы присвоили person1 = null;, объект всё ещё существует, поскольку на него ссылается person2.
Как только все ссылки будут убраны (например, person2 = null; или метод, в котором была локальная ссылка, завершится и стек «очистится»), объект становится недостижимым.
Java применяет алгоритм mark-and-sweep для сборки мусора, поэтому даже если два объекта ссылаются друг на друга, но на них никто извне не ссылается, они будут помечены как недостижимые и удалены.
#Java #для_новичков #beginner #reference_types #Object
3.2. Состояние объектов при сборке мусора
Touchable (доступный): объекты, на которые есть хотя бы одна живая ссылка.
Resurrectible (возродимый): объекты, на которые больше нет обычных ссылок, но в методе finalize() ещё есть возможность «оживить» объект (устаревший механизм, не рекомендуется к использованию).
Untouchable (недоступный): объекты, окончательно помеченные для удаления сборщиком мусора.
Иерархия переходов такова:
Пока есть ссылки — объект «доступен» и используется.
Если ссылок нет, но метод finalize() ещё не вызывался — объект попадает в очередь финализации.
После выполнения finalize() (или если он не переопределён) объект окончательно переходит в состояние «недоступен» и убирается сборщиком мусора.
3.3. Удаление объектов
Перечислять и освобождать память вручную, как в C++, в Java не нужно.
Можно лишь рекомендовать запуск сборщика мусора через System.gc(), но вызов этого метода не гарантирует немедленного выполнения GC.
Метод finalize() устаревает (deprecated) и не рекомендуется к использованию, поскольку его выполнение непредсказуемо и может негативно влиять на производительность.
При работе с ресурсами (файлы, сокеты, потоки) рекомендуется применять конструкцию try-with-resources или явно закрывать ресурсы в блоке finally, а не полагаться на GC или finalize().
4. Использование объектов
4.1. Вызов методов и доступ к полям
После того как объект создан и на него есть ссылка, мы можем обращаться к его полям и методам:
Ключевое понимание:
Любой метод вызывается через ссылку на объект.
Внутри метода this указывает на тот же объект, на который указывает переменная, через которую мы вызвали метод.
4.2. Инкапсуляция и модульность
Объекты позволяют:
Инкапсулировать внутреннее состояние (часто делая поля private и предоставляя доступ через геттеры/сеттеры).
Скрыть детали реализации, предоставляя только публичный интерфейс (методы).
Повторно использовать код: один и тот же класс можно инстанцировать в разных местах программы.
4.3. Передача объектов в методы
Когда мы передаём объект в метод, копируется сама ссылка, а не весь объект.
Это значит, что метод получает «копию адреса», указывающую на тот же экземпляр:
Вызов list.add(10) изменил тот же объект, что и numbers.
А переприсваивание list = new ArrayList<>() коснулось только локальной копии ссылки внутри метода.
5. Трудности и подводные камни
5.1. NullPointerException
Самая распространённая ошибка при работе с объектами — попытка вызвать метод или обратиться к полю на null-ссылке:
Рекомендуемые практики:
При инициализации объектов делать явные проверки, либо использовать Objects.requireNonNull(obj).
При наличии неопределённости возвращать Optional<T> вместо потенциально null.
В местах, где возможно получение null, проверять ссылку прежде чем обращаться к её методам или полям.
#Java #для_новичков #beginner #reference_types #Object
Touchable (доступный): объекты, на которые есть хотя бы одна живая ссылка.
Resurrectible (возродимый): объекты, на которые больше нет обычных ссылок, но в методе finalize() ещё есть возможность «оживить» объект (устаревший механизм, не рекомендуется к использованию).
Untouchable (недоступный): объекты, окончательно помеченные для удаления сборщиком мусора.
Иерархия переходов такова:
Пока есть ссылки — объект «доступен» и используется.
Если ссылок нет, но метод finalize() ещё не вызывался — объект попадает в очередь финализации.
После выполнения finalize() (или если он не переопределён) объект окончательно переходит в состояние «недоступен» и убирается сборщиком мусора.
3.3. Удаление объектов
Перечислять и освобождать память вручную, как в C++, в Java не нужно.
Можно лишь рекомендовать запуск сборщика мусора через System.gc(), но вызов этого метода не гарантирует немедленного выполнения GC.
Метод finalize() устаревает (deprecated) и не рекомендуется к использованию, поскольку его выполнение непредсказуемо и может негативно влиять на производительность.
При работе с ресурсами (файлы, сокеты, потоки) рекомендуется применять конструкцию try-with-resources или явно закрывать ресурсы в блоке finally, а не полагаться на GC или finalize().
4. Использование объектов
4.1. Вызов методов и доступ к полям
После того как объект создан и на него есть ссылка, мы можем обращаться к его полям и методам:
person1.sayHello(); // вызов метода объекта
int age = person1.getAge(); // чтение свойства через геттер
Ключевое понимание:
Любой метод вызывается через ссылку на объект.
Внутри метода this указывает на тот же объект, на который указывает переменная, через которую мы вызвали метод.
4.2. Инкапсуляция и модульность
Объекты позволяют:
Инкапсулировать внутреннее состояние (часто делая поля private и предоставляя доступ через геттеры/сеттеры).
Скрыть детали реализации, предоставляя только публичный интерфейс (методы).
Повторно использовать код: один и тот же класс можно инстанцировать в разных местах программы.
4.3. Передача объектов в методы
Когда мы передаём объект в метод, копируется сама ссылка, а не весь объект.
Это значит, что метод получает «копию адреса», указывающую на тот же экземпляр:
void modifyList(List<Integer> list) {
list.add(10); // модифицирует оригинальный список
list = new ArrayList<>(); // переприсвоение локальной переменной — не влияет на внешний список
list.add(20); // меняет уже новый (локальный) список
}
List<Integer> numbers = new ArrayList<>();
modifyList(numbers);
System.out.println(numbers); // [10], но не [10, 20]
Вызов list.add(10) изменил тот же объект, что и numbers.
А переприсваивание list = new ArrayList<>() коснулось только локальной копии ссылки внутри метода.
5. Трудности и подводные камни
5.1. NullPointerException
Самая распространённая ошибка при работе с объектами — попытка вызвать метод или обратиться к полю на null-ссылке:
String s = null;
int length = s.length(); // NullPointerException
Рекомендуемые практики:
При инициализации объектов делать явные проверки, либо использовать Objects.requireNonNull(obj).
При наличии неопределённости возвращать Optional<T> вместо потенциально null.
В местах, где возможно получение null, проверять ссылку прежде чем обращаться к её методам или полям.
#Java #для_новичков #beginner #reference_types #Object