Библиотека собеса по Java | вопросы с собеседований
6.32K subscribers
370 photos
4 videos
290 links
Вопросы с собеседований по Java и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/08c603b6

Для обратной связи: @proglibrary_feeedback_bot
加入频道
ℹ️ Как устроен под капотом HashMap?

HashMap — это коллекция, обеспечивающая хранение пар "ключ-значение" и быструю работу с элементами за амортизированное O(1) время для операций вставки и поиска.

🔹 Структура HashMap

В основе HashMap лежит массив, где каждый элемент представляет собой "корзину" (bucket), и эти корзины хранят связные списки или сбалансированные деревья. Как работает эта структура:

▪️ Ключи: Ключ должен быть иммутабельным, а также допускается null в качестве ключа.
▪️ Хэширование: Для вычисления индекса бакета HashMap находит хэш для ключа. Далее используется операция побитового И (&) хэш-функции и n-1, где n - текущий размер массива бакетов (index = (n - 1) & hash).
▪️ Коллизии и цепочки: Если несколько ключей попадают в одну корзину (коллизия), HashMap использует связные списки для хранения этих значений. Когда длина связного списка превышает 8 элементов, HashMap автоматически преобразует его в красно-черное дерево для повышения эффективности поиска и вставки, обеспечивая O(log n) сложность для операций в таких корзинах.

🔹 Производительность

▪️ Добавление: За амортизированное O(1) время. При добавлении ключа HashMap сначала вычисляет хэш, а затем индекс корзины, где будет храниться элемент. Если корзина пуста, добавляется новый элемент. Если элемент с таким ключом уже есть, он заменяется.
▪️ Удаление: В зависимости от структуры корзины, время удаления элемента составляет O(1) для небольших корзин или O(log n) для корзин, содержащих красно-черное дерево.
▪️ Поиск: За амортизированное O(1) время при низком уровне коллизий. Однако в случае высоких коллизий и преобразования корзины в дерево сложность поиска возрастает до O(log n).

🔹 Использование памяти


Каждый элемент HashMap хранит не только ключ и значение, но также ссылки на следующий элемент в связном списке (или ссылки в дереве, если оно используется). Для эффективной работы HashMap настраивается порог "коэффициента загрузки" (load factor), после которого размер массива увеличивается вдвое, чтобы сократить количество коллизий.

🔹 Преимущества и недостатки

▪️ Преимущества:
- Доступ к элементам за амортизированное O(1).
- Возможность использования как связных списков, так и красно-черных деревьев позволяет HashMap эффективно справляться с коллизиями.

▪️ Недостатки:
- HashMap не гарантирует порядок элементов, в отличие от, например, TreeMap.
- Ссылки на элементы создают определенные накладные расходы, а при увеличении массива корзин в процессе реасширения требуются дополнительные ресурсы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥2🎉1
Разница между итераторами fail-fast и fail-safe?

🔹 Fail-fast итераторы обнаруживают изменения в коллекции во время итерации (например, добавление или удаление элементов) и немедленно выбрасывают ConcurrentModificationException. Эти итераторы работают напрямую с исходной коллекцией и обеспечивают высокую производительность, но не защищены от одновременных модификаций. Примеры коллекций, поддерживающих fail-fast итераторы, — ArrayList, HashSet, HashMap.

🔹 Fail-safe итераторы, в свою очередь, создают копию коллекции для итерации, что позволяет обходить коллекцию, даже если в нее вносятся изменения во время обхода. Они защищены от ConcurrentModificationException, но требуют больше памяти и процессорных ресурсов. Примеры коллекций, поддерживающих fail-safe итераторы, — CopyOnWriteArrayList и ConcurrentHashMap.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3🎉2
Что такое Garbage Collector?

Garbage Collector (GC) — это компонент JVM, который управляет памятью приложения. Он освобождает память, удаляя объекты, которые больше не используются, и к которым нет активных ссылок. Благодаря GC можно не заботиться о ручном освобождении памяти, как в некоторых других языках, что упрощает разработку и снижает риск утечек памяти.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2🎉1
Что такое сериализация?

