Модульное и интеграционное тестирование — это два различных типа тестирования программного обеспечения, которые служат для разных целей и проводятся на разных этапах процесса разработки.
Модульное тестирование направлено на проверку отдельных частей кода, обычно функций или методов, изолированно от остальных частей системы. Оно позволяет обнаруживать ошибки на ранней стадии разработки, способствует упрощению поиска и исправления дефектов, снижению затрат на исправление ошибок в дальнейшем. В качестве библиотеки для модульного тестирования может быть использована, например JUnit.
Пример: если есть функция, которая выполняет вычисление площади круга, модульный тест будет проверять правильность работы этой функции с разными входными значениями (радиусами).
Интеграционное тестирование направлено на проверку взаимодействия между различными модулями или компонентами системы, чтобы убедиться, что они правильно работают вместе. Одна из библиотек для интеграционного тестирования - TestNG.
Пример: если есть система, состоящая из двух модулей: один выполняет вход пользователя, а другой — отображение информации о пользователе, интеграционный тест проверит, что после успешного входа отображается правильная информация о пользователе.
#java #test #JUnit #TestNG
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1🔥1
🤔4👍3❤1
Цикл for со счетчиком
for (initialization; condition; update) {
// тело цикла
}
Описание:
initialization: выполняется один раз перед началом цикла. Обычно используется для инициализации счетчика.
condition: проверяется перед каждой итерацией. Если условие истинно, выполняется тело цикла.
update: выполняется после каждой итерации. Обычно используется для изменения счетчика.
int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
System.out.println(i + ": " + numbers[i]);
}
Применение:
Используется, когда известно количество итераций заранее. Часто применяется для работы с массивами или коллекциями, когда нужен индекс.
Цикл for-each
for (type element : collection) {
// тело цикла
}
Описание:
Итерируется по каждому элементу коллекции (например, массива, списка, множества). Обеспечивает удобный способ доступа к каждому элементу без использования индексов.
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
Применение:
Предпочтителен, когда не нужен доступ к индексам элементов.
Цикл while
while (condition) {
// тело цикла
}
Описание:
condition: проверяется перед каждой итерацией. Если условие истинно, выполняется тело цикла.
String code = UUID.randomUUID().toString();
boolean isCodeExists = repo.isCodeExists(code);
while (isCodeExists) {
code = UUID.randomUUID().toString();
isCodeExists = repo.isCodeExists(code);
}
repo.saveCode(code);
Применение:
Используется, когда количество итераций неизвестно заранее и определяется во время выполнения программы. Цикл может не выполниться ни одного раза.
Цикл do-while
do {
// тело цикла
} while (condition);
Описание:
Выполняет тело цикла хотя бы один раз, а затем проверяет условие condition. Если условие истинно, цикл повторяется.
String command;
do {
command = readCommand();
doCommand(command);
} while (!"EXIT".equals(command));
Применение:
Используется, когда тело цикла должно выполниться хотя бы один раз, независимо от условия. Часто применяется для меню или ввода данных, где сначала нужно выполнить действие, а затем проверить условие.
#java #cycles #for #while
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥1
Скрытие полей (Hiding Fields)
Внутри класса поле, имеющее то же имя, что и поле суперкласса, скрывает поле суперкласса, даже если их типы различны.
Внутри подкласса на поле суперкласса нельзя ссылаться по простому имени. Вместо этого доступ к полю должен осуществляться через
Скрывать поля не рекомендуем, поскольку это затрудняет чтение кода.
#java #HidingFields
Внутри класса поле, имеющее то же имя, что и поле суперкласса, скрывает поле суперкласса, даже если их типы различны.
Внутри подкласса на поле суперкласса нельзя ссылаться по простому имени. Вместо этого доступ к полю должен осуществляться через
super. Скрывать поля не рекомендуем, поскольку это затрудняет чтение кода.
#java #HidingFields
❤4👍4🔥1👏1🤔1
Нет. В таком случае компилятор выдаст ошибку:
"Illegal combination of modifiers: ‘abstract’ and ‘static’". Модификатор
abstract говорит, что метод будет реализован в другом классе, а static наоборот указывает, что этот метод будет доступен по имени класса.#java #abstract #static
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Bearer-токен используется для идентификации пользователя и предоставления доступа к его личным данным или другим защищенным ресурсам. Он должен храниться в безопасном месте и не передаваться третьим лицам.
Bearer-токен обеспечивает простой механизм аутентификации и авторизации пользователей без необходимости использования cookies или сессий. Он является частью стандарта аутентификации OAuth 2.0 и широко используется во многих современных веб-приложениях и API.
Пример запроса:
GET /api/resource HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvZSBEb2UiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.SdUMMAsFFk83SHyqGjfQ1pt8v_8t4WZku5Ty3CLMaH4
В данном примере Bearer token представлен в заголовке
Authorization. Вместо значения Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvZSBEb2UiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.SdUMMAsFFk83SHyqGjfQ1pt8v_8t4WZku5Ty3CLMaH4 должен быть ваш актуальный Bearer-токен для доступа к защищенным ресурсам.Обычно, чтобы получить этот токен, нужно сделать запрос на авторизацию, и в ответе приходит этот токен.
Пример запроса:
POST /login HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 52
{
"username": "admin",
"password": "admin"
}
Пример ответа:
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvZSBEb2UiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.SdUMMAsFFk83SHyqGjfQ1pt8v_8t4WZku5Ty3CLMaH4","username":"admin"}
#java #OAuth #Bearer
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20
Ссылки на методы — это способ упрощенного вызова методов или конструктора, который позволяет передавать их как аргументы в методы или сохранять в переменных. Ссылки на методы появились в Java 8 и являются частью улучшенной поддержки функционального программирования в языке.
Есть несколько видов ссылок на методы:
1️⃣ Ссылка на статический метод
Используется для вызова статических методов класса.
Синтаксис:
Пример:
2️⃣ Ссылка на метод экземпляра конкретного объекта
Используется для вызова методов экземпляра объекта.
Синтаксис:
Пример:
3️⃣ Ссылка на метод экземпляра произвольного объекта определенного типа
Синтаксис:
Пример:
Отличие от предыдущего вида в том, что в предыдущем ссылка на метод получается у конкретного объекта, стало быть вызовется метод этого объекта, а в нашем случае при получении ссылки на метод, мы знаем только метод, но объект у которого вызовется этот метод еще не известен, он будет предоставлен при вызове метода. Код выше будет означать "Hello, World!".length()
4️⃣ Ссылка на конструктор
Используется для вызова конструктора.
Синтаксис:
Пример:
#java #MethodReference
Есть несколько видов ссылок на методы:
1️⃣ Ссылка на статический метод
Используется для вызова статических методов класса.
Синтаксис:
ContainingClass::staticMethodName
Пример:
import java.util.function.Function;
public class MethodReferenceExample {
public static void main(String[] args) {
Function<String, Integer> converter = Integer::parseInt;
Integer number = converter.apply("123");
System.out.println(number); // 123
}
}
2️⃣ Ссылка на метод экземпляра конкретного объекта
Используется для вызова методов экземпляра объекта.
Синтаксис:
containingObject::instanceMethodName
Пример:
import java.util.Arrays;
import java.util.List;
public class MethodReferenceExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println);
}
}
3️⃣ Ссылка на метод экземпляра произвольного объекта определенного типа
Синтаксис:
ContainingType::methodName
Пример:
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
Function<String, Integer> stringLength = String::length;
Integer length = stringLength.apply("Hello, World!");
System.out.println(length); // 13
}
}
Отличие от предыдущего вида в том, что в предыдущем ссылка на метод получается у конкретного объекта, стало быть вызовется метод этого объекта, а в нашем случае при получении ссылки на метод, мы знаем только метод, но объект у которого вызовется этот метод еще не известен, он будет предоставлен при вызове метода. Код выше будет означать "Hello, World!".length()
4️⃣ Ссылка на конструктор
Используется для вызова конструктора.
Синтаксис:
ClassName::new
Пример:
import java.util.function.Supplier;
public class MethodReferenceExample {
public static void main(String[] args) {
Supplier<MethodReferenceExample> exampleSupplier = MethodReferenceExample::new;
MethodReferenceExample example = exampleSupplier.get();
System.out.println(example); // MethodReferenceExample@<hashcode>
}
}
#java #MethodReference
👍19✍2🫡1
java.util.function и предназначен для представления функций, принимающих один аргумент и возвращающих результат. Этот интерфейс широко используется в функциональном программировании и особенно полезен при работе с лямбда-выражениями и методами, которые принимают функции в качестве параметров.Интерфейс
Function аннотирован @FunctionalInterface, что означает, что он предназначен для использования с лямбда-выражениями и содержит ровно один абстрактный метод:
R apply(T t);
Принимает один аргумент типа T и возвращает результат типа R.
Пример:
Function<String, Integer> stringLength = String::length;
Integer length = stringLength.apply("Hello, World!");
System.out.println(length); // 13
Еще один:
Function<Double, Double> areaOfCircle = r -> Math.PI * r * r;
System.out.println(areaOfCircle.apply(5.0));
// 78.53981633974483
#java #function
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Если у вас есть поток, который может содержать повторяющиеся элементы, используйте операцию
distinct(), чтобы удалить их.
var list = Arrays.asList(1, 2, 3, 3, 4, 5, 5);
var distinctList = list.stream()
.distinct()
.collect(Collectors.toList());
// distinctList: [1, 2, 3, 4, 5]
#java #stream #distinct
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥2❤1👏1
Модификатор
static говорит о том, что данный метод или поле принадлежат самому классу и доступ к ним возможен даже без создания экземпляра класса. Поля, помеченные static инициализируются при инициализации класса. На методы, объявленные как static, накладывается ряд ограничений:✔️ Они могут вызывать только другие статические методы.
✔️ Они должны осуществлять доступ только к статическим переменным.
✔️ Они не могут ссылаться на члены типа
this или super.В отличии от статических, поля экземпляра класса принадлежат конкретному объекту и могут иметь разные значения для каждого. Вызов метода экземпляра возможен только после предварительного создания объекта класса.
Пример:
public class MainClass {
public static void main(String args[]) {
System.out.println(TestClass.v);
new TestClass().a();
System.out.println(TestClass.v);
}
}
public class TestClass {
public static String v = "Initial val";
{
System.out.println("!!! Non-static initializer");
v = "Val from non-static";
}
static {
System.out.println("!!! Static initializer");
v = "Some val";
}
public void a() {
System.out.println("!!! a() called");
}
}
Результат:
!!! Static initializer
Some val
!!! Non-static initializer
!!! a() called
Val from non-static
#java #static
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8👨💻3❤1🔥1
java.util.function и предназначен для представления поставщика результатов. Этот интерфейс используется для работы с функциями, которые не принимают никаких аргументов и возвращают результат. Supplier часто используется в ленивой инициализации, генерации данных и других сценариях, где требуется получение значения без ввода.Интерфейс
Supplier аннотирован @FunctionalInterface, что означает, что он предназначен для использования с лямбда-выражениями и содержит ровно один абстрактный метод:
T get();
Возвращает результат типа T.
Пример:
Supplier<String> supplier = () -> "Hello, World!";
String message = supplier.get();
System.out.println(message); // Hello, World!
Еще один:
Supplier<Double> randomSupplier = Math::random;
Stream.generate(randomSupplier)
.limit(5)
.forEach(System.out::println);
// 5 дробных чисел от 0 до 1
#java #supplier
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤1🔥1👏1
This media is not supported in your browser
VIEW IN TELEGRAM
Когда код наконец-то заработал, но не совсем так, как хотелось бы
🤣27👍9😁5👏2
✔️ Статические поля можно инициализировать при объявлении, в статическом или нестатическом блоке инициализации.
✔️ Нестатические поля можно инициализировать при объявлении, в нестатическом блоке инициализации или в конструкторе.
#java #initialization #static #nonstatic
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Оптимистичная блокировка предполагает, что конфликтов при параллельном доступе к данным будет мало. Изменения данных происходят без блокировки, но при попытке сохранения изменений проверяется, что данные не изменились с момента последнего чтения.
Алгоритм:
1️⃣ Чтение данных.
2️⃣ Обновление данных в памяти.
3️⃣ Попытка записи изменений с проверкой версии или временной метки.
4️⃣ Если данные были изменены другим процессом, транзакция откатывается и повторяется.
Например, можно использовать поле
version в таблице. При чтении данных запоминаем значения этого поля, а записываем данные с условием что поле version не изменилось. SQL-запрос может быть примерно таким:
update table set field1='data1', field2='data2', version=<version>+1 where id=<id> and version=<version>
После выполнения запроса нужно проверить сколько записей обновилось, если ни одной, то значит другой процесс изменил запись, и нужно начать с начала.
Пессимистичная блокировка предполагает, что конфликты будут частыми. Данные блокируются при чтении, чтобы предотвратить их изменение другими транзакциями до завершения текущей транзакции.
Алгоритм:
1️⃣ Чтение данных с блокировкой.
2️⃣ Обновление данных.
3️⃣ Запись изменений.
4️⃣ Снятие блокировки после завершения транзакции.
Как пример, может быть использован запрос
SELECT ... FOR UPDATE для блокировки строк при чтении.#java #database #optimistic #pessimistic #locking
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4
Класс называется вложенным (Nested class), если он определен внутри другого класса. Вложенный класс должен создаваться только для того, чтобы обслуживать обрамляющий его класс. Если вложенный класс оказывается полезен в каком-либо ином контексте, он должен стать классом верхнего уровня. Вложенные классы имеют доступ ко всем (в том числе приватным) полям и методам внешнего класса, но не наоборот. Из-за этого разрешения использование вложенных классов приводит к некоторому нарушению инкапсуляции.
Существуют четыре категории вложенных классов:
1️⃣ Static nested class (Статический вложенный класс);
2️⃣ Member inner class (Простой внутренний класс);
3️⃣ Local inner class (Локальный класс);
4️⃣ Anonymous inner class (Анонимный класс).
Такие категории классов, за исключением первого, также называют внутренними (Inner class). Внутренние классы ассоциируются не с внешним классом, а с экземпляром внешнего.
Каждая из категорий имеет рекомендации по своему применению. Если вложенный класс должен быть виден за пределами одного метода или он слишком длинный для того, чтобы его можно было удобно разместить в границах одного метода и если каждому экземпляру такого класса необходима ссылка на включающий его экземпляр, то используется нестатический внутренний класс. В случае, если ссылка на обрамляющий класс не требуется - лучше сделать такой класс статическим. Если класс необходим только внутри какого-то метода и требуется создавать экземпляры этого класса только в этом методе, то используется локальный класс. А, если к тому же применение класса сводится к использованию лишь в одном месте и уже существует тип, характеризующий этот класс, то рекомендуется делать его анонимным классом.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1🔥1👏1
class Base {
public String className = "Base";
}
class Derived extends Base {
private String className = "Derived";
}
public class Quest {
public static void main(String[] args) {
System.out.println(new Derived().className);
}
}