Java for Beginner
743 subscribers
708 photos
196 videos
12 files
1.14K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Обратное давление: контроль

Одна из ключевых фишек — backpressure (обратное давление). В традиционных системах, если производитель данных быстрее потребителя, буфер переполняется, и система падает. В Reactive Streams подписчик через Subscription.request(n) говорит: "Дай мне n элементов". Издатель выдаёт ровно столько, сколько запрошено. Это как шлюзы на реке: предотвращают наводнение.


Пример в Flux:
Flux<integer> fastFlux = Flux.range(1, 1000); // Быстрый источник
fastFlux.subscribe(new BaseSubscriber<integer>() {

@Override
protected void hookOnSubscribe(Subscription subscription) {
request(10); // Запрашиваем только 10 элементов сначала
}

@Override
protected void hookOnNext(Integer value) {
System.out.println(value);
if (value % 10 == 0) request(10); // Запрашиваем ещё по мере обработки
}
});


Подписчик контролирует темп, избегая перегрузки.


Почему это новый подход, который нам нужен?

Реактивное программирование не просто добавляет инструменты — оно меняет мышление. Вместо "императивного" кода (делай то, жди это), мы пишем "декларативно": опиши, как реагировать на поток. Это масштабируется: на сервере с 4 ядрами можно обрабатывать тысячи подключений, потому что нет блокирующих потоков. Библиотеки вроде Reactor интегрируются с неблокирующими драйверами (например, reactive JDBC или WebFlux для веб), решая боли блокировок.


#Java #middle #Reactor #data_stream
👍4
Что выведет код?

import java.util.HashSet;
import java.util.Set;

public class Task180925 {
public static void main(String[] args) {
Point p1 = new Point(1, 2);
Point p2 = new Point(1, 3);
Set<Point> set = new HashSet<>();
set.add(p1);
set.add(p2);
System.out.println(set.size());
}

public record Point(int x, int y) {
public Point {
if (x < 0) throw new IllegalArgumentException("x < 0");
if (y < 0) throw new IllegalArgumentException("y < 0");
}

public boolean equals(Object o) {
return o instanceof Point p && p.x == x;
}

public int hashCode() {
return x;
}
}
}


#Tasks
👍2
👍2
Небольшой анонс на воскресение в 16:00 🤫

Приходите
😉
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Вопрос с собеседований

Что такое dependency inversion principle (DIP)? 🤓

Ответ:

DIP (SOLID)
— высокоуровневые модули не зависят от низкоуровневых, а от абстракций.

Пример:
Использовать интерфейс Database вместо конкретного MySQLDatabase.

С Inversion of Control (IoC) упрощает тестирование.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🗓 История IT-технологий сегодня — 19 сентября


ℹ️ Кто родился в этот день

Вале́рий Пантеле́евич Бака́лов (19 сентября 1940, Новосибирск — 21 июня 2021, там же) — советский/российский деятель в области связи и образования, доктор технических наук; был ректором Сибирского государственного университета телекоммуникаций и информатики (НЭИС), руководил кафедрами, развивал специальности по связи, информационно-измерительной технике и телеметрии.

Конвей Морис Бернерс-Ли (19 сентября 1921 — 1 февраля 2019) — математик и компьютерный учёный; участвовал в разработке Ferranti Mark 1 — одной из первых коммерческих ЭВМ с хранимой в памяти программой.

Яков За́лманович Цы́пкин (19 сентября 1919[1], Екатеринослав — 2 декабря 1997) — советский кибернетик и инженер-электрик, член АН СССР; внёс значительный вклад в теорию автоматического управления, разработку релейных и импульсных автоматов, критериев устойчивости систем.

Питер Смит (19 сентября 1956 — 27 мая 2025) — британский учёный в области искусственного интеллекта / компьютерных наук; профессор, наставник многих докторов, внёс вклад в развитие PhD-образования и исследовательской поддержки в ИИ.

Администратор канала Java for Beginner - просто Ден.


🌐 Знаковые события

1982 — Скотт Фалман предложил использовать смайлики в качестве способа выражения эмоций при общении в Сети.

1990 — Ассоциация пользователей UNIX зарегистрировала домен верхнего уровня SU для применения на территории СССР.


#Biography #Birth_Date #Events #19Сентября
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Основы ООП в Java

Глава 7. Принципы проектирования и хорошего кода

SOLID

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

1. Принцип единственной ответственности (S — Single Responsibility Principle)

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

Почему важно: Если класс отвечает за несколько задач, то при изменении одной из них (например, из-за новых требований бизнеса) вы рискуете сломать другие части. Это приводит к ошибкам и усложняет поддержку кода.

Подробное объяснение: Представьте, что класс одновременно читает данные из файла, обрабатывает их и выводит на экран. Если изменится формат файла, вам придется менять весь класс, даже если обработка и вывод не изменились. Лучше разделить: один класс для чтения, другой для обработки, третий для вывода.

Пример нарушения принципа:
public class Report {
// Нарушение: Класс делает всё сразу
public void readDataFromFile(String fileName) {
// Код для чтения данных
}

public void processData() {
// Код для обработки данных
}

public void printReport() {
// Код для печати отчета
}
}

Здесь класс имеет три ответственности. Если изменится способ чтения файлов, придется трогать весь класс.


Пример правильного применения:
public class DataReader {
public String readDataFromFile(String fileName) {
// Только чтение данных
return "Данные из файла";
}
}

public class DataProcessor {
public String processData(String data) {
// Только обработка
return "Обработанные данные: " + data;
}
}

public class ReportPrinter {
public void printReport(String processedData) {
// Только печать
System.out.println(processedData);
}
}

Теперь каждый класс имеет одну ответственность. Изменение в чтении не затронет печать.


Совет: Задайте вопрос: "Сколько причин для изменения у этого класса?" Если больше одной — разделите.


2. Принцип открытости-закрытости (O — Open-Closed Principle)

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

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

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



#Java #для_новичков #beginner #OOP #SOLID
👍4🔥1
Пример нарушения принципа:
public class ShapeCalculator {
public double calculateArea(Object shape) {
if (shape instanceof Circle) {
// Код для круга
return Math.PI * ((Circle) shape).getRadius() * ((Circle) shape).getRadius();
} else if (shape instanceof Square) {
// Код для квадрата
return ((Square) shape).getSide() * ((Square) shape).getSide();
}
// Если добавить треугольник, придется менять метод
return 0;
}
}

Добавление новой фигуры требует изменения метода, что нарушает принцип.


Пример правильного применения:Используем абстракцию и полиморфизм.

public abstract class Shape {
public abstract double calculateArea(); // Метод для расширения
}

public class Circle extends Shape {
private double radius;

public Circle(double radius) {
this.radius = radius;
}

@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}

public class Square extends Shape {
private double side;

public Square(double side) {
this.side = side;
}

@Override
public double calculateArea() {
return side * side;
}
}

// Для новой фигуры просто добавьте класс, без изменения старого кода

Теперь ShapeCalculator может быть:
public class ShapeCalculator {
public double calculateArea(Shape shape) {
return shape.calculateArea(); // Полиморфизм, закрыт для изменений
}
}

Добавление треугольника — новый класс extends Shape, без изменений в калькуляторе.


Совет: Используйте абстрактные классы или интерфейсы для "открытости", а переопределение — для расширения.



3. Принцип подстановки Лисков (L — Liskov Substitution Principle)

Этот принцип, предложенный Барбарой Лисков, гласит, что объекты подкласса должны быть способны заменять объекты суперкласса без изменения правильности программы. Иными словами, подкласс не должен нарушать ожидания, установленные суперклассом.

Почему важно: Если подкласс меняет поведение суперкласса неожиданным образом, код, использующий суперкласс, может сломаться при подстановке подкласса. Это нарушает полиморфизм.

Подробное объяснение: Подкласс должен сохранять контракты суперкласса: предусловия (входные данные) не ужесточаются, постусловия (выход) не ослабляются, инварианты (постоянные свойства) сохраняются.


