Telegram Web Link
📖 Фундаментальное руководство по пакетам в Java

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

Java-пакеты реализуют так называемое пространство имен (namespace), позволяющее использовать в проекте файлы с одинаковыми именами. Такой подход существует с давних времен во многих языках.

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

И наконец, с помощью пакетов можно ограничивать доступ (из других пакетов) как целиком к классам, так и к их отдельным элементам.

Об этом и многом другом и пойдет речь в данной статье.

1. Что такое пакет

2. Примеры пакетов

3. Назначение пакетов

4. Правила создания пакетов

5. Импорт классов

6. Компиляция и запуск

7. Возможные ошибки и их решение

📌 Читать

@javatg
👍134🔥3👎1
🍀 NetMock: простой подход к тестированию HTTP-запросов в Java, Android и Kotlin Multiplatform

NetMock — это мощная и удобная библиотека, которая упрощает имитацию HTTP-запросов и ответов.

Улучшение стратегии тестирования HTTP-кода

Подход предполагает изолирование HTTP-кода в отдельные компоненты, что позволяет проводить независимое тестирование остальной системы.
Несмотря на то, что данный подход упрощает репозитории и тестовые классы, он часто пренебрегает тестированием самого HTTP-кода из-за сопутствующих сложностей.
В результате возникает потребность проверять важнейшую логику, связанную с HTTP-запросами и парсингом JSON.

Данная проблема прослеживается в проектах, задействующих Retrofit.

Эта библиотека абстрагирует HTTP-логику посредством интерфейсов. Рассмотрим следующий фрагмент кода:
interface GitHubService {
@GET("users/{user}/repos")
suspend fun listRepos(@Path("user") user: String): List<RepoDto>
}

class GitHubRepositoryImpl(
private val githubService: GitHubService,
private val repoMapper: RepoMapper
): GitHubRepository {
override suspend fun listRepos(user: String): List<Repo> {
val repoDtos = githubService.listRepos(user)
return repoMapper.map(repoDtos)
}
}


Хотя этот подход упрощает репозитории и тестовые классы, он часто пренебрегает важными тестами для HTTP-логики. Кроме того, существует вероятность создания ненужных компонентов исключительно для упрощения модульного тестирования репозиториев.

Цель модульного тестирования — предотвращать и выявлять ошибки разработчиков, тем самым гарантируя правильную работу кода. Без надлежащих тестов даже простые ошибки, такие как изменение пути с users/{user}/repos на user/{user}/repos или переименование поля в RepoDto, могут остаться незамеченными, что неприемлемо в профессиональном проекте.

Я вовсе не критикую Retrofit. Наоборот, считаю ее отличной и удобочитаемой библиотекой.

Более того, признаю целесообразность изолирования HTTP-кода в отдельные компоненты ради улучшения структуры и удобства сопровождения.

Я просто указываю на недостатки стратегии тестирования, которую наблюдал во многих проектах. Она вынуждает больше внимания уделять комплексному тестированию HTTP-кода, вследствие чего потенциальные проблемы остаются незамеченными. Акцентируя данную проблему, призываю разработчиков с особой ответственностью подходить к тестированию HTTP-логики, тем самым обеспечивая общее качество и надежность проектов.

Имитация запросов и ответов с помощью NetMock
@Test
fun `your test`() = runTest {
val user = "some_user"
netMock.addMock(
request = {
method = Method.Get
requestUrl = "https://api.github.com/users/$user/repos"
},
response = {
code = 200
body = readFromResources("responses/repo_list.json")
}
)

val result = sut.listRepos(user)

//...
}


Для имитации запросов и ответов применяется простой API, предоставляемый NetMock.

Добавляя mock-объект в очередь ожидаемых запросов и ответов, вы можете перехватывать и контролировать поведение HTTP-взаимодействий во время тестирования.

Создание экземпляра NetMock

Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83🔥3
🎉🎉🎉 Вышел Kotlin 1.9.10

Исправлено много багов, среди них, самые интересные:

В компиляторе:
KT-60659 unresolved reference: addFirst в JDK 21
KT-60986 Статические кеши в рантайме на Linux
KT-60231 NoClassDefFoundError: $$$$$NON_LOCAL_RETURN$$$$$ после обновы до 1.9.0

Gradle:
KT-61147 Компилятор 1.9.0 и Gson
KT-60543 NoClassDefFoundError для com/gradle/scan/plugin/BuildScanExtension

Native:
KT-60230 "unknown options: -ios_simulator_version_min -sdk_version" на Xcode 15 beta 3
KT-60758 'iOS-simulator' в dylib сборке для 'iOS' в Xcode 15 beta 4

https://fossies.org/linux/misc/kotlin-1.9.10.tar.gz/

@javatg
👍102🔥2👎1🤩1
Все что вам нужно знать о таймаутах

Зачем устанавливать таймауты

Давайте для начала ответим на простой вопрос: "Зачем устанавливать таймауты?". Успешный ответ сервиса, даже если он занимает много времени, лучше, чем ошибка закрытия соединения по таймауту.
▪️Хм... не всегда, давайте разбираться.

Прежде всего если сервис не отвечает или отвечает слишком медленно, никто не будет ждать. Вместо того чтобы испытывать терпение ваших пользователей, следуйте принципу fail-fast. Позвольте вашим клиентам повторить запрос или обработать ошибку на их стороне. Когда возможно, возвращайте fallback значение.

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

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

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

Но для продакшен сервисов - это недопустимо. Это может быть даже опасным. Например, в нативном java HttClient connection/request таймауты отключены, я не думаю что это в рамках вашего SLA :)

📌 Продолжение

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍2🔥1
🖥 Android Interview Questions

Очень полезная шпаргалка для собеседования по Android - Вопросы для собеседования по Android

Github

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83🔥1
🔋Основы реактивного программирования

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

Основное назначение Reactor — предоставление набора инструментов и абстракций для создания реактивных приложений. Reactor предлагает набор основных компонентов, таких как Flux и Mono, которые представляют собой потоки данных и событий. Эти компоненты могут быть объединены и преобразованы с помощью набора операторов, таких как map, filter и reduce, для создания сложных потоков данных.

Сравнение Mono и Flux
Как уже говорилось, реактивное программирование работает по модели “издатель-подписчик”. И Mono, и Flux предоставляют абстракцию для публикации событий.

Разница между ними заключается в том, что Mono может публиковать только одно событие за раз, а Flux — несколько событий за раз. Поэтому когда нужно публиковать только одно событие, выбирают Mono, а когда нужно публиковать несколько событий — Flux.

Теперь приведу небольшой пример, поясняющий каждую упоминаемую ранее концепцию.

Демо
Все начинается с того, что издатель выдает событие для потребителя.

Как и java-потоки, Flux и Mono придерживаются ленивого выполнения, т.е. значение выражения не обрабатывается до тех пор, пока в нем нет необходимости.

Начнем с создания простого Flux.
Flux<Integer> flux = Flux.just(1, 2, 3, 4, 5);

Метод “just” позволяет создать Flux, если есть доступное значение. Это самый простой способ создания Flux. Несмотря на то что я привожу пример с Flux, шаги остаются такими же и для Mono. В Mono также используется метод “just” с той разницей, что Mono применяется только для одного элемента. Поэтому если задать несколько значений, то получим ошибку.
Flux<String> mappedFlux = flux.map(i -> "Number: " + i)
The above flux gets converted to
"Number: 1", "Number: 2", "Number: 3", "Number: 4", "Number: 5"


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

1. Map: преобразует каждый элемент, выдаваемый потоком данных, применяя к нему функцию.
2. Filter: фильтрует элементы, выдаваемые потоком данных, на основе предикатной функции.
3. Reduce: агрегирует элементы, выдаваемые потоком данных, в одно значение с помощью функции-аккумулятора.
4. Merge: объединяет несколько потоков данных в один.
5. Concat: конкатенирует нескольких потоков данных в один в определенном порядке.
6. FlatMap: преобразует каждый элемент, выдаваемый потоком данных, в другой поток данных, а затем сводит полученные потоки в один.
7. Zip: объединяет элементы, выдаваемые несколькими потоками данных, в один элемент с помощью функции-комбинатора.

Применим еще несколько операторов для пояснения их работы.
Flux<String> filteredFlux = mappedFlux.filter(s -> !s.endsWith("2") && !s.endsWith("4"));

Flux преобразуется в:
"Number: 1", "Number: 3", "Number: 5"

Теперь сведем Flux к одной строке.
Mono<String> reducedMono = filteredFlux.reduce("", (a, b) -> a+ ", " + b);

Flux преобразуется в:
"Number: 1, Number: 3, Number: 5"

Эти шаги представляют собой обработку события. Мы начали с исходного события Flux, состоящего из списка чисел, и использовали операторы для обработки событий.

*️⃣Следует отметить, что я добавил преобразованный вывод для пояснения, а на самом деле никаких вычислений не происходит. Как уже говорилось, Flux следует модели ленивого исполнения. Пока мы не подпишемся на поток событий, никаких вычислений не происходит. А когда подписываемся, получаем возможность контролировать то, что нужно сделать с полученным событием.

Чтобы упростить задачу и показать, как работает подписчик, просто выведу Flux.

📌Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍165🔥2
🔥 Дайджест полезных материалов из мира : Java за неделю

Почитать:
Все о нестатических блоках инициализации в Java
Jackson ObjectMapper Streaming API без возни
Релиз Jmix 2.0 — новой версии платформы для быстрой разработки бизнес-приложений на Java
Компилирование «железного» бинарника Java-программы Google Closure Stylesheets с GraalVM
Нагрузочное тестирование API без использования UI
Удобная подсветка покрытия кода тестами в Merge Request GitLab
Генерируем простой web интерфейс для просмотра таблиц PostgreSQL
Реквием по «Расскажи, как работает HashMap?»
Разбираемся в «базовых» алгоритмах для проекта
Почему WebAssembly плохо годится для Java
Why Java Is an Object-Oriented Programming Language?
Leet Code — 2744. Find Maximum Number of String Pairs
Data Science with Python and Java: A Dynamic Duo for Modern Analytics
Curso de Programação para Iniciantes Intensivo e Gratuito
Leet Code — 709. To Lower Case
What Happens When We Run a .java Code?
Captura de dados antes de Captura de linha: "erro" e solução, em Java.
Javascript ➡️ Java: Strings
Testing Native Queries with Functions in Spring Boot with JPA and H2


Посмотреть:
🌐 Code Reflection ( 41:46)
🌐 Upgrading from Java 17 to 21 #RoadTo21 ( 24:41)
🌐 Continuations - Under the Covers ( 34:07)
🌐 Java 21 new feature: Virtual Threads #RoadTo21 ( 33:35)
🌐 Difference between and intermediate and a terminal operation? - Cracking the Java Coding Interview ( 01:00)
🌐 What list can you pass to a method that takes a List of Number? - Cracking the Java Coding Interview ( 00:54)
🌐 Generational ZGC and Beyond ( 33:34)
🌐 Project Lilliput - Compressed Object Headers ( 51:26)
🌐 Fast JVM Startup with Checkpoint & Restore ( 47:28)
🌐 Java 21 JVM & GC Improvements #RoadTo21 ( 12:09)

Хорошего дня!

@javatg
👍13🔥41
🚀 Как интегрировать Kafka со Spring Boot

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

Для создания эффективных, несвязанных и отзывчивых приложений разработчики могут гармонично реализовать возможности Kafka в сочетании с простотой и производительностью фреймворка Spring Boot.

Рассмотрим пошаговую интеграцию Kafka и Spring Boot.

Шаг 1. Настройте Kafka
Установите Kafka и запустите кластер Kafka. Инструкции по установке есть в официальной документации Kafka.

