View on GitHub

java-interview

Вопросы для собеседования на разработчика Java

Вопросы для собеседования

Проектирование ПО

Что такое «интернационализация», «локализация»?

Интернационализация (internationalization) - способ создания приложений, при котором их можно легко адаптировать для разных аудиторий, говорящих на разных языках.

Локализация (localization) - адаптация интерфейса приложения под несколько языков. Добавление нового языка может внести определенные сложности в локализацию интерфейса.

к оглавлению

Что такое Big O («O большое»)?

Big O («O большое») - математическое обозначение для сравнения асимптотического поведения функций. Другими словами в программировании Big O показывает верхнюю границу зависимости между входными параметрами функции и количеством операций, которое выполнит процессор.

При расчёте Big O:

В алгоритмах, где каждую итерацию берётся половина элементов, сложность будет включать O(log N), так как максимальное количество итераций равно 2^N, где N - количество элементов.

Существует также Θ («тета») для точной верхней и нижней оценки, Ω («омега большое») для неточной нижней оценки границы.

к оглавлению

Рассчитайте сложность следующей функции

int[] a = int[N]; //N - натуральное число
int s = 0;
for (int i = 0; i < a.length; i++) {
    for (int j = i; i < a.length; i++) {
        s = i + j;
    }
}

Первый массив O(N), второй массив O(N + (N-1) + (N-2) + … + 2 + 1), т.е. общий будет равен O (N^2/2). Отбрасывая константы, получаем в итоге O ( N^2).

к оглавлению

Какие Вы знаете алгоритмы сортировки?

В таблице ниже приведены основные виды сортировок и оценка времени выполнения

Название Лучшее Среднее Худшее
Quicksort Ω(n log(n)) Θ(n log(n)) O(n^2)
Mergesort Ω(n log(n)) Θ(n log(n)) O(n log(n))
Timsort Ω(n) Θ(n log(n)) O(n log(n))
Heapsort Ω(n log(n)) Θ(n log(n)) O(n log(n))
Bubble Sort Ω(n) Θ(n^2) O(n^2)
Insertion Sort Ω(n) Θ(n^2) O(n^2)
Selection Sort Ω(n^2) Θ(n^2) O(n^2)
Tree Sort Ω(n log(n)) Θ(n log(n)) O(n^2)
Shell Sort Ω(n log(n)) Θ(n(log(n))^2) O(n(log(n))^2)
Bucket Sort Ω(n+k) Θ(n+k) O(n^2)
Radix Sort Ω(nk) Θ(nk) O(nk)
Counting Sort Ω(n+k) Θ(n+k) O(n+k)
Cubesort Ω(n) Θ(n log(n)) O(n log(n))

к оглавлению

Опишите термин «технический долг»

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

Общие причины технического долга (может быть несколько):

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

к оглавлению

Что означает «унаследованный код»?

Унаследованный код (legacy code) нередко употребляется как жаргонное обозначение трудноизменяемого кода, который совершенно непонятен. На самом деле унаследованный код — это просто код без тестов.

Изменения в коде делаются двумя основными способами:

В основу метода Cover and Modify положен принцип работы с «сеткой безопасности». Это своего рода покров из тестов, который мы надеваем на код в процессе работы, чтобы исключить из него утечку неудачных изменений. Имея в своем распоряжении хороший набор тестов, окружающий фрагмент кода, мы можем вносить изменения и быстро обнаруживать их положительное или отрицательное воздействие на код.

к оглавлению

Что такое UML?

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

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

к оглавлению

Что такое «диаграмма», «нотация» и «метамодель» в UML?

Диаграмма - графическое представление совокупности элементов модели в форме связного графа, вершинам и ребрам (дугам) которого приписывается определенная семантика

Нотация – совокупность символов и правила их применения, используются для представления понятий и связей между ними. Нотация диаграммы определяет способ представления, ассоциации, множественности. Причем эти понятия должны быть точно определены.

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

к оглавлению

Какие существуют типы диаграмм в UML?

Структурные диаграммы:

классов (Class diagram) описывает структуру системы, демонстрирующая классы системы, их атрибуты, методы и зависимости между классами.

объектов (Object diagram) демонстрирует полный или частичный снимок моделируемой системы в заданный момент времени. На диаграмме объектов отображаются экземпляры классов (объекты) системы с указанием текущих значений их атрибутов и связей между объектами.

