Telegram Web Link
🖥 Поднимаем стенд Spring микросервисов в Kubernetes

В статье будет описан процесс поднятия домашнего стенда для экспериментов c k8s, c базовым CI/CD для микросервисов Spring.

Код статьи c инструкцией установки доступен в репозиториях:

https://github.com/alexandr-leonov/eda-configuration
https://github.com/alexandr-leonov/eda-order-service

➡️ Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍53
🖥 Изучаем J-Юнит в Java: тестирование и возможные его аннотации

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

У Java него есть средства, которые значительно упрощают процесс работы с создаваемыми утилитами. Одна из них носит название JUnit. Ей будет уделено основное внимание в данной статье.

Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥42🤔1
🖥 Список полезных ресурсов для Java-разработчиков 2023.

В данной статье я хочу поделиться различными полезными библиотеками и инструментами для повышения производительности Java-приложений.

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

Читать
Зеркало

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥91👍1👏1
🖥 RoadMap для Java-разработчика 2023

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

Читать
Зеркало

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍132🔥1😱1
Java Memory Management: A comprehensive guide to garbage collection and JVM tuning (2022)
Автор
: Maaike van Putten

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

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

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

📚 Книга

@javatg
👍14🔥31
🖥 Простое ускорение Java с помощью Quarkus и JHipster

Quarkus — "родной" для Kubernetes Java-платформе для создания высокопроизводительных веб, бессерверных (serverless) и нативных приложений (оптимизированных для используемых микропроцессоров).

В ней используются предварительная компиляция AOT и агрессивная оптимизация, например сканирование путей к классам, перезагрузка конфигурации и предварительная конфигурация самозагрузки приложения в процессе сборки. Результатом становится впечатляющая скорость загрузки. Другими словами, приложения, созданные с Quarkus, запускаются не просто быстро, а очень быстро!

Так же как для платформ Spring и Micronaut, в Quarkus можно использовать преимущество GraalVM для преобразования JVM-приложений в нативные исполняемые файлы, что ещё больше повышает их быстродействие.

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

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍161🔥1
🖥 В чем разница между HashMap и IdentityHashMap? Для чего нужна IdentityHashMap?

IdentityHashMap - это структура данных, так же реализующая интерфейс Map и использующая при сравнении ключей (значений) сравнение ссылок, а не вызов метода` ˚Другими словами, в IdentityHashMap два ключа k1 и k2 будут считаться равными, если они указывают на один объект, т.е. выполняется условие k1 == k2.

IdentityHashMap не использует метод hashCode(), вместо которого применяется метод System.identityHashCode(), по этой причине IdentityHashMap по сравнению с HashMap имеет более высокую производительность, особенно если последний хранит объекты с дорогостоящими методами equals() и hashCode().

Одним из основных требований к использованию HashMap является неизменяемость ключа, а, т.к. IdentityHashMap не использует методы equals() и hashCode(), то это правило на него не распространяется.

IdentityHashMap может применяться для реализации сериализации/клонирования. При выполнении подобных алгоритмов программе необходимо обслуживать хэш-таблицу со всеми ссылками на объекты, которые уже были обработаны. Такая структура не должна рассматривать уникальные объекты как равные, даже если метод equals() возвращает true.

Пример кода:

import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;

public class Q2 {

public static void main(String[] args) {
Q2 q = new Q2();
q.testHashMapAndIdentityHashMap();
}

private void testHashMapAndIdentityHashMap() {
CreditCard visa = new CreditCard("VISA", "04/12/2019");

Map<CreditCard, String> cardToExpiry = new HashMap<>();
Map<CreditCard, String> cardToExpiryIdenity = new IdentityHashMap<>();

System.out.println("adding to HM");
// inserting objects to HashMap
cardToExpiry.put(visa, visa.getExpiryDate());

// inserting objects to IdentityHashMap
cardToExpiryIdenity.put(visa, visa.getExpiryDate());
System.out.println("adding to IHM");

System.out.println("before modifying keys");
String result = cardToExpiry.get(visa) != null ? "Yes" : "No";
System.out.println("Does VISA card exists in HashMap? " + result);

result = cardToExpiryIdenity.get(visa) != null ? "Yes" : "No";
System.out.println("Does VISA card exists in IdenityHashMap? " + result);

// modifying value object
visa.setExpiryDate("02/11/2030");

System.out.println("after modifying keys");
result = cardToExpiry.get(visa) != null ? "Yes" : "No";
System.out.println("Does VISA card exists in HashMap? " + result);

result = cardToExpiryIdenity.get(visa) != null ? "Yes" : "No";
System.out.println("Does VISA card exists in IdenityHashMap? " + result);

System.out.println("cardToExpiry.containsKey");
System.out.println(cardToExpiry.containsKey(visa));
System.out.println("cardToExpiryIdenity.containsKey");
System.out.println(cardToExpiryIdenity.containsKey(visa));
}

}

class CreditCard {
private String issuer;
private String expiryDate;

public CreditCard(String issuer, String expiryDate) {
this.issuer = issuer;
this.expiryDate = expiryDate;
}

public String getIssuer() {
return issuer;
}

public String getExpiryDate() {
return expiryDate;
}

public void setExpiryDate(String expiry) {
this.expiryDate = expiry;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((expiryDate == null) ? 0 : expiryDate.hashCode());
result = prime * result + ((issuer == null) ? 0 : issuer.hashCode());
System.out.println("hashCode = " + result);
return result;
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍62
@Override
public boolean equals(Object obj) {
System.out.println("equals !!! ");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CreditCard other = (CreditCard) obj;
if (expiryDate == null) {
if (other.expiryDate != null)
return false;
} else if (!expiryDate.equals(other.expiryDate))
return false;
if (issuer == null) {
if (other.issuer != null)
return false;
} else if (!issuer.equals(other.issuer))
return false;
return true;
}

}
Результат выполнения кода:

adding to HM
hashCode = 1285631513
adding to IHM
before modifying keys
hashCode = 1285631513
Does VISA card exists in HashMap? Yes
Does VISA card exists in IdenityHashMap? Yes
after modifying keys
hashCode = 791156485
Does VISA card exists in HashMap? No
Does VISA card exists in IdenityHashMap? Yes
cardToExpiry.containsKey
hashCode = 791156485
false
cardToExpiryIdenity.containsKey
true
👍16🔥41
🔥41👍1
👍16😢12🔥4👎2🥰1🎉1
🖥 Сравнение производительности сжатия данных MySQL на Java 2023

Каков лучший способ хранения двоичных данных в MySQL? Это вопрос, на который есть несколько ответов, в зависимости от ваших целей. Например, если вам нужно оптимизировать размер хранилища, вам, вероятно, потребуется использовать какой-либо алгоритм сжатия, который эффективно сжимает ваши данные. В моём случае мне действительно нужна высокая производительность, то есть максимально быстрое время отклика для извлечения большого двоичного объекта из MySQL.

Давайте отложим в сторону вопрос о том, подходит ли MySQL для хранения двоичных данных. Вопрос здесь будет заключаться в том, как хранить двоичные данные, чтобы считывание из БД происходило как можно быстрее?

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

➡️ Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51🔥1
Какой результат выведет следующая программа?
👍10🔥31
Какой результат выведет следующая программа?
Anonymous Quiz
39%
Hello world!
32%
Ошибку при выполнении
30%
Ошибку компиляции
👍22👎8🔥21
🖥 Как удалить определенные элементы коллекции с учетом сдвига?

Наиболее простой/лаконичный современный (Java 8+) способ удаления элементов из коллекции -- использовать метод Collection::removeIf, в который следует передать функцию-предикат для определения удаляемых элементов. Также для проверки на чётность можно проверять младший бит на равенство 0:

List<Integer> data = new ArrayList<>(Arrays.asList(2,3,4,6,8,10,22,-2,-5,0));
data.removeIf(n -> (n & 1) == 0); // [3, -5]


Упомянутый метод использует под капотом итератор и его метод Iterator::remove, который как раз рекомендуется для безопасного удаления элементов из коллекции при прохождении по ней, так как позволяет избежать излишних сложностей с индексной арифметикой и проблем с ConcurrentModificationException со времён Java 1.2 и появления Collection Framework.

List<Integer> data = new ArrayList<>(Arrays.asList(2,3,4,6,8,10,22,-2,-5,0));
for (Iterator<Integer> it = data.iterator(); it.hasNext();) {
if (0 == (it.next() & 1)) {
it.remove();
}
}

Однако если стоит задача реализовать удаление именно с использованием индексов, можно удалять элементы с конца, согласно совета в комментариях:

for (int i = data.size(); i-- > 0;) {
if (data.get(i) % 2 == 0) {
data.remove(i);
}
}


Если же и такой вариант -- недопустимая хитрость, и нужен классический for цикл по индексам именно с начала списка, то коррекцию индексов и размера списка можно выполнить так:

for (int i = 0, n = data.size(); i < n; i++) {
if (data.get(i) % 2 == 0) {
data.remove(i--); // коррекция индекса при удалении
n--; // коррекция размера списка
}
}
Пишите свое решение в комментариях👇

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102🔥1😢1
🖥 Регулярные выражения Сборник рецептов

Сборник содержит более 100 рецептов, которые помогут научиться эффективно оперировать данными и текстом с применением регулярных выражений.

📚Книга

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍151🔥1
🖥 Реализация структурированной конкурентности в Java и Kotlin

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

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

Читать

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥42
🖥 Напишите программу, в которой создаются два потока, которые выводят на консоль своё имя по очереди.

Решение:

class StepThread extends Thread {

// общий для двух потоков lock
private Object lock;

public StepThread(Object object) {
this.lock = object;
}

/**
* Идея такая: выводим имя потока, потом поток засыпает,
* перед этим уведомив другой поток, о том, что теперь его очередь.
*
* После вызова первым потоком lock.notify() второй поток
* не просыпается сразу, а ждёт,
* пока lock не будет освобождён. А когда это происходит, уже вызван
* метод lock.wait(), и первый поток ждёт своей очереди. И так по кругу.
*/
@Override
public void run() {
while (true) {
synchronized (lock) {
try {
System.out.println(getName());
lock.notify();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

public class Main {
public static void main(String[] strings) {
Object lock = new Object();
new StepThread(lock).start();
new StepThread(lock).start();
}
}


Пишите свое решение в комментариях👇

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥31
🖥 Stanford CoreNLP

Бибилиотека предоставляет набор инструментов для анализа естественного языка (NLP), написанных на Java.

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

🖥 Github
📌Документация

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102🔥1
🖥 Напишите свой класс StringBuilder с поддержкой операции undo.

Для этого делегируйте все методы стандартному StringBuilder, а в собственном классе храните список всех операций для выполнения undo(). Это будет реализацией шаблона «Команда».

Решение

/**
* StringBuilder с поддержкой операции undo
* java.lang.StringBuilder — класс с модификатором <b>final</b>,
* поэтому нет наследования, используем делегирование.
*/
class UndoableStringBuilder {

private interface Action{
void undo();
}

private class DeleteAction implements Action{
private int size;

public DeleteAction(int size) {
this.size = size;
}

public void undo(){
stringBuilder.delete(
stringBuilder.length() - size, stringBuilder.length());
}
}

private StringBuilder stringBuilder; // делегат

/**
* операции, обратные к выполненным.
* То есть при вызове append, в стек помещается
* операция "delete". При вызове undo() она
* будет выполнена.
*/
private Stack<Action> actions = new Stack<>();

// конструктор
public UndoableStringBuilder() {
stringBuilder = new StringBuilder();
}

/**
see {@link java.lang.AbstractStringBuilder#reverse()}

После того, как сделан reverse(),
добавляем в стек операций обратную — тоже reverse().

Далее таким же образом.
*/
public UndoableStringBuilder reverse() {
stringBuilder.reverse();

Action action = new Action(){
public void undo() {
stringBuilder.reverse();
}
};

actions.add(action);

return this;
}


public UndoableStringBuilder append(String str) {
stringBuilder.append(str);

Action action = new Action(){
public void undo() {
stringBuilder.delete(
stringBuilder.length() - str.length() -1,
stringBuilder.length());
}
};

actions.add(action);
return this;
}

// ..... остальные перегруженые методы append пишутся аналогично (см. выше)......

public UndoableStringBuilder appendCodePoint(int codePoint) {
int lenghtBefore = stringBuilder.length();
stringBuilder.appendCodePoint(codePoint);
actions.add(new DeleteAction(stringBuilder.length() - lenghtBefore));
return this;
}

public UndoableStringBuilder delete(int start, int end) {
String deleted = stringBuilder.substring(start, end);
stringBuilder.delete(start, end);
actions.add(() -> stringBuilder.insert(start, deleted));
return this;
}

public UndoableStringBuilder deleteCharAt(int index) {
char deleted = stringBuilder.charAt(index);
stringBuilder.deleteCharAt(index);
actions.add(() -> stringBuilder.insert(index, deleted));
return this;
}

public UndoableStringBuilder replace(int start, int end, String str) {
String deleted = stringBuilder.substring(start, end);
stringBuilder.replace(start, end, str);
actions.add(() -> stringBuilder.replace(start, end, deleted));
return this;
}

public UndoableStringBuilder insert(int index, char[] str, int offset, int len) {
stringBuilder.insert(index, str, offset, len);
actions.add(() -> stringBuilder.delete(index, len));
return this;
}

public UndoableStringBuilder insert(int offset, String str) {
stringBuilder.insert(offset, str);
actions.add(() -> stringBuilder.delete(offset, str.length()));
return this;
}

// ..... остальные перегруженные методы insert пишутся аналогично (см. выше)......

public void undo(){
if(!actions.isEmpty()){
actions.pop().undo();
}
}

public String toString() {
return stringBuilder.toString();
}
}

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥32👏2
🖥 ChatGpt для Java программистов.


В этом посте я приведу пример, как можно использовать нейросеть ChatGpt для помощи в работе при написании Java кода.

Я привел свои запросы и ответы с кодом от ChatGPt, оцените качество кода, который пишет бот.

Читать
Как писать код с ChatGpt

@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥2🥰1
2025/10/02 06:18:14
Back to Top
HTML Embed Code: