Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Технологии программирования. Общие вопросы

Покупка
Артикул: 753019.01.99
Доступ онлайн
2 000 ₽
В корзину
Рассмотрены общие вопросы проектирования и сопровождения программного обеспечения: жизненный цикл программы, постановка задачи программирования, составление алгоритмов, кодирование, отладка и тестирование. Обсуждаются вопросы создания общей теории компьютерного программирования, постановки экспериментов в этой области и авторских прав. Кратко описаны инструментальные средства программирования: алгоритмические языки, операционные системы и среды. Для студентов высших учебных заведений, обучающихся по специальностям «Прикладная информатика (по областям)», «Автоматизированные системы обработки информации и управления», «Прикладная математика» и др.угим специальностям в области информационных и компьютерных технологий.
Калашников, Е. А. Технологии программирования. Общие вопросы : учебное пособие / Е. А. Калашников, С. В. Никифоров ; под. ред. А. Г. Дьячков. - Москва : ИД МИСиС, 2004. - 131 с. - Текст : электронный. - URL: https://znanium.com/catalog/product/1232340 (дата обращения: 19.04.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов. Для полноценной работы с документом, пожалуйста, перейдите в ридер.
Оглавление 

Введение 
5 

1. Развитие программирования 
8 

1.1. Этапы становления 
8 

1.2. Структурное программирование 
9 

1.3. Объектно-ориентированное программирование 
13 

1.4. Требования к современному программированию 
15 

Вопросы для самопроверки 
16 

2. Обсуждение вопросов создания общей теории 
программирования 
17 

2.1. Организация программных систем 
19 

2.2. Жизненный цикл программы 
20 

2.3. Целесообразность разработки программной системы 
23 

2.4. Заключительные замечания 
31 

Вопросы для самопроверки 
32 

3. Постановка задачи программирования (психологические 
и организационные аспекты) 
33 

3.1. Субъекты процесса 
33 

3.2. Организационно-экономическое отступление 
36 

3.3. Типичные задачи 
41 

Вопросы для самопроверки 
43 

4. Проектирование программы 
44 

4.1. Нисходящее проектирование 
44 

4.2. Использование блок-схем 
51 

4.3. Модульность 
55 

Вопросы для самопроверки 
56 

5. Тестирование программ 
57 

5.1. Ошибки программирования 
59 

5.2. Первопричинные ошибки 
60 

5.3. Ручное тестирование 
62 

5.4. Машинное тестирование 
63 

5.5. Критерий завершения тестирования 
65 

Вопросы для самопроверки 
67 

6. Сопровождение как производственная деятельность 
68 

6.1. Принятие к сопровождению 
68 

6.2. Права на программный продукт 
71 

Вопросы для самопроверки 
73 

3 

7. Эксперимент в программировании 
74 

7.1. Ранние эксперименты 
75 

7.2. Практические результаты 
76 

Вопросы для самопроверки 
77 

8. Языки программирования 
78 

8.1. История развития 
80 

8.2. Уровни языков 
85 

8.3. Современные языки программирования 
88 

8.4. Типизация данных 
90 

8.5. Языки Модула и Си 
95 

8.6. Неосуществленный проект 
100 

8.7. Объектно-ориентированные языки. Java 
101 

8.8. Объектно-ориентированное мышление 
102 

8.9. Язык и программная система 
103 

8.10. Являются ли ассемблеры языками высокого уровня? 
105 

8.11. Значение языков в программировании 
ПО 

Вопросы для самопроверки 
111 

9. Инструментальные средства программирования 
112 

9.1. Операционные системы 
113 

9.2. Операционные системы Unix 
114 

9.3. Операционные системы MS Windows 
116 

9.4. Лицензирование операционных систем 
118 

9.5. Интегрированные среды 
120 

9.6. Документация к программному продукту 
121 

Вопросы для самопроверки 
126 

Библиографический список 
127 

Предметный указатель 
129 

4 

Введение 

В современном компьютеризированном мире техническая литература уделяет огромное внимание основному аспекту работы с компьютерами - их программированию. Последние полтора десятка лет 
в литературе по программированию рассматриваются практически 
лишь специальные вопросы: обучение программированию на конкретном языке или в конкретной среде, а также программные решения конкретных классов задач. Из литературы, которая посвящена 
общим вопросам программирования, можно отметить, пожалуй, 
лишь книги [10, 19, 20]. 

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

Иначе обстояло дело в 70-80 годы XX века. В это время публиковалось очень большое количество литературы по общим вопросам 
программирования или, говоря шире, проектирования и эксплуатации программных комплексов. Одни названия говорят сами за себя 
(см. далеко не полный список литературы). Как и теперь, эта литература в оригинале была в основном англоязычной. В России (тогда в 
Советском Союзе) считалось, что надо больше внимания уделять 
конкретике. А так как открытых для свободной публикации программных продуктов было очень мало, то в основном русскоязычная 
литература была посвящена вопросам решения конкретных классов 
задач. Каким-то образом получилось, что все эти абстрактные методы и классы (не путать с методами и классами из объектноориентированных языков программирования) оказались никому не 
интересными и ненужными. Даже большинство российских программных разработок были выброшены за ненадобностью. Почему 
так получилось? Будем надеяться, что настоящая работа прольет некоторый свет на этот вопрос. 

5 

Прежде чем приступить к изложению материала по современному 
состоянию компьютерного программирования, обратим внимание на 
один парадокс. Основная цель, которой добивались программисты и 
исследователи 70-80 годов, - это повышение надежности программных разработок. Все остальные характеристики их качества 
всегда ставились на подчиненные места. Произошло ли сейчас столь 
желаемое тогда повышение надежности? Безусловно, да. Является ли 
это повышение результатом проводимой в то время исследовательской работы? Если и да, то в минимальной степени. Современные 
программисты, может быть, лишь интуитивно разделяют прежние 
выводы - они с ними практически не знакомы. Результат дал достаточно слепой естественный отбор среди программной продукции и 
среди самих программистов. Профессионально и последовательно 
программированием занимается сейчас гораздо меньший, чем раньше, процент из тех, кто так или иначе приближался к этому роду деятельности. 

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

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

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

Так повелось, что профессиональными программистами становятся освоившие работу на уровне элементарных операций, т.е. то, что 
называется программированием на алгоритмическом языке, ассемб
6 

лере или в машинных кодах (последнее сегодня практически уже не 
встречается). 

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

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

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

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

7 

1. РАЗВИТИЕ ПРОГРАММИРОВАНИЯ 

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

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

Точно также доминирующее сейчас объектно-ориентированное 
программирование вовсе не отменяет структурного программирования. Они сосуществуют как две взаимосвязанные части современной 
программной продукции. 

1.1. Этапы становления 

