Проектирование ПО
- Что такое «интернационализация», «локализация»?
- Что такое Big O («O большое»)?
- Рассчитайте сложность следующей функции
- Какие Вы знаете алгоритмы сортировки?
- Опишите термин «технический долг»
- Что означает «унаследованный код»?
- Что такое UML?
- Что такое «диаграмма», «нотация» и «метамодель» в UML?
- Какие существуют типы диаграмм в UML?
- Какие виды отношений существуют в структурной диаграмме классов в UML?
- Что такое SOLID?
- Что такое «шаблон проектирования»?
- Назовите основные характеристики шаблонов
- Типы шаблонов проектирования
- Приведите примеры основных шаблонов проектирования
- Приведите примеры порождающих шаблонов проектирования
- Приведите примеры структурных шаблонов проектирования
- Приведите примеры поведенческих шаблонов проектирования
- Что такое шаблон MVC?
- Что такое GRASP?
- Что такое «антипаттерн»? Какие антипаттерны вы знаете?
- Что такое Domain-driven design?
- Какие бывают гарантии доставки сообщений?
- Расскажите про Event-driven Architecture
- Расскажите про Service-oriented Architecture (SOA)?
- Что такое микросервисы?
- Расскажите про Enterprise Integration Patterns (EIP)?
- Расскажите про Patterns of Enterprise Applications Architecture (PoEAA)?
- Расскажите про CQRS?
- Расскажите про Event Sourcing?
- Что такое ACID?
- В чем смысл CAP теоремы?
- Что такое BASE-архитектура?
- Что такое CRDT?
Что такое «интернационализация», «локализация»?
Интернационализация (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) нередко употребляется как жаргонное обозначение трудноизменяемого кода, который совершенно непонятен. На самом деле унаследованный код — это просто код без тестов.
Изменения в коде делаются двумя основными способами:
- правка наудачу (Edit and Pray)
- покрытие и модификация (Cover and Modify)
В основу метода Cover and Modify положен принцип работы с «сеткой безопасности». Это своего рода покров из тестов, который мы надеваем на код в процессе работы, чтобы исключить из него утечку неудачных изменений. Имея в своем распоряжении хороший набор тестов, окружающий фрагмент кода, мы можем вносить изменения и быстро обнаруживать их положительное или отрицательное воздействие на код.
Что такое UML?
UML – это унифицированный графический язык моделирования для описания, визуализации, проектирования и документирования объектно-ориентированных систем. UML призван поддерживать процесс моделирования на основе объектно-ориентированного подхода, организовывать взаимосвязь концептуальных и программных понятий, отражать проблемы масштабирования сложных систем.
Отличительной особенностью UML является то, что словарь этого языка образуют графические элементы. Каждому графическому символу соответствует конкретная семантика, поэтому модель, созданная одним человеком, может однозначно быть понята другим человеком или программным средством, интерпретирующим UML. Отсюда, в частности, следует, что модель системы, представленная на UML, может автоматически быть переведена на объектно-ориентированный язык программирования, то есть, при наличии хорошего инструментального средства визуального моделирования, поддерживающего UML, построив модель, мы получим и заготовку программного кода, соответствующего этой модели.
Что такое «диаграмма», «нотация» и «метамодель» в UML?
Диаграмма - графическое представление совокупности элементов модели в форме связного графа, вершинам и ребрам (дугам) которого приписывается определенная семантика
Нотация – совокупность символов и правила их применения, используются для представления понятий и связей между ними. Нотация диаграммы определяет способ представления, ассоциации, множественности. Причем эти понятия должны быть точно определены.
Метамодель – диаграмма, определяющая нотацию. Метамодель помогает понять, что такое хорошо организованная, т.е. синтаксически правильная, модель.
Какие существуют типы диаграмм в UML?
Структурные диаграммы:
классов (Class diagram) описывает структуру системы, демонстрирующая классы системы, их атрибуты, методы и зависимости между классами.
объектов (Object diagram) демонстрирует полный или частичный снимок моделируемой системы в заданный момент времени. На диаграмме объектов отображаются экземпляры классов (объекты) системы с указанием текущих значений их атрибутов и связей между объектами.
компонентов (Component diagram) показывает разбиение программной системы на структурные компоненты и связи (зависимости) между компонентами.
-
развёртывания/размещения (Deployment diagram) служит для моделирования работающих узлов и артефактов, развёрнутых на них.
-
пакетов (Package diagram) используется для организации элементов в группы по какому-либо признаку с целью упрощения структуры и организации работы с моделью системы.
-
профилей (Profile diagram) действует на уровне метамодели и показывает стереотип класса или пакета.
-
композитной/составной структуры (Composite structure diagram) демонстрирует внутреннюю структуру класса и, по возможности, взаимодействие элементов (частей) его внутренней структуры.
- кооперации (Collaboration diagram) показывает роли и взаимодействие классов в рамках кооперации.
Диаграммы поведения:
деятельности (Activity diagram) показывает разложение некоторой деятельности на её составные части. Под деятельностью понимается спецификация исполняемого поведения в виде координированного последовательного и параллельного выполнения подчинённых элементов — вложенных видов деятельности и отдельных действий, соединённых между собой потоками, которые идут от выходов одного узла к входам другого. Диаграммы деятельности используются при моделировании бизнес-процессов, технологических процессов, последовательных и параллельных вычислений.
состояний/автомата/конечного автомата (State Machine diagram) представляет конечный автомат с простыми состояниями, переходами и композитными состояниями. Конечный автомат (State machine) — спецификация последовательности состояний, через которые проходит объект или взаимодействие в ответ на события своей жизни, а также ответные действия объекта на эти события. Конечный автомат прикреплён к исходному элементу (классу, кооперации или методу) и служит для определения поведения его экземпляров.
вариантов использования/прецедентов (Use case diagram) отражает отношения существующие между актёрами и вариантами использования. Основная задача — представлять собой единое средство, дающее возможность заказчику, конечному пользователю и разработчику совместно обсуждать функциональность и поведение системы.
взаимодействия (Interaction diagram):
-
коммуникации (Communication diagram) изображает взаимодействия между частями композитной структуры или ролями кооперации при этом явно указываются отношения между элементами (объектами), а время как отдельное измерение не используется (применяются порядковые номера вызовов).
-
последовательности (Sequence diagram) показывает взаимодействия объектов, упорядоченные по времени их проявления.
-
обзора взаимодействия (Interaction overview diagram) — разновидность диаграммы деятельности, включающая фрагменты диаграммы последовательности и конструкции потока управления.
-
синхронизации (Timing 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 — это руководства, которые также могут применяться во время работы над существующим программным обеспечением для его улучшения - например для удаления «дурно пахнущего кода».
- Принцип единственной ответственности (The Single Responsibility Principle, SRP) — принцип ООП, обозначающий, что каждый объект должен иметь одну ответственность и эта ответственность должна быть полностью инкапсулирована в класс. Все его поведения должны быть направлены исключительно на обеспечение этой ответственности.
- При́нцип откры́тости/закры́тости (The Open Closed Principle, OCP) - принцип ООП, устанавливающий следующее положение: «программные сущности (классы, модули, функции и т. п.) должны быть открыты для расширения, но закрыты для изменения».
- Принцип подстановки Барбары Лисков (Liskov Substitution Principle, LSP) - в объектно-ориентированном программировании является специфичным определением подтипа, предложенным Барбарой Лисков в 1987 году на конференции в основном докладе под названием Абстракция данных и иерархия.
- Принцип разделения интерфейса (Interface Segregation Principle, ISP) - данный принцип говорит, что слишком «толстые» интерфейсы необходимо разделять на более маленькие и специфические, чтобы программные сущности маленьких интерфейсов знали только о методах, которые необходимы им в работе.
- Принцип инверсии зависимостей (Dependency inversion principle, DIP) - важный принцип объектно-ориентированного программирования, используемый для уменьшения зацепления в компьютерных программах. Является частным случаем «Инверсии контроля» (Inversion of Control).
Что такое «шаблон проектирования»?
Шаблон (паттерн) проектирования (design pattern) — это проверенное и готовое к использованию решение. Это не класс и не библиотека, которую можно подключить к проекту, это нечто большее - он не зависит от языка программирования, не является законченным образцом, который может быть прямо преобразован в код и может быть реализован по разному в разных языках программирования.
Плюсы использования шаблонов:
- снижение сложности разработки за счёт готовых абстракций для решения целого класса проблем.
- облегчение коммуникации между разработчиками, позволяя ссылаться на известные шаблоны.
- унификация деталей решений: модулей и элементов проекта.
- возможность отыскав удачное решение, пользоваться им снова и снова.
- помощь в выборе выбрать наиболее подходящего варианта проектирования.
Минусы:
- слепое следование некоторому выбранному шаблону может привести к усложнению программы.
- желание попробовать некоторый шаблон в деле без особых на то оснований.
Назовите основные характеристики шаблонов
- Имя - все шаблоны имеют уникальное имя, служащее для их идентификации;
- Назначение назначение данного шаблона;
- Задача - задача, которую шаблон позволяет решить;
- Способ решения - способ, предлагаемый в шаблоне для решения задачи в том контексте, где этот шаблон был найден;
- Участники - сущности, принимающие участие в решении задачи;
- Следствия - последствия от использования шаблона как результат действий, выполняемых в шаблоне;
- Реализация - возможный вариант реализации шаблона.
Типы шаблонов проектирования
- Основные (Fundamental) - основные строительные блоки других шаблонов. Большинство других шаблонов использует эти шаблоны в той или иной форме.
- Порождающие шаблоны (Creational) — шаблоны проектирования, которые абстрагируют процесс создание экземпляра. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять созданный объект, а шаблон, порождающий объекты, делегирует создание объектов другому объекту.
- Структурные шаблоны (Structural) определяют различные сложные структуры, которые изменяют интерфейс уже существующих объектов или его реализацию, позволяя облегчить разработку и оптимизировать программу.
- Поведенческие шаблоны (Behavioral) определяют взаимодействие между объектами, увеличивая таким образом его гибкость.
Приведите примеры основных шаблонов проектирования
- Делегирование (Delegation pattern) - Сущность внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту.
- Функциональный дизайн (Functional design) - Гарантирует, что каждая сущность имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие.
- Неизменяемый интерфейс (Immutable interface) - Создание неизменяемого объекта.
- Интерфейс (Interface) - Общий метод структурирования сущностей облегчающий их понимание.
- Интерфейс-маркер (Marker interface) - В качестве атрибута (как пометки объектной сущности) применяется наличие или отсутствие реализации интерфейса-маркера. В современных языках программирования вместо этого применяются атрибуты или аннотации.
- Контейнер свойств (Property container) - Позволяет добавлять дополнительные свойства сущности в контейнер внутри себя, вместо расширения новыми свойствами.
- Канал событий (Event channel) - Создаёт централизованный канал для событий. Использует сущность-представитель для подписки и сущность-представитель для публикации события в канале. Представитель существует отдельно от реального издателя или подписчика. Подписчик может получать опубликованные события от более чем одной сущности, даже если он зарегистрирован только на одном канале.
Приведите примеры порождающих шаблонов проектирования
- Абстрактная фабрика (Abstract factory) - Класс, который представляет собой интерфейс для создания других классов.
- Строитель (Builder) - Класс, который представляет собой интерфейс для создания сложного объекта.
- Фабричный метод (Factory method) - Делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне.
- Прототип (Prototype) - Определяет интерфейс создания объекта через клонирование другого объекта вместо создания через конструктор.
- Одиночка (Singleton) - Класс, который может иметь только один экземпляр.
Приведите примеры структурных шаблонов проектирования
- Адаптер (Adapter) - Объект, обеспечивающий взаимодействие двух других объектов, один из которых использует, а другой предоставляет несовместимый с первым интерфейс.
- Мост (Bridge) - Структура, позволяющая изменять интерфейс обращения и интерфейс реализации класса независимо.
- Компоновщик (Composite) - Объект, который объединяет в себе объекты, подобные ему самому.
- Декоратор(Decorator) - Класс, расширяющий функциональность другого класса без использования наследования.
- Фасад (Facade) - Объект, который абстрагирует работу с несколькими классами, объединяя их в единое целое.
- Приспособленец (Flyweight) - Это объект, представляющий себя как уникальный экземпляр в разных местах программы, но по факту не являющийся таковым.
- Заместитель (Proxy) - Объект являющийся посредником между двумя другими объектами и реализующий/ограничивающий доступ к объекту, к которому обращаются через него.
Приведите примеры поведенческих шаблонов проектирования
- Цепочка обязанностей (Chain of responsibility) - Предназначен для организации в системе уровней ответственности.
- Команда (Command) - Представляет действие. Объект команды заключает в себе само действие и его параметры.
- Интерпретатор (Interpreter) - Решает часто встречающуюся, но подверженную изменениям, задачу.
- Итератор(Iterator) - Представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого + __из объектов, входящих в состав агрегации.
- Посредник (Mediator) - Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга.
- Хранитель (Memento) - Позволяет не нарушая инкапсуляцию зафиксировать и сохранить внутренние состояния объекта так, чтобы позднее восстановить его в этих состояниях.
- Наблюдатель(Observer) - Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии.
- Состояние (State) - Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния.
- Стратегия (Strategy) - Предназначен для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости.
- Шаблонный метод (Template method) - Определяет основу алгоритма и позволяет наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом.
- Посетитель (Visitor) - Описывает операцию, которая выполняется над объектами других классов. При изменении класса Visitor нет необходимости изменять обслуживаемые классы.
Что такое шаблон MVC?
Model-View-Controller (MVC, «Модель-Представление-Контроллер», «Модель-Вид-Контроллер»)— схема разделения данных приложения, пользовательского интерфейса и управляющей логики на три отдельных компонента: модель, представление и контроллер — таким образом, что модификация каждого компонента может осуществляться независимо.
- Модель (Model) - предоставляет данные и реагирует на команды контроллера, изменяя своё состояние.
- Представление (View) - отвечает за отображение данных модели пользователю, реагируя на изменения модели.
- Контроллер (Controller) - интерпретирует действия пользователя, оповещая модель о необходимости изменений.
Что такое GRASP?
GRASP (англ. general responsibility assignment software patterns) — шаблоны, используемые в объектно-ориентированном проектировании для решения общих задач по назначению ответственностей классам и объектам. В книге Крейга Лармана «Применение UML и шаблонов проектирования» описано 9 таких шаблонов: каждый помогает решить некоторую проблему, возникающую как в объектно-ориентированном анализе, так и в практически любом проекте по разработке программного обеспечения. Таким образом, шаблоны «G.R.A.S.P.» — хорошо документированные, стандартизированные и проверенные временем принципы объектно-ориентированного анализа, а не попытка привнести что-то принципиально новое.
- Информационный эксперт (Information Expert) - ответственность должна быть назначена тому, кто владеет максимумом необходимой информации для исполнения. Если его не учесть — получится спагетти-код, в котором трудно разобраться.
- Создатель (Creator) - класс должен создавать экземпляры тех классов, которые он может содержать или агрегировать, записывать, использовать, инициализировать, имея нужные данные.
- Контроллер (Controller) - отвечает за операции, запросы на которые приходят от пользователя, и может выполнять сценарии одного или нескольких вариантов использования (например, создание и удаление). Не выполняет работу самостоятельно, а делегирует компетентным исполнителям.
- Слабое зацепление (Low Coupling) - мера неотрывности элемента от других элементов (либо мера данных, имеющихся у него о них).
- Высокая связность (High Cohesion) - мера сфокусированности предметных областей его методов.
- Полиморфизм (Polymorphism) - Что такое «полиморфизм»?.
- Чистая выдумка (Pure Fabrication) - Не относится к предметной области, но уменьшает зацепление, повышает связность, упрощает повторное использование, отражает концепцию сервисов в модели проблемно-ориентированного проектирования.
- Посредник (Indirection) - слабое зацепление между элементами системы (и возможность повторного использования) обеспечивается назначением промежуточного объекта их посредником.
- Устойчивость к изменениям (Protected Variations) - Шаблон защищает элементы от изменения другими элементами (объектами или подсистемами) с помощью вынесения взаимодействия в фиксированный интерфейс, через который (и только через который) возможно взаимодействие между элементами. Поведение может варьироваться лишь через создание другой реализации интерфейса.
Что такое «антипаттерн»? Какие антипаттерны вы знаете?
Антипаттерн (anti-pattern) — это распространённый подход к решению класса часто встречающихся проблем, являющийся неэффективным, рискованным или непродуктивным.
Poltergeists (полтергейсты) - это классы с ограниченной ответственностью и ролью в системе, чьё единственное предназначение — передавать информацию в другие классы. Их эффективный жизненный цикл непродолжителен. Полтергейсты нарушают стройность архитектуры программного обеспечения, создавая избыточные (лишние) абстракции, они чрезмерно запутанны, сложны для понимания и трудны в сопровождении. Обычно такие классы задумываются как классы-контроллеры, которые существуют только для вызова методов других классов, зачастую в предопределенной последовательности.
Признаки появления и последствия антипаттерна
- Избыточные межклассовые связи.
- Временные ассоциации.
- Классы без состояния (содержащие только методы и константы).
- Временные объекты и классы (с непродолжительным временем жизни).
- Классы с единственным методом, который предназначен только для создания или вызова других классов посредством временной ассоциации.
- Классы с именами методов в стиле «управления», такие как startProcess.
Типичные причины
- Отсутствие объектно-ориентированной архитектуры (архитектор не понимает объектно-ориентированной парадигмы).
- Неправильный выбор пути решения задачи.
- Предположения об архитектуре приложения на этапе анализа требований (до объектно-ориентированного анализа) могут также вести к проблемам на подобии этого антипаттерна.
Внесенная сложность (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 особо полезен в ситуациях, когда разработчик не является специалистом в области разрабатываемого продукта. К примеру: программист не может знать все области, в которых требуется создать ПО, но с помощью правильного представления структуры, посредством предметно-ориентированного подхода, может без труда спроектировать приложение, основываясь на ключевых моментах и знаниях рабочей области.
Какие бывают гарантии доставки сообщений?
- At-most-once delivery (“как максимум однократная доставка”). Это значит, что сообщение не может быть доставлено больше одного раза. При этом сообщение может быть потеряно.
- At-least-once delivery (“как минимум однократная доставка”). Это значит, что сообщение никогда не будет потеряно. При этом сообщение может быть доставлено более одного раза.
- Exactly-once delivery (“строго однократная доставка”). Все сообщения доставляются строго единожды.
Расскажите про 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)?
Каталог архитектурных шаблонов приложений уровня предприятия, состоит из следующих категорий:
- Domain Logic Patterns
- Data Source Architectural Patterns
- Object-Relational Behavioral Patterns
- Object-Relational Structural Patterns
- Object-Relational Metadata Mapping Patterns
- Web Presentation Patterns
- Distribution Patterns
- Offline Concurrency Patterns
- Session State Patterns
- Base Patterns
Расскажите про 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 описывает требования к транзакционной системе (например, к СУБД), обеспечивающие наиболее надёжную и предсказуемую её работу.
-
Атомарность (англ. atomicity) - гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. Поскольку на практике невозможно одновременно и атомарно выполнить всю последовательность операций внутри транзакции, вводится понятие «отката» (rollback): если транзакцию не удаётся полностью завершить, результаты всех её до сих пор произведённых действий будут отменены и система вернётся во «внешне исходное» состояние — со стороны будет казаться, что транзакции и не было. (Естественно, счётчики, индексы и другие внутренние структуры могут измениться, но, если СУБД запрограммирована без ошибок, это не повлияет на внешнее её поведение.)
-
Согласованность (англ. consistency). Транзакция, достигающая своего нормального завершения (EOT — end of transaction, завершение транзакции) и, тем самым, фиксирующая свои результаты, сохраняет согласованность базы данных. Другими словами, каждая успешная транзакция по определению фиксирует только допустимые результаты. Это условие является необходимым для поддержки четвёртого свойства.
Согласованность является более широким понятием. Например, в банковской системе может существовать требование равенства суммы, списываемой с одного счёта, сумме, зачисляемой на другой. Это бизнес-правило и оно не может быть гарантировано только проверками целостности, его должны соблюсти программисты при написании кода транзакций. Если какая-либо транзакция произведёт списание, но не произведёт зачисления, то система останется в некорректном состоянии и свойство согласованности будет нарушено.
Наконец, ещё одно замечание касается того, что в ходе выполнения транзакции согласованность не требуется. В нашем примере, списание и зачисление будут, скорее всего, двумя разными подоперациями и между их выполнением внутри транзакции будет видно несогласованное состояние системы. Однако не нужно забывать, что при выполнении требования изоляции никаким другим транзакциям эта несогласованность не будет видна. А атомарность гарантирует, что транзакция либо будет полностью завершена, либо ни одна из операций транзакции не будет выполнена. Тем самым эта промежуточная несогласованность является скрытой.
-
Изолированность (англ. isolation). Во время выполнения транзакции параллельные транзакции не должны оказывать влияния на её результат. Изолированность — требование дорогое, поэтому в реальных БД существуют режимы, не полностью изолирующие транзакцию (уровни изолированности Repeatable Read и ниже).
-
Стойкость (англ. durability) Независимо от проблем на нижних уровнях (к примеру, обесточивание системы или сбои в оборудовании) изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. Другими словами, если пользователь получил подтверждение от системы, что транзакция выполнена, он может быть уверен, что сделанные им изменения не будут отменены из-за какого-либо сбоя.
В чем смысл CAP теоремы?
Теорема CAP — эвристическое утверждение, что в любой реализации распределённых вычислений возможно обеспечить не более двух из трёх следующих свойств:
- C - (англ. consistency) согласованность данных — во всех вычислительных узлах в один момент времени данные не противоречат друг другу;
- A - (англ. availability) доступность — любой запрос к распределённой системе завершается корректным откликом, однако без гарантии, что ответы всех узлов системы совпадают;
- P - (англ. partition tolerance) устойчивость к разделению — расщепление распределённой системы на несколько изолированных секций не приводит к некорректности отклика от каждой из секций.
Что такое BASE-архитектура?
BASE (англ. Basically Available, Soft-state, Eventually consistent) — базовая доступность, неустойчивое состояние, согласованность в конечном счёте - подход построения распределённых систем. Такой подход напрямую противопоставляется ACID.
- Basically Available (базовая доступность) - подразумевается такой подход к проектированию приложения, чтобы сбой в некоторых узлах приводил к отказу в обслуживании только для незначительной части сессий при сохранении доступности в большинстве случаев.
- Soft-state (неустойчивое состояние) - подразумевает возможность жертвовать долговременным хранением состояния сессий (таких, как промежуточные результаты выборок, информация о навигации, контексте), при этом концентрируясь на фиксации обновлений только критичных операций.
- Eventually consistent (согласованность в конечном счёте) - трактуется, как возможность противоречивости данных в некоторых случаях, но при обеспечении согласования в практически обозримое время, посвящено значительное количество самостоятельных исследований.
Что такое CRDT?
Бесконфликтные реплицированные типы данных (англ. Conflict-free replicated data type, CRDT) - структуры, в которых обеспечивается сильная согласованность в конечном счёте (англ. strong eventual consistency,SEC) и монотонность состояний. Из известных, описанных в работах и реализованных в библиотеках, есть такие структуры:
- G-Counter - (grow-only) монотонно увеличивающийся счётчик
- PN-Counter - (positive-negative) счётчик, который можно уменьшать
- LWW-Register - (last-writer-wins) регистр с принципом последняя запись приоритетнее
- MV-Register - (multi-value) регистр с несколькими значениями
- G-Set - множество элементов без удаления
- 2P-Set - с приоритетным удалением
- PN-Set - использует счётчик операций включения-удаления
- LWW-Set - с приоритетом времени операции
- OR-Set - (observed-remove) список с идентификаторами