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

Примерно та же ситуация происходит при создании сложных современных программных систем. В начале 80х гг была начата СОИ (стратегическая оборонная инициатива), ее идея была в том, чтобы создать сложной технической системы, которая бы в автоматическом режиме установила контроль за пусковыми установками СССР и стран Варшавского блока, и в случае фиксации старта с наших позиций какого-то непродекларированного объекта автоматически начиналась война. То есть запускались бы средства уничтожения данного объекта и средства для ответных действий. Реально тот департамент вооруженных сил, который занимался этим проектом, испытал ряд кризисов в связи с тем, что ведущие специалисты в области программного обеспечения отказывались участвовать в реализации этого проекта из-за невозможности корректно его спроектировать, потому что система обладала гигантским потоком входных данных, на основе которых должны были быть приняты однозначные решения, ответственность за которые оценить весьма сложно. На самом деле эта проблема подтолкнула к развитию с одной стороны - языков программирования, которые обладали надежностью, в частности, язык Ада, одной из целью которого было создание безошибочного ПО. В таких языках накладывались ограничения на места, где наиболее вероятно возникновение ошибки (межмодульные интерфейсы; выражения, где присутствуют разные типы данных и т.п.) Заметим, что язык C не удовлетворяет требованиям безопасности. С другой стороны - к детальному проектированию, которое бы позволяло некоторым формальным образом описывать создаваемый проект и работать с проектом в части его детализации. Причем, переход от детализации к кодированию не имел бы четкой границы. Понятно, что это есть некоторая задача не сегодняшнего, а завтрашнего дня, но реально разработчики программ находятся на пути создания таких средств, которые позволили бы совместить проектирование и кодирование. Сегодняшние системы программирования, которые строятся на объектно-ориентированном подходе, частично решают эту проблему.

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

Но тем не менее следует понимать, что период проектирования есть очень важный момент.

Кодирование

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

Основной компонент системы кодирования - язык программирования. В голове каждого программиста лежит иерархия языков программирования - от машинного кода и ассемблера до универсальных языков программирования (FORTRAN, Algol, Pascal, C и т.д.), специализированных языков (SQL, HTML, Java и т.д.)

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

Компилятор - это транслятор, переводящий текст программы в машинный код.

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

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

На сегодняшний день каждый из методов - и компиляция и интерпретация занимают свои определенные ниши.

Лекция №20

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

* проектирование

* кодирование

* тестирование

* отладка

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

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

Этап кодирования

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

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