1. Она помогает сосредоточиться на функциональности, игнорируя реализацию.
2. В программировании реализуется через абстрактные классы, интерфейсы и методы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🤔5
Это процесс отладки (debugging), который позволяет выявить и исправить дефекты в коде. Ошибки в программе могут быть синтаксическими, логическими или связанными с выполнением программы.
Симптомы ошибки: Программа выдает ошибочное поведение, например, неожиданный результат, исключение или сбой.
Типы ошибок:
Синтаксические: Ошибки в написании кода (например, пропущенная точка с запятой).
Логические: Код выполняется без ошибок, но результат не соответствует ожиданиям.
Ошибки выполнения: Программа завершает работу из-за исключения (например, деление на ноль).
Компилятор/интерпретатор: Сообщает о синтаксических ошибках и указывает строку, где возникла проблема.
Стек вызовов (stack trace): Для ошибок выполнения предоставляет информацию о том, где произошла ошибка.
Пример:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:5)
Прочитайте проблемный участок кода и проверьте его на соответствие логике задачи.
Ищите типичные ошибки, такие как:
Неправильное использование переменных.
Ошибки в условных операторах (
if, switch).Пропущенные или лишние элементы кода.
Отладчик (Debugger):
Отладчики встроены в IDE, такие как IntelliJ IDEA, Eclipse или NetBeans.
Позволяют ставить точки останова (breakpoints), чтобы программа останавливалась в конкретных местах.
Позволяют пошагово выполнять код и проверять значения переменных.
Логирование (Logging):
Используйте
System.out.println для вывода промежуточных данных: System.out.println("Value of x: " + x);
Пример
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
int x = 10;
int y = 0;
try {
int result = x / y;
} catch (ArithmeticException e) {
logger.error("Division by zero!", e);
}
}
}
Покрытие тестами: Напишите автоматические тесты для выявления ошибки.
Используйте фреймворки, такие как JUnit или TestNG.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@Test
void testAddition() {
assertEquals(5, Calculator.add(2, 3));
}
}
Если ошибка в сторонней библиотеке, проверьте документацию и известные проблемы. Убедитесь, что вы правильно используете методы и классы.
Исправьте ошибку, убедившись, что исправление не приводит к новым ошибкам. Проверьте весь код на предмет аналогичных ошибок.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤1
1. Оно позволяет переиспользовать код базового класса.
2. Поддерживает полиморфизм, что упрощает работу с типами
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
Это способность объектов разных классов реагировать на одинаковые методы по-разному. В Java полиморфизм достигается через наследование, переопределение методов и использование абстрактных классов или интерфейсов.
Наследование и переопределение методов
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // Полиморфизм
Animal myCat = new Cat(); // Полиморфизм
myDog.sound(); // Вывод: Dog barks
myCat.sound(); // Вывод: Cat meows
}
}Использование интерфейсов
interface Shape {
void draw();
}
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class Main {
public static void main(String[] args) {
Shape shape1 = new Circle(); // Полиморфизм
Shape shape2 = new Rectangle(); // Полиморфизм
shape1.draw(); // Вывод: Drawing a Circle
shape2.draw(); // Вывод: Drawing a Rectangle
}
}Реальный пример использования полиморфизма
class Animal {
public void sound() {
System.out.println("Some generic animal sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Woof Woof");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal[] animals = {new Dog(), new Cat(), new Animal()};
for (Animal animal : animals) {
animal.sound(); // Полиморфный вызов
}
}
}Результат
Woof Woof
Meow
Some generic animal sound
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19
2. Нефункциональное: проверка производительности, надёжности, безопасности.
3. Модульное: тестирование отдельных частей кода.
4. Интеграционное: проверка взаимодействия модулей.
5. Системное и пользовательское тестирование: проверка полной системы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17❤1👍1
В программировании существует множество видов тестирования, которые можно разделить на категории по уровню тестирования, методам выполнения и целям. Вот основные виды:
Тестирование отдельных методов или классов.
Цель: Проверить работу минимальных компонентов программы.
Инструменты: JUnit, TestNG.
@Test
public void testAddition() {
assertEquals(5, Calculator.add(2, 3));
}
Тестирование взаимодействия между модулями.
Цель: Убедиться, что модули правильно работают вместе.
Пример: Проверка взаимодействия сервиса и базы данных.
Инструменты: Spring Test, Apache Camel Test.
Проверка всей системы как единого целого.
Цель: Убедиться, что все компоненты работают вместе и система соответствует требованиям.
Проводится с участием клиента или конечных пользователей.
Цель: Убедиться, что система удовлетворяет бизнес-требованиям.
Тесты выполняются вручную.
Цель: Найти ошибки, которые может не уловить автоматизация.
Пример: Тестировщик вручную проверяет пользовательский интерфейс.
Тесты выполняются автоматически с использованием скриптов и инструментов.
Цель: Снизить время и затраты на повторяющиеся тесты.
Инструменты: Selenium, JUnit, Appium.
Проверяет, что функции системы работают как ожидалось.
Цель: Убедиться в соответствии требованиям.
Инструменты: Selenium, Postman.
Тестирование производительности (Performance Testing): Проверяет скорость, отклик и стабильность.
Инструменты: JMeter, Gatling.
Тестирование безопасности (Security Testing): Проверяет защиту системы.
Инструменты: OWASP ZAP, Burp Suite.
Тестирование удобства использования (Usability Testing): Проверяет интерфейс на удобство для пользователя.
Быстрая проверка работоспособности ключевых функций.
Цель: Убедиться, что основные функции работают, прежде чем углубляться в тесты.
Проверяет, что новые изменения не сломали старую функциональность.
Цель: Убедиться, что баги, исправленные ранее, не повторились.
Проверяет систему без знаний о внутреннем устройстве.
Цель: Оценить функциональность с точки зрения пользователя.
Проверяет систему с учетом внутренней структуры кода.
Цель: Оценить корректность логики программы.
Проверяет, какая версия системы лучше (например, два варианта интерфейса).
Цель: Повысить пользовательский опыт.
Проверяет, как система работает под большой нагрузкой.
Инструменты: Apache JMeter.
Проверяет, как система работает в условиях сверхвысокой нагрузки.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18
1. CI: автоматизация сборки и тестирования кода при каждом коммите.
2. CD: автоматическая доставка обновлений на сервер или в продакшен.
3. Это ускоряет релизы и улучшает качество продукта.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24🔥4
Это компонент, который отвечает за отправку логов в различные места назначения, такие как файлы, консоль, базы данных, сетевые сокеты или даже удаленные серверы. Каждый Appender реализует конкретный способ обработки и хранения логов.
Appender позволяет гибко управлять тем, куда и как сохраняются логи. В зависимости от требований приложения, вы можете:
Писать логи в файл.
Выводить их в консоль.
Отправлять их в удалённые хранилища или базы данных.
Логи выводятся в консоль.
Полезно для разработки и отладки.
<Appender type="Console" name="ConsoleAppender">
<Target>System.out</Target>
</Appender>
Логи записываются в файл.
Используется для длительного хранения логов.
<Appender type="File" name="FileAppender">
<FileName>logs/app.log</FileName>
<Append>true</Append>
</Appender>
Расширение FileAppender с возможностью ротации логов (ограничение размера файла, создание новых файлов при переполнении).
<Appender type="RollingFile" name="RollingFileAppender">
<FileName>logs/app.log</FileName>
<FilePattern>logs/app-%d{yyyy-MM-dd}.log</FilePattern>
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
</Appender>
Логи записываются в файл, который ротационно создаётся каждый день.
<Appender type="DailyRollingFile" name="DailyRollingAppender">
<FileName>logs/app.log</FileName>
<DatePattern>.yyyy-MM-dd</DatePattern>
</Appender>
Отправляет логи через сеть (TCP или UDP).
Используется для централизованного логирования.
Записывает логи в базу данных.
<Appender type="JDBC" name="JDBCAppender">
<ConnectionSource>
<DriverManagerConnectionSource>
<DriverClass>org.h2.Driver</DriverClass>
<Url>jdbc:h2:mem:logdb</Url>
<User>sa</User>
</DriverManagerConnectionSource>
</ConnectionSource>
<TableName>log_table</TableName>
</Appender>
Вот пример конфигурации с использованием нескольких Appender
XML-конфигурация
<Configuration>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level: %msg%n"/>
</Console>
<File name="FileAppender" fileName="logs/app.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level: %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
Java-конфигурация
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
private static final Logger logger = LogManager.getLogger(Main.class);
public static void main(String[] args) {
logger.info("This is an info log");
logger.error("This is an error log");
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1
1. Он запускается внутри сервлет-контейнера, такого как Apache Tomcat.
2. Используется для создания веб-приложений на Java.
3. Обрабатывает запросы и генерирует динамический контент, например, HTML.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥6❤1
В Java существуют несколько подходов для чтения XML-файлов, каждый из которых имеет свои преимущества и недостатки.
XML-файл загружается целиком в память в виде древовидной структуры. Разработчик может работать с узлами (nodes), элементами (elements) и атрибутами (attributes) через API.
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class DomExample {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("example.xml");
NodeList nodeList = doc.getElementsByTagName("element");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
System.out.println(element.getTextContent());
}
}
}
XML обрабатывается построчно (по событиям). При чтении вызываются методы обработчика событий (например, начало элемента, конец элемента).
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SaxExample {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse("example.xml", new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) {
System.out.println("Start Element: " + qName);
}
public void characters(char[] ch, int start, int length) {
System.out.println("Text: " + new String(ch, start, length));
}
public void endElement(String uri, String localName, String qName) {
System.out.println("End Element: " + qName);
}
});
}
}
XML обрабатывается как поток, но предоставляет больше контроля, чем SAX. Поддерживает чтение и запись.
import javax.xml.stream.*;
import java.io.FileReader;
public class StaxExample {
public static void main(String[] args) throws Exception {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("example.xml"));
while (reader.hasNext()) {
int event = reader.next();
if (event == XMLStreamReader.START_ELEMENT) {
System.out.println("Start Element: " + reader.getLocalName());
} else if (event == XMLStreamReader.CHARACTERS) {
System.out.println("Text: " + reader.getText().trim());
} else if (event == XMLStreamReader.END_ELEMENT) {
System.out.println("End Element: " + reader.getLocalName());
}
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
1. Они помогают выполнять действия при наступлении определённых событий (например, инициализация ресурсов или логирование).
2. Примеры слушателей: ServletContextListener, HttpSessionListener, ServletRequestListener.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍2
В основе фреймворка Spring лежит концепция инверсии управления (IoC, Inversion of Control) и внедрения зависимостей (DI, Dependency Injection). Эти принципы обеспечивают гибкость, расширяемость и удобство в управлении зависимостями между компонентами приложения, делая код более модульным, тестируемым и поддерживаемым.
Это парадигма, при которой контроль над выполнением программы частично или полностью передаётся фреймворку или библиотеке. В контексте Spring IoC означает, что сам фреймворк управляет созданием объектов и их жизненным циклом, а не программист напрямую. Это достигается через использование "контейнера IoC", который автоматически создаёт и связывает объекты в соответствии с конфигурацией приложения, заданной в XML-файлах, аннотациях или Java-конфигурации.
Это техника реализации IoC, при которой объектам "внедряются" или "предоставляются" их зависимости извне. Вместо того чтобы компоненты приложения самостоятельно создавали или искали необходимые им объекты (зависимости), Spring контейнер автоматически предоставляет им все необходимые зависимости в момент создания объекта. Это уменьшает связность между компонентами и упрощает управление зависимостями, а также их изменение и тестирование.
Включает в себя IoC и DI, обеспечивая основу для фреймворка.
Позволяет реализовывать поперечные задачи (например, логирование, транзакции) в виде аспектов, не изменяя основной бизнес-логики.
Фреймворк для создания веб-приложений по модели MVC.
Предоставляет набор инструментов для быстрой разработки и запуска приложений с минимальной конфигурацией.
Упрощает доступ к данным, работу с базами данных и операциями CRUD.
Предоставляет комплексные средства безопасности для аутентификации и авторизации.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍10❤1
2. Слушатели применяются для реагирования на события в жизненном цикле сервлетов, сессий или контекста (например, инициализация ресурсов).
3. Выбор зависит от задачи: фильтры — для работы с данными запросов/ответов, слушатели — для событий приложения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
В контексте JVM (Java Virtual Machine) типы данных делятся на два основных класса: примитивные типы данных и ссылочные типы данных.
Примитивные типы данных представляют собой базовые типы, которые не являются объектами и хранят непосредственно значения. Они делятся на числовые типы, логический тип и символьный тип.
Целочисленные типы
byte: 8-битный знаковый целочисленный тип данных (диапазон от -128 до 127).
short: 16-битный знаковый целочисленный тип данных (диапазон от -32,768 до 32,767).
int: 32-битный знаковый целочисленный тип данных (диапазон от -2^31 до 2^31-1).
long: 64-битный знаковый целочисленный тип данных (диапазон от -2^63 до 2^63-1).
Типы с плавающей точкой
float: 32-битный IEEE 754 тип данных с плавающей точкой одинарной точности.
double: 64-битный IEEE 754 тип данных с плавающей точкой двойной точности.
boolean: Представляет логическое значение (true или false).char: 16-битный тип данных, представляющий символ Unicode (диапазон от '\u0000' до '\uffff').Ссылочные типы данных представляют собой объекты и массивы. Они хранят ссылку на область памяти, где хранятся данные объекта или массива.
Любой объектный тип данных является экземпляром класса. Классы могут быть как стандартными (например,
String, Integer), так и пользовательскими.Интерфейсы определяют набор методов, которые должны быть реализованы классами, которые их реализуют.
Массивы могут быть одномерными или многомерными и могут хранить как примитивные, так и ссылочные типы данных.
public class DataTypesExample {
public static void main(String[] args) {
// Примитивные типы данных
byte aByte = 10;
short aShort = 100;
int anInt = 1000;
long aLong = 10000L;
float aFloat = 10.5f;
double aDouble = 10.55;
boolean aBoolean = true;
char aChar = 'A';
// Ссылочные типы данных
String aString = "Hello, World!";
Integer anInteger = 1000;
int[] anArray = {1, 2, 3, 4, 5};
// Вывод примитивных типов данных
System.out.println("byte: " + aByte);
System.out.println("short: " + aShort);
System.out.println("int: " + anInt);
System.out.println("long: " + aLong);
System.out.println("float: " + aFloat);
System.out.println("double: " + aDouble);
System.out.println("boolean: " + aBoolean);
System.out.println("char: " + aChar);
// Вывод ссылочных типов данных
System.out.println("String: " + aString);
System.out.println("Integer: " + anInteger);
System.out.println("Array: " + java.util.Arrays.toString(anArray));
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍16❤1
2. Если значение параметра больше или равно 0, сервлет будет инициализирован при старте приложения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍3🤔1
Метод
equals() в Java предназначен для проверки равенства двух объектов. Если объект, переданный в метод equals(), равен null, метод должен возвращать `false`, так как объект не может быть равен null по определению. Рассмотрим этот случай более подробно.Согласно спецификации Java, метод
equals() должен возвращать false, если объект, переданный в метод, равен null. Это необходимо для корректного сравнения объектов.Симметричность: Если
a.equals(b) возвращает true, то b.equals(a) также должно возвращать true.Для
null: Вызов x.equals(null) всегда должен возвращать false.Если метод
equals() не проверяет, является ли объект null, попытка доступа к его полям или методам вызовет NullPointerException.Вот стандартный способ реализации метода
equals()@Override
public boolean equals(Object obj) {
// Проверяем, равен ли объект null
if (obj == null) {
return false;
}
// Проверяем, является ли объект тем же самым
if (this == obj) {
return true;
}
// Проверяем, принадлежит ли объект тому же классу
if (getClass() != obj.getClass()) {
return false;
}
// Приводим объект к текущему типу
MyClass other = (MyClass) obj;
// Сравниваем необходимые поля
return this.field.equals(other.field);
}
Если вы не проверяете
null, код вроде следующего приведет к ошибкеMyClass obj1 = new MyClass("Hello");
MyClass obj2 = null;
System.out.println(obj1.equals(obj2)); // Если нет проверки null -> NullPointerExceptionПример с проверкой
nullclass MyClass {
private String value;
public MyClass(String value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
MyClass other = (MyClass) obj;
return value.equals(other.value);
}
}
public class Main {
public static void main(String[] args) {
MyClass obj1 = new MyClass("Hello");
MyClass obj2 = null;
System.out.println(obj1.equals(obj2)); // false
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤2
2. Использовать
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥4
В контексте Java, Heap (куча) и Stack (стек) являются областями памяти, используемыми JVM для управления памятью, необходимой для выполнения программы. Каждая из этих областей имеет свои характеристики и используется для разных целей.
Heap — это область памяти, выделенная для динамического распределения памяти объектов и массивов. Все объекты, созданные с использованием оператора
new, размещаются в куче.Куча разделена на поколения: молодое поколение (Young Generation) и старое поколение (Old Generation).
Молодое поколение включает в себя области Eden Space и Survivor Spaces (S0 и S1).
Старое поколение хранит долгоживущие объекты.
Куча управляется сборщиком мусора (Garbage Collector), который автоматически освобождает память, занятую объектами, которые больше не используются.
Куча используется для хранения объектов, массивов и классов, информация о которых сохраняется на протяжении всего времени их жизни.
public class Example {
public static void main(String[] args) {
Example obj = new Example(); // obj создается в куче
}
}Стек — это область памяти, используемая для управления вызовами методов и хранения локальных переменных, параметров методов и информации о возвратах.
Каждый поток имеет свой собственный стек.
Стек хранит кадры (frames) для каждого вызова метода. Каждый кадр содержит локальные переменные метода и информацию о вызовах.
Память в стеке автоматически управляется при вызове методов и выходе из них. Когда метод вызывается, создается новый кадр в стеке; когда метод завершает выполнение, его кадр удаляется из стека.
Стек используется для хранения примитивных типов данных и ссылок на объекты, которые находятся в куче.
Локальные переменные методов и параметры методов хранятся в стеке.
public class Example {
public static void main(String[] args) {
int localVar = 10; // localVar хранится в стеке
Example obj = new Example(); // Ссылка на obj хранится в стеке, а сам объект — в куче
obj.method();
}
public void method() {
int anotherVar = 20; // anotherVar хранится в стеке
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍30
2. Содержит параметры инициализации из web.xml и ссылку на ServletContext.
3. Используется для настройки сервлета при его инициализации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
2. Предоставляет доступ к общей информации и ресурсам приложения, таким как параметры конфигурации, файлы, сервлеты.
3. Используется для взаимодействия между различными частями приложения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2