Сериализация — это процесс преобразования объекта в поток байтов для сохранения его состояния или передачи по сети. Этот процесс позволяет сохранять данные объекта и его связи с другими объектами, так что их можно восстановить (десериализовать) позже. Сериализация поддерживает версионность с помощью serialVersionUID, что помогает проверять совместимость классов при изменениях.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍12🔥2🥱1👾1
🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

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

Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.

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

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
👍2
👀 Задачи с собеседований: Поиск первого уникального символа в строке (jun+)

— Как найти первый уникальный символ в строке?

💡 Ключевые моменты:

- Используйте доп. структуру данных для хранения количества вхождений каждого символа
- Предложите в комментарии другие варианты решения.

Реализация через Map на картинке 👆🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🎉2🔥1
Что такое Integration Tests?

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

Ключевые особенности:

🧩 Взаимодействие компонентов: Integration-тесты помогают выявить проблемы в интеграции разных модулей, таких как базы данных, внешние API и другие системные компоненты.

🌐 Зависимость от окружения: Часто требуют доступ к реальной или тестовой среде, например, к базе данных или к другим внешним ресурсам. Для изоляции и имитации окружения могут использоваться инструменты вроде Testcontainers и WireMock.

⏱️ Медленное выполнение: Интеграционные тесты занимают больше времени, чем unit-тесты, из-за необходимости взаимодействия с внешними системами. Поэтому их обычно выполняют реже — например, перед релизом или при существенных изменениях в коде.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥1🎉1
Что такое IoC?

IoC (Inversion of Control) — это принцип проектирования, при котором объекты не создают свои зависимости самостоятельно, а получают их извне, обычно через контейнер управления зависимостями. В Java одной из популярных реализаций этого принципа является Spring Framework, который использует IoC-контейнер для создания, связывания и управления жизненным циклом объектов приложения.

Основная идея IoC заключается в том, что контейнер берет на себя ответственность за инициализацию и конфигурацию объектов, позволяя разработчику сфокусироваться на логике приложения, а не на управлении зависимостями. Это достигается через Dependency Injection (DI) — механизм, при котором зависимости передаются объекту в момент его создания.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3🤔21
ℹ️ Какие виды тестирования существуют?

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

🔗 Integration-тесты: Проверяют, как разные модули приложения взаимодействуют между собой. Часто требуют настройки окружения, например, базы данных или API, и помогают выявить ошибки на уровне интеграции.

🎭 End-to-End (E2E) тесты: Проверяют полную цепочку действий в приложении, начиная от пользовательского интерфейса и заканчивая бекендом и базой данных. Цель — убедиться, что вся система работает корректно от начала до конца.

🔄 Regression-тесты: Направлены на проверку, что новые изменения в коде не сломали существующую функциональность. Обычно включают в себя повторение уже существующих тестов.

🛠 Acceptance-тесты: Проверяют, соответствует ли функциональность приложения требованиям заказчика или конечного пользователя. Обычно проводятся на последнем этапе, перед выпуском продукта в продакшн.

💡 Performance-тесты: Оценивают производительность системы — время отклика, пропускную способность и поведение под нагрузкой. Помогают убедиться, что приложение остаётся стабильным при большом количестве запросов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2🎉1
⚡️Самые полезные каналы по Java в одной папке

В ней:
канал для подготовки к собеседованиям
интересные задачи
основной канал
книги по Java
лучшие вакансии из сферы
и наш чат, в котором можно общаться и задавать вопросы

Добавляйте 👉 тык сюда
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👏1😁1
ℹ️ Как устроен под капотом LinkedHashSet?

LinkedHashSet — это коллекция, обеспечивающая хранение уникальных элементов с сохранением порядка их вставки. LinkedHashSet, как и HashSet, работает с элементами за амортизированное O(1) время, но, в отличие от HashSet, сохраняет порядок добавления элементов благодаря дополнительной структуре связного списка.

🔹 Структура LinkedHashSet

