Технология программирования
Покупка
Новинка
Тематика:
Программирование и алгоритмизация
Издательство:
ИНТУИТ
Автор:
Терехов Алексей Николаевич
Год издания: 2016
Кол-во страниц: 116
Дополнительно
Вид издания:
Учебное пособие
Уровень образования:
ВО - Бакалавриат
ISBN: 978-5-94774-669-3
Артикул: 837481.01.99
В достаточно популярной форме излагаются основные аспекты жизненного цикла создания и сопровождения программных продуктов, организации коллективов программистов, сведения о стандартах качества.
Как пример наиболее трудной, по мнению автора, задачи в этой области рассматриваются вопросы создания встроенных систем реального времени.
Тематика:
ББК:
УДК:
ОКСО:
- 00.00.00: ОБЩИЕ ДИСЦИПЛИНЫ ДЛЯ ВСЕХ СПЕЦИАЛЬНОСТЕЙ
- ВО - Бакалавриат
- 09.03.01: Информатика и вычислительная техника
- 09.03.02: Информационные системы и технологии
- 09.03.04: Программная инженерия
ГРНТИ:
Скопировать запись
Фрагмент текстового слоя документа размещен для индексирующих роботов
Введение в технологию программирования 2-е издание, исправленное Терехов А.Н. Национальный Открытый Университет “ИНТУИТ” 2016 2
УДК 004.42 (075.8) ББК 18 Т35 Технология программирования / Терехов А.Н. - M.: Национальный Открытый Университет “ИНТУИТ”, 2016 ISBN 978-5-94774-669-3 В достаточно популярной форме излагаются основные аспекты жизненного цикла создания и сопровождения программных продуктов, организации коллективов программистов, сведения о стандартах качества. Как пример наиболее трудной, по мнению автора, задачи в этой области рассматриваются вопросы создания встроенных систем реального времени. (c) ООО “ИНТУИТ.РУ”, 2007-2016 (c) Терехов А.Н., 2007-2016 3
Понятие технологии программирования, жизненный цикл программы и постановка задачи Понятие технологии программирования Технология – это набор правил, методик и инструментов, позволяющих наладить производственный процесс выпуска какого-либо продукта [1]. Разумеется, это определение нельзя назвать полным. Надо упомянуть процессы планирования, измерения, оценки качества, ответственность исполнителя и многое другое. Но в мою задачу не входит написание статьи для энциклопедии на слово “технология” – я дал какое-то представление о его значении и для начала разговора этого вполне хватит. Подчеркну только еще раз производственный характер понятия “технология”. Почемуто именно слово “производство” сильно раздражает моих коллег-математиков, занимающихся программированием. “Ты бы еще технологию создания романа “Война и мир” создал”. Недаром же известный специалист Дональд Кнут назвал свой знаменитый многотомный труд “Искусство программирования”. Наконец, мне удалось выяснить отношение к этому понятию самого Д. Кнута. Несколько лет назад наш университет присвоил этому несомненно блистательному ученому звание почетного доктора. По такому случаю наш декан собрал для встречи с Д. Кнутом десятьдвенадцать руководителей лабораторий и заведующих кафедрами, имеющих отношение к программированию. Дело было летом, Д. Кнут был с женой, переводчица поминутно смотрела на часы, напоминая, что гостям пора “на фонтаны”, сам почетный доктор откровенно дремал, словом, это было скучнейшее мероприятие. Я решил пошутить, чтобы как-то развеять унылую атмосферу. И когда подошла моя очередь выступать, я вместо тридцатисекундного перечисления заслуг нашего коллектива сказал, что лично мне профессор Кнут доставил много неприятностей. Тот аж подскочил: “Я же в первый раз вас вижу!” Тут я объяснил, что много лет занимаюсь промышленной технологией программирования, а многие коллеги, включая и тех, кто сидит сейчас за этим столом, ссылаясь на его книгу, не признают это наукой, имеющей отношение к математике. Профессор очень разволновался, принял мою шутку вполне всерьез и пожаловался, что все это происходило и с ним: “Вы знаете, что я много лет занимался созданием и продвижением на рынок издательской системы TEX? Это что – не производство? Могу я на старости лет написать книжку с теоремами?” В общем, я получил огромный заряд положительных эмоций. Разумеется, я понимаю, что Д. Кнут известен скорее своими теоретическими работами, а TEX – это скорее от безысходности, он задумал его после выпуска первого тома “Искусства программирования”, поражаясь скудости рынка инструментальных средств для набора математических текстов, прервался на несколько лет для реализации TEX и только потом продолжил свой титанический труд. Для него промышленное программирование – скорее бравада, что вот, мол, мы все можем, но все равно приятно получить поддержку от такого знаменитого ученого. Мое первое столкновение с промышленностью состоялось в 1980-м году. К тому времени я уже несколько лет руководил лабораторией системного программирования, занимались мы самыми трудными проблемами, часто имеющими весьма отдаленное 4
отношение к практике, но нас это нисколько не беспокоило. “Мат-мех – лучше всех” – в глубине души я и сейчас в этом уверен. Так вот, в декабре 1980-го года меня пригласили в кабинет ректора ЛГУ, там было человек двадцать в военной форме и несколько партийных деятелей во главе с начальником оборонного отдела Обкома КПСС. Мне было сказано, что оборонная промышленность столкнулась с массой проблем при создании программного обеспечения (ПО) систем оборонного назначения, поэтому решено, что ЛГУ в лице нашей лаборатории должен помочь. Моего согласия никто не спрашивал, да в те времена этого и не требовалось. Так я начал работать с ЛНПО “Красная Заря”, “Импульс”, “Морфизприбор”, “Ленинец”, “Аврора”, “Гранит” – ведущими предприятиями Ленинграда, работающими в интересах различных родов войск и ведомств. С большинством этих предприятий мы работаем до сих пор. Нас использовали как “пожарную команду”. Много лет сотрудники названных и других предприятий разрабатывали ПО для важных заказов, когда же все сроки (и деньги!) истекали, приглашали нас, чтобы мы навели порядок. Нельзя сказать, что до этого мы жили в башне из слоновой кости. У нас были договора с НИЦЭВТ по созданию транслятора с языка Алгол 68 [2] для только что созданного (мы говорили “создранного”) семейства ЕС ЭВМ, так что мы одними из первых освоили новую операционную систему OS/360. Пользуясь открытостью университета, к нам все время приходили какие-то люди (в том числе и военные) с просьбой найти ошибку в программе. Не было случая, чтобы мы искали ошибку больше двух дней. Но все это не идет ни в какое сравнение с трудностями нашего понимания проблем реальной промышленности. Одно дело, когда у тебя в подчинении пятнадцать человек в университетской лаборатории, которых никогда не надо подгонять, сомневаться в их способностях, когда царит дух соревнования (не только между собой), когда все понимают друг друга с полуслова. Совсем другое дело — триста человек с совершенно разными способностями и образованием, явно отсиживающие свои восемь часов, работающие в кодах (буквально с инженерного пульта ЭВМ), причем все это погружено в атмосферу секретности. Мне никогда не забыть, как одна женщина целый час объясняла мне схему распределения памяти, которую она вычитала у одного японского автора. С большим трудом удалось выяснить, что она имеет в виду стек. Другой программист запомнился мне тем, что для возврата из процедуры использовал регистр Р7, хотя остальные триста человек для этой цели применяли Р10. Он еще доказывал, что именно он прав, так как Р7 – индексный регистр, поэтому передача управления по его содержимому выполняется на целую микросекунду быстрее. Мне так и не удалось объяснить ему важность соблюдения соглашения о связях. Первыми из военных организаций к нам обратились сотрудники ЛНПО “Красная Заря” с просьбой помочь в программировании широкого класса задач управления и связи, в частности, в создании функционального программного обеспечения (ФПО) телефонных станций, управляемых специализированными ЭВМ (СЭВМ). Несколько лет ушло на изучение предметной области, пробные реализации и решение организационных вопросов. У сотрудников ЛГУ был исходный принцип важности использования алгоритмических языков высокого уровня (АЯВУ), основанный на опыте предыдущей работы. Однако начинать пришлось совсем не с этого, а с повышения общей культуры программирования разработчиков ФПО. Дело в том, что в области встроенного ФПО реального времени традиционно используются СЭВМ с 5
нестандартной архитектурой, ориентированной на заданную предметную область (правда, неясно, в чем должна выражаться такая ориентация: например, если ЭВМ хорошо выполняет какие-то специальные операции, но плохо — условные переходы и вызовы процедур, которые встречаются гораздо чаще, можно ли считать, что данная ЭВМ соответствует предметной области?). Нестандартность архитектуры и малая тиражность таких СЭВМ приводят к отсутствию достаточно развитых операционных систем, трансляторов, средств отладки и других, ставших уже привычными, инструментов программирования. Поэтому мы столкнулись с работой на перфокартах и непосредственно за пультом СЭВМ “на тумблерах”. Мы пытались воспользоваться известными в то время технологиями, однако оказалось, что, например, Р-технология [3] не имеет никаких средств настройки на СЭВМ, а предлагаемые в ней графический стиль программирования и программа-организатор с ручным вводом мало помогают в решении задач реального времени; технология РУЗА позволяет автоматизированным образом (но с большими доработками) построить кросс-ассемблер нужной ЭВМ и интерпретатор ее системы команд, а также осуществить некоторую регламентацию работы (например, стандартизовать имена объектов). Р-технология была отвергнута практически сразу (за неимением конкретных программных средств на заданных нам СЭВМ), РУЗА в течение полугода была настроена на одну СЭВМ, однако полностью учесть все особенности СЭВМ так и не удалось; кроме того, параметрически настраиваемые кросс-ассемблер и интерпретатор замедляют работу в 5-7 раз. Мы решили, что из-за таких простых программ, как ассемблер, не стоит “городить огород”, и за короткое время реализовали новые кросс-ассемблер и интерпретатор, которые вместе с текстовым документатором и некоторыми сервисными программами составили основу первой внедренной нами в производство (1984 год) технологической системы, интенсивно использовавшейся сотнями разработчиков ФПО. Разумеется, мы отчетливо понимали ограниченность возможностей такой технологии, но ее популярность имела свои причины: применение вместо СЭВМ широко доступной ЕС ЭВМ с многопользовательской ОС и широкими сервисными возможностями; работа одновременно многих пользователей за терминалами, а не с перфокартами; богатые отладочные возможности интерпретатора СЭВМ, недостижимые непосредственно на СЭВМ; впервые осознанная разработчиками ФПО ценность документации на машинном носителе, легкость ее оформления, исправления и тиражирования; практически неограниченные возможности развития технологии, удивительно быстро схваченные разработчиками ФПО, в результате чего практически ежемесячно появлялись новые идеи и предложения, большинство из которых было быстро реализовано. На протяжении всей совместной работы сотрудников ЛГУ и “Красной Зари” имело место противостояние двух позиций относительно понятия технологии программирования. Сотрудники ЛГУ, в основном, подразумевали под ним широкое использование инструментальных средств, а сотрудники “Красной Зари” настаивали на 6
том, что технология — это, прежде всего, набор формальных методик и регламентирующих средств, позволяющих, в частности, на каждом этапе провести экспертизу, архивацию и измерение объема и качества проделанной работы. Такой подход вызывал постоянное раздражение профессиональных программистов. Разумеется, мы понимали, что работа без четких сроков и ответственности перед соисполнителями возможна только исследовательская и экспериментальная, да и то в ограниченных объемах, но работа по конкретным заказам в промышленности дала массу новых впечатлений и импульсов для изучения. Например, уход исполнителя в самом разгаре работ. Оказалось, что в промышленности это довольно частое явление (отсюда необходимость архивации и других средств отчуждения результатов работы от исполнителя); в коллективе из нескольких сот человек всегда есть люди, попросту не желающие работать, и хотя мы понимаем, что оценка работы программиста в байтах весьма сомнительна, это не отменяет необходимости учета индивидуально выполненной работы (измерение). Даже такое “приземленное” соображение, как разделение ответственности за принятые решения и ошибки, также нельзя сбрасывать со счетов (отсюда строгое документирование). Особенно много разночтений вызывала необходимость оформления постановки задачи по стандартным правилам. Дело в том, что аккуратное оформление требует усилий, причем не только технического порядка, а программисту кажется, что, имея в руках такой мощный инструмент, как АЯВУ, легче сразу выразить свое понимание задачи в программе, а не в каких-то таблицах и диаграммах. Но непосредственное программирование лишает программиста обратной связи с функционалистом (постановщиком задачи) и уж тем более — с заказчиком. Большинство сложных систем невозможно сдать в эксплуатацию из-за огромного количества сравнительно мелких замечаний, вызванных разночтениями и неясностями в постановке задачи. Мы настаивали на том, что, занимаясь вопросами документирования, ценообразования, способами регламентирования и контроля за ходом работ, нельзя забывать, что основным результатом применения технологии является программа, действующая в заданной вычислительной среде, хорошо отлаженная и документированная, доступная для понимания и развития в процессе сопровождения (“нам нужны не приборы в принципе, а приборы в корпусе”). Только после двух-трех лет работы в промышленности мы осознали, что нельзя все сводить к программному инструментарию. Поначалу мы с гневом отказывались от требований начальства детально документировать, кто, что и за какой период написал, но оказалось, что в большом коллективе всегда находятся милые в общении, всеми любимые организаторы всевозможных мероприятий, которые вообще ничего не делают по работе. Первую сдачу проекта для Управления правительственной связи КГБ я завалил, так как буквально перед самой сдачей кто-то стащил одну (!) перфокарту, а эти товарищи всегда начинали с чистой машины и полной перетрансляции. Вредителя так и не нашли, зато я получил хороший урок. Мы быстро реализовали контрольно-учетные программы, архивы с контролируемым доступом, многоуровневые системы сбора версий ПО и тому подобные “шпионские штучки”. Так я впервые осознал разницу между “программированием для себя” и “программированием для хозяина”, о которой так красочно рассказывал академик А. 7
П.Ершов. В более поздних публикациях эту разницу стали выражать более канцелярским стилем – просто программа и программный продукт. Жизненный цикл программы Итак, мы знаем, что программный продукт является результатом некоего производственного процесса. Этот процесс нужно спланировать, оценить ресурсы, для чего, в свою очередь, требуются более или менее точные спецификации, что же необходимо заказчику. Затем продукт надо спроектировать в виде системы, состоящей из многих компонентов, описать функции этих компонентов и их связи между собой, после чего компоненты нужно запрограммировать, автономно отладить, собрать вместе, провести комплексную отладку, подготовить документацию на систему, обучить пользователей, провести опытную эксплуатацию и организовать сопровождение системы на весь период ее эксплуатации. Разумеется, это лишь приблизительная схема, которая может варьироваться в широких пределах, но, тем не менее, она дает представление о том, что такое “жизненный цикл программы” (ЖЦП) [4]. Почему “цикл”? Потому что редко разработка развивается столь прямолинейно, хотя одну из первых моделей ЖЦП действительно назвали “водопадная”, подчеркивая тот факт, что к предыдущей фазе проектирования вернуться невозможно. Действуя по этой модели, коллектив последовательно разрабатывает проект – от исходной концепции до комплексного тестирования. Модель требует определить опорные точки, в которых будет оцениваться сделанное и решаться вопрос о том, можно ли двигаться дальше. Такой подход хорош для проектов, в которых требования легко формулируются с самого начала, но не годится для сложных, когда требования могут неоднократно меняться. Кроме того, водопадная модель вынуждает готовить огромную массу документации и требует единообразной процедуры оценки результатов на каждом этапе. Эти две особенности часто приводят к синдрому “аналитического паралича”, напряженным отношениям между разработчиками, заказчиками и пользователями. В реальной жизни, конечно же, чисто водопадная модель не применяется. Появляются новые требования заказчиков, изменяется аппаратура, находятся такие ошибки, которые невозможно исправить, не затронув результаты предыдущих фаз и т.д. Развитие системы – это именно циклическое повторение практически всех фаз, постоянный возврат к предыдущим фазам. Если не принять специальных мер (что, собственно, и является предметом технологии программирования), процесс может стать бесконечным. Одной из первых практически полезных моделей ЖЦП стала модель создания прототипов. С самого начала разработчики пытаются выделить основные, существенные требования заказчика и реализовать только их в виде работающего прототипа системы. Этот прототип демонстрируется заказчику. Часто бывает, что заказчик в ужасе кричит, что его неправильно поняли, он хотел совсем другого, зато теперь он хоть может внятно сформулировать свои требования, глядя на работу 8
прототипа. Цикл разработки и показа прототипа повторяется несколько раз, пока заказчик не скажет: “Да, это, кажется, то, что мне нужно”. Только после этого дорабатываются куски, выброшенные в начале разработки, подготавливается документация, короче, делаются многие вещи, на которые время было бы потрачено зря, если бы их делали для самого первого, неудачного прототипа. Для небольших систем, особенно для тех, в которых велик процент интерактивных (взаимодействующих с пользователем) компонентов, такая модель работает, хотя каждый раз, когда я про нее рассказываю, мне вспоминается анекдот. Празднуется золотая свадьба. Набежали журналисты, спрашивают: “Как же так, все семьи разваливаются, а вы прожили пятьдесят лет?” Глава семьи отвечает: “Как только мы поженились, сразу договорились, что все важные жизненные проблемы решаю я, а жена не спорит, а остальные – решает жена, а я в них не лез. Так и прожили”. Журналисты не унимаются: “А что такое – важные проблемы? Ну, например, назовите проблему, которую Вы решали в последнее время”. Глава семьи отвечает: “Ну как же, как же, недельки две назад я долго размышлял, вернется Далай-Лама в Тибет или нет”. В этом анекдоте, как всегда, отображена вся правда жизни. На моей памяти много случаев, когда важные аспекты просто упускались при разработке прототипа, из-за чего позже все приходилось переделывать заново. Некоторым обобщением модели создания прототипов является спиральная модель, в которой разработка приложения выглядит как серия последовательных итераций. На первых этапах уточняются спецификации продукта, на последующих — добавляются новые возможности и функции. Цель этой модели – по окончании каждой итерации осуществить заново оценку рисков продолжения работ. Программисты часто увлекаются технической сутью выполняемого проекта и не видят общей картины, особенно в части производственных затрат. Нам все кажется, что вот еще немного, еще чуть-чуть, и все проблемы будут решены, но “асфальтовая топь” (по выражению Ф. Брукса[5]) засасывает нас, не давая шансов достичь твердых осязаемых результатов. Один мой знакомый бизнесмен представил эту проблему так: “Вот ты затратил 100 000 долларов, но задачу пока не решил. Нужно сто раз подумать, что лучше — истратить еще столько же, чтобы успешно завершить проект, или через год снова оказаться перед тем же выбором, но тогда уже с риском потерять не 100 000, а 200 000 долларов?” В силу своей итеративной природы спиральная модель допускает корректировки по ходу работы, что способствует улучшению продукта. При большом числе итераций разработка по этой модели нуждается в глубокой автоматизации всех процессов, иначе она становится неэффективной. На практике у заказчиков и пользователей иногда возникает ощущение нестабильности продукта, так как они не успевают уследить за слишком быстрыми изменениями в нем. Один очень важный вывод мы можем сделать даже при таком начальном знакомстве с понятием ЖЦП. Собственно программирование не является единственным занятием коллектива, занятого промышленными разработками. Более того, оно не является даже главным, наиболее трудоемким делом. Многие исследования отдают на фазу программирования не более 15-20% времени, затраченного на разработку (сопровождение вообще бесконечно). Может быть, эти цифры заставят вас задуматься 9
о важности и других аспектов образования – от умения найти и обосновать эффективный алгоритм до искусства владения родным языком, как устным, так и письменным. Постановка задачи. Оценка осуществимости Обычно заказчик выдает две-три страницы текста задания и сразу же просит оценить время исполнения заказа и его стоимость. Надо быть сумасшедшим, чтобы на это согласиться. Нередки случаи, когда целые коллективы ошибаются в пять-десять раз и попадают в кабалу или теряют профессиональную репутацию. Чтобы избежать такой ситуации, нужно предложить заказчику оформить начальный договор на две-четыре недели с тем чтобы два-три системных аналитика разобрались в задаче, с помощью каких-то инструментальных средств выполнили декомпозицию системы на компоненты, прикинули возможные объемы этих компонентов и, соответственно, время их реализации. Такая начальная стадия ЖЦП называется “оценкой осуществимости”. Можно, конечно, выполнить эту работу за свой счет (и многие крупные предприятия так и делают), но, во-первых, отношение к внутренним разработкам – более спокойное, а, во-вторых, оплаченный договор гарантирует серьезность намерений обеих сторон. К сожалению, часто бывает, что недобросовестные заказчики пользуются таким приемом, чтобы бесплатно получить идеи разработки или просто выполнить экспертизу оценок своих специалистов без всякого намерения передать разработку на сторону. Постановка задачи – наиболее творческая часть ЖЦП, которая поднимает почти философские проблемы. Требуется описать поведение разрабатываемой системы. Эта система получает какието сигналы из ее окружения, поэтому надо описать поведение окружения, но окружение само зависит и изменяется под влиянием системы, ее сигналов, особенно аварийных. Разрешают это противоречие, постепенно уточняя поведение как системы, так и ее окружения. Для действительно важных систем заказчик требует разработки имитационных моделей системы и окружения, не уступающих по сложности и детальности самой системе. Была у меня однажды трагикомическая ситуация, когда военные заказчики потребовали модель системы, точно соответствующую реальной жизни. Никакие мои объяснения про сущность моделирования не помогали. Кончилось тем, что я сказал: “Хорошо, я сделаю такую модель, но саму систему делать не буду. Зачем? Ведь модель и так все делает”. Это произвело на них впечатление. Хотя, конечно, стремиться к более точным моделям нужно всегда. Несколько слов о декомпозиции системы. Я не устаю удивляться, насколько точнее оценка сложности системы, которая является суммой оценок ее компонентов, полученных в результате декомпозиции, чем первоначальная оценка системы в целом. Ведь делают эти оценки одни и те же системные аналитики, наверняка у них уже было примерное представление о системе и ее компонентах, когда они давали 10