Java Backend | YeaHub
521 subscribers
115 photos
22 videos
2 files
234 links
Теория, подготовка к интервью и курсы для Java разработчиков

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

Платформа: https://yeahub.ru

Для связи: @ruslan_kuyanets
Download Telegram
#Вакансии
👨‍💻 Java разработчик

Локация: Удаленно в РФ
Компания: Фамтех
ЗП: от 250 000 до 370 000 р. на руки
Занятость: Полная
Грейд: Middle/ Middle+/ Senior

🚩Обязательные требования:
▪️Java 11 (SpringBoot 2.3) (Backend);
▪️PostgreSQL, Liquibase, RabbitMQ, Kafka, REST, k8s, Jenkins, Gitlab, Kibana, Grafana, Prometheus, Zabbix, SonarCube, Jmeter, Selenium, Junit, Cucumber;
▪️Опыт коммерческой разработки на Java от 3 лет (Spring, Boot);
▪️Способность решать задачи самостоятельно и работать в команде;
▪️Участие в управлении командами разработки совместно с СРО.

🚩Дополнительные требования
▪️Опыт работы в крупных проектах;
▪️Использование методологии agile.

🚩Задачи на проекте
▪️Занятие технологически сложными задачами проекта и проектировать архитектуру сервисов в сотрудничестве с командой;
▪️Передача опыта и внедрение лучших практик как в код, так и в процессы;
▪️Принятие решений по найму и развитию сотрудников, участие в технических интервью;
▪️Поиск оптимальных решений, балансирующих потребности бизнеса, сроки релиза и техническое совершенство вместе с командой.

🚩Мы предлагаем
▪️Удаленка;
▪️оформление в аккредитованную IT компанию или ИП/ГПХ;
▪️Работа по московскому времени;
▪️ДМС после прохождения испытательного срока;
▪️Реферальная программа: бонус за рекомендации;
▪️Выдаем технику для работы или можете работать на своей;
▪️Пересмотр заработной платы раз в год.

​​​​​​​​​​​​​💬 Резюме отправлять: @romanchuk_ye

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЛитКод
Задача: 590. N-ary Tree Postorder Traversal

Дано корневое дерево с n-арной структурой, верните обход дерева в постфиксном порядке для значений его узлов.

Сериализация входных данных n-арного дерева представлена в обходе уровней. Каждая группа детей разделяется значением null (см. примеры).

Пример:
Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Output: [2,6,14,11,7,3,12,8,4,13,9,10,5,1]


👨‍💻 Алгоритм:

1⃣Инициализируйте стек для хранения узлов и список для хранения значений узлов в обратном порядке.

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

3⃣В конце верните список значений узлов.

😊 Решение:
class Solution {
public List<Integer> postorder(Node root) {
LinkedList<Node> stack = new LinkedList<>();
LinkedList<Integer> output = new LinkedList<>();
if (root == null) {
return output;
}

stack.add(root);
while (!stack.isEmpty()) {
Node node = stack.pollLast();
output.addFirst(node.val);
for (Node item : node.children) {
if (item != null) {
stack.add(item);
}
}
}
return output;
}
class Node {
public int val;
public List<Node> children;

public Node() {}

public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
}
}


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Какие минусы есть у пула строк с точки зрения безопасности?

Пул строк (String Pool) в Java представляет собой особую область памяти в методной области (Metaspace начиная с Java 8), где хранятся строковые литералы.

🚩Минусы

Уязвимость к анализу памяти (Memory Analysis)
Поскольку строковые литералы хранятся в пуле строк и не уничтожаются до тех пор, пока JVM работает, злоумышленник, получивший доступ к дампу памяти, может извлечь чувствительные данные, такие как пароли, токены или личные данные, если они были сохранены как строковые литералы.

Уязвимость к атакам по кэшированию (Caching Attacks)
Злоумышленник может попытаться использовать кэширование строк для проведения атак. Например, если однажды созданный строковый литерал остается в пуле строк, его можно найти и использовать повторно, даже если оригинальная строка больше не используется программой.

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

Потенциальная уязвимость к атакам типа "Deduplication"
Если две строки с одинаковым содержимым помещаются в пул строк, они будут указывать на один и тот же объект. Это может позволить злоумышленнику, знающему об этой особенности, попытаться извлечь чувствительные данные путем поиска дубликатов строк.

🚩Пример уязвимости к анализу памяти

public class Example {
public static void main(String[] args) {
String password = "secretPassword123"; // Строка хранится в пуле строк
System.out.println("Password is set.");
}
}


🚩Как уменьшить риски