LinkedHashSet базируется на HashMap, но имеет уникальную особенность — упорядочивание элементов за счёт использования связного списка поверх стандартной хеш-таблицы.

▪️ Хранение данных: LinkedHashSet использует LinkedHashMap для хранения элементов. Каждый добавляемый элемент выступает в роли ключа, а значение всегда фиксировано (обычно это объект-заглушка).
▪️ Связный список: Для поддержания порядка добавления, элементы связаны друг с другом в виде двусвязного списка. Это позволяет итерациям проходить элементы в порядке их вставки.
▪️ Уникальность элементов: Как и в HashSet, каждый элемент уникален. При попытке добавить дублирующий элемент он игнорируется, сохраняя уникальность всех значений.

🔹 Производительность

▪️ Добавление: Добавление элементов происходит за амортизированное O(1) время. LinkedHashSet вычисляет хэш элемента и индекс, где он будет храниться в массиве бакетов LinkedHashMap.
▪️ Удаление: Удаление происходит также за амортизированное O(1) время. LinkedHashSet находит элемент по хэшу, удаляет его из связного списка и освобождает место в корзине.
▪️ Поиск: Поиск происходит за амортизированное O(1) время благодаря хэш-таблице.

🔹 Использование памяти

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

🔹 Преимущества и недостатки

▪️ Преимущества:
- Сохранение порядка добавления элементов.
- Быстрая работа с элементами за амортизированное O(1) время, как и в HashSet.

▪️ Недостатки:
- Потребление ресурсов возрастает при большом количестве элементов, так как структура требует больше памяти для поддержания порядка.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥21🎉1
🚀🐘 Оптимизация хранимых процедур в PostgreSQL: 4 трюка для взрывного ускорения

Кто из нас не сталкивался с медленными хранимыми процедурами в PostgreSQL? Наверняка таких мало. Сегодня поговорим о том, как реально ускорить их работу. Никакой сухой теории — только проверенные на практике методы. Разберем, как анализировать запросы, правильно использовать индексы и применять другие хитрости, которые действительно работают.

Читать статью
👍31🔥1
Что такое ORM?

ORM (Object-Relational Mapping) — это прослойка между приложением и реляционной базой данных, которая автоматически преобразует объекты в строки таблиц и наоборот. ORM реализуется через спецификацию JPA (Java Persistence API) и такие фреймворки, как Hibernate и EclipseLink, которые воплощают JPA и предоставляют инструменты для работы с базой данных на основе объектно-ориентированного подхода, избавляя от необходимости писать SQL-запросы вручную.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥31
Самые полезные каналы для программистов в одной подборке!

Сохраняйте себе, чтобы не потерять 💾

🔥Для всех

Библиотека программиста — новости, статьи, досуг, фундаментальные темы
Книги для программистов
IT-мемы
Proglib Academy — тут мы рассказываем про обучение и курсы
Азбука айтишника — здесь мы познаем азы из мира программирования

🤖Про нейросети
Библиотека робототехники и беспилотников | Роботы, ИИ, интернет вещей
Библиотека нейрозвука | Транскрибация, синтез речи, ИИ-музыка
Библиотека нейротекста | ChatGPT, Gemini, Bing
Библиотека нейровидео | Sora AI, Runway ML, дипфейки
Библиотека нейрокартинок | Midjourney, DALL-E, Stable Diffusion

#️⃣C#

Книги для шарпистов | C#, .NET, F#
Библиотека шарписта — полезные статьи, новости и обучающие материалы по C#
Библиотека задач по C# — код, квизы и тесты
Библиотека собеса по C# — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Вакансии по C#, .NET, Unity Вакансии по PHP, Symfony, Laravel

☁️DevOps

Библиотека devops’а — полезные статьи, новости и обучающие материалы по DevOps
Вакансии по DevOps & SRE
Библиотека задач по DevOps — код, квизы и тесты
Библиотека собеса по DevOps — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования

🐘PHP

Библиотека пхпшника — полезные статьи, новости и обучающие материалы по PHP
Вакансии по PHP, Symfony, Laravel
Библиотека PHP для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по PHP — код, квизы и тесты