Первый этап. Зачаточное состояние программирования. По времени он совпадает с появлением и первоначальным использованием 
электронно-вычислительных машин (ЭВМ). Первыми программистами были конструкторы этих машин. В то время программирование и конструирование ЭВМ* непосредственно влияли друг на друга. 
Конструкторы сами изобретали программные средства (основываясь 

• Термин ЭВМ - электронно-вычислительная машина - соответствует английскому 
термину Computer. В 1950-1980-е годы такой взаимный перевод был общепринятым. В последние годы в связи с огромным распространением ЭВМ в настольном 
конструктиве получил широкое распространение термин «персональный компьютер» (ПК). Для краткости его стали называть просто компьютером. Мы будем пользоваться обоими терминами. Возможно, первый из них будет чаще относиться к 
более ранним реализациям, а второй - к более поздним. 

8 

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

Второй этап. Он охватывает период приблизительно с конца 50-х 
до середины 70-х годов. В это время появились люди, принципиально способные создавать программный продукт (способные писать 
программы). Этим они отличались от непрограммистов, людей неспособных писать программы или абсолютно незнакомых с программированием. В то время не существовало практически никакой 
теории создания программных систем, да и программ вообще. Каждая программная разработка зависела от опыта, знаний, интуиции 
исполнителей, у которых перед глазами даже не было скольконибудь существенных примеров или прецедентов. Тем не менее 
лучшие программисты и коллективы того времени сумели создать 
достаточно мощные и надежные программные средства, заложив тем 
самым основу современных представлений и теории программирования. Было разработано много трансляторов, операционных и прикладных систем, что явилось хорошей базой современного практического программирования - ведь все современные программные системы создавались с использованием старых. 

В этот период бурно проектировались и реализовывались алгоритмические языки, что заложило основы будущего надежного программирования. Наибольшее распространение в мире получили языки Кобол, Алгол и Фортран. Однако отсутствие теоретической базы 
помешало даже выбрать лучший из этих языков - Алгол. В качестве 
основного языка для решения задач общего характера долгое время 
использовался Фортран (подробнее см. [20]). 

1.2. Структурное программирование 

Третий этап. Он начался в середине 70-х годов и продолжается 
по сей день. Некоторые авторы, например Н. Грогоно [11], характеризуют его как эпоху структурного программирования. Нам кажется, 

9 

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

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

- использование методов структурного программирования; 
- 
модульность; 

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

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

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

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

10 

низкую себестоимость. А поскольку основная часть затрат приходится на сопровождение (по опубликованным данным эти затраты составляют от 40 до 80 % [15], а для России эта оценка, безусловно, 
ближе к верхнему пределу), то ключ к снижению себестоимости лежит именно в уменьшении затрат на сопровождение. Другими словами, программный продукт надо сразу делать хорошо! Всякие черновые, предварительные, экспериментальные варианты, требующие 
бесконечных доработок, нерентабельны. 

Что же требуется для реализации такого подхода? Нужно, чтобы 
программировали квалифицированные люди. Их способности, их 
умение, их, если хотите, талант должны быть использованы в полной 
мере. И двадцать учеников не сделают такой детали, какую может 
сделать высококвалифицированный мастер. По поводу последнего 
сравнения возможно возражение: «В производстве нужна массовость, изделия лучше выпускать поточным методом». 

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

Реальная жизнь устроена так, что совершенно одинаковых задач в 
разных сферах трудовой деятельности почти не бывает. Могут быть 
похожие задачи, которые требуют расширения или, лучше сказать, 
переработки существующих программных средств. Быть может такая 
ситуация и породила заблуждение о «потоке» в создании программных продуктов: мол, требуются небольшие (имеется в виду несложные) изменения, но этих изменений много; давайте организуем «конвейер» по внесению изменений или написанию новых несложных 
программ. 

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

11 

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

Вопрос о размере нового текста или изменений в программах требует особого обсуждения. Он тесно связан с оценками масштаба, и 
здесь также бытуют заблуждения. Например, если необходимо написать тысячу новых команд или операторов языка, то кажется, что 
это- существенное изменение и требует большой работы. Это не 
так. Если программист знает, как решать задачу, то 1000 команд для 
него не проблема. Йодан [15] приводит данные, когда один программист за полгода написал (в смысле отладил, т.е. изготовил) 80 тыс. 
операторов. 

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

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

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

12 

Данная ситуация подробно разобрана в книге Брукса [4]. Однако положение дел не меняется к лучшему... 

Умозрительно можно представить себе ситуацию, когда работа 
дается помощникам в расчете на дальнюю перспективу. Но в этом 
случае дающий задание программист сам не может достаточно подробно представить себе результирующий продукт. На самом деле 
такая ситуация еще хуже, чем первая. На большой срок дают обычно 
большую программу, по существу подсистему. В итоге такой работы 
придется заниматься уже стыковкой подсистем, что является гораздо 
более сложной задачей, чем включение в систему малой программы. 
Подсистемы могут вообще не состыковаться, даже если их делали 
высококвалифицированные программисты. Трудности такого рода 
рассмотрены в книге Гласса и Нуазо [9]. 

И наконец, совершенно недопустимой является практика, когда 
самостоятельную работу по изготовлению программного продукта 
поручают группе неквалифицированных программистов для того, 
например, чтобы занять их хоть какой-нибудь работой: вдруг получится что-либо путное. Ничего хорошего получиться не может. Лучший выход - оставить их результирующую работу без внимания, 
чтобы не отвлекать от дел других специалистов. Однако правила человеческого общежития порицают такие поступки, поэтому с негодной работой приходится еще долго мучиться. Ситуация такого рода 
рассматривается в [4]. 

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

1.3. Объектно-ориентированное 
программирование 

В последнее время обозначился четвертый этап. Но аналогии с 
превалирующими сейчас языками программирования его можно охарактеризовать как объектно-ориентированный. Ранее во многом интуитивное понятие «модуль» формализовалось и расширилось. При 
объектно-ориентированном подходе общая задача разлагается на 
связанные между собой подзадачи, каждая из которых становится 
самостоятельным объектом. Новые языки программирования основаны на трех базовых концепциях: инкапсуляции, полиморфизме и 
наследовании. 

Инкапсуляция - это механизм, который объединяет данные и программный код для их обработки. При этом одновременно осуществ
13 

ляется защита от внешнего вмешательства и неправильного использования данных. Полученный в результате инкапсуляции модуль называется объектом. Внутри объекта коды и данные могут быть закрытыми (private) и открытыми (public). Закрытые части недоступны извне объекта. 

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

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

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

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

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

14 

Доступ онлайн
2 000 ₽
В корзину