Пример нарушения принципа:
Представьте суперкласс Bird (Птица) с методом fly() (летать). Подкласс Penguin (Пингвин) переопределяет fly() и бросает исключение, потому что пингвины не летают. Тогда код Bird bird = new Penguin(); bird.fly(); сломается, хотя ожидалось, что любая птица может летать.
public class Bird {
public void fly() {
System.out.println("Летаю!");
}
}

public class Penguin extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("Пингвины не летают!");
}
}

Это нарушение: подстановка пингвина ломает код.


Пример правильного применения:
Лучше разделить: суперкласс Animal, интерфейс Flyable для летающих. Пингвин extends Animal, но не implements Flyable.
public class Animal {
// Общие методы
}

public interface Flyable {
void fly();
}

public class Eagle extends Animal implements Flyable {
@Override
public void fly() {
System.out.println("Орел летает высоко!");
}
}

public class Penguin extends Animal {
// Нет fly(), так что не нарушает
}

Теперь код работает только с Flyable, без неожиданностей.


Совет: Проверяйте: "Можно ли заменить суперкласс подклассом без проблем?" Если нет — пересмотрите дизайн.


#Java #для_новичков #beginner #OOP #SOLID
👍4🔥1
4. Принцип разделения интерфейсов (I — Interface Segregation Principle)

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

Почему важно: Большой интерфейс заставляет классы реализовывать ненужные методы, что приводит к "пустым" реализациям и усложняет код.

Подробное объяснение: Лучше несколько маленьких интерфейсов, чем один большой. Это делает систему модульной и легче для понимания.


Пример нарушения принципа:
public interface Worker {
void work(); // Для всех
void eat(); // Только для людей
void charge(); // Только для роботов
}

Класс Human реализует charge() бесполезно, Robot — eat().


Пример правильного применения:

Разделите на маленькие интерфейсы.
public interface Workable {
void work();
}

public interface Eatable {
void eat();
}

public interface Chargeable {
void charge();
}

public class Human implements Workable, Eatable {
@Override
public void work() { /*...*/ }

@Override
public void eat() { /*...*/ }
}

public class Robot implements Workable, Chargeable {
@Override
public void work() { /*...*/ }

@Override
public void charge() { /*...*/ }
}

Теперь классы реализуют только нужное.


Совет: Интерфейс должен быть "толстым" для клиента, но "тонким" для реализатора — маленькие интерфейсы.


5. Принцип инверсии зависимостей (D — Dependency Inversion Principle)


Этот принцип утверждает, что высокоуровневые модули (бизнес-логика) не должны зависеть от низкоуровневых (детали реализации), а оба должны зависеть от абстракций (интерфейсов). Абстракции не зависят от деталей, детали зависят от абстракций.

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

Подробное объяснение: Используйте интерфейсы или абстрактные классы как "прослойку". Высокий уровень зависит от интерфейса, низкий — реализует его.


Пример нарушения принципа:
public class ReportService {
private MySQLDatabase db = new MySQLDatabase(); // Зависит от конкретной реализации

public void generateReport() {
db.connect();
// ...
}
}

Смена базы данных требует изменения сервиса.


Пример правильного применения:
public interface Database {
void connect();
// ...
}

public class MySQLDatabase implements Database {
@Override
public void connect() { /*...*/ }
}

public class ReportService {
private Database db; // Зависит от абстракции

public ReportService(Database db) { // Инъекция зависимости
this.db = db;
}

public void generateReport() {
db.connect();
// ...
}
}

Теперь можно передать любую реализацию: new ReportService(new MySQLDatabase()) или new ReportService(new PostgreSQLDatabase()).


Совет: Используйте dependency injection (внедрение зависимостей) для передачи абстракций.


Полезные советы для новичков

Применяйте SOLID постепенно: Начните с единственной ответственности, потом добавляйте другие.
Примеры в Java: Смотрите стандартную библиотеку — она следует SOLID.
Ресурсы: Книга "Clean Code" Роберта Мартина для глубокого понимания.
Практика: Возьмите свой код и проверьте на соответствие каждому принципу.



#Java #для_новичков #beginner #OOP #SOLID
👍3🔥21
Что выведет код?

class Animal190925 {
public String speak() {
return "Some sound";
}
}

class Dog190925 extends Animal190925 {
public String speak() {
return "Woof";
}

public String fetch() {
return "Fetching stick";
}
}

public class Task190925 {
public static void main(String[] args) {
Animal190925 myAnimal = new Dog190925();
System.out.println(myAnimal.speak());
System.out.println(myAnimal.fetch());
}
}


#Tasks
👍4
Вопрос с собеседований

Что такое паттерн Chain of Responsibility? 🤓

Ответ:

Chain of Responsibility
— паттерн, где запрос передается по цепочке обработчиков.

Пример:
abstract class Handler {
protected Handler next;
abstract void handle(Request request);
}
class ConcreteHandler extends Handler {
void handle(Request request) { if (canHandle) process(); else next.handle(request); }
}

Используется в logging или обработке событий.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🗓 История IT-технологий сегодня — 20 сентября


ℹ️ Кто родился в этот день

Анатолий Васильевич Мошинский (бел. Анатоль Васілевіч Машынскі; 20 сентября 1937 Мерефа, СССР — 15 марта 1996 Республика Беларусь) — советский/белорусский учёный в радиофизике и электронике; профессор БГУ информатики и радиоэлектроники, занимался математическим моделированием физических процессов и прикладной электротехникой, что близко к вычислительной и электронной технике.

Дороти Джин Джонсон Воган (20 сентября 1910 г. — 10 ноября 2008 г.) — американская "human computer" и программист в NACA/NASA; одна из первых чернокожих женщин-руководителей вычислительного отдела, обучала себя и сотрудников языку Fortran, участвовала в адаптации и автоматизации вычислительных методов.

Чандрасекаран Пандуранган (родился 20 сентября 1955 года) — индийский учёный в компьютерных науках, профессор; исследования в областях алгоритмов, теории графов, криптографии, параллельных и VLSI-алгоритмов.


🌐 Знаковые события

1954 — скомпилирована и запущена первая программа, написанная на Фортране.

2000 — власти Тайваня арестовали 25-летнего Чэн Инь-Хао, создателя компьютерного вируса CIH («ЧИХ»), названного по инициалам автора. В народе вирус известен как «Чернобыль», так как одна из его версий активируется 26 апреля, в годовщину аварии на атомной электростанции.


#Biography #Birth_Date #Events #20Сентября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
С 13.09 по 19.09
Предыдущий пост(с 06.09 по 12.09)

Воскресный мотивационный пост:
не было

Выбранная голосованием тема:
не было

Запись встреч/видео:
не было.

Обучающие статьи:

Реактивное программирование
Реактивное программирование - вступление
Что такое потоки данных в реактивном мире?

Java:
static: поля, методы, блоки инициализации
Перечисления (enum)
Принципы проектирования и хорошего кода: SOLID

Полезные статьи и видео
:

Про IT в 2025 году
Обратная совместимость в Java-мире

Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование

#memory
🔥21
Предлагаем темы для разбора и публикации! 📖

В комментариях к данному посту предлагайте вопросы, которые вы хотели бы увидеть максимально подробно разобранными в постах, а если будет интересно то и на видео.

Голосование будет проводиться всю неделю, а статья или видео - выходить по выходным.

Примерные правила:
🟢 темы, не выше уровня middle, чтоб был интерес общим.
🟢Один человек - одна тема.
🟢Тема должна быть отдельным теоретически-практическим вопросом. Готовый проект - это не тема!

Жду Ваших предложений! 👏
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Выбираем темы для рассмотрения в следующие выходные! 🤨
Anonymous Poll
17%
AOP
23%
Введение в Camunda
27%
Введение в gRPC
33%
Введение в GraphQL
👍1
А вы придете завтра на встречу по изучению Spring AI в 16:00 по МСК?
Anonymous Poll
41%
Да, обязательно!
47%
Хочу, но не могу...
12%
Не приду, фигню рассматриваете
👍1