🐍Python

Библиотека питониста — полезные статьи, новости и обучающие материалы по Python
Вакансии по питону, Django, Flask
Библиотека Python для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Python — код, квизы и тесты

Java

Книги для джавистов | Java
Библиотека джависта — полезные статьи по Java, новости и обучающие материалы
Библиотека Java для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Java — код, квизы и тесты
Вакансии для java-разработчиков

👾Data Science

Книги для дата сайентистов | Data Science
Библиотека Data Science — полезные статьи, новости и обучающие материалы по Data Science
Библиотека Data Science для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Data Science — код, квизы и тесты
Вакансии по Data Science, анализу данных, аналитике, искусственному интеллекту

🦫Go

Книги для Go разработчиков
Библиотека Go разработчика — полезные статьи, новости и обучающие материалы по Go
Библиотека Go для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Go — код, квизы и тесты
Вакансии по Go

🧠C++

Книги для C/C++ разработчиков
Библиотека C/C++ разработчика — полезные статьи, новости и обучающие материалы по C++
Библиотека C++ для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по C++ — код, квизы и тесты
Вакансии по C++

💻Другие каналы

Библиотека фронтендера
Библиотека мобильного разработчика
Библиотека хакера
Библиотека тестировщика
Вакансии по фронтенду, джаваскрипт, React, Angular, Vue
Вакансии для мобильных разработчиков
Вакансии по QA тестированию
InfoSec Jobs — вакансии по информационной безопасности
Библиотека разработчика игр | Gamedev, Unity, Unreal Engine

📁Чтобы добавить папку с нашими каналами, нажмите 👉сюда👈

Также у нас есть боты:
Бот с IT-вакансиями
Бот с мероприятиями в сфере IT

Мы в других соцсетях:
🔸VK
🔸YouTube
🔸Дзен
🔸Facebook *
🔸Instagram *

* Организация Meta запрещена на территории РФ
👍2🔥21👏1
Что такое дедлок, и как его избежать?

Дедлок (взаимная блокировка) — это ситуация, при которой два или более потока навсегда блокируют друг друга, ожидая освобождения ресурсов, которые каждый из них удерживает. Такой "замкнутый круг" возникает, если два потока пытаются получить доступ к ресурсам, уже занятым друг другом.

🎯 Пример: A захватил ресурс 1 и пытается получить доступ к ресурсу 2, а поток B в это же время захватил ресурс 2 и пытается получить доступ к ресурсу 1. Это приведёт к дедлоку, так как оба потока будут в бесконечном ожидании.

💻 Как избежать:

- Гарантировать, что все потоки запрашивают ресурсы в одинаковом порядке.
- Использование tryLock()
- Избегать слишком большого количества вложенных синхронизированных блоков, чтобы снизить вероятность взаимных блокировок.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🔥2
Что означает ключевое слово native?

Ключевое слово native обозначает, что метод реализован не на Java, а, как правило, на языке C или C++. Такие методы, называемые "native-методами", позволяют Java-классам взаимодействовать с кодом на уровне операционной системы или с другими программами, что полезно при работе с аппаратными ресурсами или для повышения производительности в специфичных задачах. Native-методы подключаются через JNI (Java Native Interface), который предоставляет мост между Java и низкоуровневым кодом.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥411🎉1
Какие есть методы в Stream API?

1️⃣ Промежуточные операции (Intermediate) - эти методы возвращают новый Stream, позволяя строить конвейеры:

- filter(Predicate<T> predicate) — фильтрация элементов.
- map(Function<T, R> mapper) — К каждому элементу применяется функция, возвращается одно значение.
- flatMap(Function<T, Stream<R>> mapper) — К каждому элементу применяется функция, возвращается поток для каждого значения. Затем все потоки объединяются в один общий поток.
- sorted(Comparator<T> comparator) — сортировка.
- distinct() — удаление дубликатов.
- limit(long maxSize) / skip(long n) — ограничение или пропуск элементов.

