Java | Вопросы собесов
11.4K subscribers
31 photos
2 videos
1.12K links
Download Telegram
🤔 Почему синглтон называют антипаттерном?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍31🤯1
🤔 Что нужно, чтобы написанная на Java программа, заработала?

Чтобы написанная на Java программа заработала, необходимо выполнить несколько шагов, начиная с написания кода и заканчивая его запуском.

🚩Шаги

1⃣Написание кода
Напишите Java-код в текстовом редакторе или интегрированной среде разработки (IDE), такой как IntelliJ IDEA, Eclipse или NetBeans.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}


2⃣Установка Java Development Kit (JDK)
Убедитесь, что на вашем компьютере установлен JDK (Java Development Kit). JDK включает в себя компилятор (javac) и виртуальную машину Java (JVM). Скачайте и установите последнюю версию JDK с сайта Oracle или OpenJDK.

3⃣Компиляция кода
Компилируйте Java-код в байт-код, который будет выполняться на JVM. Для этого используйте команду javac. После компиляции появится файл HelloWorld.class, содержащий байт-код.
javac HelloWorld.java


4⃣Запуск программы
Запустите скомпилированный байт-код с помощью виртуальной машины Java (JVM), используя команду java.
java HelloWorld


Вывод должен быть:
Hello, World!


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13😁4🎉4
🤔 Назови сколько существует нормальных форм в SQL?

Существует шесть нормальных форм: 1NF, 2NF, 3NF, BCNF, 4NF и 5NF. Обычно используют до третьей или формы Бойса-Кодда, так как этого достаточно для большинства задач. Более высокие формы применяются редко из-за их сложности и дополнительных ограничений.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍7
🤔 За счет чего создаваемые классы могут быстро менять реализацию?

🟠Интерфейсы и абстрактные классы
Использование интерфейсов и абстрактных классов позволяет определить контракт (набор методов), который класс должен реализовать. Это позволяет легко менять реализацию, не изменяя код, который использует эти интерфейсы.
// Интерфейс
public interface PaymentProcessor {
void processPayment(double amount);
}

// Одна реализация
public class CreditCardPaymentProcessor implements PaymentProcessor {
@Override
public void processPayment(double amount) {
System.out.println("Processing credit card payment of " + amount);
}
}

// Другая реализация
public class PayPalPaymentProcessor implements PaymentProcessor {
@Override
public void processPayment(double amount) {
System.out.println("Processing PayPal payment of " + amount);
}
}


🟠Принцип инверсии зависимостей (Dependency Inversion Principle)
Этот принцип подразумевает, что высокоуровневые модули не должны зависеть от низкоуровневых модулей. Оба должны зависеть от абстракций. Это достигается с помощью внедрения зависимостей (Dependency Injection, DI).
public class PaymentService {
private PaymentProcessor paymentProcessor;

// Конструктор принимает интерфейс, а не конкретную реализацию
public PaymentService(PaymentProcessor paymentProcessor) {
this.paymentProcessor = paymentProcessor;
}

public void makePayment(double amount) {
paymentProcessor.processPayment(amount);
}
}

// Использование разных реализаций
PaymentService service = new PaymentService(new CreditCardPaymentProcessor());
service.makePayment(100.0);

service = new PaymentService(new PayPalPaymentProcessor());
service.makePayment(200.0);


🟠Паттерн Стратегия (Strategy Pattern)
Паттерн Стратегия позволяет определять семейство алгоритмов, инкапсулировать их и делать их взаимозаменяемыми. Это позволяет алгоритмам изменяться независимо от клиентов, которые их используют.
// Интерфейс стратегии
public interface CompressionStrategy {
void compress(String data);
}

// Конкретная стратегия
public class ZipCompressionStrategy implements CompressionStrategy {
@Override
public void compress(String data) {
System.out.println("Compressing using ZIP");
}
}

// Другая стратегия
public class RarCompressionStrategy implements CompressionStrategy {
@Override
public void compress(String data) {
System.out.println("Compressing using RAR");
}
}

// Контекст, использующий стратегию
public class CompressionContext {
private CompressionStrategy strategy;

public void setStrategy(CompressionStrategy strategy) {
this.strategy = strategy;
}

public void compress(String data) {
strategy.compress(data);
}
}

// Использование
CompressionContext context = new CompressionContext();
context.setStrategy(new ZipCompressionStrategy());
context.compress("MyData");

context.setStrategy(new RarCompressionStrategy());
context.compress("MyData");


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16
🤔 Чем отличаются LEFT JOIN от INNER JOIN?

LEFT JOIN возвращает все строки из левой таблицы, включая не совпадающие, с null вместо отсутствующих данных. INNER JOIN возвращает только те строки, которые имеют совпадения в обеих таблицах. Таким образом, LEFT JOIN полезен для сохранения всех данных из одной таблицы, даже если нет соответствий.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
🤔 Расскажи об этапах (фазах) жизненного цикла JSP.?

🟠Перевод (Translation)
JSP страница переводится в сервлетный Java-код. JSP контейнер анализирует содержимое JSP страницы и создает соответствующий сервлетный исходный код (.java файл).

🟠Компиляция (Compilation)
Сервлетный исходный код компилируется в байт-код, создавая .class файл (сервлет). Этот этап аналогичен компиляции обычного Java-кода.

🟠Загрузка (Loading)
Скомпилированный класс сервлета загружается в память. Контейнер загружает класс сервлета, чтобы он мог быть выполнен.

🟠Инициализация (Initialization)
Контейнер вызывает метод jspInit(). Этот метод вызывается один раз при первом создании сервлета или при перезапуске сервера и предназначен для выполнения инициализационных задач (например, настройка ресурсов).

🟠Обработка запросов (Request Processing)
Для каждого HTTP-запроса вызывается метод jspService(). Этот метод обрабатывает входящий запрос и генерирует соответствующий ответ. Основная работа по генерации динамического содержимого происходит на этом этапе.

🟠Завершение (Destruction)
Когда JSP страница выводится из эксплуатации (например, при остановке сервера), контейнер вызывает метод jspDestroy(). Этот метод используется для освобождения ресурсов (например, закрытие соединений с базой данных).

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Что такое полиморфизм?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🤔1
🤔 Расскажи о методах жизненного цикла JSP?

Жизненный цикл JSP страницы включает несколько ключевых методов, которые выполняются на различных этапах от инициализации до завершения.

🚩Методы:

🟠`jspInit()`
Этот метод вызывается контейнером сервлетов один раз, когда JSP страница загружается впервые или когда она перезагружается. Инициализация ресурсов, таких как подключение к базе данных, настройка начальных параметров и другие задачи подготовки.
public void jspInit() {
// Инициализация ресурсов
System.out.println("jspInit() вызван");
}


🟠`_jspService(HttpServletRequest request, HttpServletResponse response)`
Этот метод вызывается контейнером для обработки каждого запроса, поступающего к JSP странице. Метод обрабатывает HTTP-запросы и генерирует ответы. Основная логика для обработки запроса и генерации динамического HTML содержимого.
public void _jspService(HttpServletRequest request, HttpServletResponse response) {
// Обработка запроса
response.getWriter().println("Обработка запроса в _jspService()");
}


🟠`jspDestroy()`
Этот метод вызывается контейнером сервлетов перед тем, как JSP страница будет выгружена из памяти (например, при завершении работы сервера или при перезагрузке приложения). Очистка и освобождение ресурсов, таких как закрытие подключений к базе данных и другие задачи завершения.
public void jspDestroy() {
// Очистка ресурсов
System.out.println("jspDestroy() вызван");
}


🚩Иллюстрация использования методов

<%-- JSP Page --%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Life Cycle Methods</title>
</head>
<body>
<h1>Hello, JSP!</h1>
<p>Current time: <%= new java.util.Date() %></p>
</body>
</html>

<%!
// Инициализация
public void jspInit() {
System.out.println("jspInit() вызван");
}

// Завершение
public void jspDestroy() {
System.out.println("jspDestroy() вызван");
}
%>


🚩Порядок вызова методов

1⃣`jspInit()`
Вызывается один раз при загрузке JSP страницы.
2⃣`_jspService(HttpServletRequest request, HttpServletResponse response)`
Вызывается каждый раз при получении нового запроса к JSP странице.
3⃣`jspDestroy()`
Вызывается один раз перед выгрузкой JSP страницы из памяти.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой цикл жизни Spring Beans?

Цикл жизни Spring Beans включает создание объекта, внедрение зависимостей, вызов методов инициализации, использование бина и завершение его жизненного цикла. Spring управляет всем этим процессом через контейнер ApplicationContext. Перед удалением вызываются методы завершения, если они определены.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥6
🤔 Какие методы жизненного цикла JSP могут быть переопределены?

🟠`jspInit()`
Метод вызывается один раз при инициализации JSP страницы. Используется для выполнения инициализационных задач, таких как настройка ресурсов (например, подключение к базе данных).
public void jspInit() {
// Инициализация ресурсов
System.out.println("jspInit() вызван");
}


🟠`jspDestroy()`
Метод вызывается один раз перед выгрузкой JSP страницы из памяти. Используется для очистки ресурсов, таких как закрытие подключений к базе данных.
public void jspDestroy() {
// Очистка ресурсов
System.out.println("jspDestroy() вызван");
}


🟠`_jspService(HttpServletRequest request, HttpServletResponse response)`
Метод вызывается для обработки каждого запроса к JSP странице. Основная логика обработки запросов и генерации ответа. Этот метод автоматически генерируется контейнером сервлетов и не может быть переопределен вручную в JSP странице.
public void _jspService(HttpServletRequest request, HttpServletResponse response) {
// Обработка запроса
response.getWriter().println("Обработка запроса в _jspService()");
}


🚩Пример переопределения методов в JSP

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Life Cycle Methods</title>
</head>
<body>
<h1>Hello, JSP!</h1>
<p>Current time: <%= new java.util.Date() %></p>
</body>
</html>

<%!
// Инициализация
public void jspInit() {
System.out.println("jspInit() вызван");
}

// Завершение
public void jspDestroy() {
System.out.println("jspDestroy() вызван");
}
%>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 В чем идея многопоточности?

Многопоточность позволяет выполнять несколько задач одновременно в рамках одного процесса. Это улучшает производительность и эффективность, особенно на многопроцессорных системах. Однако требует контроля синхронизации для предотвращения гонок данных и других проблем.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍33🔥6👾2
🤔 Как можно предотвратить прямой доступ к JSP странице из браузера?

🟠Размещение в `WEB-INF`
Поместите JSP страницы в директорию WEB-INF.
/WEB-INF/jsp/protected.jsp


🟠Перенаправление через сервлет
Используйте сервлет для доступа к JSP страницам.
@WebServlet("/protectedPage")
public class ProtectedServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/protected.jsp").forward(request, response);
}
}


🟠Использование фильтров
Создайте фильтр для проверки условий доступа.
@WebFilter("/WEB-INF/*")
public class AuthenticationFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (httpRequest.getSession().getAttribute("user") == null) {
httpResponse.sendRedirect(httpRequest.getContextPath() + "/login.jsp");
} else {
chain.doFilter(request, response);
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 Что такое полиморфизм?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥2
🤔 Какая разница между динамическим и статическим содержимым JSP?

🟠Статическое содержимое
Неподвижный контент, который не изменяется при каждом запросе. Обычно это HTML, CSS, JavaScript, изображения и другие медиафайлы. HTML-теги, текст, ссылки и изображения, которые всегда одинаковы для каждого пользователя.
<!DOCTYPE html>
<html>
<head>
<title>Static Content Example</title>
</head>
<body>
<h1>Welcome to my website</h1>
<p>This is a static paragraph.</p>
</body>
</html>


🟠Динамическое содержимое
Контент, который может изменяться при каждом запросе в зависимости от данных, входных данных пользователя или бизнес-логики. Это генерируется на сервере с использованием Java-кода. Результаты поиска, данные пользователя, время и дата, данные из базы данных.
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Content Example</title>
</head>
<body>
<h1>Welcome to my website</h1>
<p>Current date and time: <%= new java.util.Date() %></p>
<p>Your IP address: <%= request.getRemoteAddr() %></p>
</body>
</html>


🚩Основные различия

🟠Изменяемость
-Статическое содержимое
Не меняется при каждом запросе.
-Динамическое содержимое
Может изменяться в зависимости от условий и данных.

🟠Производительность
Статическое содержимое
Быстро загружается, так как не требует обработки на сервере.
Динамическое содержимое
Может быть медленнее, так как требует обработки и генерации контента на сервере.

🟠Использование ресурсов
-Статическое содержимое
Не использует серверные ресурсы для генерации.
Динамическое содержимое
-Использует серверные ресурсы для выполнения логики и генерации контента.

🟠Примеры использования
Статическое содержимое
-Основные страницы, справочные документы, статические изображения.
Динамическое содержимое
-Пользовательские профили, результаты поиска, данные из базы данных.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43😁1
🤔Что такое класс object?

Object — это базовый класс в Java, от которого наследуются все другие классы, предоставляющий ключевые методы, такие как equals, hashCode, toString, и clone.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15👀1
🤔 Какие существуют основные типы тегов JSP?

JSP предоставляет различные типы тегов для упрощения разработки веб-страниц, позволяя интегрировать Java-код и управлять контентом.

🚩Директивы (Directives)

🟠`<%@ page %>`
Устанавливает атрибуты страницы, такие как кодировка, язык, импорты и другие параметры.
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="java.util.Date" %>


🟠`<%@ include %>`
Включает содержимое другого файла во время компиляции страницы.
<%@ include file="header.jsp" %>


🟠`<%@ taglib %>`
Декларирует библиотеку тегов, используемых на странице.
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>


🚩Скриплеты (Scriptlets)

<%
String message = "Hello, World!";
out.println(message);
%>


🚩Выражения (Expressions)

<p>Current date and time: <%= new java.util.Date() %></p>


🚩Декларации (Declarations)

<%! 
private int counter = 0;
public int getCounter() {
return counter++;
}
%>


🚩Теги действий (Action Tags)

🟠`<jsp:include>`
Включает содержимое другого ресурса во время выполнения.
<jsp:include page="header.jsp" />


🟠`<jsp:forward>`
Перенаправляет запрос на другой ресурс.
<jsp:forward page="login.jsp" />


🟠`<jsp:useBean>`
Создает и инициализирует JavaBean.
<jsp:useBean id="user" class="com.example.User" scope="session" />


🟠`<jsp:setProperty>`
Устанавливает значение свойства JavaBean.
<jsp:setProperty name="user" property="name" value="John Doe" />


🟠`<jsp:getProperty>`
Получает значение свойства JavaBean.
<jsp:getProperty name="user" property="name" />


🚩Теги JSTL (JSP Standard Tag Library)

JSTL предоставляет стандартный набор тегов для выполнения задач, таких как итерация, условные конструкции и работа с XML. Теги Core
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:forEach var="item" items="${itemList}">
${item}
</c:forEach>


Теги Format
<%@ taglib uri="https://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd" />


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какие знаешь Spring Scope?

Основные Spring Scope: singleton (один экземпляр на контейнер), prototype (новый экземпляр для каждого запроса), request (один экземпляр на HTTP-запрос), session (один экземпляр на HTTP-сессию) и application (один экземпляр на контекст веб-приложения).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23👍10
🤔 Что знаешь о действиях JSP Action tag и JSP Action Elements?

JSP (JavaServer Pages) предоставляет разработчикам возможность создавать динамические веб-страницы с использованием Java. В JSP существуют специальные теги, называемые Action Tags (теги действий) и Action Elements (элементы действий), которые помогают выполнить определенные задачи и управлять контентом на странице.

🚩JSP Action Tags

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

🟠<jsp:include>
Включает содержимое другого ресурса (JSP, HTML, или сервлета) в текущую страницу. Когда нужно динамически вставить контент из другого файла.
<jsp:include page="header.jsp" />


🟠<jsp:forward>
Перенаправляет запрос на другой ресурс. Для перенаправления пользователя на другую страницу или ресурс.
<jsp:forward page="newPage.jsp" />


🟠 <jsp:param>
Используется для передачи параметров другим JSP страницам или сервлетам. Внутри <jsp:include> или <jsp:forward>.
<jsp:forward page="newPage.jsp">
<jsp:param name="userId" value="123" />
</jsp:forward>


🟠<jsp:useBean>
Создает или находит экземпляр JavaBeans и связывает его с JSP страницей. Для интеграции с JavaBeans.
<jsp:useBean id="user" class="com.example.User" scope="session" />


🟠<jsp:setProperty>
Устанавливает значение свойства JavaBeans. В связке с <jsp:useBean>.
<jsp:setProperty name="user" property="name" value="John Doe" />


🟠<jsp:getProperty>
Получает значение свойства JavaBeans и выводит его на страницу. В связке с <jsp:useBean>.
Имя пользователя: <jsp:getProperty name="user" property="name" />


🚩JSP Action Elements

Это более общие термины, которые могут включать любые действия, выполненные с помощью JSP Action Tags или других механизмов JSP. Эти элементы используются для управления динамическим контентом, взаимодействия с JavaBeans, и включают в себя теги действий.

🚩Зачем нужны JSP Action Tags и Elements

🟠Упрощение разработки
Они предоставляют готовые механизмы для выполнения общих задач.
🟠Повторное использование кода
Легко включать и переиспользовать компоненты.
🟠Разделение логики и представления
Поддержание чистого и организованного кода.
🟠Интерактивность
Позволяют создавать динамические и интерактивные веб-страницы.

<jsp:include page="header.jsp" />

<jsp:useBean id="user" class="com.example.User" scope="session" />
<jsp:setProperty name="user" property="name" value="John Doe" />
<p>Имя пользователя: <jsp:getProperty name="user" property="name" /></p>

<jsp:include page="footer.jsp" />


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🤔 Почему нельзя сравнивать объекты через «==»?

Оператор == сравнивает ссылки на объекты, а не их содержимое, поэтому результат может быть некорректным для объектов с одинаковыми данными.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20
🤔 Взаимодействие JSP - сервлет - JSP?


1⃣Пользовательский запрос
Пользователь отправляет HTTP-запрос (например, через веб-браузер).

2⃣Сервлет
Запрос попадает к сервлету, который обрабатывает бизнес-логику. Сервлет может получать данные от пользователя, обрабатывать их, взаимодействовать с базой данных или другими компонентами приложения.

3⃣Передача данных на JSP
После обработки запроса сервлет перенаправляет его на JSP-страницу, передавая необходимые данные (атрибуты) для отображения.

4⃣JSP
JSP-страница генерирует HTML-ответ, используя переданные данные, и отправляет его обратно пользователю.

🚩Почему это нужно

1⃣Разделение задач
Сервлеты отвечают за обработку бизнес-логики, а JSP - за представление данных. Это позволяет разделить код на более управляемые части и облегчить сопровождение.

2⃣Повторное использование кода
Логику обработки данных можно легко использовать повторно в различных сервлетах, а JSP-страницы могут использоваться для разных представлений одних и тех же данных.

3⃣Упрощение разработки
Разработчики могут сосредоточиться на своих частях задачи (логика или представление), что ускоряет разработку и делает код более читабельным.

🚩Пример взаимодействия

Пользователь отправляет запрос
GET /users


Сервлет UserServlet
@WebServlet("/users")
public class UserServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Логика получения списка пользователей
List<User> users = UserService.getUsers();

// Передача данных на JSP
request.setAttribute("users", users);
RequestDispatcher dispatcher = request.getRequestDispatcher("users.jsp");
dispatcher.forward(request, response);
}
}


JSP users.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Список пользователей</title>
</head>
<body>
<h1>Список пользователей</h1>
<ul>
<c:forEach var="user" items="${users}">
<li>${user.name} - ${user.email}</li>
</c:forEach>
</ul>
</body>
</html>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5