Ответы к экзамену по ТП 2009

Preview:

Citation preview

1. Понятие технологии программированияТехнологией программирования называется совокупность методов и средств, используемых в процессе

разработки ПО.Структура описания технологических операций

2. Этапы развития ТП. «Стихийное» программирование. Структурный подход к программированию. Объектный подход к программированию. Компонентный подход.Этапы развития технологии программирования:

1. «Стихийное программирование»2. Структурный подход3. Объектно-ориентированное программирование4. Компонентный подход«Стихийное» программирование.

Программирование – искусство манипулирования машинными кодами.Появление ассемблера позволило вместо двоичных или шестнадцатеричных

кодов использовать символические имена.Создание языков высокого уровня Fortran и Algol упростило

программирование, снизило уровень детализации операций, позволило увеличить сложность программ.

Структурный подходВ основе лежит декомпозиция (разбиение на части) сложных систем с целью последующей реализации в

виде отдельных небольших (40-50 операций) подпрограмм.

Поддержка принципов структурного программирования была заложена в основу процедурных языков PL/1, Algol 68, Pascal, C.

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

Современные версии Pascal, C/C++, языки Ada и Modula.

Объектно-

ориентированное программированиеПредставление программ в виде совокупности объектов, каждый из которых является экземпляром

определённого типа (класса), а класс образует иерархию с наследованием свойств. Взаимодействие программных объектов в самой системе осуществляется путём передачи сообщений.

Впервые реализована в языке имитационного моделирования Simula, затем Smalltalk, далее Pascal, C++, Modula, Java.

Компонентный подходПредполагает построение ПО из отдельных компонентов – физически отдельных существующих частей

ПО, которые взаимодействуют через стандартизованные двоичные интерфейсы.

Лежит в основе технологий, разработанных на базе COM (Component Object Model) и технологии создания распределённых приложений CORBA (Common Object Request Broker Architecture}.

3. Проблемы разработки сложных программных системГлавная сложность - логическая сложность решаемых задач.Дополнительные факторы:

сложность формального определения требования к критическим системам; отсутствие удовлетворительных средств описания поведения дискретных систем с большим числом

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

4. Блочно-иерархический подход к созданию сложных системБлочно-иерархический подход = декомпозиция + иерархическая упорядоченность

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

5. Жизненный цикл и этапы разработки программного обеспечения. Стандарт ISO/IEC 12207: 1995. По ГОСТ 19.102-77 «Стадии разработки»Жизненным циклом ПО называется период от момента появления идеи создания ПО до момента

завершения его поддержки фирмой-разработчиком.Стадии разработки ПО согласно ГОСТ 19.102-77 «СТАДИИ РАЗРАБОТКИ»:

1. Техническое задание2. Эскизный проект 3. Технический проект 4. Рабочий проект 5. Внедрение 1. Техническое задание

a) Обоснование необходимости разработки программы b) Научно-исследовательские работы c) Разработка и утверждение технического задания

2. Эскизный проект a) Разработка эскизного проекта b) Утверждение эскизного проекта

3. Технический проект a) Разработка технического проекта b) Утверждение технического проекта

4. Рабочий проект a) Разработка программы b) Разработка программной документации c) Испытания программы

5. Внедрение a) Подготовка и передача программы

6. Эволюция моделей жизненного цикла ПО

1. Каскадная модель (1970-1985 гг)

2. Модель с промежуточным контролем

3. Спиральная модель (сер. 80-х гг)

7. Оценка качества процессов создания ПО. Международные стандарты серии ISO 9000. Стандарт CMM.

CMM (Capability Maturity Model) определяет 5 уровней зрелости организаций-разработчиков:1. Начальный уровень (initial level) - данный уровень характеризуется тем, что компании занимаются

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

2. Повторяемый уровень (repeatable level). – на данном этапе в компании наблюдается строгий контроль и планирование проводимых операций. Основные процессы стабилизируются и становятся контролируемыми и повторяемыми. Наблюдается оптимизация за счёт повторяющихся процессов.

3. Определённый уровень (defined level). – на данном уровне процессы так же становятся настолько формализованными и строгими, что поддаются документированию. В компании наблюдается разграничение функций и описание обязанностей каждого из сотрудников. Благодаря документированности процесса производства возможен оперативный контроль за использованием ресурсов. Как правило, в таких компаниях производится только ретроспективный анализ деятельности (т. е. на показателях прошлых периодов), так же отсутствует долгосрочное планирование деятельности.

4. Управляемый уровень (managed level) – на данном уровне компания оптимизирует свои действия по улучшению качества продукции и качества предоставляемых услуг, с целью занять большую долю рынка. В организации формируются корпоративные стандарты качества к продукции и услугам, при чём стандарты устанавливаются для всех, от партнёров компании до конечных потребителей продукции. Становится возможным долгосрочное планирование бизнеса.

5. Оптимизационный уровень (optimizing level) - достичь этого уровня чрезвычайно трудно, и удается это лишь немногим компаниям, лидирующим в индустрии. Здесь управление качеством по количественным показателям происходит по всей цепи взаимосвязанных процессов, а модификация или совершенствование системы — по результатам обратной связи. Для организации характерно не только построение стратегических планов, но и оптимизация путей их достижения. Стратегия компании направлена на достижение организационного, финансового, технологического преимущества.

Software Engineering Institute Carnegie Mellon University http://www.sei.cmu.edu/cmm/

8. Сертификация организаций, специалистов

9. Качество и сертификация программного обеспечения. Параметры

10. Пользовательские интерфейсыПользовательский интерфейс - это способ взаимодействия программы с конечным пользователем, на сегодня выделяют несколько типов пользовательских интерфейсов:

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

2. Графический интерфейс - обычно создается средствами ООП, и является наиболее удобным и простым для пользователя. Объекты в графическом интерфейсе можно разделить на несколько групп:

a. Кнопки - обычно прямоугольные элементы с надписями и\или иконками, при нажатии на которые происходит заданное действие.

b. Текстовые поля - поля предназначенные для отображения текста.c. Контейнеры - используются для группировки других элементов или для выделения отдельной

области, чаще всего, для вывода мультимедиа контента.d. Меню - главные, контекстные.

Пользовательский интерфейс характеризуется следующими критериями:1. Простота освоения2. Скорость получения результата3. Удобство использования, красота, ...

11. Психофизические особенности человека, связанные с восприятием, запоминанием и обработкой информации

При построении дизайна стоит учитывать, что мы должны:1. обеспечить удобство работы пользователя2. минимизировать время необходимое для освоения программы3. удерживать внимание пользователя на важных деталях интерфейса

При этом необходимо учитывать следующие психофизические особенности восприятия человека:

1. количество цветов, которые человек может комфортно воспринимать на одном интерфейсе не более 3-5, причём 3 цвета на форме, одновременно, это уже не хорошо.

2. количество одновременно удерживаемых в памяти объектов обычно от 5 до 9 у разных типов людей, причём 3-5 элементов обеспечивают максимально комфортную работу с интерфейсом.

3. время запоминания оперативной информации обычно не более 15-30 секунд.4. время восприятия содержимого какого либо информационного контейнера или сообщения, обычно от 3

до 10 секунд, в зависимости от возраста и содержания.

12. Модели интерфейсов создаваемых программ примитивные - реализуют единственный сценарий работы, например, ввод данных - обработка - вывод

результатов; меню - реализует множество сценариев работы, операции которых организованы в иерархические

структуры; со свободной навигацией - реализует множество сценариев, операции которых не привязаны к уровням

иерархии и предполагают определённые множества возможных операций на конкретном шаге работы; прямого манипулирования - реализует множество сценариев, представленных в операциях над объектами,

основные операции инициируются перемещением пиктограмм объектов мышью.До 80% программного кода может реализовывать пользовательский интерфейс.Тип интерфейса также включает набор технологии работы с документами:

однодокументная (SDI - Single Document Interface); многодокументная (MDI --- Multiplay Document Interface).

