Файл: "История развития программирования в России".pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 19.06.2023

Просмотров: 48

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Машина проводила вычисления и выдавала результат, однако, логика её работы, программа по сути, была обусловлена внутренней уникальной схемой, что не позволяло проводить различные вычисления на этой же машине. Важно заметить, что для программирования тогда использовались именно электротехнические элементы, то есть, программист-инженер по сути создавал программу посредством соединения непосредственно устройств, исполнявших операции. Уникальность, и как следствие дороговизна, привели к тому, что было разработано новое поколение машин — эти устройства, по своей сути, стали первыми программируемыми в полном смысле слова. Языком программирования для этих машин в начале служила коммутационная панель, на которой, соединяя гнёзда различных устройств, программист мог задавать последовательность действий для машины — что уже было достаточно большим различием в синтаксисе языка. Если раньше программист исполнял роль инженера-схемотехника и применял сами компоненты для создания программы, то теперь при программировании он мог использовать универсальные блоки — заранее объединенные группы компонент, имеющие необходимые свойства и умеющие выполнять необходимые операции. В дальнейшем в связи с развитием оборудования панель была заменена на перфокарты, перфоленты, магнитные ленты и барабаны — однако, программирование всё ещё сводилось к формированию последовательности единиц и нулей.

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

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


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

Целью появления этих языков стало формирование ещё одного уровня абстракции, программист теперь был свободен от решения задач переноса данных внутри машины и мог больше внимания уделять самому алгоритму программы. Именно на этом этапе языки программирования получили программы — компиляторы и интерпретаторы.

Оба эти класса программ необходимы для перевода и трансформации текстового представления программы, которое удобно для программиста и построено согласно правилам языка в машинное представление — при этом управляющие команды в большей степени являются средствами языка и не привязаны к аппаратной реализации машины. Важным моментом здесь является то, что язык ассемблер не имеет компилятора, а использует ассемблер (утилита, проводящая сборку бинарной программы для машины из исходного кода, на языке ассемблера называется также) — программу, которая лишь ставит в соответствие мнемоническим символам бинарные последовательности, но не трансформирует программу. Эти изменения привели к значительному ускорению разработки и удешевлению программ, однако создание больших программ всё ещё оставалось трудоёмким. Одной из основных проблем стала не сложность программирования, а сложность самих программ. Большие программные продукты было очень трудно контролировать, так как не было единого стиля мышления и программирования. Решением этой проблемы занялся ряд выдающихся учёных, в котором особо необходимо отметить имена Эдсгера Дейкстры, Коррады Бёма и Джузеппе Якопини. За несколько лет в результате работы многих учёных и практиков был сформирован базис структурного подхода к программированию. Отличительной особенностью стало выявление трёх базовых элементов любой программы: последовательность, ветвление и цикл[4].

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


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

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

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

Таким образом дальнейшая миниатюризация становится всё более трудоёмкой и дорогостоящей[5]. Эти причины и привели в 2000-х годах к популяризации многопроцессорных систем, а как следствие, и к обострению проблемы параллельного программирования. Важно заметить, что эта проблема на данный момент всё ещё не является решённой в полном смысле слова, так как причиной её появления служит сама архитектура современных машин[6].


Глава 2 Развитие языков программирования

2.1 Характеристики и свойства языков программирования

Языки программирования являются средством представления знаний для компьютерных систем. Они предлагают концептуальные средства представления и возможности моделирования, приспособленные к решению конкретных задач[7]. При этом концепции языков программирования складываются и развиваются в результате стремления разработчиков снизить «семантический разрыв» между языком описания работы вычислительного устройства и языком, на котором осуществляется постановка задачи. Развитие языков на эмпирическом уровне определяется развитием вычислительной техники. На теоретическом уровне изменения в представлениях о языках программирования определяется выбором формы управления вычислительными устройствами. Многообразие концепций языков, разработанных за период в 60 лет, привело к многообразию парадигм программирования, сложившихся к настоящему времени[8].

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

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

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

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

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


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

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

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

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

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

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