2️⃣ Терминальные операции (Terminal) - эти методы завершают поток и возвращают результат:

- forEach(Consumer<T> action) — выполнение действия для каждого элемента.
- collect(Collector<T, A, R>) — преобразование в коллекцию или другой объект.
- reduce(BinaryOperator<T> accumulator) — агрегация.
- count() — количество элементов.
- anyMatch, allMatch, noneMatch(Predicate<T>) — проверки условий.
- findFirst(), findAny() — поиск элементов.

3️⃣ Параллельные операции - для работы с большими данными:

- parallel() — перевод в параллельный поток.
- sequential() — возврат к последовательному выполнению.

4️⃣ Создание потоков:

- Stream.of(T... values) — из значений.
- Arrays.stream(T[] array) — из массива.
- Stream.generate(Supplier<T>) / Stream.iterate(T seed, UnaryOperator<T>) — создание бесконечных потоков.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥21🎉1
👀 Задачи с собеседований: Проверка, является ли бинарное дерево деревом поиска (middle)

— Как определить, является ли заданное бинарное дерево деревом поиска (BST)?

💡 Ключевые моменты:

- Бинарное дерево поиска (BST) — это бинарное дерево, в котором для каждого узла все значения в левом поддереве меньше значения узла, а все значения в правом поддереве больше.
- Для проверки можно использовать рекурсивный подход с отслеживанием допустимых диапазонов значений для каждого узла.
- Как изменить реализацию для работы с любыми типами данных в узлах дерева?

Реализация с числами в узлах на картинке 👆🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍3🤔1🎉1
ℹ️ Что такое нормализация базы данных, и какие существуют нормальные формы?

Нормализация — это процесс приведения структуры базы данных к оптимальному виду для устранения избыточности данных и обеспечения их целостности. Процесс состоит из последовательных этапов, соответствующих нормальным формам (НФ).

Основные нормальные формы (НФ):

1️⃣ Первая нормальная форма (1НФ):
Данные делятся на атомарные (неделимые) значения.
Пример: В одной ячейке таблицы не может быть списка телефонов, вместо этого создается отдельная строка для каждого телефона.

2️⃣ Вторая нормальная форма (2НФ):
Требует выполнения 1НФ и исключения зависимости от части составного первичного ключа. Это устраняет проблему дублирования данных.
Пример: Если таблица использует составной ключ (например, "Курс" и "Студент"), информация, относящаяся только к "Курсу", выносится в отдельную таблицу.

3️⃣ Третья нормальная форма (3НФ):
Выполняется 2НФ и устраняются транзитивные зависимости — неключевые атрибуты должны зависеть только от ключа.
Пример: Если в таблице есть "ID сотрудника", "Отдел" и "Название отдела", то "Название отдела" переносится в отдельную таблицу "Отделы".

Редко используемые нормальные формы:

- Нормальная форма Бойса-Кодда (BCNF): Уточнённая версия 3НФ, где каждое определяющее множество является суперключом. Используется для устранения более сложных аномалий.
- Четвёртая нормальная форма (4НФ): Устраняет многозначные зависимости, которые появляются при использовании нескольких связей между одними и теми же атрибутами.
- Пятая нормальная форма (5НФ): Делает базу данных устойчивой к разделению данных, устраняя зависимости соединений.

Эти формы применяются в сложных сценариях, например, при проектировании корпоративных систем с огромным количеством взаимосвязей. Для большинства приложений 3НФ оказывается достаточной.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥6🎉21
🔨🐳 Секреты стройности от многоэтапной сборки

Docker-образы тоже мечтают сбросить пару лишних мегабайтов и выглядеть подтянутыми. Если ваши контейнеры уже начали тяжело вздыхать на старте или требуют отдельного хранилища для своих «боков», самое время узнать, как их «подсушить».

В статье «Стройные контейнеры: как уменьшить Docker-образ с помощью многоэтапной сборки» раскрываются секреты того, как отправить ваш образ на диету и сделать его быстрее, легче и безопаснее.

📎 Читать статью
👍41🔥1