Выбор подхода к разработке связан с выбором интерфейса. Интерфейсы 3 и 4 предполагают ООП, 2 можно реализовать структурным и объектным подходами. ООП не эффекивно для систем реального времени.

Выбор языка программирования.Группы языков программирования:

универсальные языки высокого уровня; специальные языки разработки ПО; специальные языки пользователя; языки низкого уровня.

Выбор среды программирования.Выбор или формирование стандартов разработки.

13. Критерии оценки интерфейсов пользователями

Интуитивно понятный интерфейс Уровень сложности выполнения различных операций Информативность диалогов Уровень документированности программы Наличие интуитивно понятного интерфейса Приемлемость задержек между запросом пользователя и ответом программы

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

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

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

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

от документированности, сложности кода и качества проектирования ПО. тестируемость - возможность измерения приёмочных характеристик, возможность получить данные о

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

14. Разновидности диалогов. Стадии разработки диалогов.

15. ДеревьяДерево – наиболее важная нелинейная структура, задающая отношение «ветвления».

Дерево – конечное множество Т одного или более узлов со следующими свойствами: а) существует один выделенный узел, а именно – корень(root) данного дерева Т; b) остальные узлы (за исключение корня) распределены среди m ≥ 0 непересекающихся множеств Т1,…,Тm и каждое из этих множеств, в свою очередь, является деревом: деревья Т1,…,Тm называются поддеревьями (subtrees) данного корня.

Определение рекурсивно, но здесь нет порочного круга.Дерево с одним узлом – это корень, а остальные определяются на основе деревьев меньшего размера.Из определения следует, что каждый узел дерева является корнем некоторого поддерева данного дерева. Количество поддеревьев узла называется степенью (degree) этого узла.Узел со степенью нуль называется концевым узлом (terminal node) или листом (leaf).Неконцевой узел называется узлом ветвления (branch node).Уровень (level) узла по отношению к дереву Т определяется рекурсивно: уровень корня дерева Т равен

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

А – кореньдва поддерева:{В},{С,D,E,F,G} C – корень {С,D,E,F,G} поддерева, имеет уровень 1, включает 3 поддерева {D},{E},{F,G}Þ степень равна трем Если в пункте b) имеет значение относительный порядок поддеревьев Т1,…,Тm , то дерево является упорядоченным (ordered tree).Их также называют плоскими (plane tree), т.к. при их размещении на плоскости имеет значение упорядочение.Если не считать различными два дерева, которые отличаются только относительным порядком

поддеревьев узлов, то дерево называется ориентированным (oriented tree), поскольку имеет значение только относительная ориентация узлов, а не их порядок.Ориентированные деревья:

Лес (forest) – это множество (обычно упорядоченное), не содержащее ни одного непересекающегося дерева или содержащее несколько непересекающихся поддеревьев.Лес и дерево тесно связаны: если из дерева исключить корень, то получим лес, и, наоборот, если добавить один узел в лес, все деревья которого рассматриваются, как поддеревья нового узла, получим дерево.

16. Обход бинарных деревьевПредставление бинарного дерева в памяти компьютера: каждый узел имеет связи LLINK и RLINK, а также переменную связи Т, которая является указателем дерева. Если дерево пусто, то Т = L, в противном случае Т является адресом корневого узла этого дерева, а LLINK(Т) и RLINK(T) это указатели на левое и правое поддеревья этого корня соответственно. Пример:

А

B C

D F E

G

А

B C

D E F

G

А

B C

D E F

G

ур.0

ур.1

ур.2

ур.3

ст.2

ст.3

ст.1

лист

лист лист

лист

Обход(traversing) дерева – это алгоритм работы с древовидной структурой, при котором каждый узел посещается только один раз. Полный обход дерева задает линейное упорядочивание узлов.3 способа обхода:

• в прямом порядке (preorder)• в центральном порядке (inorder)• в обратном порядке (posorder)

Эти способы определяются рекурсивно: если бинарное дерево пусто, то для его «обхода» ничего делать не потребуется, иначе обход выполняется в 3 этапа: Прямой порядок: 1.попасть в корень 2.пройти левое поддерево 3.пройти правое поддеревоЦентральный порядок: 1.пройти левое поддерево 2.попасть в корень 3.пройти правое поддеревоОбратный порядок: 1.пройти левое поддерево 2.пройти правое поддерево 3.попасть в кореньВо многих приложениях бинарных деревьев понятие левого и правого поддеревьев совершенно симметричны, в таких случаях термин симметричный порядок используется в качестве синонима понятия центрированный порядок.Алгоритм (обхода дерева в симметричном порядке)Пусть Т – указатель на бинарное дерево, тогда все узлы обходятся в симметричном порядке с помощью вспомогательного стека А:T1.[Инициализация] Опустошить стек А и установить Р ¬ Т. Т2.[Р = L?] Если Р = L , то перейти к шагу Т4. Т3.[Стек Ü Р] Установить А Ü Р, т.е. вставить значение Р в стек А. Затем установить Р ¬ LLINK(P) и вернуться к шагу Т2.Т4.[Р Ü Стек] Если стек А пуст, то выполнение алгоритма прекращается; иначе установить Р Ü А. Т5.[Попасть в Р] Попасть в узел NODE(P). Затем установить Р ¬ RLINK(P) и вернуться к шагу Т2.Обозначения: Р* – адрес узла-последователя NODE(P) при обходе в прямом порядке. Р$ – адрес узла-последователя NODE(P) при обходе в симметричном порядке. Р# – адрес узла-последователя NODE(P) при обходе в обратном порядке.Аналогично *Р, $Р, #P, только с тем различием, что адрес узла-предшественника, а не последователя.Свойства: *(P*) = (*P)* = P; $(P$) = ($P)$ = P; #(P#) = (#P)# = PПусть INFO(P) – буква изображенная в узле NODE(P), Р – корень, тогда INFO(P) = А, INFO(P*) = B? INFO(P$) = E, INFO($P) = B, INFO(#P) = C и Р# = *P = LOC(T), обозначает что узел не имеет последователя или предшественника.Другое представление бинарных деревьев. В примере дерево содержит больше пустых связей, чем всех остальных, поэтому можно хранить двухбитовый «признак» (tag), который указывает пустая или непустая связь LLINK(RLINK). Можно также предложить способ А.Дж.Перлиса и И. Торнтона.17. Прошитые бинарные деревьяЗдесь концевые связи заменяются нитями (threads), которые связаны с другими частями дерева для упрощения обхода дерева.

Пунктиром обозначены «нити», которые всегда направлены к более высокому узлу дерева.Представление прошитого бинарного дерева в памяти компьютера: вводятся дополнительные однобитовые поля LTAG и RTAG.Обычное представление: LLINK(P) = L LLINK(P) = Q ≠ L

RLINK(P) = L RLINK(P) = Q ≠ L Прошитое представление: LTAG(P) = 1, LLINK(P) = $PLTAG(P) = 0, LLINK(P) = QRTAG(P) = 1, RLINK(P) = P$RTAG(P) = 0, RLINK(P) = Q 18. Представление деревьев в виде бинарных деревьевОсновные различия: 1) Дерево всегда имеет корень, т.е. оно никогда не бывает пустым: каждый узел может иметь 0,1,2,… детей. 2) Бинарное дерево может быть пустым, а каждый его узел может иметь 0,1 или 2 детей. (будем различать левых и правых детей)Рассмотрим лес, состоящий из двух деревьев:

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

Такое приведение узлов (1) – (3) называется естественным соответствием между лесом и бинарным деревом.

Пусть F = (T1,T2,…,Tn) – некоторый лес деревьев, тогда бинарное дерево B(F), соответствующее F, можно строго определить следующим образом: а) Если n = 0, то B(F) пусто.в) Если n > 0, то корень B(F) является корнем (Т1); В(Т11,Т12,…,Т1m) является левым поддеревом дерева B(F), где Т11,Т12,…,Т1m – поддеревья корня (Т1); В(Т2,…,Тn) является правым поддеревом дерева B(F).

19. Методы сортировки. Понятия. Классификация методов• Для решения задач группирования(собрать вместе все элементы с одинаковыми значениями

некоторого признака)• Поиск общих элементов в двух и более массивах (если два или более массивов рассортировать в одном

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

представлять информацию в удобном для человека виде)Пусть необходимо упорядочить N элементов: R1,R2,…RN .Назовем их записями, а всю совокупность записей назовем файлом. Каждая записьRj имеет ключ Kj , который управляет процессом сортировки. Помимо ключа запись может содержать дополнительную «сопутствующую информацию», которая не влияет на процесс сортировки, но всегда остается в записи.

Отношение порядка на множестве ключей(“<“) вводится так, чтобы " a, b, c выполнятся условия:

• Справедливо одно и только одно из соотношений a < b, a = b, b < a (закон трихотомии).• Если a < b и b < c,то a < c (закон транзитивности)

Эти два свойства определяют математическое понятие линейное упорядочение, называемое также совершенным упорядочиванием.Задача сортировки – найти такую перестановку записей p(1),p(2),…p(N) с индексами {1,2,…,N}, после которой ключи расположились бы в порядке неубывания: Kp(1)≤Kp(2)≤…≤Kp(N). Сортировка называется устойчивой, если записи с одинаковыми ключами остаются в прежнем порядке p(i) ≤ p(j) " Kp(i) = Kp(j) и i < j. В одних случаях физически перемещают данные в памяти, в других достаточно создать вспомогательную таблицу.Некоторые методы сортировки предполагают существования величин «¥» и «-¥»: -¥ ≤ Kj≤ ¥ " 1 ≤ j ≤ N .Методы сортировки обычно делятся на два класса: внутренние и внешние.Сортировка называется внутренней в том случае, когда все данные хранятся в быстрой памяти, а внешней, когда все записи в быстрой памяти не помещаются.Достаточно хороший алгоритм сортировки затрачивает на упорядочивание N элементов время пропорциональное N logN , при этом требуется logN «проходов» по данным. Это минимальное время, если записи расположены в произвольном порядке и сортировка производится попарным сравнением ключей.Таким образом, если количество записей возрастает в 2 раза, то и время при прочих равных условиях возрастает немногим более чем вдвое.

20. Методы сортировки выбором. Сортировка простым выбором, квадратичным выбором, кубическим выбором. Пирамидальная сортировка.

21. Методы сортировки вставками. Сортировка простыми и двухпутевыми вставками. Сортировка бинарными вставками. Метод Шелла (с убывающим шагом).

22. Методы обменной сортировки. Метод пузырькового всплытия. Шейкер-сортировка. Поразрядная обменная сортировка. Сортировка с разделением (быстрая сортировка Хоара).

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

24. Методы сортировки слиянием: простое, двухпутевое, естественное.

25. Сортировка подсчетом. Подсчет сравнений. Подсчет распределений.

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

Цель поиска – нахождение информации, хранящейся в ассоциированной с К записи. К – аргумент поиска, который является ключом.Результаты поиска: а)поиск завершен успешно, уникальная запись найдена; б)запись с ключом К не найдена.Классификация методов поиска: 1)внутренний и внешний поиск, подобно алгоритмам сортировки. 2)статический и динамический, где содержимое остается неизменным, или таблица изменяется путем вставки или удаления. 3)на чем основаны: на сравнении ключей или на некоторых числовых свойствах ключей.

Идея: начать сначала, и продолжать, пока не будет найден искомый ключ; затем остановиться.Алгоритм S (Последовательный поиск) Дана таблицы записей R1,R2,…,RN (N ≥ 1) с ключами K1,K2,…,KN . Алгоритм предназначен для поиска записи с заданным ключом К.1.[Инициализация] Установить i ¬ 1. 2.[Сравнение] Если K = Ki , то алгоритм успешно завершается. 3.[Продвижение] Увеличить i ¬ i +1. 4.[Конец файла?] Если i ≤ N, то перейти к шагу 2, иначе алгоритм завершается неудачно.

Среднее значение сравнений при одинаковой вероятности входных ключей составит при этом среднеквадратичное отклонение велико 0.289N.Алгоритм Q (Быстрый последовательный поиск) Тот же алгоритм S, но добавлен фиктивный элемент, что уменьшает количество сравнений.1.[Инициализация] Установить i ¬ 1 и KN+1 ¬ K. 2.[Сравнение] Если K = Ki , то прейти к шагу 4. 3.[Продвижение] Увеличить i ¬ i+1 и перейти к шагу 2. 4.[Конец файла?] Если i ≤ N, то алгоритм завершается успешно; иначе неудачно (i = N + 1).Частота обращений. До сих пор предполагалось, что все аргументы поиска равновероятны. В общем случае это не так. Вероятность запроса на поиск с ключом Kj равна pj , причем p1 + p2 + … +pN = 1. Время поиска, пропорциональное количеству сравнений c, которое имеет среднее значение СN = р1 + 2р2 + … + NpN

. Значение СN минимально при р1 ≥ р2 ≥ …≥рN , т.е. когда наиболее часто встречаемые записи находятся в начале таблицы. При р 1 = р2 = … = рN = 1/N, СN = (N + 1)/2 как и ранее. При р1 = 1/2 , р2 = 1/4 ,…,рN = 1/2N-1 , тогда СN = 2 – 21-N , при этом среднее количество сравнений меньше двух. При р1 = Nc, p2 = (N – 1)c,…,pN = c, c = 2/(N(N + 1)).

N

kN

NkNkcC

1 3

2)1(

При оптимальном размещении экономится треть времени.Наиболее реальное распределение Зипфа: р1 = с/1, р2 = с/2,…,рN = с/N, где с = 1/HN

CN = N/HN . Поиск осуществляется примерно в ½ Ln N раз быстрее, чем в неупорядоченном файле.Последовательный поиск. Массив упорядочен по типу используемого поискового термина. Если данные о размещении записей отсутствуют или же массив хранится в ЗУ с последовательной выборкой, то требуется сопоставление каждой записи R1, R2…Rn, пока не будут найдены нужные записи. Если будет найдена запись, значение сортировочного ключа которой превосходит его значение для термина запроса, извлечение записи не производится и поиск прекращается.Быстрый последовательный поиск. Является улучшенным последовательным поиском. Имеется таблица записей R1, R2,..Rn, снабженных соответственно ключами К1,К2..Кn. Алгоритм предназначен для поиска с данным ключом К. Предполагается, что в конце файла стоит фиктивная запись Rn+1.

В большинстве случаев вероятности обращений априори неизвестны. Можно было бы хранить счетчик обращений к записи и на основании полученных данных переупорядочивать их, но стоит ли тратить место под выделение счетчиков.Существует простая схема: когда запись успешно обнаружена, она перемещается в начало таблицы. Идея «самоорганизующейся» технологии заключается в том, что наиболее часто используемые записи в результате будут расположены в начале таблицы. (+-)27. Методы поиска среди упорядоченных данных. Бинарный поиск. Однородный бинарный поиск.

Фибоначчиев поиск. Интерполяционный поиск. Поиск со вставкой по дереву. Цифровой поиск со вставкой по дереву.

Идея: начать со среднего элемента таблицы, сравнить и затем откинуть половину.(Не более, чем за Log2 N элемент будет найден)Алгоритм В Дана таблица записей R1 ,R2 ,…,RN , ключи: K1 < K2 < … < KN . Алгоритм используется для поиска в таблице, заданной аргументом К.1.[Инициализация] Установить L ¬ 1, u ¬ N. 2.[Получение середины] Если u < L, алгоритм завершается неудачно, иначе i ¬ ë(L+u)/2û , чтобы i соответствовало середине рассматриваемой части таблицы.

3.[Сравнение] Если K < Ki , то перейти к шагу 4, если K > Ki , то перейти к шагу 5, если K = Ki , то алгоритм успешно завершается. 4.[Изменение u] Установить u ¬ i – 1 и перейти на шаг 2. 5.[Изменение L] Установить L ¬ i + 1 и перейти на шаг 2.Примеры бинарного поиска:Ищем число 426. [ 061 087 154 170 275 426 503 509]

[ 426 ] [426]

Ищем число 80. [ 061 087 154 170 275 426 503 509] [ 087 ] [ 061 ] ] 061 [Результат (процесс) бинарного поиска удобно изображать в виде бинарного дерева.

Альтернативой к бинарному поиску может служить поиск Фибоначчи, где используется не степени 2, а числа Фибоначчи.Однородный бинарный поиск. Модификация предыдущего метода, используется H – длина отрезка. H=H/2. Если X<Ai, то нет l=I i=i+H иначе R=i i=i-H. Трудоемкость log2N.Для данной длины массива заранее рассчитываются смещения для деления неохваченного куска пополам, т.е. во вспомогательном массиве D длиной в разрядность машинного слова (32, например) хранятся величины Len/2, Len/4 и т.д. При поиске на каждой итерации новый индекс рассчитывается не делением пополам, а прибавлением или вычитанием очередного D[i].Актуальность алгоритма невелика - может чуть повыситься скорость при многократных поисках в массиве или массивах одной длины, и на тех процессорных архитектурах, в которых деление интервала пополам (m := (l + r) shr 1 {div 2} намного медленнее взятия из массива.Фибоначчиев поиск.Поиск берется с конца, берется последнее число Фибоначчи, не превышающее длины массива. А1… А2… А3… А5… А8… А13… А21… А34. Сравниваем до тех пор, пока не попадем в ситуацию, когда X больше первого. В правом фрагменте берем позицию элементов AFi+Fi-2. Если организовать рекурсивно, то массив передается в функцию. Трудоемкость log2N. Алгоритм фибоначчиева поиска:1. Шаг 1. Задаются начальные границы отрезка a,b и число итераций n, рассчитывают начальные точки деления: x1 = a+(b-a)*F{n-2}/F{n}, x2 = a+(b-a)*F{n-1}/F{n} и значения в них целевой функции: y1=f(x1), y2=f(x2).2. Шаг 2. n=n-1.* Если y1>y2, то a=x1, x1=x2, x2=b-(x1-a),y1=y2,y2=f(x2).* Иначе b=x2,x2=x1,x1=a+(b-x2),y2=y1,y1=f(x1).3. Шаг 3.* Если n=1, то x=x1=x2 и останов.* Иначе возврат к шагу 2.Представьте себе, что Вы ищете слово в словаре. Маловероятно, что Вы сначала загляните в середину словаря, затем отступите от начала на 1/4 или 3/4 и т.д, как в бинарном поиске.Если нужное слово начинается с буквы 'А', вы наверное начнете поиск где-то в начале словаря. Когда найдена отправная точка для поиска, ваши дальнейшие действия мало похожи на рассмотренные выше методы.Если Вы заметите, что искомое слово должно находиться гораздо дальше открытой страницы, вы пропустите порядочное их количество, прежде чем сделать новую попытку. Это в корне отличается от предыдущих алгоритмов, не делающих разницы между 'много больше' и 'чуть больше'.Мы приходим к алгоритму, называемому интерполяционным поиском: Если известно, что К лежит между Kl и Ku, то следующую пробу делаем на расстоянии (u-l)(K-Kl)/(Ku-Kl) от l, предполагая, что ключи являются числами, возрастающими приблизительно в арифметической прогрессии.// Поиск в массиве K[1..N] числа X интерполяционным поискомl=1; u=N;while(u>=l) { i=l+¦(u-l)*(X-K[l])/(K[u]-K[l]);

if(X<K[i]] u=i-1; else if(X>K[i]] l=i+1; else НАШЛИ, X==K[i].}Не нашли.Интерполяционный поиск работает за log log N операций, если данные распределены равномерно. Как правило, он используется лишь на очень больших таблицах, причем делается несколько шагов интерполяционного поиска, а затем на малом подмассиве используется бинарный или последовательный варианты.Алгоритм Т (Поиск по дереву со вставкой). Дана таблица записей, образующая бинарное дерево. Алгоритм предназначается для поиска данного аргумента К. Если К в таблице отсутствует, то новый узел, содержащий К, вставляется в дерево в надлежащее место. KEY(P) – ключ, хранится в узле NODE(P)LLINK(P) – указатель на левое поддерево узла NODE(P) RLINK(P) – указатель на правое поддерево узла NODE(P)Пустые поддеревья представляются пустым указателем L. Переменная ROOT указывает на корень дерева ROOT ≠ L.1.[Инициализация] Установить P ¬ ROOT. 2.[Сравнение] Если K < KEY(P), то перейти на шаг 3, если K > KEY(P), то перейти на шаг 4, если K = KEY(P), то поиск успешно завершен. 3.[Перемещение влево] Если LLINK(P) ≠ L, то P ¬ LLINK(P) и перейти на шаг 2, иначе – шаг 5. 4.[Перемещение вправо] Если RLINK(P) ≠ L, то P ¬ RLINK(P) и перейти на шаг 2. 5.[Вставка в дерево] Установить Q ¬ AVAIL , KEY(Q) ¬ K, LLINK(Q) ¬ RLINK(Q) ¬ L. Если К был меньше, чем KEY(P), то LLINK(P) ¬ Q, иначе RLINK(P) ¬ Q. (Теперь можно P ¬ Q и считать поиск успешно завершенным)(+-)

28. Критические системы. Надежность систем. Составляющие функциональной надежности.Угрозы безопасности информации и программного обеспечения КС возникают как в процессе их эксплуатации, так и при создании этих систем, что особенно характерно для процесса разработки ПО, баз данных и других информационных компонентов КС.Наиболее уязвимы с точки зрения защищенности информационных ресурсов являются так называемые критические компьютерные системы. Под критическими компьютерными системами будем понимать сложные компьютеризированные организационно-технические и технические системы, блокировка или нарушение функционирования которых потенциально приводит к потере устойчивости организационных систем государственного управления и контроля, утрате обороноспособности государства, разрушению системы финансового обращения, дезорганизации систем энергетического и коммуникационно - транспортного обеспечения государства, глобальным экологическим и техногенным катастрофам.При решении проблемы повышения уровня защищенности информационных ресурсов КС необходимо исходить из того, что наиболее вероятным информационным объектом воздействия будет выступать программное обеспечение, составляющее основу комплекса средств получения, семантической переработки, распределения и хранения данных, используемых при эксплуатации критических систем.В настоящее время одним из наиболее опасных средств информационного воздействия на компьютерные системы являются программы - вирусы или компьютерные вирусы.Наибольшее распространение компьютерные вирусы получили с развитием персональных ЭВМ (ПЭВМ) и появлением микропроцессоров фирмы Intel. Это обусловлено тем, что для ПЭВМ наиболее распространенными операционными системами (ОС) были и используются по настоящее время (в новых версиях) ОС MS-DOS и ОС Windows, которые по многим параметрам открыты и беззащитны к вирусной угрозе. В известных классификациях вирусов [3,59] более 90% от их общего числа составляют именно вирусы для среды этих операционных систем. Для наиболее распространенных современных сетевых и многозадачных операционных систем ряда Windows, OS/2 и клона Unix по сравнению с этим вирусов обнаружено не столь много.В последние 10-15 лет компьютерные вирусы нанесли значительный ущерб, как отдельным средствам вычислительной техники, так и сложным телекоммуникационным системам различного назначения. Интенсивные проявления вирусных заражений начались примерно в середине 80-х годов. Так, с 1986 по 1989 год было зарегистрировано 450 случаев проникновения через сеть INTERNET компьютерных вирусов в сеть Министерства обороны США DDN, из которых 220 были классифицированы как успешные. Только стоимость операций по выявлению источников вирусных атак в DDN превысила 100 тысяч долларов. Факты попыток проникновения с использованием компьютерных вирусов в информационные банки критических систем в первой половине 80-х были зарегистрированы в различных сетях США, Франции, Великобритании, ФРГ, Израиля, Пакистана и Японии. По мнению исследователей, после заражения одной ЭВМ в сети среднее время заражения следующего узла сети составляет от 10 до 20 минут. При такой интенсивности размножения некоторые вирусы способны за несколько часов вывести из строя всю сеть.Надежность.

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

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

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

Существует четыре основные составляющие функциональной надежности программных систем (рис. 16.1), неформальные определения которых приведены ниже.

1. Работоспособность – свойство системы выполнять свои функции в любое время эксплуатации.2. Безотказность – свойство системы корректно (так, как ожидает пользователь) работать весь

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

окружающей среды.4. Защищенность – свойство системы противостоять случайным или намеренным вторжениям в

нее.

Дополнительные меры, повышающие функциональную надежность системы, могут резко увеличивать стоимость ее разработки. На рис. 16.2 показана зависимость между стоимостью разработки и различными уровнями функциональной надежности. Здесь подразумевается, что функциональная надежность содержит все составляющие: работоспособность, безотказность, безопасность и защищенность. Экспоненциальный характер зависимости "стоимость-надежность" не позволяет говорить о возможности создания систем со стопроцентной надежностью, так как стоимость их создания была бы очень большой.

Рис. 16.2. Зависимость между стоимостью разработки системы и ее надежностью

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

1. Ненадежные системы часто остаются невостребованными. Если к системе нет доверия пользователя, она не будет востребована. Более того, пользователи могут отказаться от других программных продуктов той же компании-разработчика, поскольку будут также считать их ненадежными.

2. Стоимость отказа системы может быть огромна. Для некоторых приложений, таких, как системы управления реакторами или системы навигации, стоимость последствий отказа может превышать стоимость самой системы.

3. Трудно модернизировать ненадежную систему для повышения ее надежности. Обычно есть возможность улучшить неэффективную систему, так как в этом случае основные усилия будут затрачены на модернизацию отдельных программных модулей. Систему, к которой нет доверия, трудно улучшить, поскольку ненадежность "распределена" по всей системе.

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

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

Надежность системы зависит от технологии разработки ПО. Многократные тестирования с целью исключения ошибок способствуют разработке надежных систем. Однако нет простой связи между качеством процесса создания и качеством готовой системы. Вопросы взаимосвязи между процессом создания ПО и качеством готовой продукции рассматриваются в главах 24 и 25, где представлены темы управления качеством и модернизации систем.

29. Типы критических систем. Системные компоненты критических систем, склонных к отказу. Примеры критических систем.

Обычно отказ систем, управляемых с помощью ПО, вызывает неудобства, но они не приводят к длительным последствиям. Однако имеются системы, отказы которых могут приводить к значительным экономическим потерям, физическим повреждениям или создавать угрозу человеческой жизни. Такие системы обычно называют критическими. Функциональная надежность – необходимое требование к критическим системам, и все ее составляющие (работоспособность, безотказность, безопасность и защищенность) очень важны. Не менее важен для критических систем и высокий уровень надежности.Существует три основных типа критических систем.1. Системы, критические пo обеспечению безопасности. Системы, отказ которых приводит к разрушениям, создает угрозу жизни человека или наносит вред окружающей среде. В качестве примера можно привести систему управления производством на химическом заводе.2. Системы, критические для целевого назначения. Системы, отказ которых может привести к ошибкам в действиях, направленных на обеспечение определенной цели. Примером может служить навигационная система космического корабля.3. Системы, критические для бизнеса. Отказ таких систем может нанести вред делу, в котором они используется. Примером является система, обслуживающая счета клиентов в банке.Цена ошибки критической системы часто очень велика. Она включает прямые расходы, связанные с внесением изменений в систему или ее заменой, косвенные расходы, например судебные, и расходы, связанные с потерями в бизнесе. Из высокой возможной цены отказа системы следует, что качество методов разработки и сам процесс создания ПО обычно более важны, чем стоимость применения этих методов.Поэтому при создании критических систем обычно используются испытанные методы разработки, а не новые, еще не имевшие большого практического применения. Только сравнительно недавно такие

относительно новые методы, как, например, объектно-ориентированные, стали использоваться для разработки критических систем, вместе с тем до сих пор при разработке многих критических систем все еще применяются функционально-ориентированные методы.С другой стороны, методы разработки ПО, которые обычно нерентабельны, могут использоваться для разработки критических систем, например метод формальных спецификаций и формализованной проверки программ на соответствие таким спецификациям. Одной из причин использования этих методов является уменьшение количества требующегося тестирования. Для критических систем стоимость проверки и аттестации обычно очень высока и может составлять более 50% общей стоимости системы.Хотя эта книга посвящена разработке программных систем, а не общей теории систем, необходимо отметить, что функциональная надежность – общесистемное понятие. Рассматривая надежность критических систем, можно выделить три типа системных "компонентов", склонных к отказу.1. Аппаратные средства системы, отказывающие либо из-за ошибок конструирования, либо из-за ошибок изготовления, либо из-за полного износа.2. Программное обеспечение системы, которое может отказывать из-за ошибок либо в технических требованиях к системе, либо в архитектуре системы, либо в программном коде.3. Человеческий фактор, который своими действиями нарушает правильную работу системы.Таким образом, если цель состоит в том, чтобы повысить надежность системы, необходимо рассматривать все эти аспекты во взаимосвязи. Я поясняю это положение на нескольких примерах в других главах этой части книги.16.1.1. Системы, критические по обеспечению безопасностиВ этом разделе в качестве примера системы, критической по обеспечению безопасности, рассмотрим систему, управляющую дозировкой инъекций инсулина при заболевании диабетом. Предполагается, что большинство читателей имеют общее представление об этом заболевании и его лечении. Эта система описана в главе 9, где была представлена ее формальная спецификация.Диабет – заболевание, при котором человеческий организм не может выработать достаточное количество гормона, называемого инсулином и регулирующего содержание сахара в крови. Если уровень инсулина в организме будет избыточным, содержание сахара в крови может понизиться, что влечет за собой очень серьезные последствия – прекращение питания мозга, приводящее к потере сознания и даже летальному исходу. Если же организм вырабатывает инсулин в недостаточном количестве, то уровень сахара повышается, что приводит к нарушению зрения, заболеванию почек и всего организма.Благодаря появлению миниатюрных датчиков стало возможным создание автоматизированной системы инъекций инсулина. Она контролирует уровень сахара в крови, и, если необходимо, в организм вводится соответствующая доза инсулина. Конечно, такие системы могут пока работать только в стационарных условиях. В дальнейшем, будучи подключенными к человеку, они станут доступны широкому кругу больных диабетом.Для работы такой системы микродатчик вживляется в тело больного. Этот датчик контролирует определенный параметр крови, который характеризует уровень сахара. Результат посылается в контрольный блок, который вычисляет уровень сахара, определяет необходимую дозу инсулина и посылает сигнал для инъекций постоянно подсоединенной игле. Совершенно очевидно, что такой системой должна управлять надежная программа. На рис. 16.3 показаны компоненты и организация системы дозировки инъекций инсулина. На рис. 16.4 показана модель потока данных, где видно, как входное значение уровня сахара в крови преобразуется в последовательность команд управления дозировкой инъекций инсулина.

Рис. 16.3. Структура системы дозировки инъекций инсулина

Рис. 16.4. Модель потока данных системы дозировки инъекций инсулинаНадежность системы дозировки инъекций инсулина характеризуется тремя составляющими.1. Работоспособность. При возникновении критической ситуации система должна быть готовой ввести необходимую дозу инсулина.2. Безотказность. В зависимости от уровня сахара в крови система должна правильно определить дозу инсулина и ввести ее пациенту.3. Безопасность. Отказ такой системы может привести к чрезмерной дозе инсулина, что представляет опасность для жизни больного. Необходимо добиться, чтобы такого рода отказов в системе не было.

Работоспособность и безотказностьВ этом разделе обсуждаются две близко связанные составляющие функциональной надежности –

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

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

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

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

Безотказность и работоспособность системы могут быть определены более точно следующим образом.

1. Безотказность – это способность системы безотказно работать определенное время с указанной целью в определенном окружении.

2. Работоспособность – это способность системы правильно функционировать и предоставлять вовремя требуемые сервисы.

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

Следовательно, оценка безотказности в одном окружении не обязательно переносится в другое окружение, где система используется по-другому.

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

Также важны способы использования системы и реакция человека на ее работу. Представим себе, что у автомобиля неисправна стеклоочистительная система – происходит сбой в работе стеклоочистителей. В дождливую погоду работа этой системы очень важна. Безотказность такой системы будет определяться местностью, где происходит действие, и реакцией водителя. Для водителя из Сиэтла (влажный климат) этот отказ будет более чувствителен, чем для водителя из Лас-Вегаса (сухой климат). Водитель из Сиэтла будет считать, что система не является безотказной, в то время как водитель из Лас-Вегаса вообще никогда не столкнется с этой проблемой.

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

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

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

Безотказность системы определяется отсутствием сбоев. Отказы системы могут происходить из-за плохого или неправильного ее обслуживания, могут быть следствием ошибок в алгоритме, а могут быть вызваны неисправностями систем связи. Однако во многих случаях причиной ошибочного поведения системы являются дефекты в самой системе. При рассмотрении безотказности полезно понимать различие в терминах сбой, ошибка и отказ, которые определены в табл. 16.1.Таблица 16.1. Терминология безотказностиТермин ОписаниеОтказ системы Прекращение функционирования системы

Системные ошибки Ошибочное поведение системы, не соответствующее ее спецификации

Сбой системы Неправильное поведение системы, непредвиденное ее разработчиками

Ошибка оператора Неверные действия пользователя, вызвавшие сбой в работе системы

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

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

1. Предотвращение сбоев. Подход к разработке ПО, минимизирующий возможность появления ошибок и/или обнаруживающий ошибки прежде, чем они приведут к сбоям системы. Пример такого подхода – исключение подверженных ошибкам определенных конструкций языков программирования (например, указателей) и постоянный анализ программ для обнаружения различных аномалий программного кода (см. главу 19).

2. Обнаружение ошибок и их устранение. Использование разнообразных методов проверки системы в различных режимах позволяет обнаружить ошибки и устранить их до ввода системы в эксплуатацию. Регулярное тестирование системы и ее отладка – пример данного подхода.

3. Устойчивость к сбоям. Использование специальных методов, гарантирующих, что ошибки в системе не приведут к сбоям и что сбои не приведут к отказам системы. Пример такого подхода – применение средств самовосстановления системы с использованием дублирования модулей.

Разработка систем, устойчивых к сбоям, описана в главе 18, где также кратко обсуждаются некоторые методы предотвращения сбоев. Методы разработки ПО, предотвращающие сбои, приведены в главе 24. Вопросы обнаружения системных ошибок обсуждаются в главах 19 и 20.

Рис. 16.5. Программная система как отображение входных данных на множество выходных данныхПрограммный сбой приводит к отказу системы, когда "сбойный" программный код выполняется

над определенными входными данными, приводящими к сбою системы. При этом программа может корректно работать на других входных данных. На рис. 16.5, заимствованным из работы [221], программная система представлена как отображение множества входных данных (входов) на множество выходных данных (выходов). Программа обрабатывает входные данные, получая выходные данные.

Некоторые из входных данных (см. рис. 16.5) приводят к отказам системы, в результате программа генерирует ошибочные выходные данные. Безотказность программного обеспечения характеризуется вероятностью, с которой при выполнении программы среди множества входных данных встретятся такие, что приведут к ошибочным результатам вычислений.

Существует сложная взаимосвязь между наблюдаемой безотказностью системы и количеством скрытых программных дефектов. В работе [239] подчеркивается, что не все программные ошибки в равной степени вызывают отказ системы. Обычно в множестве входных данных Iê, приводящих к ошибочным выходным данным, имеется ряд данных, вероятность выбора которых больше, чем у других данных. Если эти входные данные не требуют для своей обработки той части ПО, которая содержит ошибки, то системных сбоев не будет. Таким образом, безотказность системы зависит преимущественно от количества входных данных, приводящих к ошибочным результатам во время нормальной эксплуатации системы. Сбои системы, которые проявляются только в исключительных ситуациях, мало влияют на ее надежность.

Надежность системы связана с вероятностью ошибки, проявляющейся во время эксплуатации системы. Устранение программных ошибок в редко используемых системных модулях мало повлияет на повышение безотказности системы. В работе [239] показано, что устранение 60% программных ошибок только на 3% повысит безотказность системы. Это подтверждается и исследованиями ошибок в программных продуктах IBM. В работе [4] показано, что многие ошибки в программных продуктах реально вызывают сбои системы после сотен или тысяч месяцев эксплуатации.

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

Рис. 16.6. Использование множества входных данных разными пользователямиКаждый пользователь системы по-своему избегает "встречи" с системными ошибками. Ошибки, с

которыми встречается один пользователь, могут никогда не встретиться другому. На рис. 16.6 показано множество входных данных, используемых разными пользователями. Входные данные, выбранные пользователем 2 пересекаются с входными данными, приводящими к сбою системы. Поэтому пользователь 2 будет сталкиваться со сбоями системы. Пользователи 1 и 3 никогда не используют входных данных, приводящих к сбою системы, – для них программное обеспечение всегда будет безотказно.

30. Предотвращение ошибок программирования. Языковые конструкции, подверженные ошибкам. Сокрытие информации.

31. Генерация последовательностей случайных чисел. Линейная конгруэнтная последовательность. Выбор модуля. Выбор множителя. Линейная конгруэнтная последовательность, имеющая максимальный период. Потенциал л.к.п.

Числа, которые выбираются случайным образом имеет множество полезных применений.а)Моделирование. Случайные числа помогают приблизиться к реальности. б)Выборочный метод. Часто невозможно проверить все варианты, поэтому делают случайную выборку. в)Численный анализ. Существует множество технологий использующих случайные числа в численном анализе. г)Компьютерное программирование. Случайные числа являются хорошим источником для тестирования эффективности алгоритмов. д)Принятие решений. Случайность является важной частью оптимальных стратегий. е)Эстетика. Небольшая добавка случайности оживляет музыку и компьютерную графику. ж)Развлечение. Случайные числа используются в компьютерных играх.Часто говорят не о том является ли это число случайным, а о последовательности случайных чисел с заданным законом распределения.Равновероятным распределением на конечном множестве чисел называется такое распределение, при котором любое из возможных чисел имеет одинаковую вероятность.Л.к.п.Д. Г. Лехмер 1949 год.Выберем четыре «волшебных числа»: m – модуль, 0 < m a – множитель, 0 ≤ а < m c – приращение, 0 ≤ с < m X0 – начальное значение, 0 ≤ X0 < m Затем получим желаемую последовательность <Xn>(2) Xn+1 = (aXn + c) mod m, n ≥0Линейная конгруэнтная последовательность. Пример: M = 10, X0 = a = c = 7 7,6,9,0,7,6,0,… Основная задача подобрать «волшебные числа». Линейная конгруэнтная последовательность всегда образует петли (циклы). Повторяющийся цикл из называется периодом.Линейная конгруэнтная последовательность при с = 0 называется мультипликативной, а при с ≠ 0 называется смешанной.

Случай когда a = 1 можно сразу отбросить, так как Xn = (X0 + nc) mod m – это явно не случайная последовательность Þ необходимо брать a ≥ 2, b ≥ 1. Обобщим формулу (2). Xn+k = (akXn + (ak – 1)c/b) mod m, k ≥ 0, n ≥ 0. где (n + k) член выраженный через (n) член. Снова получилась линейная конгруэнтная последовательность. Так как с = 1, X0 = 0 Þ Y0=0, Yn+1=(aYn + 1) mod m при Yk º (ak – 1)/b mod m Þ Xk = (AYn + X0) mod m, где A = (X0b + c) mod m. I) Выбор модуля. Выясним как выбирать m. 1) m должен быть достаточно большим так как период ≤ m. 2) (aXn + c) mod m должен вычисляться быстро. Удобно использовать m равноt длине машинного слова ω = 2e. Однако, более рационально использовать m = ω ± 1, поскольку если m = ω = 2е , то четыре младших разряда Yn

= Xn mod 24 формируют конгруэнтную последовательность с периодом 16 или меньше.5 младших разрядов – конгруэнтную последовательность с периодом ≤ 32 Þ наименьший значащий разряд либо постоянный, либо строго периодический.Но этого не возникает, когда m = ω ± 1. Например, при ω = 235, m = 235 – 1. Числа последовательности будут не очень случайны только если рассмотреть их остатки по модулям 31,71,127,122921(делители числа 235 – 1).Но последовательность по модуля 2 будет достаточно случайной. Существует альтернатива: m взять наибольшее простое меньшее ω. II)Выбор множителя. Длина периода это не единственное условие, так как при а = с = 1: Xn+1 = (Xn + 1) mod m имеет период длины m, н она не является случайной.Необходимо найти а, с, X0 такие, которые дают период m. Теорема A . Линейная конгруэнтная последовательность, определенная числами m,a,c,X0 имеет период длиной m Û 1.числа с и m взаимно простые; 2.b = a – 1 кратно р для каждого простого р, являющегося делителем m; 3.b кратно 4, если m кратно 4. В случае когда с = 0, мультипликативная конгруэнтная последовательность, Xn+1 = aXn mod m , значение 0 может появиться только в вырождающейся в нуль последовательности. Þ максимальный период не может быть достигнут. К тому же, если Xn кратно d, то Xn+1 , Xn+2 ,… будут кратны d.Так что при с = 0, необходимо чтобы Xn и m были взаимно простые "n, такого что ограничивает период до φ(m) – число целых взаимно простых с m в интервале от 0 до m. III)Потенциал. Если z – основание системы счисления машины, то m = ze и множитель ak = zk + 1, 2 ≤ k < e удовлетворяют условиям теоремы А. Можно взять с = 1. Þ Xn+1 = ((zk + 1)Xn + 1) mod ze .Потенциал линейной конгруэнтной последовательности с максимальным периодом определяется как наименьшее целое число s, такое что bs º 0 (mod m) и оно существует так как b кратно каждому простому делителю m. Пусть X0 = 0, так как ноль входит в последовательность Þ Xn = ((an – 1)c/b) mod m. Если разложить an – 1 = (b + 1)n – 1 по биномиальной формуле (*) Xn = c(n + Cn

2b + …+Cns bs-1) mod m , то все

члены разложения bs, bs+1… можно исключить, так как они кратны m. Итак получим:1)a = 1 Þ Xn º cn (mod m) и потенциал равен 1, такая последовательность наверняка неслучайна. 2)Если потенциал равен 2, то Xn = cn + cbCn

2 , опять не совсем случайна, так как Xn+1 – Xn º c + cbn. Т.о. разность между последующими генерируемыми числами выражена простой зависимостью от n. Если потенциал равен 3, то последовательность становится более или менее похожей на случайную, но остается высокая степень зависимости Xn, Xn+1 , Xn+2 . Последовательность с потенциалом 4, а лучше 5 можно считать случайной! Пример: m = 235 , a = 2k + 1 Þ b = 2k Þ b2 = b2k кратны m, когда k ≥ 18. потенциал равен 2.Если k = 17,16,…,12, то потенциал равен 3. Если k = 11,10,9, то потенциал равен 4.

Þ Множители приемлемы когда k ≤ 8, т.е. а ≤ 257, но малых множителей также необходимо избегать!Высокий потенциал не является достаточным условием случайности, но следует исключать все методы с низким потенциалом!Линейная конгруэнтная последовательность должна пройти «спектральный тест»! 32. Другие методы генерации случайных последовательностей: квадратичный конгруэнтный метод,

числа Фибоначчи, генератор Дж.Ж. Митчелла и Д.Ф. Мура, обратная конгруэнтная последовательность. Рандомизация перемешиванием.

Ошибочным является мнение: взять случайный генератор, немного его модернизировать и получить более случайный генератор. Это не так! Пусть Xn+1 = (aXn + c) mod m Возьмем Xn+1 = ((aXn) mod (m + 1) + c) mod m. Но она не будет более случайной!Квадратичный конгруэнтный метод: Xn+1 = (dXn

2 + aXn + c) mod m Пример: Р. Р. Ковэю X0 mod 4 = 2, Xn+1 = Xn (Xn + 1) mod 2e ,n ≥ 0. метод похож на метод средних квадратов, гарантирует большой период. Другой подход: Пусть Xn+1 зависит не только от Xn , но и от Xn-1 , тогда можно достичь периода m2, так как последовательность не станет повторяться пока не будет получено (Xn+λ , Xn+λ+1) = (Xn , Xn+1)Пример: числа ФибоначчиXn+1 = (Xn + Xn-1) mod m ; обычно дает длину большую m, но числа не достаточно случайны.Пример: Xn+1 = (Xn + Xn-k) mod m, где k – сравнительно большое число. При k ≤ 15 дало отрицательный результат, при k = 16 – положительный. Митчелл и Мур.(7) Xn = (Xn-24 + Xn-55) mod m , n ≥ 55где m – четное число, X0,…,X54 – произвольные целые, не все четные числа.Длина периода последовательности 2е – 1, когда m = 2e.Другие примеры пары индексов, приводящих к длинным периодам по модулю 2: (24,55) (37,100) (83,258) (38,89) (30,127) (107,378) …Дж. Марсалья:(7’) Xn = (Xn-24 Xn-55) mod m , n ≥ 55 где m кратно 4; X0,…,X54 – нечетны, но сравнимы с 1 (mod 4) Тогда второстепенные младшие разряды имеют период 255 – 1 , старшие более тщательно перемешаны. Период (7’) лишь незначительно меньше периода (7).Комбинация. Лучше использовать когда m простое.Xn = (a1Xn-1 + …+akXn-k) mod p ; имеет период рk – 1.X0,…,Xk-1 – произвольны, не все равны нулю.Обратная конгруэнтная последовательность: Xn+1 = (aXn

-1 + c) mod pгде р – простое, Xn Î {0,1,…,p – 1,¥}, 0-1 = ¥, ¥-1 = 0. Рандомизация перемешиванием.Заданы методы генерирования двух последовательностей <Xn> и <Yn>. Вспомогательная таблица V[0],V[1],…,V[k – 1], где k – некоторое число ≈ 100.Сначала V заполняется значениями X - последовательности.M1. Положим X иY следующие значения последовательности <Xn> и <Yn>. M2. Присвоим j ← ëkY/mû , где m – модуль в последовательности <Yn>.(0 ≤ j ≤ k) M3. Выведем V[j], затем V[j] ← X. Методы перемешивания имеют «врожденный дефект»: Они меняют порядок следования, но не сами числа. И если изначальная последовательность нехороша, то перемешивание ничего не дает.Советуют объединять последовательность <Xn>,<Yn> более простым способом, лишенным дефекта перемешивания.Zn = (Xn – Yn) mod m ; где 0 ≤ Xn ≤ m, 0 ≤ Yn < m’ ≤ m.Другой способ: выбросить некоторое количество чисел из последовательности. Например: генерируем 500 чисел по формуле (7), берем из них 55 и затем генерируем еще 500. Генерируем последовательность двоичных разрядов B1,B2,…Xn+1 = Xn

2 mod M, Bn = Xn mod 2.или Xn+1 = Xn

2 mod M, Bn = XnZ mod 2.Здесь Z – r-разрядная «маска», r-число разрядов в M.M может быть произведением двух простых больших чисел вида 4k + 3, а начальное значение X0 взять простым с M. 33. Реализация статистического критерия χ2.Статистические критерии будем использовать для проверки случайности сгенерированных последовательностей.S – сумма очков на двух костяхps – вероятность выпадания S очков

Если бросить кости n раз, то величину S получим nPs раз.Пусть наблюдаемые значения сумм S будут Ys.

S 2 3 4 5 6 7 8 9 10 11 12

Ys 2 4 10 12 22 29 21 15 14 9 6

nPs 4 8 12 16 20 24 20 16 12 8 4

Установим веса для разных исходов

Получаем статистику

Учитывая что

Получим

Алгоритм критерия хи-квадрат.1. Выполняем достаточно большое число n независимых наблюдений.2. Подсчитываем число наблюдений, относящихся к каждой из k категорий и величину V.3. Сравниваем V с числами из таблицы при ν = k-1.Если V<1% –точки и V>99% –точки, то

отбрасываем эти числа как недостаточно случайные. Если же V лежит между 1% и 5% или 95% и 99% , то эти числа “подозрительные”. Если V лежит между 5% и 10 % или 90% и 95% , то числа “почти подозрительные”.

34. Реализация статистического критерия Колмогорова-Смирнова.Выполняем n независимых наблюдений случайной величины x=(x1, x2… xn) и построим эмпирическую функцию распределения Fn(x).

Fn(x)→F(x) при n→∞

Чтобы построить КС – критерий, образуем статистики:

где - наибольшее отклонение, когда Fn>F,

- наибольшее отклонение, когда Fn<F.Множитель необходим для того, чтобы и не зависели от n. Подсчет статистик.

1. Получить независимые наблюдения x1, x2…, xn.2. Упорядочить наблюдения в порядке неубывания: x1≤ x2…≤ xn.3. Статистики задаются формулами:

Выбор n: Лучше выбрать n=1000 и взять достаточно много для различных частей случайной последовательности.

Применим КС-критерий к этой последовательности с функцией распределения

Аналогично для 35. Эмпирические критерии. Критерий равномерности. Критерий серий. Критерий интервалов. Покер-

критерий. Критерий собирания купонов. Критерий перестановок. Критерий монотонности.Каждый критерий применяется к последовательности действительных чисел <Un>= U1,U2 ,U3… , которые по предположению независимы и равномерно распределены между 0 и 1.Некоторые используют целые числа, тогда <Yn>= Y1, Y2 ,Y3… , Yn= d Un равномерно распределена на интервале от 0 до d-1.

Критерий равномерности. Использовать критерий КС с F(x)=x , 0≤x≤1 Использовать дискретную последовательность, где d=64 или d=128 ∀r , 0≤r<d.

Подсчитаем число случаев, в которых Yj=r ∀0≤j<n. Затем применим «хи-квадрат» критерий, принимая k=d с вероятностями для каждой категории.Критерий серий.Пары последовательных чисел должны быть равномерно распределены независимым образом.Подсчитывается число случаев, в которых пара(Y2j, Y2j+1)=(q,r), 0≤j<n, для всех таких 0≤q, r <d.Затем применяем «хи-квадрат» критерий к этим k=d2 категориям, с вероятностью пары 1/d2. Должно выполняться условие 5d2 ≤ n . Критерий интервалов.Используется для проверки длины «интервалов» между появлением Uj на определенном отрезке 0≤α<β<1. Рассмотрим длины последовательностей: Uj, Uj+1,…, Uj+r , в которых Uj+rÎ(α, β), а другие Us не лежат. Эту подпоследовательность из r+1 чисел называют интервалом длины r. Используется Алгоритм G для подсчета числа интервалов длиной 0,1,…,t-1 и интервалов больше либо равных t, пока не получится n интервалов. Затем «хи-квадрат» применяется с k=t+1.

«Классический» покер-критерий рассматривает n групп по пять последовательных целых чисел {Y5j, Y5j+1,Y5j+2,Y5j+3,Y5j+4} ∀ 0≤j<n и проверяются семь комбинаций: все разные : abcde полный набор : aaabb одна пара : aabcd четыре числа : aaaab две пары : aabbc пять чисел : aaaaa три числа : aaabc Критерий собирания купонов.Используем Y0,Y1,… и находим длины отрезков Yj+1,Yj+2 ,…Yj+r содержащих «полный» набор целых чисел от 0 до d-1.Далее применяется критерий «хи-квадрат». Критерий перестановок.Разделим последовательность на входе на n групп по t элементов в каждой

(Ujt , Ujt+1 ,…Ujt+t-1), 0≤j<n.Элементы в каждой группе можно упорядочивать t! способами. Подсчитываем число групп с любым возможным порядком и применяем «хи-квадрат» критерий с k=t! и p=1/t!. Критерий монотонности.В последовательности можно проверить распределение восходящих и нисходящих серий.Проверка монотонных частей заданной последовательности.Рассмотрим 1298536704|129|8|5|367|04| - линия ставится, если xj> xj+1.Выделяются восходящие серии: длины 3,1,1,3,2.Затем подсчитывается специальная статистика.

36. Параллельное программирование. Кластеры. Основы программирования в MPI. Закон Амдала.

37. Сочетания, перестановки, коды Грея.В комбинаторике сочетанием из n по k называется набор k элементов, выбранных из данных n элементов. Наборы, отличающиеся только порядком следования элементов (но не составом), считаются одинаковыми, этим сочетания отличаются от размещений.Так, например, наборы (3-элементные сочетания, подмножества, k = 3) {2, 1, 3} и {3, 2, 1} 6-элементного множества {1, 2, 3, 4, 5, 6} (n = 6) являются одинаковыми (однако, как размещения были бы разными) и состоят из одних и тех же элементов {1,2,3}.В общем случае число, показывающее, сколькими способами можно выбрать k элементов из множества, содержащего n различных элементов, стоит на пересечении k-й диагонали и n-й строки треугольника Паскаля.Число сочетаний из n по k равно биномиальному коэффициенту

При фиксированном n производящей функцией последовательности чисел сочетаний , , ,… является:

Двумерной производящей функцией чисел сочетаний является

Сочетания с повторениямиСочетанием с повторениями называются наборы, в которых каждый элемент может участвовать несколько раз.Число сочетаний с повторениями из n по k равно биномиальному коэффициенту

При фиксированном n производящей функцией чисел сочетаний с повторениями из n по k является:

Двумерной производящей функцией чисел сочетаний с повторениями является:

В комбинаторике перестано®вка — это упорядоченный набор чисел обычно трактуемый как биекция на множестве , которая числу i ставит соответствие i-й элемент из набора. Число n при этом называется порядком перестановки.В теории групп под перестановкой (подстановкой) произвольного множества подразумевается биекция этого множества на себя.Свойства.

Число всех перестановок порядка n равно числу размещений из n по n, т.е. факториалу:[1][2][3][4]

Композиция определяет операцию произведения на перестановках одного порядка:

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

Любая группа является подгруппой группы перестановок множества элементов этой группы (теорема Кэли). При этом каждый элемент сопоставляется с перестановкой πa, задаваемой тождеством

где g — произвольный элемент группы G, а — групповая операция.Коды Грея.Код Грея — система нумерования, в которой два соседних значения различаются только в одном разряде. Наиболее часто на практике применяется рефлексный двоичный код Грея, хотя в общем случае существует бесконечное множество кодов Грея для систем счисления с любым основанием. В большинстве случаем, под термином "код Грея" понимают именно рефлексивный бинарный код Грея.Изначально предназначался для защиты от ложного срабатывания электромеханических переключателей. Сегодня коды Грея широко используются для упрощения выявления и исправления ошибок в системах связи, а также в формировании сигналов обратной связи в системах управления.Название рефлексный (отражённый) двоичный код происходит от факта, что вторая половина значений в коде Грея эквивалентна первой половине, только в обратном порядке, за исключением старшего бита, который просто инвертируется. Если же разделить каждую половину ещё раз пополам, свойство будет сохраняться для каждой из половин половины и т. д.

Код получил имя исследователя лабораторий Bell Labs Фрэнка Грея. Он использовал этот код в своей импульсной системе связи, для чего был написан патент за номером 2632058.

38. Тестирование (структурное, функциональное, модулей, критерий завершения, программирование с защитой от ошибок)

Recommended