🟠Избегайте использования строк для хранения чувствительных данных
Вместо строк используйте массивы символов (char[]), так как их содержимое можно обнулить после использования.
char[] password = new char[] {'s', 'e', 'c', 'r', 'e', 't'};
// Очистка массива после использования
java.util.Arrays.fill(password, '\0');


🟠Используйте библиотеки безопасности
Используйте специализированные библиотеки, которые обеспечивают более безопасное управление чувствительными данными, такие как Java Cryptography Architecture (JCA).
🟠Минимизируйте использование строковых литералов для чувствительных данных
Не храните пароли, ключи и другие конфиденциальные данные как строковые литералы.
🟠Шифрование данных
Шифруйте данные перед их хранением или передачей. Даже если данные будут извлечены из памяти, без ключа расшифровки они останутся бесполезными.

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
🤓 Как правильно объявить переменную?
Anonymous Quiz
5%
$i=0
0%
java.int i=0;
95%
int i=0;
#ЛитКод
Задача: 606. Construct String from Binary Tree

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

🚩Представление узлов
Каждый узел в дереве должен быть представлен его целочисленным значением.

🚩Скобки для дочерних узлов
Если у узла есть хотя бы один дочерний узел (левый или правый), его дочерние узлы должны быть представлены в скобках. Конкретно:

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

🚩Пропуск пустых скобок
Любые пустые пары скобок (т.е. ()) должны быть опущены в окончательном строковом представлении дерева, за одним исключением: когда у узла есть правый дочерний узел, но нет левого дочернего узла. В таких случаях вы должны включить пустую пару скобок, чтобы указать на отсутствие левого дочернего узла. Это гарантирует, что однозначное соответствие между строковым представлением и исходной структурой бинарного дерева сохраняется.

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

Пример
Input: root = [1,2,3,4]
Output: "1(2(4))(3)"
Explanation: Originally, it needs to be "1(2(4)())(3()())", but you need to omit all the empty parenthesis pairs. And it will be "1(2(4))(3)".


👨‍💻 Алгоритм:

1⃣Инициализация и рекурсия
Начинаем с корневого узла бинарного дерева и выполняем прямой обход (preorder traversal) с использованием рекурсии. Для каждого узла добавляем его значение к строке результата.

2⃣Обработка дочерних узлов
Случай 1: Если у узла есть оба дочерних узла (левый и правый), оборачиваем результаты прямого обхода для обоих дочерних узлов в скобки. Случай 2: Если у узла нет дочерних узлов, пропускаем скобки для них. Случай 3: Если у узла есть только левый дочерний узел, обходим его и добавляем результат в скобках, пропуская пустые скобки для правого дочернего узла. Случай 4: Если у узла есть только правый дочерний узел, добавляем пустые скобки для левого дочернего узла и обходим правый дочерний узел, добавляя его результат в скобках.

3⃣Объединение результатов
Собираем результаты для каждого узла, учитывая все упомянутые случаи, чтобы получить строковое представление дерева.

😊 Решение
public class Solution {
public String tree2str(TreeNode t) {
StringBuilder res = new StringBuilder();
dfs(t, res);
return res.toString();
}

private void dfs(TreeNode t, StringBuilder res) {
if (t == null)
return;
res.append(t.val);
if (t.left == null && t.right == null)
return;
res.append('(');
dfs(t.left, res);
res.append(')');
if (t.right != null) {
res.append('(');
dfs(t.right, res);
res.append(')');
}
}
}


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Расскажи про иерархию интерфейсов Collection Framework.

🟠Collection — базовый интерфейс, от которого наследуются все коллекции.
🟠List (например, ArrayList, LinkedList) — упорядоченные коллекции, поддерживающие дублирующиеся элементы.
🟠Set (например, HashSet, TreeSet) — коллекции, хранящие только уникальные элементы.
🟠Queue (например, PriorityQueue, LinkedList) — коллекции с FIFO-поведеним.
🟠Map — пары ключ-значение (HashMap, TreeMap) — не наследуется от Collection.

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Что такое Dispatcher Servlet?

Центральный компонент в Spring MVC, который обрабатывает входящие HTTP-запросы. Он распределяет запросы к соответствующим контроллерам, управляет данными и формирует ответы. Этот компонент действует как координатор между различными частями приложения, такими как контроллеры, сервисы и представления.

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЛитКод
Задача: 525. Contiguous Array


Дан бинарный массив nums. Верните максимальную длину непрерывного подмассива с равным количеством 0 и 1.

