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

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Совет по Spring Boot

RestTestClient для тестирования API

RestTestClient это единый инструмент для тестирования REST API, который можно использовать вместо WebTestClient, TestRestTemplate (удалён) или MockMVC.

1. Определи объект RestTestClient в тесте
2. Привяжи его к конкретному компоненту. Это может быть controller, MockMVC, server или Spring context
3. Потом используй RestTestClient в тесте

@SpringBootTest
public class PersonControllerWithHeadersTests {

private WebApplicationContext context;
private RestTestClient restTestClient;

@BeforeEach
public void setup(WebApplicationContext context) {
restTestClient = RestTestClient
.bindToApplicationContext(context)
.build();
}

@Test
void addPersonTest() {
restTestClient.post()
.uri("/persons")
.body(Instancio.create(Person.class))
.exchange()
.expectStatus().is2xxSuccessful()
.expectBody(Person.class)
.value(p -> assertNotNull(p.getId()));
}
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3
Java-подсказка: начиная с Java 11, если нужно повторить строку n раз, можно использовать метод repeat(n) у String.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍3🔥3😁1
Если у тебя начинают получаться сложные вложенные подзапросы, лучше перейти на CTE , чтобы сделать запросы читабельнее.

CTE позволяет вынести часть логики в отдельный блок и использовать результат как временную таблицу. Это помогает структурировать запросы и делать их понятнее.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17
Java-команды часто ищут прорывы не там.

Spring + JVM получает больше профита от Kotlin, чем от попыток перезабрести фреймворк.

Kotlin прокачивает базу.

А именно база решает, движется ли команда быстро или нет

1. Код становится проще.

Меньше шаблонного мусора.
Более безопасные дефолты.
Четче выраженные намерения.
Команда делает те же фичи быстрее и с меньшим количеством багов.

2. Работа с конкурентностью становится чище.

Коррутины стабильнее и удобнее, чем вечная возня с потоками.
Та же JVM. Тот же Spring.
Но асинхронный код наконец становится предсказуемым

3. Миграция с низкими рисками.

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

Так выглядит распространенный сценарий в успешных командах:

Один инженер пробует -> остальные замечают разницу -> adoption летит вверх.

4. Бизнес тоже ощущает разницу.

Меньше дефектов.
Быстрее онбординг.
Выше скорость разработки.
Лучше асинхронное поведение.
И все это без замены стека.

Kotlin не переписывает ваш проект.
Он исправляет мелочи, которые тормозят бекенд-команду годами.

Если ты уже на Spring + JVM, это самый выгодный апгрейд, который можно выкатить хоть завтра 🍌

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣6🔥3🤔2💊2🌭1
Какой Java Map быстрее для 1 млн обращений?

Производительность (в среднем):

HashMap get(): ~0.8 ms (O(1))

TreeMap get(): ~15 ms (O(log n))

HashMap put(): ~1.2 ms

TreeMap put(): ~18 ms


HashMap выигрывает по сырым скоростям примерно в 15–20 раз.

TreeMap жертвует производительностью ради отсортированного порядка ключей.

HashMap использует хеширование с операциями за амортизированное константное время.

TreeMap использует красно-черное дерево, гарантируя O(log n), но за счет скорости.

Используй HashMap, когда важна скорость, и TreeMap, когда нужны отсортированные ключи или диапазонные запросы.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍6🔥3
Быстрый Kafka consumer на виртуальных потоках.

Каждое новое сообщение, которое получает listener, обрабатывается в отдельном виртуальном потоке.

Естественно, при таком подходе теряется порядок сообщений внутри одного partition.

Выбирай, что для тебя важнее.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2
Подсказка по 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
1👍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
👍104😁1
Как Яндекс кошмарит вас на собеседованиях ❤️

Успешно пройти секцию по профильным хардам, но смачно опозориться на логической задаче с часами? В этом вся суть интервью в Яндексе 😆

Автор этой истории побывал на собесе в Яндексе и рассказал всю правду о клоунаде, которая там происходила. Готовьте попкорн!

Вита Заебумба | Путь корпората — топовый канал про IT, сферу найма, трешовые собесы и работу в корпорациях. Просто кладезь кулстори не только от автора, но и от подписчиков

Атмосфера 12/10: авторская подача, юмор и топ комменты от аудитории, состоящей из бизнес/системных, дата аналитиков, разрабов, продактов и других айтишников

🔥Истории, которые уже успели стать бестселлером:

🟡Поймала дешёвок за руку на собесе в Ягодках 🛍
🟡Мое мнение, что будет с рынком найма в 2026 году + полезные материалы
🟡Эффект Писюхи, или как я столкнулась с эйджизмом в найме
🟡Aston, разлогинься, или как продать свою жопу в рабство
🟡Если твой руководитель ведет себя так, беги оттуда

Но тут не только про веселье и треш. Подписывайтесь, если хотите:

🟢Узнать лайфхаки продающего резюме
🟢Быть в курсе актуальной ситуации на рынке
🟢Обойти 90% кандидатов
🟢Не продешевить на собесе и выгодно себя продать

➡️ @vitazaebymba
Please open Telegram to view this post
VIEW IN TELEGRAM
😁21🌚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
8👍3