Шаг 2. Создайте проект Spring Boot
Настройте новый проект Spring Boot, используя предпочитаемую IDE или Spring Initializr. Включите необходимые зависимости:
spring-kafka предоставляет основную функциональность для интеграции Kafka в Spring;
spring-boot-starter-web включает веб-функции в Spring Boot.

Шаг 3. Настройте свойства Kafka
В файле проекта Spring Boot application.properties настройте необходимые свойства Kafka, такие как серверы начальной загрузки и названия разделов, а также любые дополнительные. Например:

spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=my-group
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.template.default-topic=my-topic


Шаг 4. Создайте Kafka Producer
Внедрите Kafka producer для отправки сообщений в разделы (topic) Kafka. Создать простой producer позволяет KafkaTemplate, предоставленный Spring Kafka. Например:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

@Service
public class KafkaProducerService {
private final KafkaTemplate<String, String> kafkaTemplate;

@Autowired
public KafkaProducerService(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}

public void sendMessage(String message) {
kafkaTemplate.send("my-topic", message);
}
}


📌Читать

@javatg
10👍6🔥3😱1
📌Как узнать кто вызывал функцию? StackTrace стек вызовов в Kotlin & Java

В видео рассказывается что такое - «Стек вызовов функций». Но как можно узнать конкретно какой он был и что можно сделать с этой информацией? Узнаете в ролике.

@javatg
👍13🔥21
🖥 Новости Java

Spring Modulith 1.0 GA Released. Новый -релиз получила Spring Modulith — часть экосистемы Spring, призванная упростить построение модульных монолитов.

Announcing Testcontainers Desktop Free Application — свежий анонс утилиты, удобной для работы с тест-контейнерами. Из интересного — быстрое переключение между docker/colima/podman, возможность запуска контейнеров на фиксированных портах и их фриз на время дебага.

Выпущен Jmix 2.0 — новая версия платформы для быстрой разработки бизнес-приложений на Java. В статье — подробности о том, для чего нужен этот инструмент и как он позволяет сокращать время разработки бизнес-приложения.

OpenAI выложила на Github OpenCopilot. OpenCopilot — это ИИ-помощник, способный интегрироваться в продукт. Он готов к встраиванию через базовые API и может вызывать эти API по необходимости. Модель OpenCopilot основана на обширной лингвистической базе и способна определить, требует ли запрос пользователя выполнения вызова к какой-либо конечной точке API.

Дмитрий Иванов, Андрей Кулешов — Пирамида потребностей Маслоу для Java/Kotlin-разработчика. Виде — это полноценная методичка, посвященная тому, как начать и развить свой open-source-проект. От стадии кодинга и до построения комьюнити — каждый шаг расписан детально, с приведением полезных инструментов и практик.

JDK 21 G1/Parallel/Serial GC changes — статья о том, как изменятся сборщики мусора в JDK 21, и о планах их развития. Основные изменения коснутся G1 GС:

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍122🔥2
🔥 Дайджест полезных материалов из мира : Java за неделю

Почитать:
Всё, что вы хотели знать о Java, но не доходили руки спросить: что будет на Joker 2023
Как добавить кастомный аутентификатор в KeyCloak и подружить его со сторонней системой
Java Digest #4
Высокие технологии или дешевые фокусы с двойным дном
Байки джависта
Создание приложения для распознавания текста с изображений и аудиофайлов
Параллельность в Java на практике
Динамическое создание слушателей в Kafka
Аудит пользователей Spring Data JPA
Ускоряем java-рефлексию в 2023
🔐 Unlock the Power of Data Security with Our Online Encryption and Decryption Tool! 🔐
Securing the Path: A Comprehensive Guide to Spring Security Migration
Elevate Your Security Game: Spring Security’s Lambda DSL Unleashed
Parâmetros em API RESTful: Tipos e Exemplos
Kafka in a Nutshell 🌰: Events, Topics, and APIs made simple
Testes Mutantes com Pitest
Aumente a Qualidade do seu Código Java: Um Guia para Utilizar o JaCoCo em sua API REST
Simplifying Java Multithreading (Runnable interface) with a Construction Analogy
Application and Webserver Logging in Spring Boot 3.1
Exercising DSA with Java

Посмотреть:
🌐 Java 21 JVM & GC Improvements #RoadTo21 ( 12:09)
🌐 Value Objects in Valhalla ( 51:42)
🌐 Learn All You Need To Know For Your Java 17-21 Update #Java #Java21 #RoadTo21 ( 00:46)
🌐 Java 21 Tool Enhancements: Better Across the Board #RoadTo21 ( 17:39)
🌐 What is a deadlock? - Cracking the Java Coding Interview ( 00:56)
🌐 Project Leyden - Capturing Lightning in a Bottle ( 47:57)
🌐 Creating an instance of a Class using the Reflection API? - Cracking the Java Coding Interview ( 00:53)
🌐 Everything You Never Wanted to Know about Java Class Initialization ( 39:01)

Хорошего дня!

@javatg
👍12🔥41😱1
🖥Перестаём бояться генерировать байт-код

Многие, возможно, думают, что работа с байт-кодом Java (будь то чтение или, тем более, генерация) — это какая-то особенная магия, доступная только продвинутым разработчикам с особенно крутым опытом. На самом деле, я считаю такую точку зрения ошибочной.

JVM устроена гораздо проще, чем CPU; она оперирует такими высокоуровневыми понятиями как классы, интерфейсы, методы, а не просто лопатит байты в памяти. В отличие от CPU, который легко уронить криво сгенерированным машинным кодом, JVM заботливо отверифицирует любой байт-код и в общем не даст выстрелить в ногу.

Но с чего начать погружение в байт-кодную магию? В сети есть некоторое количество туториалов по этому вопросу. Как мне кажется, они либо показывают слишком простые случаи, от которых непонятно, как перейти к чему-то более интересному, либо очень основательные и требуют вникать в теорию, собирать целиком картину в голове по кусочкам. Я хотел бы попробовать внести свой вклад в эту тему — надеюсь, у меня получится показать, как можно побороть первый страх и написать что-то похожее на реалистичный сценарий без особого вникания в теорию на первом этапе.

Весь приведённый код доступен в репозитории.



Задача
Я вдохновился книгой Бьёрна Страуструпа, по которой лет 20 назад изучал C++. В одной из первых глав в качестве задачи для введения в язык предлагается написать калькулятор выражений. Я же предлагаю не вычислять выражения, а генерировать байт-код, который вычисляет выражения.

Итак, формулировка: необходимо написать метод, которые принимает на вход строку с математическими выражениями и выдаёт на выходе экземпляр такого интерфейса:

public interface Expression {
double evaluate(Function<String, Double> inputs);
}

Выражения в списке разделены точкой с запятой (;), метод evaluate возвращает результат вычисления последнего из выражений. Выражения определим так:

Число (например, 2, 42, 3.14) — это выражение.
Идентификатор (например, foo, pi, myVar_1)
— это выражение. Значение по-умолчанию для переменной вычисляется с помощью вызова inputs.apply(id).
Если A и B — выражения, то A + B, A - B, A * B, A / B, -A, (A) — так же выражения
Если A — это идентификатор, и B — это выражение, то A = B — так же выражение
Генерируем класс
Для начала напишем генератор класса, реализующего интерфейс Expression.

Читать дальше
Github

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥43
Легкий способ получать свежие обновлении и следить за трендами в разработке на вашем языке. Находите свой стек и подписывайтесь:

Data Science: www.tg-me.com/data_analysis_ml
Java: www.tg-me.com/java_library
Базы данных: www.tg-me.com/sqlhub
Машинное обучение: www.tg-me.com/ai_machinelearning_big_data
Go: www.tg-me.com/Golang_google
C/C++/ www.tg-me.com/cpluspluc
C#: www.tg-me.com/csharp_ci
Хакинг: www.tg-me.com/linuxkalii
Мобильная разработка: www.tg-me.com/mobdevelop
Docker: www.tg-me.com/+0WdB4uvOwCY0Mjdi
Python: www.tg-me.com/python_job_interview
Rust: www.tg-me.com/rust_code
Javascript: www.tg-me.com/javascriptv
React: www.tg-me.com/react_tg
PHP: www.tg-me.com/phpshka
Android: www.tg-me.com/android_its
Linux: www.tg-me.com/+A8jY79rcyKJlYWY6
Big Data: www.tg-me.com/bigdatai
Devops: www.tg-me.com/devOPSitsec
Тестирование:https://www.tg-me.com/+F9jPLmMFqq1kNTMy
Собеседования: https://www.tg-me.com/machinelearning_interview

