ПИСМ_Экзамен (2).pdf

Full Transcript

1. Метод и этапы структурного анализа. Программные системы, их ЖЦ. Анализ целевых и системных требований. Разработка требования к программным системам. Структурный анализ - метод исследования системы, который начинается с общего обзора ее и затем детализируется, приобретая иерархическую структуру со...

1. Метод и этапы структурного анализа. Программные системы, их ЖЦ. Анализ целевых и системных требований. Разработка требования к программным системам. Структурный анализ - метод исследования системы, который начинается с общего обзора ее и затем детализируется, приобретая иерархическую структуру со все большим числом уровней. Он включает следующие этапы: - декомпозиция системы на подсистемы и элементы, формирование структур и их описание; - определение качественных и количественных характеристик выделенных структур; - формирование критериев и оценка эффективности выделенных структур; - принятие решения о необходимости совершенствования структурных характеристик системы. ПС - система, состоящая из ПО и, компьютерного оборудования для его выполнения. ЖЦ ПС - период времени, который начинается с момента принятия решения о необходимости создания ПС и заканчивается в момент ее полного изъятия из эксплуатации. 5 основных процессов ЖЦ: приобретение, поставка, разработка, эксплуатация и сопровождение. 8 вспомогательных процессов обеспечивают выполнение основных процессов - документирование, управление конфигурацией, обеспечение качества, верификация, аттестация, совместная оценка, аудит, разрешение проблем. 4 организационных процесса: управление, создание инфраструктуры, усовершенствование и обучение. На этапе анализа целевых требований определяются общие характеристики системы, которым она должна удовлетворять, устанавливается, что и как должна делать система. Анализ системных требований - описание, как должны удовлетворяться запросы пользователя, описываются действия предполагаемой системы, хранимые данные, используемый интерфейс. Требования к ПО - совокупность утверждений относительно атрибутов, свойств или качеств программной системы, подлежащей реализации. Они могут выражаться в виде текстовых утверждений и графических моделей. 2. Метод и стадии объектно-ориентированного анализа и определение основных абстракций и механизмов. Объектно-ориентированный анализ – процедура определения требований к разработке ПО, разработка спецификаций программного обеспечения в терминах объектной модели системы программного обеспечения, которая состоит из взаимодействующих объектов. Он исследует требования с точки зрения классов и объектов, найденных в словаре проблемной области. Он включает такие этапы: - идентификация объектов - организация объектов путем создания диаграммы объектной модели - определение внутренних объектов или атрибутов объекта - определение поведения объектов, т.е. действий объекта - описание того, как объекты взаимодействуют 3. Основы проектирования программного обеспечения, принципы аспекты проектирования. Разработка проектных решений и проектных процедур. Проектирование — итерационный процесс, при помощи которого требования к ПС транслируются в инженерные представления ПС. Модели проектирования предоставляют 3 типа информации. Информационная модель описывает информацию, которую, по мнению заказчика, должна обрабатывать ПС. Функциональная модель определяет перечень функций обработки. Поведенческая модель фиксирует желаемую динамику системы (режимы ее работы). На выходе этапа проектирования — разработка данных, разработка архитектуры и процедурная разработка ПС. В проектировании выделяют две ступени: предварительное проектирование и детальное проектирование. Предварительное проектирование формирует абстракции архитектурного уровня, детальное проектирование уточняет эти абстракции, добавляет подробности алгоритмического уровня. Во многих случаях выделяют интерфейсное проектирование, цель которого — сформировать графический интерфейс пользователя (GUI). Принципы: S - Single Responsibility (единственная ответственность), каждый класс работает лишь над одной целью. Этот класс несет ответственность только в рамках достижения этой цели и изменяется лишь по одной причине. Общий принцип можно сформулировать так: для каждого класса важно определить единственное назначение, а все ресурсы, которые нужны для имплементации, следует инкапсулировать в данный класс и подчинить единственной задаче. O - Open Closed (открытость/закрытость), Класс должен быть открыт для расширения, однако закрыт для изменений. То есть мы можем добавить в класс новую функциональность, однако не можем редактировать существующие функции так, чтобы они противоречили используемому коду. Таким образом, программные сущности должны быть открыты для расширения, однако закрыты для модификации. L - Liskov substitution (принцип подстановки Барбары Лисков), Объекты в разрабатываемой программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы. I - Interface Segregation (принцип разделения интерфейсов), По принципу разделения интерфейсов класс должен обладать способностью реализовывать множество интерфейсов. То есть код надо писать так, чтобы классу не надо было реализовывать функцию, которая не является важной для задач класса. Вывод тут прост: следует разделять свои интерфейсы на категории. Или же: много интерфейсов, которые специально предназначены для клиентов, -- это лучше, чем 1 интерфейс общего назначения. D - Dependency Inversion Principles (принцип инверсии зависимостей). Зависимости строятся на абстракциях, а точнее, отсутствие зависимости на что-либо конкретное. Проектное решение - промежуточное или конечное описание объекта проектирования, необходимое и достаточное для рассмотрения и определения дальнейшего направления или окончания проектирования. Этапы проектирования состоят из отдельных проектных процедур, которые заканчиваются частным проектным решением. Наиболее известными проектными процедурами являются: анализ, синтез и оптимизация. Анализ позволяет оценить степень удовлетворения проектного решения заданным требованиям и его пригодность. Процедура синтеза заключается в создании проектного решения (описания) по заданным требованиям, свойствам и ограничениям. Типичной проектной процедурой является оптимизация, которая приводит к оптимальному (по определенному критерию) проектному решению. 4. Этапы проектирования программного обеспечения. Модульное программирование. Нисходящее и восходящее проектирование программ. При проектировании сложных систем выделяется следующие этапы проектирования: - Стадия предварительного проектирования связана с поиском принципиальных возможностей построения систем, исследованием новых принципов, структур, технических средств, обоснованием наиболее общих решений; результат - техническое предложение. - Стадия эскизного проектирования или опытно-конструкторских работ – производится детальная проработка всех частей проекта, конкретизируются и детализируются технические решения. - Стадия рабочего проекта - формируется вся необходимая документация для изготовления изделия. Модульное программирование — это организация программы как совокупности небольших независимых блоков, называемых модулями, структура и поведение которых подчиняются определенным правилам. Использование модульного программирования позволяет упростить тестирование программы и обнаружение ошибок. Способы проектирования многомодульных программ - восходящее и нисходящее проектирование. Восходящее проектирование. При использовании восходящего подхода сначала проектируют и реализуют модули нижнего уровня, затем предыдущего и т. д. Каждый модуль при восходящем проектировании автономно программируется, тестируется и отлаживается. После этого отдельные модули объединяются в подсистемы с помощью управляющего модуля, в котором определяется последовательность вызовов модулей, ввод-вывод и контроль данных и результатов. В свою очередь, подсистемы затем объединяются в более сложные системы и в общий программный комплекс, который подвергается комплексной отладке с проверкой правильности межмодульных связей. При нисходящем проектировании появляется возможность использовать вертикальное управление в схеме иерархии с использованием таких правил: модуль возвращает управление вызвавшему; модуль вызывает только модули более низкого уровня; принятие основных решений возлагается на модули максимально высокого уровня. 5. Принципы объектно-ориентированного представления программных систем. Классы, объекты, общая характеристика и отношения между классами и объектами. Объектно-ориентированные методы анализа и проектирования. Принципы объектно-ориентированного представления программных систем: - Абстрагирование - каждая абстракция фиксирует основные характеристики объекта, которые отличают его от других видов объектов и обеспечивают ясные границы. - Инкапсуляция - процесс разделения элементов абстракции на секции с различной видимостью. Обычно скрывается структура данных объектов и реализация их методов. - Модульность - модули служат физическими контейнерами, в которых объявляются классы и объекты логической разработки. Изменение реализации модулей должно проводиться без знания реализации других модулей и без влияния на их поведение. - Иерархическая организация - упрощаются понимание проблем заказчика и их реализация — сложная система становится обозримой человеком. Она задает размещение абстракций на различных уровнях описания системы. Объект — это конкретное представление абстракции. Объект обладает индивидуальностью, состоянием и поведением. Структура и поведение подобных объектов определены в их общем классе. Класс — описание множества объектов, которые разделяют одинаковые свойства, операции, отношения и смысл. Любой объект — просто экземпляр класса. Три основных отношения между классами: Наследование – класс есть подвид другого класса. - Ассоциация - объекты двух классов могут ссылаться один на другой, иметь связь между друг другом. - Агрегация — отношение когда один объект является частью другого (Студент входит в Класс). - Композиция — еще более «жесткое отношение, когда объект не только является частью другого объекта, но и вообще не может принадлежат еще кому-то (Машина и Двигатель). 6. Языки визуального моделирования. Язык UML. Отношения, механизмы и диаграммы. Приемы моделирования. Языки визуального моделирования - формализованные наборы графических символов и правила построения из них визуальных моделей. Сейчас известны и активно используются на практике такие языки визуального моделирования, как UML и BPMN. UML (Unified Modeling Language), — унифицированный язык моделирования. Это графический язык, который с помощью диаграмм и схем описывает разнообразные процессы и структуры. Механизмы: - спецификации (Specifications) - задний план, который полностью включает в себя составные части всех моделей системы, согласованные между собой; - дополнения (Adornments) - каждый элемент нотации UML содержит базовый для него символ, к которому можно добавлять разнообразные специфичные для него дополнения; - принятые деления (Common divisions) - описывают конкретные способы представления объектов реального мира в модели; - механизмы расширения (Extensibility mechanisms) - применяются в случае, когда базовые возможности UML не удовлетворяют выдвигаемым требованиям. Отношения: Зависимость – семантическое отношение между сущностями, при котором изменение одной из них, независимой, может повлиять на семантику другой(пунктирная стрелка, данные -обработчик данных). Ассоциация – структурное отношение, описывающее совокупность связей, где под связью понимается некоторая смысловая связь между объектами(сплошная линия, машина-имеет-колесо). Обобщение (наследование) – отношение, при котором объект специализированного элемента (потомок) может быть подставлен вместо объекта обобщенного элемента (родителя). Реализация – семантическое отношение между классификаторами, при котором один классификатор определяет обязательство, а другой гарантирует его выполнение. Отношение реализации встречаются между интерфейсами и реализующими их классами или компонентами. Виды диаграмм UML: - Структурные (показывают различные уровни абстракции и реализации) 1. Диаграмма классов 2. Диаграмма объектов (показывает системные объекты и их взаимосвязи) 3. Диаграмма компонентов (показывает логические группы элементов и их взаимосвязи) 4. Диаграмма развертывания (показаны аппаратные и программные компоненты и их взаимосвязи) 5. Диаграмма пакетов (зависимости между пакетами, которые составляют модель) - Поведенческие (показывают функциональные возможности системы и демонстрируют, что должно происходить в моделируемой системе) 1. Диаграмма деятельности (пошаговый процесс с четким началом и концом) 2. Диаграмма вариантов использования (представляет функциональные требования системы) 3. Временная диаграмма (сколько времени занимают события и какие изменения происходят в зависимости от ограничений продолжительности) 4. Диаграмма последовательности (показывая последовательность сообщений и взаимодействий между операторами и объектами в хронологическом порядке) Моделируя классы на UML, помните, что каждый класс должен отображать некоторую осязаемую или концептуальную абстракцию из предметной области конечного пользователя или разработчика. Изображая класс в UML, вы должны: - показать только те его свойства, которые важны для понимания абстракции в данном контексте; - организовать длинные списки атрибутов и операций, группируя их по категориям; - представить взаимосвязанные классы на одной диаграмме. 7. Моделирование основных архитектурных решений с применением UML, моделирование поведения программных систем. Разработка поведенческих моделей. Для визуализации, специфицирования, конструирования и документирования программных систем необходимо рассматривать их с различных точек зрения. Архитектура - это совокупность существенных решений касательно организации программной системы; выбора структурных элементов, составляющих систему, и их интерфейсов; поведения этих элементов, специфицированного в кооперациях с другими элементами; составления из этих структурных и поведенческих элементов все более и более крупных подсистем; стиля, направляющего и определяющего всю организацию системы: статические и динамические элементы, их интерфейсы, кооперации и способ их объединения. Архитектура может быть описана с помощью пяти взаимосвязанных видов: - Вид с точки зрения прецедентов (диаграммы вариантов использования, use case diagrams) - Вид с точки зрения проектирования - Вид с точки зрения процессов, - Вид с точки зрения реализации - Вид с точки зрения развертывания Модель поведения ‒ описание алгоритма работы системы. Существует два основных типа поведенческих сущностей: - взаимодействие - это поведение, суть которого заключается в обмене сообщениями между объектами в рамках конкретного контекста для достижения определенной цели; - автомат - алгоритм поведения, определяющий последовательность состояний, через которые объект или взаимодействие проходят в ответ на различные события. Требования, предъявляемые к модели поведения: - Модель должна быть достаточно детальной для того, чтобы послужить основой для составления компьютерной программы — компьютер не сможет самостоятельно "додумать" опущенные детали. - Модель должна быть компактной и обозримой, чтобы служить средством общения между людьми в процессе разработки системы и для обмена идеями. - Модель не должна зависеть от особенностей реализации конкретных компьютеров, средств программирования и технологий, чтобы не сужать область применения языка UML. - Средства моделирования поведения в UML должны быть знакомыми и привычными для большинства пользователей языка и не должны противоречить требованиям наиболее ходовых парадигм программирования. 8. Шаблоны проектирования. Виды шаблонов и их классификация, распределение обязанностей между шаблонами. Паттерны проектирования — это решения распространенных проблем при разработке кода. В отличие от готовых функций или библиотек, паттерн представляет собой не конкретный код, а общую концепцию решения проблемы, которую еще нужно подстроить под задачи. 1) Порождающие предназначены для создания экземпляра объекта или группы связанных объектов. Abstract Factory (предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, без непосредственной спецификации их конкретных классов) Builder - метод создания составного объекта Factory – логика создания объектов выносится в отдельный класс Singleton - наличие единственного экземпляра класса 2) Структурные связаны с композицией объектов, с тем, как сущности могут использовать друг друга. Adapter - применение функций объекта который нельзя модифицировать, специальным интерфейсом. Bridge - разделяет абстракцию и реализацию таким образом, чтобы они могли меняться независимо Composite (Компоновщик) - объединять объекты в древовидную структуру, даёт клиентам возможность обращаться к отдельным объектам и к группам объектов одинаковым образом Decorator - динамическое подключение дополнительного поведения к объекту Facade - все возможные внешние вызовы сводятся к одному и тому же объекту, который передаёт эти вызовы соответствующим объектам системы Proxy - объект, контролирующий доступ к другому объекту, перехватывая при этом все вызовы 3) Поведенческие связаны с распределением обязанностей между объектами. Их отличие от структурных шаблонов заключается в том, что они описывают не только структуру, но и способы общения между ними. К ним относятся: Chain of responsibility (Цепочка обязанностей) - организация уровней ответственности в системе Iterator - доступ к элементам коллекции, а также навигацию по ним Mediator — Посредник - позволяет обеспечить взаимодействие нескольких объектов Memento - закрепление и сохранение внутреннего состояния объекта без нарушения инкапсуляции Observer - особый механизм у класса, который даёт возможность экземпляру объекта этого класса получать уведомления от остальных объектов. State - когда в процессе выполнения программы объект должен изменять свое поведение, в зависимости от того, в каком состоянии он находится Template method - даёт наследникам возможность переопределять те или иные шаги алгоритма, оставляя его общую структуру нетронутой Паттерны GRASP также называют паттернами распределения обязанностей, которые позволяют структурировать и именовать базовые принципы проектирования. GRASP состоит из 9 паттернов, описывающих базовые принципы объектно-ориентированного проектирования: 1. Создатель - какие условия должны соблюстись, что бы объекты верно порождали друг друга 2. Информационный эксперт – предоставление информации об объекте. 3. Слабая связность (Low Coupling) - объекты в системе знают друг о друге как можно меньше. 4. Контроллер - к кому именно должны обращаться вызовы из V (View), и кому C должен делегировать запросы на выполнение. 5. Высокое зацепление (High Cohesion) - класс должен стараться выполнять как можно меньше не специфичных для него задач, и иметь вполне определенную область применения. 6. Полиморфизм - позволяет обрабатывать альтернативные варианты поведения на основе типа. 7. Чистая выдумка (Pure Fabrication) - Создать новый искусственный класс с высоким зацеплением и слабым связыванием не являющийся частью предметной области. 8. Посредник (Indirection) - назначение обязанностей по взаимодействию классов доп.объекту. 9. Устойчивость к изменениям (Protected Variations) - устранении точек неустойчивости, которые наиболее часто будут подвержены изменению/модификации. 9. Методы применения шаблонов проектирования. Разработка программной архитектуры и кодирование приложений на основе типовых решений. Систематизация приемов программирования и принципов организации классов получила название шаблона. При решении задач с применением шаблонов следует придерживаться следующих рекомендаций: —шаблоны приносят пользу вне зависимости от того, как часто они используются при программировании; — не следует торопиться с применением шаблонов при решении новой задачи; — шаблон в чистом виде, как правило, неприменим, применимы только вариации; — при применении шаблона следует начинать с его простейшей реализации, а уж затем вносить изменения по адаптации к конкретной ситуации; — если после применения шаблона код стал хуже, то шаблон лучше убрать. Архитектура ПО - совокупность важнейших решений об организации программной системы. Примеры архитектурных шаблонов: · Многоуровневый шаблон (Layered pattern). Система разбивается на уровни, изображаются один над другим. Каждый уровень может вызывать только уровень на 1 ниже него. разработку каждого уровня можно вести независимо. Недостатки - усложнение системы и снижение производительности. · Шаблон посредника (Broker pattern). В системе много модулей, сложное взаимодействие друг с другом. Вводится посредник, по которому модули общаются. Повышается совместимость модулей системы. Недостатки - наличие посредника: он понижает производительность, его недоступность может сделать недоступной всю систему, он может стать объектом атак и узким местом системы. · Шаблон «Модель-Вид-Контроллер» (Model-View-Controller pattern). Интерфейс меняется, сохраняя корректное взаимодействие с данными (чтение, сохранение). · Клиент-серверный шаблон (Client-Server pattern). Подход повышает масштабируемость и доступность системы. При его недоступности становится недоступна вся система. 10. Качество и эффективность ПО. Генерация кода на основе моделей. Конструирование высококачественного кода. Тестирование, отладка, рефакторинг и оптимизация кода Качество ПО - это совокупность характеристик ПО, относящихся к его способности удовлетворять установленные и предполагаемые потребности. Характеристики качества ПО - Функциональность определяется способностью ПО решать задачи, которые соответствуют зафиксированным и предполагаемым потребностям пользователя, при заданных условиях использования ПО. Т.е. эта характеристика отвечает за то, что ПО работает исправно и точно, функционально совместимо, соответствует стандартам отрасли и защищено от несанкционированного доступа. - Надежность – способность ПО выполнять требуемые задачи в обозначенных условиях на протяжении заданного промежутка времени или указанное количество операций. Атрибуты данной характеристики – это завершенность и целостность всей системы, способность самостоятельно и корректно восстанавливаться после сбоев в работе, отказоустойчивость. - Удобство использования – возможность легкого понимания, изучения, использования и привлекательности ПО для пользователя. - Эффективность – способность ПО обеспечивать требуемый уровень производительности в соответствие с выделенными ресурсами, временем и другими обозначенными условиями. - Удобство сопровождения – легкость, с которой ПО может анализироваться, тестироваться, изменяться для исправления дефектов, для реализации новых требований, для облегчения дальнейшего обслуживания и адаптироваться к имеющемуся окружению. - Портативность характеризует ПО с точки зрения легкости его переноса из одного окружения в другое. Можно генерировать код на основе UML-моделей с помощью специальных приложений. Конструирование ПО - создание работающего ПО с привлечением методов верификации, кодирования и тестирования компонентов. Основные техники обеспечения качества, используемые в процессе конструирования, включают: модульное и интеграционное тестирование, разработка с первичностью тестов (тесты пишутся до конструирования кода), пошаговое кодирование (деятельность по конструированию кода разбивается на мелкие шаги, только после тестирования результатов, которых производится переход к следующему шагу кодирования; известен также как итеративное кодирование с тестированием), использование процедур утверждений, отладка, технические обзоры и оценки. Выбор и использование конкретных техник диктуется стандартами, используемыми проектной командой, а также зависят от опыта специалистов, занимающихся конструированием кода При конструировании используются две формы тестирования: модульное и интеграционное. Главная цель тестирования в конструировании уменьшить временной разрыв между моментом проявления ошибок, имеющихся в коде, и моментом их обнаружения. Во многих случаях, тестирование в конструировании производится после того, как код написан. В ряде случаев, тесты пишутся до того, как создается код(TDD). Тесты бывают типов черного, белого и серого ящика. Отладка, или debugging, — это поиск, анализ и устранение ошибок (компиляции, компоновки, выполнения, логические) в ПО, которые были найдены во время тестирования. Рефакторинг — это переработка исходного кода программы, чтобы он стал более простым и понятным. Он не меняет поведение программы, не исправляет ошибки и не добавляет новую функциональность, а делает код более понятным и удобочитаемым. Оптимизация кода —методы преобразования кода ради улучшения его характеристик и повышения эффективности. Среди целей оптимизации можно указать уменьшение объема кода, объема используемой программой оперативной памяти, ускорение работы программы, уменьшение количества операций ввода-вывода. 11. Внедрение, сборка и поставка проекта. Развёртывание, технологии и средства развертывания, наладки и обслуживания проектов. Внедрение ПО — процесс настройки программного обеспечения под определенные условия использования, а также обучения пользователей работе с программным продуктом. Внедрение проекта включает в себя три этапа: - подготовка объекта к внедрению проекта; - опытное внедрение проекта (проверка правильности работы некоторых частей проекта); - сдача проекта в промышленную эксплуатацию. Внедрение может осуществляться с использованием следующих методов: - последовательный метод, когда последовательно внедряется одна подсистема за другой; - параллельный метод, при котором все задачи внедряются во всех подсистемах одновременно; - смешанный подход, согласно которому проектировщики, внедрив несколько подсистем первым методом и накопив опыт, приступают к параллельному внедрению остальных. Автоматизация процесса сборки программного продукта связана с разработкой различных скриптов для выполнения таких действий, как : компиляция исходного кода в бинарный; сборка бинарного кода; разворачивание программы на сервере (удаленном компьютере); оформление сопроводительной документации или описание изменений. Apache Ant - это императивная командная система, созданная для кроссплатформенного применения. Он был спроектирован таким образом, что часто применяемые при сборке команды ОС обернуты внутренними командами ant, а скрипты сборки описываются в формате XML. Широкое распространение получила декларативная система автоматизации сборки Apache Maven согласно описанию проектного pom.xml файла формата XML. В файлах проекта pom.xml содержатся не отдельные команды, а описание проекта. Все задачи по обработке файлов maven выполняет с использованием плагинов. Неоспоримым преимуществом maven является автоматическое управление зависимостями, хорошая структурированность проектов и отсутствие скриптов сборки как таковых, а следовательно проблем с ними. Процесс поставки - процесс, в котором описан полный и интегрированный подход к выполнению проектов определенного типа. В нем содержится полное описание модели жизненного цикла в форме последовательно упорядоченной структуры наполнения методов. Развёртывание ПО - все действия, которые делают программную систему готовой к использованию. Jenkins - автономный сервер автоматизации с открытым исходным кодом. С ним стоит работать для автоматизации всех видов задач, связанных со сборкой, тестированием, поставкой или развертыванием программного обеспечения. TeamCity - разработка от JetBrains. Он хорош простой настройкой и отличным интерфейсом. В дефолтной конфигурации есть большое кол-во функций, постоянно увеличивается число плагинов. Вся информация о результатах сборки хранится в БД. 12. Фазы, итерации и циклы разработки программного кода. Рабочие процессы, модели и артефакты. Фазы разработки ПО - Анализ требований. В рамках этой стадии происходит взаимодействие клиента и компании- разработчика, в ходе обсуждения деталей проекта помогающих более четко сформулировать требования. Результатом проведенного анализа становится формирование основного регламента, на который будет опираться исполнитель в своей работе — технического задания на разработку ПО. ТЗ должно полностью описывать поставленные перед разработчиком задачи и охарактеризовать конечную цель проекта в понимании заказчика. - Проектирование. Моделирование теоретической основы будущего продукта. В рамках данного этапа стороны должны осуществить формирование окончательной архитектуры создаваемой системы; анализ необходимости использования готовых решений; проектирование основных элементов продукта — модели базы данных, процессов и кода; выбор среды программирования и инструментов разработки, утверждение интерфейса программы, включая элементы графического отображения данных; определение основных требований к безопасности разрабатываемого ПО. - Кодирование. Непосредственная работа с кодом, опираясь на выбранный в процессе подготовки язык программирования. Кодирование может происходить параллельно со следующим этапом разработки — тестированием программного обеспечения, что помогает вносить изменения непосредственно по ходу написания кода. - Тестирование и отладка. Процесс тестирования позволяет смоделировать ситуации, при которых программный продукт перестает функционировать. Отдел отладки затем локализует и исправляет обнаруженные ошибки кода, “вылизывая” его до практически идеального состояния - Внедрение. Процедура внедрения программного обеспечения в эксплуатацию является завершающей стадией разработки и нередко происходит совместно с отладкой системы. Ключевой целью поэтапного внедрения разработанной программы становится постепенное выявление не обнаруженных ранее ошибок и недочетов кода. Именно на этой стадии выкристаллизовывается окончательная картина взаимодействия пользователя с программой. Внутри каждой фазы происходит несколько итераций. Итерация представляет полный цикл разработки, от выработки требований во время анализа до реализации и тестирования. Это завершенный этап, в результате которого выпускается версия исполняемого продукта, реализующая часть запланированных функций. Затем эта версия от итерации к итерации наращивается до получения готовой системы. Конечным результатом является выпуск готового продукта. Прохождение через основные фазы - цикл разработки. Каждый цикл завершается генерацией версии системы. Разработка ПО состоит из девяти рабочих процессов: - бизнес-анализ – предполагает определение желаемых параметров системы и нужд пользователей; - требования - формализация образа системы. - анализ и моделирование - перевод требований в формализованную программную модель. - реализация, кодирование - предполагает собственно написание кода. - тестирование – поиск и устранение возможных ошибок - внедрение - предполагает установку продукта заказчику, подготовку персонала, запуск системы. - управление конфигурацией и изменениями - управление версиями продукта. - управление проектом — предполагает набор административных действий управления проектом. - окружение - создание и поддержка средств анализа, проектирования, разработки, тестирования. Внутри каждого рабочего процесса сосредоточены связанные между собой артефакты и деятельности. Артефакты — это некоторые продукты проекта, порождаемые или используемые в нем при работе над окончательным продуктом. Модель - упрощение реального продукта; она создается для лучшего понимания разрабатываемой системы. 13. Архитектура клиент-сервер. Многоуровневая структура веб-приложения. Требования к современному веб-приложению. Клиент-серверная архитектура описывает распределенные системы, состоящие из отдельных клиента и сервера и соединяющей их сети. Простейшая форма, называемая 2-уровневой архитектурой – это серверное приложение, к которому напрямую обращаются множество клиентов. Архитектурный стиль клиент-сервер описывает отношения между клиентом и одним или более серверами, где клиент инициирует один или более запросов, ожидает ответы и обрабатывает их при получении. Для связи с клиентом сервер может использовать широкий диапазон протоколов и форматов данных. Дальнейшее развитие архитектуры Web-приложений и технологии «клиент-сервер» привело к появлению многоуровневой архитектуры, в которой дополнительно вводится сервер приложений. Он является промежуточным уровнем, который обеспечивает организацию взаимодействия клиентов («тонких» клиентов) и сервера БД. В этой модели промежуточные серверы получают запросы клиентов и обрабатывают их, координируя свои действия с подчиненными серверами, применяя бизнес-логику. Связью между клиентом и БД управляет промежуточный прикладной уровень, что позволяет клиентам получать доступ к данным из различных решений СУБД. Трехуровневая архитектура более безопасна, поскольку клиент не имеет прямого доступа к данным. Основные достоинства многоуровневой архитектуры Web-приложений заключаются в следующем: 1) разгрузка Web-сервера от выполнения части операций, перенесенных на сервер приложений и уменьшение размера модулей расширения сервера на основе разгрузки их от лишнего кода; 2) обеспечение межплатформенного управления между Web-сервером и сервером базы данных; 3) упрощение администрирования и настройки параметров сети - при внесении изменений в ПО или конфигурацию сервера БД не нужно вносить изменения в Web-сервер. Под требованиями к ПО будем понимать совокупность утверждений относительно свойств программной системы, подлежащая реализации при создании ПО. 14. Структура и размещение веб-приложения. Этапы разработки и развертывания веб-приложения. Роль веб-сервера в развертывании веб-приложения на Java Структура веб-приложения. Логика распределена между сервером и клиентом, хранение и обработка данных осуществляется, преимущественно, на сервере, её представление в удобном для пользователя виде - в браузере. Обмен информацией происходит по сети. Веб-приложения состоят как минимум из трёх основных компонентов. Серверная часть веб-приложения - программа или скрипт на сервере, обрабатывающая запросы пользователя (точнее, запросы браузера). Система управления базами данных, (СУБД) - программное обеспечение на сервере, занимающееся хранением данных и их выдачей в нужный момент. Клиентская часть веб-приложения – это отображаемый в браузере графический интерфейс. Размещение web-приложения Для того, чтобы веб-приложение стало доступно, его необходимо разместить в рамках веб-сервера Tomcat, Glassfish, JBoss, Sun и др. После этого приложение получит свой уникальный адрес в рамках протокола HTTP. Используя этот адрес, пользователь может обратиться к приложению. Этапы разработки веб-приложения: - определение целей и задач проекта; - разработка структуры сайта; - разработка дизайн-макетов; - html-вёрстка; - программирование и контроль качества; запуск и сопровождение, SEO-оптимизация. Роль web-сервера в развертывании приложения на java Веб-сервер – ПО, обеспечивающее доставку контента конечному пользователю по сети. Он реализует серверную часть протокола HTTP. Сервисы – EJB, JMS, управление ресурсами, безопасность, JSF. Функции и особенности веб-серверов: получение контента от пользователей и его передача; поддержка динамически генерируемых страниц; аутентификация и авторизация пользователей; ведение журнала обращений пользователей к ресурсам; поддержка HTTPS для защищённых соединений с клиентами. Реализации веб-серверов: Apache Tomcat – контейнер сервлетов, и Glassfish Apache Tomcat состоит из следующих компонентов: 1. Web Connector Coyote (поддерживает HTTP, для веб-серверов или контейнера приложений, прослушивает входящие соединения на определенном TCP-порту сервера). 2. Web Container Catalina (контейнер сервлетов Tomcat, даёт возможность динамически генерировать веб-контент) 3. Jasper Compiler (анализирует JSP-файлы, чтобы компилировать их в Java-код как сервлеты, которые могут быть обработаны с помощью Catalina) 15. Структура архива war. Способы создания файла war. Описатель развертывания web.xml: его назначение и содержимое. WAR (Web application ARchive) файлы используются для распостранения Java web-приложений. WAR имеет такую же структуру, как и JAR-файл, единый сжатый файл, содержащий несколько файлов внутри него. WAR-файлы используются для объединения JSP-файлов, сервлетов, Java class-файлов, XML-файлов, javascript-библиотек, JAR-библиотек, статических web-страниц и любых других ресурсов, необходимых для работы приложения. WAR-файлы обычно разворачивают в контейнерах сервлетов, но также возможно разворачивать и в Java EE серверах приложений. Когда WAR-файл разворачивается в контейнере, контейнер обычно распаковывает его для доступа к файлам, а затем запускает приложение. На основе контейнеров сервлетов получается наиболее производительная платформа для Java web-приложений, WAR-файлы являются не только стандартом Java спецификации, но WAR-файлы нельзя редактировать, пока работает приложение. Любые изменения потребуют пересборки файла. Создать WAR-архив можно следующими способами: - Паковщиком, входящим в состав J2EE SDK. - Выполнив в Apache Ant задачу «war». - Выполнив в Apache Maven команду «mvn clean install». Файл web.xml хранит информацию о конфигурации приложения. Он не является обязательной частью приложения. Если приложение содержит только JSP-файлы, этот файл не строго обязателен. Данный файл должен располагаться в папке WEB-INF приложения. При запуске Tomcat считывает его содержимое и использует считанную конфигурацию. Если же файл содержит ошибки, то Tomcat отображает ошибку. web.xml имеет определенную структуру. Все вложенные узлы, которые определяют конфигурацию, помещаются в корневой узел. У элемента web-app определяется ряд атрибутов. В данном случае атрибуты xmlns и xmlns:xsi указывают на используемые пространства имен xml. Атрибут version указывает на версию спецификации сервлетов или Servlet API, которая используется в приложении. С помощью элемента можно задать сопоставление сервлета с запрашиваемым URL. Прежде всего вначале с помощью элемента определяется сервлет. Элемент задает имя сервлета, на которое будет проецироватья класс, указанный в элементе. Затем в элементе сервлет сопоставляется с путем. 16. Порядок компоновки веб-приложения. Технологии сборки веб-приложения. Файл сборки build.xml и его содержимое. Инструменты для сборки веб-приложения. Реальное web-приложение обычно включает достаточно большое количество файлов, размещенных в разветвленной системе директорий файловой системы. Для выполнения компоновки используют специальные программные средства, позволяющие упростить этот процесс. Apache Ant – средство автоматизации, созданное на базе Java и XML, как программное обеспечение с открытым исходным кодом, которое представляет собой инструмент, позволяющий автоматизировать процесс компоновки java-проекта. Сюда относится компиляция java-файлов, создание jar-архивов и специальных файлов для размещения приложения на сервере (war-файлы). Управление процессом сборки происходит посредством XML-сценария, также называемого build-файлом. Этот файл содержит определение проекта, состоящего из отдельных целей (targets). Типичными примерами целей являются clean (удаление промежуточных файлов), compile (компиляция всех классов), deploy (развёртывание приложения на сервере). Конкретный набор целей и их взаимосвязи зависят от специфики проекта. Ant позволяет определять собственные типы заданий путём создания Java-классов, реализующих определённые интерфейсы. Ant'у необходима помощь в виде build файла. Build файл показывает Ant'у что надо делать, чтобы превратить то что есть (как правило, исходный код) в то что вы хотите. Сценарий представляет собой детальный план сборки из частей единого целого, включающий ряд операндов, позволяющих выполнять команды копирования, удаления и перемещения файлов, компиляции java- файлов, формирование документации к коду и исполняемого jar-файла. Корневой элемент сценария project может содержать три необязательных атрибута : - name - имя проекта; - default - цель проекта по умолчанию; - basedir - базовая директория, относительной которой будут вычисляться все пути. Элемент описывающий цель проекта target может содержать следующие атрибуты : - name - имя цели, обязательный атрибут; - depends - промежуточные цели, от которых зависит данная цель; имена перечисляются через запятую; - if - определяет какие свойства должны быть равны true для запуска цели; - unless - определяет какие свойства должны быть равны false для запуска цели; - description - краткое описание цели, что она делает. Параметр property определяет пару имя/значение, которая может многократно использоваться в сценарии подобно переменным. Свойства (настройки) можно определять как внутри build.xml файла, так и в отдельных файлах. При определении внутри xml файла свойства могут включать следующие атрибуты :  name - имя свойства;  value - значение свойства;  location - устанавливает значение свойства в абсолютный путь. Если значение уже абсолютный путь, то ничего не меняется, если относительный то подставляется базовая директория.  refid - ссылка на другой объект, определенный где-либо;  resource - имя ресурса содержащего настройки в формате настроечного файла;  file - путь к файлу настройки (в нем свойства определяются как имя=значение на отдельной строке);  url - адрес настройки;  environment - префикс используемый для доступа к переменным окружения. Например, если определено myenv, то к переменным обращаются как "myenv.PATH";  classpath - путь к ресурсам;  prefix - префикс добавляемый к свойствам загруженных из файла, ресурса, или url. По умолчанию префикс ".". 17. Понятие сервлета. ЖЦ сервлета: обработка событий, связанных с ЖЦ. Сервлет – модуль, расширяющий возможности серверов типа запрос-ответ, таких как Java- совместимые web-сервера. Servlet API – коды, требующиеся для построения сервлетов, содержат два пакета: – javax.servlet, javax.servlet.http. Жизненный цикл сервлета: - сервер загружает и инициализирует объект - сервер обрабатывает ноль или более запросов клиентов - сервер выгружает сервлет Для инициализации сервлета сервер запускает init-метод сервлета. Когда сервер удаляет сервлет, он запускает метод destroy(). Интерфейсы и их назначение: - Servlet – объявляет методы цикла жизни для сервлета - ServletConfig – позволяет сервлетам получать параметры инициализации - ServletContext – активирует возможности сервлетов для регистрации событий и доступа к информации об их среде - ServletRequest – используется для чтения данных из запроса клиента - ServletResponse – используется для записи данных в ответ клиенту - SingleThreadModel – указывает, что сервлет защищен от многопоточности Когда сервлет принимает вызов клиента, он получает два объекта: - ServletRequest (инкапсулирует связь клиента с сервером) - ServletResponse (инкапсулирует обратную связь сервера с клиентом) Оба являются интерфейсами. Пакет HTTP, интерфейсы: - HttpServletRequest – используется для чтения данных из HTTP (запроса клиента) - HttpSevletResponse – используется для записи данных в HTTP (ответ клиенту) - HttpSession – позволяет читать и записывать данные сеанса - HttpSessionContext – обеспечивает управляемость сеанса Класс HttpSevlet обеспечивает методы для обработки запросов и ответов HTTP. Его методы: - doGet – метод, который вызывается при получении HTTP-запроса методом GET. Этот метод принимает два параметра типа HttpServletRequest и HttpServletResponse, которые представляют запрос и ответ соответственно. - doPost – метод, который вызывается при получении HTTP-запроса методом POST. Этот метод также принимает два параметра типа HttpServletRequest и HttpServletResponse. - doPut – метод, который вызывается при получении HTTP-запроса методом PUT. Этот метод также принимает два параметра типа HttpServletRequest и HttpServletResponse. - doDelete – метод, который вызывается при получении HTTP-запроса методом DELETE. Этот метод также принимает два параметра типа HttpServletRequest и HttpServletResponse. 18. Контейнер сервлетов, его функции и назначение. Развёртывание веб-приложений на примере веб-сервера Apache. Инструменты Catalina, Coyote Jasper и их назначение. Контейнер сервлетов – программа, обеспечивающая взаимодействие между сервлетами и клиентами, обрабатывает запроса, полученные от клиентов и передает их соответствующим сервлетам. Задачи и функции контейнера сервлетов: - Обмен данными - Управление жизненным циклом сервлета - Создание программной среды - Обработка исключений - Идентификация-авторизация-аутентификация - Организация сессии Apache Tomcat – веб-сервлет. Его составляющие: - Catalina (контейнер сервлетов Tomcat дает возможность динамические генерировать любой веб-контент). - Coyote (поддерживает HTTP для веб-серверов или контейнера приложений, прослушивает входящие соединения на TCP порту сервера) - Jasper – (механизм JSP, отвечает за компиляцию JSP-страниц в сервлеты, которые могут быть запущены в Tomcat-контейнере сервлетов. Jasper также отвечает за выполнение операций, таких как проверка синтаксиса JSP-страниц и преобразование JSP-страниц в сервлеты) 19. Интерфейс ServletContext: назначение и использование. Сессия: доступ, связывание с объектами, управление. Методы getSession(), setAttribute(), getAttribute(). ServletContext – активирует возможности сервлетов для регистрации событий и доступа к информации об их среде. ServletContext представляет собой общий объект, доступный всем сервлетам в данном приложении, и содержит информацию, такую как параметры инициализации, атрибуты контекста и другие ресурсы. Сессия в веб-приложении представляет собой период времени, в течение которого клиент взаимодействует с приложением. Используя сессии, можно сохранять состояние между запросами, например, данные формы, идентификатор пользователя и другую информацию. Контейнер сервлетов обеспечивает механизмы управления сессиями. Сессии реализуются с помощью объекта интерфейса HttpSession. Он содержит набор атрибутов, которые можно использовать для хранения данных. Контейнер сервлетов генерирует уникальный идентификатор сессии, который используется для связи между клиентом и сервером. Session методы: putValue, getValue Для отправки сервлета сервлету используются методы forward(), sendRedirect(). Forward() быстрее, чем sendRedirect(). Методы интерфейса ServletContext, связанные с сессиями: - getSession() - возвращает текущий объект HttpSession, связанный с текущим запросом. Если такого объекта еще нет, метод создает новую сессию и возвращает ее. - setAttribute() - используется для связывания объекта сессии с именем атрибута в контексте приложения. Например, можно использовать этот метод для сохранения данных формы в сессии: - getAttribute() - используется для получения объекта сессии, связанного с именем атрибута в контексте приложения. Например, можно использовать для извлечения данных формы из сессии 20. Серверные страницы JSP. ЖЦ JSP-страницы. Создание статического и динамического контента. JSP расшифровывается как Java Server Pages. Это технология, которая позволяет разработчикам веб- контента создавать содержимое с динамическими и статическими компонентами. Странички JSP включают в себя текст разного типа. Первый вариант – статическая исходная информация. Она может быть представлена в: HTML; WML; XML; SVG.Второй тип текста – JSP элементы. Они отвечают за создание динамического содержимого. Также допускается применение полноценной библиотеки JSP тегов и EL. Все это помогает внедрить Java-код в статичное содержимое JSP-страничек. JSP – это некая платформенно-независимая технология, используемая для написания HTML динамического характера. Теги здесь применяются для того, чтобы извлекать информацию из БД, обмениваться имеющимися сведениями и так далее. Для запуска часто применяются среды IDE NetBeans или Eclipse. Каждый программист при написании HTML странички должен решить, каким функционалом выбранного языка пользоваться. JSP обладает рядом преимуществ перед сервлетами: - Отвечает за возможность создания и управления HTML динамического типа. В данном случае процессы будут осуществляться более просто. - Для работы не требуется загрузка дополнительного программного обеспечения или документов. Пример – можно обойтись без файла класса java и web.xml. - Обработка ведется web-container для всех корректировок кода. Это приводит к тому, что JSP помогает избежать перекомпиляции. - доступ здесь осуществляется напрямую. Сервлеты требуют предварительного проведения сопоставления с web.xml. Цикл жизни Следующий момент, достойный внимания – это жизненный цикл JSP. Он полностью повторяет servlet, но имеет один дополнительный шаг. Во время него происходит компиляция рассматриваемой технологии в сервлет. Перевод – самое начало Это – первый этап. Здесь происходит следующее: 1. Контейнер переводит JSP документ в код Джавы. Он выступает сервлетом. 2. Перевод проводится в автоматическом режиме через веб-сервер. 3. Последний находит и проверяет достоверность, а затем производит запись сервлета для JPS page. Здесь никаких проблем с пониманием быть не должно. Компиляция – шаг два После описанных ранее действий контейнер JSP будет компилировать исходный Java-код. Это необходимо для того, чтобы создавать следующие servlets и сгенерированный классовый файл. Загружаем и инициализируем – шаг три Третий этап предусматривает следующее: 1. JSP Container загружает ранее созданный servlet. 2. Если процесс прошел правильно, будет создан экземпляр класса сервлета. 3. Важно учесть, что здесь используется конструктор, не имеющий никаких аргументов. 4. Контейнер JSP проводит инициализацию экземпляра объекта через вызов метода init. Он реализуется container посредством обращения к jspInit(). Элемент кода выше наглядно демонстрирует, каким образом осуществляется инициализация экземпляра. Выполнение – шаг четыре Теперь, когда основные этапы позади, происходит не менее важный момент – выполнение. Здесь технология JSP вызовет метод _jspService(). У него два параметра:  httpServletRequest;  HttpServletResponse. Вызывается рассматриваемый метод всего один раз для каждого отдельного запроса. Упомянутый метод будет отвечать за генерацию ответов на посланный запрос. Разрушение – логическое завершение На данном этапе целесообразно говорить о прекращении жизненного цикла. При разрушении контейнер будет удалять JSP при помощи jspDestroy(). Как это происходит, указано на наглядном примере выше. Статический контент создаётся в виде HTML. Динамический контент создаётся в JSP элементах 21. Директивы, объявления. Выражения и скриптлеты в JSP. Помимо HTML-тегов JSP страницы содержат теги следующих категорий: - Директивы: обеспечивают глобальную информацию, касающуюся конкретных запросов, направляемых в JSP, представляют информацию, необходимую на стадии трансляции. Существует 3 типа директив: page (определяет свойства страницы JSP, которые воздействуют на транслятор), taglib (объявляет, что данная страница использует библиотеку тегов), include (позволяет вставлять текст или код в процессе трансляции страницы JSP в сервлет). Синтаксис директив: - Объявления: для определения переменных и методов на языке скриптов, которые в дальнейшем используются на странице JSP. Синтаксис. Пример: - Скриплеты: включают разные фрагменты кода, написанного на языке скрипта, определённого в директиве language. Фрагменты кода должны соответствовать синтаксическим конструкциям языка скриплетов, т.е. как правило, синтаксису Java. Синтаксис скриплета: Закомментированный блок: обычный комментарий. Синтаксис: Возраст более 24 лет - позволяет задать цикл 2) Formatting: предоставляет теги для форматирования чисел, дат, времени. Использует префикс "fmt" и uri "http://java.sun.com/jsp/jstl/fmt" 3) SQL: предоставляет теги для работы с sql-запросами и источниками данных. Использует префикс "sql" и uri "http://java.sun.com/jsp/jstl/sql" 4) XML: предоставляет теги для работы с xml. Использует префикс "x" и uri "http://java.sun.com/jsp/jstl/xml" 5) Functions: предоставляет функции для работы со строками. Использует префикс "fn" и uri "http://java.sun.com/jsp/jstl/functions" 25. Особенности спецификаций в Java Platform EE и возможности API в Java EE. Концепция распределенной и удаленной обработки данных. Java Platform, Enterprise Edition (Java EE) – это набор спецификаций, API и технологий для разработки и развертывания приложений, которые могут быть запущены на серверах приложений. Java EE содержит множество API и сервисов, которые обеспечивают различные функциональные возможности, такие как веб-сервисы, многопоточность, управление транзакциями, безопасность и др. Java EE спецификации определяют стандартные интерфейсы и протоколы для взаимодействия между компонентами приложений, такими как сервлеты, EJB и JMS. Кроме того, Java EE включает в себя набор расширений и API для работы с базами данных, веб-сервисами, мессенджерами и другими распространенными технологиями. Одной из ключевых функций Java EE является концепция распределенной обработки данных. Распределенная обработка данных позволяет приложениям выполнять вычисления и обработку данных на нескольких серверах или узлах сети, что обеспечивает более высокую отказоустойчивость и масштабируемость. Для реализации распределенной обработки используются технологии: - Remote Method Invocation (RMI) - Java Message Service (JMS) - Java Naming and Directory Interface (JNDI) - Enterprise JavaBeans (EJB). Эти технологии позволяют создавать распределенные приложения, в которых компоненты могут работать на разных серверах или узлах сети, а обмен данными между ними осуществляется посредством специальных протоколов и интерфейсов. 26. Архитектура и уровни распределенных систем. Модели распределенных вычислений. Многозвенные распределенные системы. Компонентные системы Java EE. Базисные архитектуры. Характеристики информационной системы: - звенья (2 звена: клиент-сервер, 3 звена: клиент-сервер-БД) - слои - уровни (уровень клиента, уровень клиента, сервер БД) Распределенная система – система, функции которой разделены между несколькими ПК; система, способная выполнять функции нескольких клиентов. «Тонкий» клиент – конфигурационная часть системы, располагающая минимумом аппаратных средств и возможностей. «Толстый» клиент – конфигурационная часть системы, располагающая максимумом аппаратных средств и возможностей. Уровни распределенных систем: 1. Уровень приложений - содержит приложения, которые используются в распределенной системе, такие как клиентские приложения, веб-приложения, сервисы и т.д. 2. Уровень сервисов - содержит сервисы, которые предоставляются распределенной системой, такие как веб-сервисы, сервисы обработки сообщений и т.д. 3. Уровень протоколов - содержит протоколы для обмена данными между компонентами системы. Это может быть протокол HTTP, протоколы сериализации данных и т.д. 4. Уровень транспорта - содержит технологии, используемые для передачи данных между устройствами, такие как TCP/IP, UDP и т.д. Самые распространенные модели распределенных вычислений, определяющие способы взаимодействия между компонентами распределенной системы: - Модель удаленного вызова процедур (RPC) - позволяет вызывать удаленные процедуры, которые выполняются на другом компьютере в распределенной сети. - Модель сообщений (Messaging) - позволяет передавать сообщения между компонентами распределенной системы с использованием протоколов, таких как JMS (Java Message Service). - Модель распределенных объектов (CORBA, RMI) - позволяет создавать объекты, которые могут быть использованы удаленно другими компонентами распределенной системы. Многозвенные распределенные системы – это системы, которые состоят из нескольких подсистем, которые могут работать независимо друг от друга и взаимодействовать только через определенные интерфейсы. Многозвенные: клиент, бизнес-логика, веб-звено, звено БД Компоненты приложения: J2EE прикладные клиенты, J2EE web-компоненты, J2EE компоненты EJB Компонент - самостоятельная функциональная программная

Use Quizgecko on...
Browser
Browser