компонентов (Component diagram) показывает разбиение программной системы на структурные компоненты и связи (зависимости) между компонентами.

Диаграммы поведения:

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

состояний/автомата/конечного автомата (State Machine diagram) представляет конечный автомат с простыми состояниями, переходами и композитными состояниями. Конечный автомат (State machine) — спецификация последовательности состояний, через которые проходит объект или взаимодействие в ответ на события своей жизни, а также ответные действия объекта на эти события. Конечный автомат прикреплён к исходному элементу (классу, кооперации или методу) и служит для определения поведения его экземпляров.

вариантов использования/прецедентов (Use case diagram) отражает отношения существующие между актёрами и вариантами использования. Основная задача — представлять собой единое средство, дающее возможность заказчику, конечному пользователю и разработчику совместно обсуждать функциональность и поведение системы.

взаимодействия (Interaction diagram):

к оглавлению

Какие виды отношений существуют в структурной диаграмме классов в UML?

Взаимосвязи классов

Обобщение (Generalization) показывает, что один из двух связанных классов (подтип) является частной формой другого (супертипа), который называется обобщением первого. На практике это означает, что любой экземпляр подтипа является также экземпляром супертипа. Обобщение также известно как наследование, «is a» взаимосвязь или отношение «является».

«Табурет» является подтипом «Мебели».

Реализация (Implementation) — отношение между двумя элементами модели, в котором один элемент (клиент) реализует поведение, заданное другим (поставщиком). Реализация — отношение целое-часть. Поставщик, как правило, является абстрактным классом или классом-интерфейсом.

«Кровать» реализует поведение «Мебели для сна»

Взаимосвязи объектов классов

Зависимость (Dependency) обозначает такое отношение между классами, что изменение спецификации класса-поставщика может повлиять на работу зависимого класса, но не наоборот.

«Расписание занятий» имеет зависимость от «Списка предметов». При изменении списка предметов расписание занятий будет вынуждено изменится. Однако изменение расписания занятий никак не влияет на список предметов.

Ассоциация (Association) показывает, что объекты одной сущности (класса) связаны с объектами другой сущности таким образом, что можно перемещаться от объектов одного класса к другому. Является общим случаем композиции и агрегации.

«Студент» и «Университет» имеют ассоциацию т.к. студент может учиться в университете и этой ассоциации можно присвоить имя «учится в».

Агрегация (Aggregation) — это разновидность ассоциации в отношении между целым и его частями. Как тип ассоциации агрегация может быть именованной. Одно отношение агрегации не может включать более двух классов (контейнер и содержимое). Агрегация встречается, когда один класс является коллекцией или контейнером других. Причём по умолчанию, агрегацией называют агрегацию по ссылке, то есть когда время существования содержащихся классов не зависит от времени существования содержащего их класса. Если контейнер будет уничтожен, то его содержимое — нет.

«Студент» не является неотъемлемой частью «Группы», но в то же время, группа состоит из студентов, поэтому следует использовать агрегацию.

Композиция (Composition) — более строгий вариант агрегации. Известна также как агрегация по значению. Композиция имеет жёсткую зависимость времени существования экземпляров класса контейнера и экземпляров содержащихся классов. Если контейнер будет уничтожен, то всё его содержимое будет также уничтожено.

«Факультет» является частью «Университета» и факультет без университета существовать не может, следовательно, здесь подходит композиция.

Общие взаимосвязи

Зависимость — это слабая форма отношения использования, при котором изменение в спецификации одного влечёт за собой изменение другого, причём обратное не обязательно. Возникает, когда объект выступает, например, в форме параметра или локальной переменной. Существует несколько именованных вариантов. Зависимость может быть между экземплярами, классами или экземпляром и классом.

Уточнение отношений имеет отношение к уровню детализации. Один пакет уточняет другой, если в нём содержатся те же самые элементы, но в более подробном представлении.

Мощность/кратность/мультипликатор отношения означает число связей между каждым экземпляром класса (объектом) в начале линии с экземпляром класса в её конце. Различают следующие типичные случаи:

Нотация Объяснение Пример
0..1 Ноль или один экземпляр кошка имеет или не имеет хозяина
1 Обязательно один экземпляр у кошки одна мать
0..или Ноль или более экземпляров у кошки могут быть, а может и не быть котят
1..* Один или более экземпляров у кошки есть хотя бы одно место, где она спит

к оглавлению

Что такое SOLID?

SOLID (сокр. от англ. single responsibility, open-closed, Liskov substitution, interface segregation и dependency inversion) в программировании — мнемонический акроним, введённый Michael Feathers для первых пяти принципов, названных Робертом Мартином в начале 2000-х, которые означали пять основных принципов объектно-ориентированного программирования и проектирования. При создании программных систем использование принципов SOLID способствует созданию такой системы, которую будет легко поддерживать и расширять в течение долгого времени. Принципы SOLID — это руководства, которые также могут применяться во время работы над существующим программным обеспечением для его улучшения - например для удаления «дурно пахнущего кода».

к оглавлению

Что такое «шаблон проектирования»?

Шаблон (паттерн) проектирования (design pattern) — это проверенное и готовое к использованию решение. Это не класс и не библиотека, которую можно подключить к проекту, это нечто большее - он не зависит от языка программирования, не является законченным образцом, который может быть прямо преобразован в код и может быть реализован по разному в разных языках программирования.

Плюсы использования шаблонов:

Минусы:

к оглавлению

Назовите основные характеристики шаблонов

к оглавлению

Типы шаблонов проектирования

к оглавлению

Приведите примеры основных шаблонов проектирования

к оглавлению

Приведите примеры порождающих шаблонов проектирования

к оглавлению

Приведите примеры структурных шаблонов проектирования

к оглавлению

Приведите примеры поведенческих шаблонов проектирования

к оглавлению

Что такое шаблон MVC?

Model-View-Controller (MVC, «Модель-Представление-Контроллер», «Модель-Вид-Контроллер»)— схема разделения данных приложения, пользовательского интерфейса и управляющей логики на три отдельных компонента: модель, представление и контроллер — таким образом, что модификация каждого компонента может осуществляться независимо.

к оглавлению

Что такое GRASP?

GRASP (англ. general responsibility assignment software patterns) — шаблоны, используемые в объектно-ориентированном проектировании для решения общих задач по назначению ответственностей классам и объектам. В книге Крейга Лармана «Применение UML и шаблонов проектирования» описано 9 таких шаблонов: каждый помогает решить некоторую проблему, возникающую как в объектно-ориентированном анализе, так и в практически любом проекте по разработке программного обеспечения. Таким образом, шаблоны «G.R.A.S.P.» — хорошо документированные, стандартизированные и проверенные временем принципы объектно-ориентированного анализа, а не попытка привнести что-то принципиально новое.

к оглавлению

Что такое «антипаттерн»? Какие антипаттерны вы знаете?

Антипаттерн (anti-pattern) — это распространённый подход к решению класса часто встречающихся проблем, являющийся неэффективным, рискованным или непродуктивным.

Poltergeists (полтергейсты) - это классы с ограниченной ответственностью и ролью в системе, чьё единственное предназначение — передавать информацию в другие классы. Их эффективный жизненный цикл непродолжителен. Полтергейсты нарушают стройность архитектуры программного обеспечения, создавая избыточные (лишние) абстракции, они чрезмерно запутанны, сложны для понимания и трудны в сопровождении. Обычно такие классы задумываются как классы-контроллеры, которые существуют только для вызова методов других классов, зачастую в предопределенной последовательности.

Признаки появления и последствия антипаттерна

Типичные причины

Внесенная сложность (Introduced complexity): Необязательная сложность дизайна. Вместо одного простого класса выстраивается целая иерархия интерфейсов и классов. Типичный пример «Интерфейс - Абстрактный класс - Единственный класс реализующий интерфейс на основе абстрактного».

Инверсия абстракции (Abstraction inversion): Сокрытие части функциональности от внешнего использования, в надежде на то, что никто не будет его использовать.

Неопределённая точка зрения (Ambiguous viewpoint): Представление модели без спецификации её точки рассмотрения.

Большой комок грязи (Big ball of mud): Система с нераспознаваемой структурой.

Божественный объект (God object): Концентрация слишком большого количества функций в одной части системы (классе).

Затычка на ввод данных (Input kludge): Забывчивость в спецификации и выполнении поддержки возможного неверного ввода.

Раздувание интерфейса (Interface bloat): Разработка интерфейса очень мощным и очень сложным для реализации.

Волшебная кнопка (Magic pushbutton): Выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса. Например, написание прикладной логики в обработчиках нажатий на кнопку.

Перестыковка (Re-Coupling): Процесс внедрения ненужной зависимости.

Дымоход (Stovepipe System): Редко поддерживаемая сборка плохо связанных компонентов.

Состояние гонки (Race hazard): отсутствие предвидения возможности наступления событий в порядке, отличном от ожидаемого.

Членовредительство (Mutilation): Излишнее «затачивание» объекта под определенную очень узкую задачу таким образом, что он не способен будет работать с никакими иными, пусть и очень схожими задачами.

Сохранение или смерть (Save or die): Сохранение изменений лишь при завершении приложения.

к оглавлению

Что такое Domain-driven design?

Предметно-ориентированное проектирование (реже проблемно-ориентированное, англ. Domain-driven design, DDD) — это набор принципов и схем, направленных на создание оптимальных систем объектов. Сводится к созданию программных абстракций, которые называются моделями предметных областей. В эти модели входит бизнес-логика, устанавливающая связь между реальными условиями области применения продукта и кодом. Предметно-ориентированное проектирование не является какой-либо конкретной технологией или методологией. DDD — это набор правил, которые позволяют принимать правильные проектные решения. Данный подход позволяет значительно ускорить процесс проектирования программного обеспечения в незнакомой предметной области. Подход DDD особо полезен в ситуациях, когда разработчик не является специалистом в области разрабатываемого продукта. К примеру: программист не может знать все области, в которых требуется создать ПО, но с помощью правильного представления структуры, посредством предметно-ориентированного подхода, может без труда спроектировать приложение, основываясь на ключевых моментах и знаниях рабочей области.

к оглавлению

Какие бывают гарантии доставки сообщений?

к оглавлению

Расскажите про Event-driven Architecture

Архитектура, управляемая событиями (англ. event-driven architecture, EDA) является шаблоном архитектуры программного обеспечения, позволяющим создание, определение, потребление и реакцию на события.

Событие можно определить как «существенное изменение состояния». Например, когда покупатель приобретает автомобиль, состояние автомобиля изменяется с «продаваемого» на «проданный». Системная архитектура продавца автомобилей может рассматривать это изменение состояния как событие, создаваемое, публикуемое, определяемое и потребляемое различными приложениями в составе архитектуры.

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

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

Архитектура, управляемая событиями соответствует сервисно-ориентированной архитектуре (SOA), поскольку сервисы могут активироваться триггерами, срабатывающими от входящих событий.

Эта парадигма особенно полезна в случае, когда сток не предоставляет собственного исполнения действий.

к оглавлению

Расскажите про Service-oriented Architecture (SOA)?

Сервис-ориентированная архитектура (англ. service-oriented architecture, SOA) — модульный подход к разработке программного обеспечения, основанный на использовании распределённых, слабо связанных (англ. loose coupling) заменяемых компонентов, оснащённых стандартизированными интерфейсами для взаимодействия по стандартизированным протоколам.

Программные комплексы, разработанные в соответствии с сервис-ориентированной архитектурой, обычно реализуются как набор веб-служб, взаимодействующих по протоколу SOAP, но существуют и другие реализации (например, на базе jini, CORBA, на основе REST).

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

к оглавлению

Что такое микросервисы?

Микросервисная архитектура (англ. microservice architecture, MSA) — вариант сервис-ориентированной архитектуры программного обеспечения, направленный на взаимодействие насколько это возможно небольших, слабо связанных и легко изменяемых модулей — микросервисов.

Свойства, характерные для микросервисной архитектуры:

к оглавлению

Расскажите про Enterprise Integration Patterns (EIP)?

Шаблоны интеграции корпоративных приложений (англ. enterprise integration patterns, EIP) состоят из 65 шаблонов, которые описывают использование приложений уровня предприятия и связующего программное обеспечения, ориентированного на обработку сообщений (англ. message-oriented middleware, MOM).

Реализуются такими продуктами, как Spring Integration, Apache Camel, Red Hat Fuse, Mule ESB and Guarana DSL.

к оглавлению

Расскажите про Patterns of Enterprise Applications Architecture (PoEAA)?

Каталог архитектурных шаблонов приложений уровня предприятия, состоит из следующих категорий:

к оглавлению

Расскажите про CQRS?

Разделение ответственности на команды и запросы (англ. command-query responsibility segregation, CQRS) — шаблон проектирования для разделения операций чтения и записи, где первый - это запрос, а второй - команда. Команды изменяют состояние и, следовательно, приблизительно эквивалентны вызову метода для агрегатных корней / сущностей. Запрашивает состояние запроса, но не изменяет его. CQRS является производным архитектурным шаблоном из шаблона проектирования под названием «Разделение команд и запросов» (CQS), который был придуман Бертраном Мейером. В то время как CQRS не требует DDD, проектирование на основе домена делает явным различие между командами и запросами вокруг концепции совокупного корня. Идея состоит в том, что данный агрегатный корень имеет метод, соответствующий команде, и обработчик команд вызывает метод в агрегатном корне. Совокупный корень отвечает за выполнение логики операции и выдачу либо количества событий, либо ответа об ошибке (перечисление / номер исключения или результата выполнения) ИЛИ (если не используется Event Sourcing (ES)), просто изменяющего свое состояние для сохранить реализацию, такую ​​как ORM, для записи в хранилище данных, в то время как обработчик команд отвечает за рассмотрение проблем инфраструктуры, связанных с сохранением состояния или событий совокупного корня, и создание необходимых контекстов (например, транзакций).

к оглавлению

Расскажите про Event Sourcing?

(англ. event sourcing, ES) - шаблон проектирования, который гарантирует, что ваши сущности (согласно DDD) не отслеживают свое внутреннее состояние посредством прямой сериализации или ORM, а посредством чтения и фиксации событий в хранилище событий. В тех случаях, когда ES объединяется с CQRS и DDD, совокупные корни отвечают за тщательную проверку и применение команд (часто с помощью вызова методов их экземпляров из обработчика команд), а затем за публикацию одного или нескольких событий, которые также являются основой для которые агрегированные корни основывают свою логику для работы с вызовами методов. Следовательно, входные данные представляют собой команду, а выходные данные представляют собой одно или несколько событий, которые транзакционно (единая фиксация) сохраняются в хранилище событий, а затем часто публикуются в брокере сообщений для пользы тех, кто заинтересован (часто представления интересуются; они затем запрашиваются с помощью Query-сообщений). При моделировании ваших агрегатных корней для выходных событий вы можете изолировать внутреннее состояние даже дальше, чем это было бы возможно при проецировании данных чтения из ваших сущностей, как это делается в стандартных n-уровневых архитектурах передачи данных. Одним из существенных преимуществ этого является то, что такие инструменты, как средства аксиоматической проверки теорем (например, Microsoft Contracts и CHESS), проще в применении, поскольку совокупный корень полностью скрывает свое внутреннее состояние. События часто сохраняются в зависимости от версии совокупного корневого экземпляра, что дает модель предметной области, которая синхронизируется в распределенных системах вокруг концепции оптимистичного параллелизма.

к оглавлению

Что такое ACID?

В информатике акроним ACID описывает требования к транзакционной системе (например, к СУБД), обеспечивающие наиболее надёжную и предсказуемую её работу.

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

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

к оглавлению

В чем смысл CAP теоремы?

Теорема CAP — эвристическое утверждение, что в любой реализации распределённых вычислений возможно обеспечить не более двух из трёх следующих свойств:

к оглавлению

Что такое BASE-архитектура?

BASE (англ. Basically Available, Soft-state, Eventually consistent) — базовая доступность, неустойчивое состояние, согласованность в конечном счёте - подход построения распределённых систем. Такой подход напрямую противопоставляется ACID.

к оглавлению

Что такое CRDT?

Бесконфликтные реплицированные типы данных (англ. Conflict-free replicated data type, CRDT) - структуры, в которых обеспечивается сильная согласованность в конечном счёте (англ. strong eventual consistency,SEC) и монотонность состояний. Из известных, описанных в работах и реализованных в библиотеках, есть такие структуры:

к оглавлению

Вопросы для собеседования