💼 Папка с вакансиями: www.tg-me.com/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: www.tg-me.com/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: www.tg-me.com/addlist/eEPya-HF6mkxMGIy
Папка ML: https://www.tg-me.com/addlist/2Ls-snqEeytkMDgy

😆ИТ-Мемы: www.tg-me.com/memes_prog

🇬🇧Английский: www.tg-me.com/english_forprogrammers

ИИ: www.tg-me.com/vistehno

📕Ит-книги бесплатно: https://www.tg-me.com/addlist/BkskQciUW_FhNjEy
3👍1🔥1
🖥 Infinity For Reddit

Крутой проект на Java. Клиент Reddit для Android. В нем нет рекламы, он отличается чистым пользовательским интерфейсом и плавным просмотром веб-страниц

Содержит такие функции, как Lazy Mode (автоматическая прокрутка сообщений), поддержка нескольких учетных записей и ночная тема.

Github
Docs

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍122🔥1
🖥 PostgreSQL JDBC Driver

Драйвер PostgreSQL JDBC Driver (сокращенно PgJDBC) позволяет Java-программам подключаться к базе данных PostgreSQL, используя стандартный, независимый от базы данных Java-код. Это JDBC-драйвер с открытым исходным кодом, написанный на языке Pure Java (Type 4) и взаимодействующий в сетевом протоколе PostgreSQL.

Github
Docs

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍133🔥2🥰1
🎮 Как уменьшить объем шаблонного кода в тестах Kotlin

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

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

Один из способов это сделать — избавиться от шаблонного кода, перегружающего тесты. В статье мы займемся решением этой задачи.

Сценарий использования
Допустим, у нас есть приложение, которое отправляет какие-либо данные принимающему API. Отправляем следующее:
data class Stuff(val name: String, val type: String)

Сервис перенаправляет запрос другому классу для фактической отправки. Код выглядит так:
import okhttp3.OkHttpClient

class StuffService() {
private val client = OkHttpClient()
.newBuilder()
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Content-Type", "application/json")
.build()
chain.proceed(request)
}.build()

private val stuffLink = StuffLink(client, "http://some.where")

fun sendStuff(stuff: Stuff) = stuffLink.sendStuff(stuff)
}


Клиент (назовем его ссылкой, тем самым исключая множественные трактовки этого понятия) выполняет фактическую отправку, создавая запрос и отправляя его посредством заданного OkHttpClient и URL. Рассмотрим код:

import com.fasterxml.jackson.databind.ObjectMapper
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response

class StuffLink(private val client: OkHttpClient, private val url: String) {
private val objectMapper = ObjectMapper()

fun sendStuff(stuff: Stuff): Response {
val request = Request.Builder()
.url(url)
.post(
objectMapper.writeValueAsString(stuff)
.toRequestBody("application/json".toMediaType()),
).build()

return client.newCall(request).execute()
}
}


Вариант теста 1

🔎 Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112🔥2
🖥 ​Что такое object в Kotlin

Известно, что в Kotlin объекты создаются с помощью конструкторов. Но это не единственный способ!

В этой статье вы узнаете о двух альтернативах: object expressions и object declarations.

📌Читать

#android

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥31
🖥 HertzBeat

HertzBeat - это система мониторинга с открытым исходным кодом, работающая в режиме реального времени, с пользовательским мониторингом, высокопроизводительным кластером и возможностью работы без агентов.

Github

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥21
🔥 Дайджест полезных материалов из мира : Java за неделю

Почитать:
Модельно-Ориентированная Java, или Навстречу Дизайну ПО
Искусство ETL. Пишем собственный движок SQL на Spark [часть 4 из 5]
Как внедрить Prototype в Singleton в Spring с помощью параметра ProxyMode
Искусство ETL. Пишем собственный движок SQL на Spark [часть 3 из 5]
Делаем свою простейшую систему сборки для Java
Микросмартфон за 100 рублей: Покупаем смартфон 11-летней давности и… пишем под него приложения
Искусство ETL. Пишем собственный движок SQL на Spark [часть 2 из 5]
Ad-hoc мониторинг: сбор, хранение и визуализация данных
Искусство ETL. Пишем собственный движок SQL на Spark [часть 1 из 5]
Разница между Data Race и Race Condition
Solving "All Nodes Distance K in Binary Tree" Leet code Question
Mutex & Race Conditions in Java Multi-Threading made so simple with real-life analogies
Hash! A magical datastructure
"I definitely didn't spend 3 hours on this question..😢#BinaryTreeAdventures" Solving Binary Tree Right Side View Leet code
Leet Code 75–2215. Find the Difference of Two Arrays
Multi-Threading in JAVA using Callables
convertTxtToHtml - A new command-line tool can process .txt files into .html
Java Interfaces Default Methods
Iniciando estudos em Kotlin
Common Mistakes of Junior Java Developers When Working with Hibernate

Посмотреть:
🌐 Java 21 API New Features #RoadTo21 ( 16:48)
🌐 #Java 21 bug fixes you need to know about ( 00:54)
🌐 What is the difference between a Collection and a List? - Cracking the Java Coding Interview ( 00:58)
🌐 Difference between toList() and Collectors.toList()? - Cracking the Java Coding Interview ( 01:00)
🌐 Java 21 Security Updates #RoadTo21 ( 27:04)
🌐 JVM Language Summit 2023 Keynote #JVMLS ( 21:15)
🌐 Java 21 Launch Event ( 00:00)

Хорошего дня!

@javatg
👍12🔥31
🏛Событийно-ориентированная архитектура

Событийно-ориентированная архитектура  — это шаблон проектирования с применением событий для запуска и передачи изменений между компонентами системы. Службы здесь взаимодействуют, обмениваясь событиями, то есть сообщениями о наступлении события или изменении состояния.

Преимущества событийно-ориентированной архитектуры
▪️Слабая связанность: службы разделены, чем обеспечивается независимость и модульность.
▪️Масштабируемость: службы масштабируются независимо, исходя из потребности в событиях, чем повышается общая производительность системы.
▪️Асинхронная обработка: событиями обеспечиваются асинхронное взаимодействие, уменьшение задержки и времени отклика.
▪️Порождение событий: поддерживается естественным образом, ведь состояние системы определяется последовательностью прошлых событий.
▪️Гибкость: добавление новых служб или изменение имеющихся не сказывается на всей системе.

Kafka

Apache Kafka  — это распределенная потоковая платформа для создания конвейеров данных в реальном времени и потоковых приложений, потоковой передачи событий с высокой пропускной способностью, отказоустойчивостью и масштабируемостью.

В основе Kafka — модель обмена сообщениями «публикация-подписка», где в темах отправителями публикуются сообщения-события, а получатели — для получения и обработки сообщений — подписываются на эти темы. События хранятся в Kafka неизменяемо и только с возможностью добавления. Данные обрабатываются как в реальном времени, так и ретроспективе.

Ключевые понятия Kafka
Темы  — каналы для публикации событий и подписки на них.
Отправители  — службы, которыми события создаются и отправляются в темы Kafka.
Получатели  — службы, которые подписываются на темы, ими обрабатываются входящие события.
Разделы: каждая тема разбивается на разделы, чем обеспечиваются параллельная обработка и распределение нагрузки.

Роль Kafka в событийно-ориентированной архитектуре

📌 Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍85🔥3
2025/09/30 07:01:53
Back to Top
HTML Embed Code: