Java Portal | Программирование
13.2K subscribers
1.15K photos
95 videos
36 files
1.05K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Подсказка по Java: начиная с Java 11 можно использовать String.strip() вместо trim(), потому что strip() корректно обрабатывает пробелы в Unicode.

Так как trim() не обрабатывает некоторые типы пробелов, определенные в Unicode, он может оставлять неожиданные символы.

String.strip() использует Character.isWhitespace(int codePoint) для определения пробельных символов, учитывая полный стандарт Unicode, а не только ASCII, и удаляет все виды пробелов.

Пример:

String text = "\u2003Hello World\u2003";
System.out.println("trim(): [" + text.trim() + "]");
System.out.println("strip(): [" + text.strip() + "]");


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍254
This media is not supported in your browser
VIEW IN TELEGRAM
Это расширение для Chrome прям находка для тех, кто активно сидит на GitHub

Называется SimRepo и показывает похожие репозитории для любого открытого проекта.

Просто устанавливаешь и забываешь — расширение автоматически срабатывает каждый раз, когда открываешь репозиторий.

Полезно, если хочешь найти что-то лучше, посмотреть альтернативы или просто открыть для себя новые проекты во время поиска ☺️

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
13🔥3👍2👀1
Совет по Java: используй WeakHashMap для кеширования, если ключи без ссылок должны автоматически очищаться сборщиком мусора.

В HashMap, пока объект карты существует, ключи и связанные с ними значения не будут собраны сборщиком мусора.

В WeakHashMap ключи хранятся через слабые ссылки, и если на ключ больше нет сильных ссылок в других частях программы, GC может освободить его, и он будет автоматически удалён из карты.

Пример:

Map<User, String> map = new WeakHashMap<>();

User u1 = new User("Mick");
map.put(u1, "Cached data");
...
u1 = null;

// Теперь ключ u1 может быть собран сборщиком мусора.


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83🔥2
Уменьшаем время выборки из БД с 2–3 секунд до ~100 мс:

SELECT * FROM transactions
WHERE user_id = 40
ORDER BY created_at DESC
LIMIT 20 OFFSET 10000;


На первый взгляд запрос нормальный?
ДА, вроде ок.

Но:

- это OFFSET-пагинация
- и это прям ПЛОХО
- БД вытягивает 10020 строк и выкидывает 10000, чтобы показать 20, лол
- чем больше OFFSET, тем больше нагрузка на БД
- со временем запрос начинает занимать больше 2 секунд, пока растет объем данных

Решение:

KEYSET (seek) пагинация: добавляем условие вида created_at < last_seen_timestamp

SELECT * FROM transactions
WHERE user_id = 40
AND created_at < '2024-05-01 10:00:00'
ORDER BY created_at DESC
LIMIT 20;


- так БД может сразу прыгнуть по индексу
- по сути это "дай следующие 20 записей после этого timestamp", где timestamp используется как ключ
- время реально падает с секунд до примерно 100–200 мс

Что если timestamp не уникален, есть дубли:

Добавляем tie-breaker: (created_at, id) и в WHERE, и в ORDER BY:

WHERE (created_at, id) < ('2024-05-01 10:00:00', 98765)
ORDER BY created_at DESC, id DESC


Так пагинация остается быстрой и детерминированной, даже при одинаковых created_at.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥54
Одна ключевая идея в Spring Boot, которая в 2025 отличает синьоров от staff/principal инженеров:

Большинство разработчиков думают, что Spring Boot это просто
@RestController + JPA.

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

Virtual Threads (Project Loom) + Spring Boot 3 позволяют блокирующему коду масштабироваться лучше, чем это когда-либо делал реактивный стек.

Теперь не нужно выбирать упрощение или производительность. Можно иметь оба варианта сразу.

Один такой сдвиг в мышлении может поднять пропускную способность системы в 10 раз и вдвое снизить сложность.

@RestController
@RequestMapping("/api/orders")
class OrderController {

@Autowired JdbcTemplate jdbc; // Оставляй свой старый добрый блокирующий JDBC
@Autowired RestTemplate rest; // Оставляй привычный блокирующий RestTemplate
@Autowired EntityManager em; // Оставляй JPA/Hibernate в том виде, как привык

@GetMapping("/{id}")
public Order get(@PathVariable Long id) {
// 100% блокирующий код — читает БД, вызывает 3 downstream HTTP-сервиса
// Но благодаря виртуальным потокам один этот endpoint
// спокойно выдерживает 50k+ RPS на 2 vCPU при < 50 ms p99

var order = jdbc.queryForObject("SELECT * FROM orders WHERE id=?", Order.class, id);
var payment = rest.getForObject("http://payment/{id}", Payment.class, id);
var shipping = rest.getForObject("http://shipping/{id}", Shipping.class, id);

return order.withPayment(payment).withShipping(shipping);
}
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🤣3
Приглашаем на ЮMoneyDay — бесплатную онлайн-конференцию про финтех и IT 🔥

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

Будут доклады по 16 направлениям:

🟣 Будущее финтеха
🟣 Бэкенд
🟣 Фронтенд
🟣 Тестирование
🟣 Python
🟣 Менеджмент проектов
🟣 Менеджмент продуктов
🟣 Системный анализ
🟣 SQL
🟣 UX
🟣 ИИ
🟣 Архитектура IT-решений
🟣 Внутренние системы
🟣 Мобильная разработка
🟣 Инфраструктура
🟣 О компании

Встречаемся онлайн 5 и 6 декабря в 11:00 мск. Чтобы участвовать, зарегистрируйтесь на сайте конференции
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1🔥1
Spring Modulith добавили поддержку Application-Module Aware миграций в Flyway.

Посмотреть, как это работает, можно тут👇
https://github.com/sivaprasadreddy/spring-modular-monolith

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
4🤔1
Совет по Spring Boot

Когда пишешь REST API на Spring Boot, обычно используют префикс /api

Чтобы не лепить @RequestMapping("/api") в каждом контроллере, можно настроить это один раз вот так:

@Configuration
class WebMvcConfig implements WebMvcConfigurer {

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("/api",
aClass -> aClass.getPackage().getName().startsWith("com.sivalabs.bookstore"));
}
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍134😁1
Какой будет вывод и почему?

class Person {
String name;
}

public class Test {
static void modify(Person obj) {
obj.name = "Rahul";
obj = new Person();
obj.name = "Amit";
}

public static void main(String[] args) {
Person p = new Person();
p.name = "Sumit";

modify(p);

System.out.println(p.name);
}
}


Если ты не можешь ответить на это, значит ты пока не готов к интервью.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍5
Можно использовать асинхронный логгинг в Spring Boot, настроив logback (logback-spring.xml).

Лог-сообщения отправляются в очередь и обрабатываются отдельным фоновым потоком.

Это уменьшает задержки, связанные с вводом-выводом.

Положи файл конфигурации logback в папку resources:

src/main/resources/logback-spring.xml


Вот пример:

<configuration>

<!-- Console appender, обёрнутый в асинхронный -->
<appender name="ASYNC_CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="CONSOLE" />
<queueSize>5000</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>false</includeCallerData>
</appender>

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger - %msg%n</pattern>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="ASYNC_CONSOLE" />
</root>

</configuration>


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52
Уроки по ИБ, белый хакинг, вирусы, социальная инженерия, безопасность

ИБ Книга
Более 1660 русскоязычных книг по ИБ и Социальной Инженерии можно найти на канале.

no system is safe // cybersec — один из древнейших ресурсов по информационной безопасности в рунете. Книги, курсы, полезные тулсы, уроки по Linux, новости клирнета и даркнета.

Python и 1000 программ уроки по Python. Python мы будем использовать для создания хакерского софта.

Этичный Хакер — один из крупнейших ресурсов по информационной безопасности в СНГ.

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

Весь материал на каналах в общем доступе. Ничего лишнего.
Media is too big
VIEW IN TELEGRAM
Разработчик выложил проект ShadowStream, систему отслеживания изменений в базе данных (CDC), построенную на PostgreSQL logical replication.

Цель проекта — ловить любые изменения в реальном времени и передавать их в потоковую инфраструктуру.

Как это работает:

- изменения в базе (INSERT, UPDATE, DELETE) сразу перехватываются через logical replication
- события сериализуются в Protobuf и отправляются в Redis Streams для быстрого доступа
- параллельно те же данные архивируются в Kafka для надежного хранения
- Kafka использует grouped consumer'ов: два обработчика работают параллельно, плюс резервная группа с отдельным offset
- поверх всего в Django Admin добавлена визуализация gRPC-вызовов

Исходники открыты на GitHub

Проект может пригодиться тем, кто работает с потоковой обработкой данных, аналитикой, репликацией или интеграцией микросервисов. 🙂

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥114
Java даёт много вариантов по части синтаксиса, но функциональные интерфейсы — одна из самых аккуратных и приятных фишек языка ☕️

Сегодня разберём 4 штуки, которые встречаются чаще всего. Если поймёшь их, писать код станет современнее, местами чище

Идея простая 👇

Функциональный интерфейс — это интерфейс с одним абстрактным методом. Благодаря этому его можно реализовать через лямбды.

В Java их много, но вот четыре, которые ты будешь видеть постоянно:

👉 Consumer — делает что-то

Consumer принимает значение и ничего не возвращает.

Отлично подходит для побочных эффектов: логирование, вывод в консоль, сохранение, отправка и так далее.

Consumer<String> consumer = str -> System.out.println(str);
consumer.accept("Hola");


Проще говоря:
"получи это и сделай с этим что-то".

👉 Supplier — дай что-то

Supplier ничего не принимает и возвращает значение.

Часто используется для получения конфигураций, генерации ID, ленивого создания объектов и прочего.

Supplier<Double> supplier = () -> Math.random();
supplier.get();


То есть:
"выдай нужную штуку, когда я попрошу".

👉 Function<T, R> — преобразуй что-то

Принимает значение типа T и возвращает значение типа R.

На практике эта штука — самая распространённая.

Function<Integer, String> function = number -> "N° " + number;
function.apply(5);


По смыслу:
"получаю T, возвращаю R".

👉Predicate — реши что-то (true/false)

Принимает значение и возвращает boolean.
Часто нужен для фильтрации списков, простых проверок, валидаций, правил.

Predicate<String> predicate = s -> s.length() > 5;
predicate.test("Java");


То есть:
"подходит или не подходит под условие".

Важно:

Эти интерфейсы существуют не ради компактного кода.

Они нужны, чтобы ты думал через операции, а не через классы.

Они идеально заходят в Streams, в коллбеки, в валидации, в композицию логики — везде, где есть простая операция, для которой не нужна отдельная сущность.

Это не замена всему на свете. Речь не про то, чтобы переписать всю систему в функциональном стиле.

Но они реально помогают во множестве сценариев.

Если научишься читать Function, Consumer, Supplier и Predicate, то спокойно разберёшь и напишешь современный Java-код без лишних страданий. И это уже хороший шаг вперёд. 😁

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍153🔥2🤣1
Кандидаты часто путаются, когда спрашивают:
в чем разница между rate limiting и throttling?


На самом деле всё очень просто.

* Rate limiting
Задаёт фиксированный максимум запросов.
Если превысил лимит — лишние запросы просто блокируются.
Пример: 100 запросов в минуту разрешено. 101-й — отклоняется.

* Throttling
Не блокирует. Он замедляет обработку запросов, когда ты начинаешь спамить.
Пример: после 100 запросов каждый следующий обрабатывается с задержкой, но всё равно проходит.

Запомнить легко:

Rate limiting — стоп сверхлимита.
Throttling — замедление сверхлимита.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4