Java for Beginner
772 subscribers
749 photos
220 videos
12 files
1.26K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Вопрос с собеседований

Зачем нужен паттерн Decorator? 🤓


Ответ:

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

Это даёт гибкость, избегает наследования, упрощает комбинацию функций и помогает соблюдать принципы SOLID, особенно Open/Closed.



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
История IT-технологий сегодня — 19 ноября


ℹ️ Кто родился в этот день

Не нашел((


🌐 Знаковые события

1969 — американский космический корабль «Аполлон-12», пилотируемый астронавтами Чарльзом Конрадом, Аланом Бином и Ричардом Гордоном, осуществил посадку на Луну.


#Biography #Birth_Date #Events #19Ноября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Если Вы работаете в IT, как давно вы устроились в текущую компанию?
Anonymous Poll
10%
Более 3х лет назад
40%
От 1 до 3 года
40%
Менее года назад
10%
Менее полугода
🗿2😱1
Запросы и мутации в GraphQL

GraphQL опирается на две основные операции:
Query — безопасные операции чтения данных.
Mutation — операции изменения состояния (создание, обновление, удаление).


Обе операции используют один и тот же язык запросов, отличаются только семантикой:
Query не влияет на состояние системы, Mutation — влияет.


1. Как выглядит запрос (Query)

GraphQL-запрос — декларативное описание структуры данных, которую клиент хочет получить.

Простой пример:
query {
user(id: 42) {
name
avatar
}
}


Здесь:
query — тип операции (можно опустить: GraphQL сам определит, что это запрос).
user(id: 42) — вызов поля корневого типа Query.
{ name, avatar } — конкретные поля, которые клиент хочет получить.

GraphQL не вернёт дополнительные поля и не допустит отсутствующих — запрос полностью определяет форму ответа.


Ответ будет ровно такой:
{
"data": {
"user": {
"name": "Den",
"avatar": "https://example.com/den.png"
}
}
}

Никаких “лишних” полей.



2. Как работает передача аргументов

Аргументы передаются в круглых скобках и могут быть любого типа, определённого в схеме:
скаляры, enum, input-объекты.

Пример схемы:
type Query {
posts(limit: Int, authorId: ID): [Post!]!
}


Пример запроса:
query {
posts(limit: 5, authorId: 42) {
id
title
}
}


Ответ будет:
{
"data": {
"posts": [
{ "id": "101", "title": "GraphQL SDL" },
{ "id": "102", "title": "gRPC vs GraphQL" }
]
}
}


2.1. Переменные запроса (не хардкодим аргументы)

GraphQL поддерживает variables, что особенно важно для фронтенда.

Запрос:

query GetUser($id: ID!) {
user(id: $id) {
name
avatar
}
}


Передаваемые переменные:
{
"id": 42
}


Сервер объединяет запрос с переменными и выполняет его.

Преимущества переменных:
запрос можно кэшировать,
тело операции не меняется,
безопаснее, чем вставлять значения в строку.



3. Что делает Mutation

Mutation изменяет данные.

Пример схемы:
type Mutation {
createPost(input: CreatePostInput!): Post!
}


Пример запроса:
mutation {
createPost(input: { title: "GraphQL", content: "SDL explained" }) {
id
title
}
}


Mutation возвращает объект результата, содержащий новое состояние или подтверждение.

Ответ:
{
"data": {
"createPost": {
"id": "501",
"title": "GraphQL"
}
}
}


Важный принцип:
Mutation считается одиночной транзакцией.
Даже если внутри происходит много действий, GraphQL гарантирует их упорядоченное выполнение.



4. Возврат данных в нужной форме

GraphQL всегда возвращает данные:
в структуре, которую запросил клиент
в иерархии, описанной в запросе
строго тех типов, которые указаны в схеме


Пример: вложенная выборка.
query {
user(id: 1) {
name
posts(limit: 2) {
title
comments {
text
}
}
}
}


Ответ:
{
"data": {
"user": {
"name": "Den",
"posts": [
{
"title": "GraphQL Basics",
"comments": [
{ "text": "Отличная статья" }
]
},
{
"title": "SDL Tutorial",
"comments": []
}
]
}
}
}

Сервер не может изменить структуру ответа — она определяется клиентом.



#Java #middle #GraphQL #Query #Mutation
👍2
5. Ошибки и partial responses

GraphQL всегда возвращает JSON-объект с двумя ключами:

data

errors


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

пример: запрос
query {
user(id: 1) {
name
posts {
title
likes
}
}
}


допустим, поле posts упало из-за ошибки в БД.

Ответ:
{
"data": {
"user": {
"name": "Den",
"posts": null
}
},
"errors": [
{
"message": "Database timeout",
"path": ["user", "posts"]
}
]
}


GraphQL:

не останавливает выполнение всего запроса,
возвращает то, что смог,
указывает путь к проблемному полю.
Это концепция partial response, которой нет ни в REST, ни в gRPC.



6. Как Mutation обрабатывает ошибки

Mutation также может вернуть частичный результат, но чаще ошибка означает, что произошло отклонение операции:

{
"data": {
"createPost": null
},
"errors": [
{
"message": "User not authorized",
"path": ["createPost"]
}
]
}


GraphQL намеренно не использует коды HTTP-статуса, кроме:
200 — запрос обработан
400 — синтаксическая ошибка запроса
500 — ошибка самого сервера GraphQL (не бизнес-ошибка)



#Java #middle #GraphQL #Query #Mutation
👍1
Что выведет код?

public class Task191125 {
public static void main(String[] args) {
Object obj = "42";

String result = switch (obj) {
case Integer i -> "Number: " + i;
case String s when s.length() > 3 -> "Long string";
case String ignored -> "Short string";
default -> "Unknown";
};

System.out.println(result);
}
}


#Tasks
👍1
Варианты ответа:
Anonymous Quiz
31%
Number: 42
8%
Long string
15%
Short string
46%
Unknown
👍1
Вопрос с собеседований

Разница между ArrayDeque и Stack? 🤓


Ответ:

Stack
— устаревший synchronized-класс на базе Vector, а ArrayDeque — современная реализация без блокировок, быстрее и гибче.

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



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
История IT-технологий сегодня — 20 ноября


ℹ️ Кто родился в этот день

Thomas M. Siebel (род. 20 ноября 1952) — предприниматель и инженер, основал Siebel Systems; известен разработкой корпоративных CRM-решений и позднее — проектов в области AI (C3.ai).


🌐 Знаковые события

1985 — Выпущена Microsoft Windows 1.0.


#Biography #Birth_Date #Events #20Ноября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Глава 2. List — списки в Java

Интерфейс List и его особенности

В мире программирования, и в Java в частности, необходимость хранить и управлять наборами данных — одна из самых частых задач. Начинающие разработчики знакомы с массивами — простыми и эффективными, но обладающими серьезным недостатком: их размер фиксирован после создания. Что же делать, если количество элементов заранее неизвестно? На помощь приходит интерфейс List (список), который является одной из краеугольных концепций в Java Collections Framework (фреймворке коллекций Java).


Что такое интерфейс List?

List — это интерфейс, который расширяет более общий интерфейс Collection. Если говорить просто, List — это контракт, который обещает определенное поведение для всех классов, которые его реализуют. Сам по себе List не является классом, поэтому вы не можете создать объект типа «List». Он лишь определяет «правила игры», а конкретные классы, такие как ArrayList или LinkedList, уже следуют этим правилам, реализуя функционал по-своему.

Главная идея List — это упорядоченная последовательность. Это его ключевая особенность, отличающая его от других коллекций, например, Set (множества).


Ключевые особенности интерфейса List

Гарантированный порядок элементов.
Это самый важный принцип. Когда вы добавляете элементы в список, система запоминает именно ту последовательность, в которой вы их добавили. Элемент «A», добавленный первым, всегда будет находиться на позиции 0 (если только его не удалили или не переместили). Элемент «B», добавленный вторым, будет на позиции 1, и так далее. Этот порядок сохраняется на протяжении всей жизни списка (если только вы сами его не измените). Это кардинально отличает список от, например, мешка с яблоками, где порядок не важен.

Доступ по индексу.
Благодаря строгому порядку, List предоставляет возможность работать с элементами по их целочисленному индексу (позиции). Индексация всегда начинается с 0, как и в массивах. Вы можете «спросить» список: «Дай мне элемент, который находится на пятой позиции», и он его вернет. Эта операция является одной из базовых и высокооптимизированной в большинстве реализаций списков.

Допустимость дубликатов.
В отличие от множеств (Set), которые гарантируют уникальность своих элементов, список совершенно спокойно относится к повторяющимся значениям. Вы можете добавить одну и ту же строку «Привет» в список десять раз, и все десять копий будут храниться в нем как самостоятельные элементы, занимая разные позиции.

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

Null-допустимость.
Список разрешает хранение специального значения null, которое обозначает отсутствие объекта. Это означает, что вы можете добавить null в список в качестве валидного элемента. Однако с этим нужно быть осторожным, так как при попытке выполнить какие-либо операции с этим null-элементом (например, вызвать его метод) может быть выброшено исключение NullPointerException.


#Java #для_новичков #beginner #List
👍2
Абстракция и полиморфизм

Одна из сильных сторон использования интерфейса List — принцип полиморфизма. В своем коде вы можете объявить переменную типа List, а затем присвоить ей любой объект, который реализует этот интерфейс.

List<String> myList; // Объявление переменной интерфейсного типа
myList = new ArrayList<>(); // Работаем с динамическим массивом
// ... позже в коде ...
myList = new LinkedList<>(); // Теперь работаем со связным списком


Это позволяет писать гибкий и слабосвязанный код. Основная логика вашей программы, которая использует методы add, get, remove, будет работать с любой реализацией List. А вы, в зависимости от конкретных требований к производительности (например, если чаще нужен быстрый доступ по индексу или частое добавление в начало), можете легко подменить одну реализацию на другую, не переписывая весь код.


#Java #для_новичков #beginner #List
👍2
Что выведет код?

public class Task201125 {
public static void main(String arg) {
System.out.println("Hello from single arg main");
}

public static void main(String[] args) {
System.out.println("Hello from main");
}

public static void main() {
System.out.println("Hello from parameterless main");
}
}


#Tasks
👍1
Вопрос с собеседований

Что такое fail-fast и fail-safe итераторы? 🤓


Ответ:

Fail-fast
итераторы бросают ConcurrentModificationException при модификации коллекции.

Fail-safe работают со snapshot-копией, не влияющей на оригинал.

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



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
История IT-технологий сегодня — 21 ноября


ℹ️ Кто родился в этот день

Никола́й Вале́рьевич Ду́ров (род. 21 ноября 1980, Ленинград) — российский программист и математик, участвовал в разработке Telegram; известен как один из ключевых технических авторов мессенджера.


🌐 Знаковые события

1998 — первый запуск китайской беспилотной космической ракеты.


#Biography #Birth_Date #Events #21Ноября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Фрагменты, директивы и переменные

GraphQL — декларативный язык, но его мощь раскрывается по-настоящему, когда вы начинаете использовать фрагменты, директивы и переменные.


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



1. Фрагменты

Фрагмент (fragment) — это именованный блок запроса, который описывает набор полей.
Он позволяет вынести общую часть и использовать её в нескольких местах.


Главная цель: избежать повторов полей.

Пример без фрагментов:
query {
user(id: 1) {
id
name
avatar
}
post(id: 10) {
author {
id
name
avatar
}
}
}

Повторяются три поля id, name, avatar.


Версия с фрагментом
fragment UserBasic on User {
id
name
avatar
}

query {
user(id: 1) {
...UserBasic
}
post(id: 10) {
author {
...UserBasic
}
}
}

Теперь изменения структуры (например, добавление role) делаются в одном месте — фрагменте.


Как работает фрагмент
fragment UserBasic on User — объявление фрагмента.
User — тип, которому фрагмент принадлежит.
...UserBasic — вставка фрагмента.
Фрагменты можно вкладывать друг в друга и использовать с union и interface.


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

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

Работа с interface и union
Позволяют описывать поля для нескольких типов.

Крупные запросы с десятками полей
Легче читать, тестировать и поддерживать.



2. Директивы

Директивы — это аннотации, которые модифицируют выполнение запроса.
Они влияют на структуру данных, которые вернёт сервер.


GraphQL имеет встроенные директивы и позволяет создавать свои.

2.1 Директива @include

Поле будет включено только если условие истинно.
query GetUser($showAvatar: Boolean!) {
user(id: 1) {
name
avatar @include(if: $showAvatar)
}
}

Переменные:

{ "showAvatar": true }

Если showAvatar = false, поле avatar пропадёт из ответа целиком.


2.2 Директива
@skip

Обратная логика:
avatar @skip(if: $binaryMode)

Если binaryMode = true, поле будет пропущено.


2.3 Директива @deprecated

Помечает поле устаревшим.
type User {
username: String @deprecated(reason: "Use 'name' instead")
}

Эта директива влияет на документацию и IDE, но не на данные.


2.4 Кастомные директивы

Пример (схема):
directive @upper on FIELD_DEFINITION


Резолвер может модифицировать строку на лету (например, вернуть верхний регистр).
Это используется для логирования, авторизации, кеширования, маскирования данных.



3. Переменные в запросах

Переменные — это место, где GraphQL становится особенно полезным.
Они позволяют использовать один и тот же запрос с разными параметрами, не переписывая запрос.


3.1 Базовый пример

Запрос:
query GetPost($id: ID!) {
post(id: $id) {
title
content
}
}


Переменные:
{
"id": 100
}


Сервер соединяет тело запроса и переменные и выполняет.

3.2 Переменные для input-объектов (в мутациях)

Мутация:
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
}
}


Переменные:
{
"input": {
"title": "GraphQL",
"content": "Powerful queries"
}
}


Это безопаснее, чем писать input прямо в теле мутации.

3.3 Комбинирование переменных с директивами
query User(
$id: ID!,
$withPosts: Boolean!
) {
user(id: $id) {
name
posts @include(if: $withPosts) {
title
}
}
}


Комбинация:
один запрос,
два режима вывода данных,
ноль дублирования.



#Java #middle #GraphQL #Query
👍2
4. Реальные производственные кейсы

Кейc 1: мобильная и web-версия используют разные наборы полей
query User(
$id: ID!,
$isMobile: Boolean!
) {
user(id: $id) {
name
avatar @skip(if: $isMobile)
posts @include(if: $isMobile) {
title
}
}
}


Мобильный клиент получает минимум данных.
Web — максимум.


Кейc 2: переиспользование структуры пользователя

fragment UserCard on User {
id
name
avatar
}

query PageData {
recommendedUsers { ...UserCard }
recentVisitors { ...UserCard }
followers { ...UserCard }
}


Все блоки страницы используют одну структуру.
CRM-интерфейсы любят такое.


Кейc 3: миграции схемы через директивы

Старая модель:
username @deprecated(reason: "Use 'login' instead")


Frontend получает предупреждение в IDE — никаких тайных поломок.

Кейc 4: сложные фильтры в одном запросе
query FilterPosts($filter: PostFilter!) {
posts(filter: $filter) {
id
title
}
}


Переменные:
{
"filter": {
"authorId": 1,
"tags": ["graphql", "java"],
"minLikes": 10
}
}


#Java #middle #GraphQL #Query
👍2
Что выведет код?

public class Task211125 {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "he" + "llo";
String s3 = "he";
String s4 = "llo";
String s5 = s3 + s4;

System.out.println(s1 == s2);
System.out.println(s1 == s5);
System.out.println(s1.equals(s5));

final String s6 = "he";
final String s7 = "llo";
String s8 = s6 + s7;
System.out.println(s1 == s8);
}
}


#Tasks
👍1
Вопрос с собеседований

Для чего используется CompletableFuture.anyOf() 🤓


Ответ:

anyOf()
запускает несколько асинхронных задач и завершается, как только выполнится любая.

Полезно, когда важен первый успешный результат.

Метод упрощает конкурентную работу, но требует аккуратного управления исключениями и понимания поведения оставшихся задач.



#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3