Пример:
Input: nums = [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.


👨‍💻 Алгоритм:

1⃣Инициализируйте переменную count для отслеживания разности между количеством 1 и 0, и переменную max_length для хранения максимальной длины подмассива. Создайте хеш-таблицу map для хранения первых встреч каждого значения count. Добавьте начальное значение (0, -1) в хеш-таблицу.

2⃣Итеративно пройдите по массиву nums. На каждой итерации обновляйте значение count (увеличивайте на 1 для 1 и уменьшайте на 1 для 0). Если текущее значение count уже существует в хеш-таблице, вычислите длину подмассива между текущим индексом и индексом из хеш-таблицы. Обновите max_length, если текущий подмассив длиннее.

3⃣Если текущее значение count не существует в хеш-таблице, добавьте его с текущим индексом. После завершения итерации верните max_length.

😊 Решение:
import java.util.HashMap;
import java.util.Map;

public class Solution {
public int findMaxLength(int[] nums) {
Map<Integer, Integer> countMap = new HashMap<>();
countMap.put(0, -1);
int maxLength = 0;
int count = 0;

for (int i = 0; i < nums.length; i++) {
count += (nums[i] == 1 ? 1 : -1);

if (countMap.containsKey(count)) {
maxLength = Math.max(maxLength, i - countMap.get(count));
} else {
countMap.put(count, i);
}
}

return maxLength;
}
}


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Что такое Dispatcher Servlet?

Центральный компонент в Spring MVC, который обрабатывает входящие HTTP-запросы. Он распределяет запросы к соответствующим контроллерам, управляет данными и формирует ответы. Этот компонент действует как координатор между различными частями приложения, такими как контроллеры, сервисы и представления.

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Что такое синхронизация и зачем она нужна?

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

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#Вакансии
👨‍💻 Java разработчик

Локация: Удаленно в РФ
Компания: Фамтех
ЗП: от 250 000 до 370 000 р. на руки
Занятость: Полная
Грейд: Middle/ Middle+/ Senior

🚩Обязательные требования
🔵 Java 11 (SpringBoot 2.3) (Backend);
🔵 PostgreSQL, Liquibase, RabbitMQ, Kafka, REST, k8s, Jenkins, Gitlab, Kibana, Grafana, Prometheus, Zabbix, SonarCube, Jmeter, Selenium, Junit, Cucumber;
🔵 Опыт коммерческой разработки на Java от 3 лет (Spring, Boot);
🔵 Способность решать задачи самостоятельно и работать в команде;
🔵 Участие в управлении командами разработки совместно с СРО.

🚩Дополнительные требования
🔵 Опыт работы в крупных проектах;
🔵 Использование методологии agile.

🚩Задачи на проекте
🔵 Занятие технологически сложными задачами проекта и проектировать архитектуру сервисов в сотрудничестве с командой;
🔵 Передача опыта и внедрение лучших практик как в код, так и в процессы;
🔵 Принятие решений по найму и развитию сотрудников, участие в технических интервью;
🔵 Поиск оптимальных решений, балансирующих потребности бизнеса, сроки релиза и техническое совершенство вместе с командой.

🚩Мы предлагаем
🔵 Удаленка;
🔵 Официальное оформление в аккредитованную IT компанию или ИП/ГПХ;
🔵 Работа по московскому времени;
🔵 ДМС после прохождения испытательного срока;
🔵 Реферальная программа: бонус за рекомендации;
🔵 Выдаем технику для работы или можете работать на своей;
🔵 Пересмотр заработной платы раз в год.

​​​​​​​​​​​​​💬 Резюме отправлять: @romanchuk_ye

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Какие методы жизненного цикла JSP могут быть переопределены ?

Жизненный цикл JSP (JavaServer Pages) включает несколько ключевых методов, которые можно переопределить для управления поведением страницы. Эти методы определены в интерфейсе javax.servlet.jsp.HttpJspPage, который расширяет интерфейс javax.servlet.jsp.JspPage.

🟠`jspInit()`
Этот метод запускается один раз при инициализации JSP. Он используется для выполнения начальных настроек, таких как создание объектов, которые будут использоваться на странице. Это аналог метода init() в сервлетах.
🟠jspDestroy()
Этот метод вызывается перед удалением JSP со страницы сервера. Он используется для освобождения ресурсов или выполнения других задач очистки. Это аналог метода destroy() в сервлетах.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.*, java.util.*" %>
<%!
// Поля класса
private Resource resource;

// Переопределение метода jspInit()
public void jspInit() {
// Инициализация ресурсов
resource = new Resource();
System.out.println("JSP инициализирована.");
}

// Переопределение метода jspDestroy()
public void jspDestroy() {
// Освобождение ресурсов
resource.close();
System.out.println("JSP уничтожена.");
}
%>
<html>
<body>
<h2>Пример переопределения методов жизненного цикла JSP</h2>
</body>
</html>


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Что такое CompletableFuture?

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

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЛитКод
Задача: 611. Valid Triangle Number

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

Пример:
Input: nums = [2,2,3,4]
Output: 3


👨‍💻 Алгоритм:

1⃣Отсортируйте массив nums.

2⃣Используйте три вложенных цикла: для каждого фиксированного третьего элемента, используйте два указателя для поиска подходящих первых двух элементов, которые удовлетворяют неравенству треугольника.

3⃣Увеличивайте счетчик на количество подходящих пар для каждого третьего элемента.

😎 Решение:
import java.util.Arrays;

public class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
int count = 0;

for (int k = n - 1; k >= 2; k--) {
int i = 0;
int j = k - 1;
while (i < j) {
if (nums[i] + nums[j] > nums[k]) {
count += j - i;
j--;
} else {
i++;
}
}
}

return count;
}
}


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Как создать поток?

🟠Наследование класса Thread: создайте подкласс Thread и переопределите метод run().
🟠Реализация интерфейса Runnable: создайте класс, реализующий Runnable, и передайте его экземпляр в конструктор Thread.
🟠Использование пула потоков: через ExecutorService для управления потоками.

👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЛитКод
Задача: 630. Course Schedule III

Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.

Пример:
Input: courses = [[100,200],[200,1300],[1000,1250],[2000,3200]]
Output: 3


👨‍💻 Алгоритм:

1⃣Сортировка курсов
Отсортируйте курсы по их конечным датам (lastDay). Это позволяет проходить курсы как можно ближе к их крайним срокам.

2⃣Проход по курсам
Используйте приоритетную очередь (max-heap) для отслеживания продолжительности пройденных курсов.

3⃣Добавление и удаление курсов
Для каждого курса: Добавьте его продолжительность в приоритетную очередь и обновите общее время прохождения курсов. Если общее время превышает крайний срок текущего курса, удалите самый длительный курс из очереди и скорректируйте общее время.

😎 Решение:
import java.util.*;

public class Solution {
public int scheduleCourse(int[][] courses) {
Arrays.sort(courses, (a, b) -> a[1] - b[1]);
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
int time = 0;

for (int[] course : courses) {
time += course[0];
maxHeap.offer(course[0]);
if (time > course[1]) {
time -= maxHeap.poll();
}
}

return maxHeap.size();
}
}


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
#ЧеКак
🤔 Какая разница между динамическим и статическим содержимым JSP?

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

🟠Директивы (Directives)
Используются для настройки JSP страницы и управления её поведением. Они предоставляют инструкции контейнеру JSP.
page: Настраивает атрибуты страницы, такие как кодировка, импорт классов, обработка исключений и т.д.
  <%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="java.util.Date" %>


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


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


🟠Скриптлеты (Scriptlets)
Позволяют включать произвольный Java код внутри JSP страницы. Код внутри скриптлета выполняется на сервере при генерации страницы.
<%
String message = "Hello, World!";
out.println(message);
%>


🟠Выражения (Expressions)
Позволяют выводить значения Java переменных и методов в HTML код. Результат выражения автоматически включается в вывод страницы.
<p>Current time: <%= new java.util.Date() %></p>


🟠Декларации (Declarations)
Позволяют объявлять методы и поля класса, в который компилируется JSP страница. Они используются для объявления переменных и методов, доступных в других частях страницы.
<%! 
private int counter = 0;

public int getCounter() {
return counter++;
}
%>
<p>Counter: <%= getCounter() %></p>


🟠Действия (Actions)
Позволяют выполнять встроенные функции, такие как включение содержимого другого ресурса или использование JavaBeans. Эти теги начинаются с <jsp: и предоставляют различные функциональные возможности.

jsp:include
Включает другой ресурс (JSP, HTML, Servlet) в текущую страницу во время выполнения.
<jsp:include page="header.jsp" />  


jsp:forward
Перенаправляет запрос на другой ресурс.
<jsp:forward page="anotherPage.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" />


🟠Теги библиотек (Tag Libraries)
Предоставляют дополнительные функции и упрощают разработку JSP страниц. Они используются для выполнения часто встречающихся задач, таких как итерация, условная логика, обработка XML, и работа с форматированием.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<c:choose>
<c:when test="${param.user == 'admin'}">
<p>Welcome, admin!</p>
</c:when>
<c:otherwise>
<p>Welcome, guest!</p>
</c:otherwise>
</c:choose>

<c:forEach var="item" items="${items}">
<p>${item.name}</p>
</c:forEach>


👉Новости 👉Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM