- •Предисловие
- •Введение
- •1Архитектура эвм
- •1.1 Биты и их хранение
- •1.1.1Вентили и триггеры
- •1.1.2Другие способы хранения битов
- •1.1.3Шестнадцатеричная система счисления
- •1.2 Оперативная память
- •1.2.1Структура памяти
- •1.2.2Измерение емкости памяти
- •1.3 Устройства хранения данных
- •1.3.1Магнитные диски
- •1.3.2Компакт-диски
- •1.3.3Магнитные ленты
- •1.3.4Хранение и поиск файлов
- •1.4 Представление информации в виде двоичного кода
- •1.4.1Представление текста
- •1.4.2Американский национальный институт стандартов
- •1.4.3Iso - международная организация по стандартизации
- •1.4.4Представление числовых значений
- •1.4.5Представление изображений
- •1.4.6Представление звука
- •1.5 Двоичная система счисления
- •1.5.1Альтернатива двоичной системе счисления
- •1.5.2Дроби в двоичной системе счисления
- •1.5.3Аналоговые и цифровые устройства
- •1.6 Хранение целых чисел
- •1.6.1Представление в двоичном дополнительном коде
- •1.6.2Сложение в двоичном дополнительном коде
- •1.6.3Проблема переполнения
- •1.6.4Представление с избытком
- •1.7 Хранение дробей
- •1.7.1Представление с плавающей точкой
- •1.7.2Ошибка усечения
- •1.8 Сжатие данных
- •1.8.1Общие методы сжатия данных
- •1.8.2Сжатие звука
- •1.8.3Сжатие изображений
- •1.9 Ошибки передачи данных
- •1.9.1Контрольный разряд четности
- •1.9.2Коды с исправлением ошибок
- •2Манипулирование данными
- •2.1 Архитектура эвм
- •2.1.1Сложение двух чисел, хранящихся в оперативной памяти
- •2.1.2Кто и что изобрел?
- •2.2 Машинный язык
- •2.2.1Система команд
- •2.2.2Кэш-память
- •2.2.3Арифметико-логические команды
- •2.2.4Команды управления
- •2.2.5Деление двух значений, хранящихся в памяти
- •2.3 Выполнение программы
- •2.3.1Пример выполнения программы
- •2.3.2Команды переменной длины
- •2.3.3Программы и данные
- •2.4 Арифметические и логические операции
- •2.4.1Логические операции
- •2.4.2Сравнение вычислительной мощности эвм
- •2.4.3Операции сдвига
- •2.4.4Арифметические операции
- •2.5 Связь с другими устройствами
- •2.5.1Связь через контроллер
- •2.5.2Строение шины
- •2.5.3Скорость передачи данных
- •2.6 Другие архитектуры
- •2.6.1Конвейерная обработка
- •3Операционные системы и организация сетей
- •3.13.1. Эволюция операционных систем
- •3.1.1Однопроцессорные системы
- •3.1.2Многопроцессорные системы
- •3.2 Архитектура операционной системы
- •3.2.1Программное обеспечение
- •3.2.2Полезное единообразие или вредная монополия?
- •3.2.3Компоненты операционной системы
- •3.2.4Операционная система linux
- •3.2.5Начало работы операционной системы
- •3.3 Координирование действий машины
- •3.3.1Понятие процесса
- •3.3.2Управление процессами
- •3.3.3Модель «клиент-сервер»
- •3.4 Обработка конкуренции между процессами
- •3.4.1Семафор
- •3.4.2Взаимная блокировка
- •3.5 Сети
- •3.5.1Основы организации сетей
- •3.5.2Интернет
- •3.5.3Топология сети Интернет
- •3.5.4Система адресов Интернета
- •3.5.5Электронная почта
- •3.5.6Всемирная паутина
- •3.6 Сетевые протоколы
- •3.6.1Управление правом отправки сообщений
- •3.6.2Сеть ethernet
- •3.6.3Javascript, апплеты, cgi и сервлеты
- •3.6.4Многоуровневый принцип программного обеспечения Интернета
- •3.6.5Комплект протоколов tcp/ip
- •3.6.6Протоколы рорз и imap
- •3.7 Безопасность
- •3.7.1Протокол защищенных сокетов
- •3.7.2Группа компьютерной «скорой помощи»
- •4Алгоритмы
- •4.1 Понятие алгоритма
- •4.1.1Предварительные замечания
- •4.1.2Формальное определение алгоритма
- •4.1.3Определение алгоритма
- •4.1.4Абстрактная природа алгоритма
- •4.2 Представление алгоритма
- •4.2.1Примитивы
- •4.2.2Псевдокод
- •4.3 Создание алгоритма
- •4.3.1Искусство решения задач
- •4.3.2Итеративные структуры в музыке
- •4.3.3Первый шаг в решении задачи
- •4.4 Итеративные структуры
- •4.4.1Алгоритм последовательного поиска
- •4.4.2Управление циклом
- •4.4.3Алгоритм сортировки методом вставок
- •4.5Рекурсивные структуры
- •4.5.1Поиск и сортировка
- •4.5.2Алгоритм двоичного поиска
- •4.5.3Управление рекурсивными структурами
- •4.6 Эффективность и правильность
- •4.6.1Эффективность алгоритма
- •4.6.2Проверка правильности программного обеспечения
- •4.6.3По ту сторону проверки правильности программ
- •5Языки программирования
- •5.1 Исторический обзор
- •5.1.1Ранние поколения
- •5.1.2Интерплатформенное программное обеспечение
- •5.1.3Независимость от машины
- •5.1.4Парадигмы программирования
- •5.2 Основные понятия традиционного программирования
- •5.2.1Культуры языков программирования
- •5.2.2Переменные и типы данных
- •5.2.3Структуры данных
- •5.2.4Константы и литералы
- •5.2.5Операторы присваивания
- •5.2.6Управляющие операторы
- •5.2.7Комментарии
- •5.3 Процедурные единицы
- •5.3.1Процедуры
- •5.3.2Событийно-управляемые программные системы
- •5.3.3Параметры
- •5.3.4Функции
- •5.3.5Операторы ввода-вывода
- •5.4 Реализация языка программирования
- •5.4.1Процесс трансляции программы
- •5.4.2Реализация java
- •5.4.3Компоновка и загрузка
- •5.4.4Пакеты разработки программного обеспечения
- •5.5 Объектно-ориентированное программирование
- •5.5.1Классы и объекты
- •5.5.3Конструкторы
- •5.5.4Дополнительные возможности
- •5.6 Параллельные операции
- •5.7 Декларативное программирование
- •5.7.1Логическая дедукция
- •5.7.2Язык программирования Prolog
- •6Разработка программного обеспечения
- •6.1 Разработка программного обеспечения
- •6.1.1Ассоциация по вычислительной технике
- •6.1.2Институт инженеров по электротехнике и электронике
- •6.2 Жизненный цикл программы
- •6.2.1Цикл как единое целое
- •6.2.2Разработка программного обеспечения на практике
- •6.2.3Этапы разработки программного обеспечения
- •6.2.4Анализ
- •6.2.5Проектирование
- •6.2.6Реализация
- •6.2.7Тестирование
- •6.2.8Современные тенденции
- •6.3 Модульность
- •6.3.1Модульная реализация программы
- •6.3.2Связь модулей системы
- •6.3.3Связность модуля
- •6.4 Методики проектирования
- •6.4.1Нисходящее и восходящее проектирование
- •6.4.2Модели проектирования
- •6.4.3Разработка открытых программных продуктов
- •6.5 Инструменты проектирования
- •6.6 Тестирование
- •6.7 Документация
- •6.8 Право собственности на программное обеспечение и ответственность
- •Часть 3 организация данных
- •7Структуры данных
- •7.1 Основы структур данных
- •7.1.1Опять абстракция
- •7.1.2Статические и динамические структуры
- •7.1.3Указатели
- •7.2 Массивы
- •7.3 Списки
- •7.3.1Непрерывные списки
- •7.3.2Реализация непрерывных списков
- •7.3.3Связные списки
- •7.3.4Поддержка абстрактного списка
- •7.4 Стеки
- •7.4.1Откат
- •7.4.2Реализация стека
- •7.5 Очереди
- •7.5.1Проблема указателей
- •7.6 Деревья
- •7.6.1Реализация дерева
- •7.6.2Сбор мусора
- •7.6.3Пакет бинарного дерева
- •7.7 Пользовательские типы данных
- •7.7.1Пользовательские типы
- •7.7.2Классы
- •7.7.3Описательное и процедурное знание
- •7.7.4Стандартная библиотека шаблонов
- •7.8 Указатели в машинном языке
- •8Файловые структуры
- •8.1 Роль операционной системы
- •8.1.1Таблицы размещения файлов
- •8.2 Последовательные файлы
- •8.2.1Обработка последовательных файлов
- •8.2.2Консорциум производителей программного обеспечения для www
- •8.2.3Текстовые файлы
- •8.2.4Текстовые и двоичные файлы
- •8.2.5Вопросы программирования
- •8.2.6Семантическая сеть
- •8.3 Индексация
- •8.3.1Основные положения индексации
- •8.3.2Вопросы программирования
- •8.3.3Расположение файлов на дисках
- •8.4 Хэширование
- •8.4.1Хэш-система
- •8.4.2Проблемы распределения
- •8.4.3Аутентификация посредством хэширования
- •8.4.4Вопросы программирования
- •9Структуры баз данных
- •9.1 Общие вопросы
- •9.2 Многоуровневый подход к реализации базы данных
- •9.2.1Система управления базой данных
- •9.2.2Распределенные базы данных
- •9.2.3Модели баз данных
- •9.3 Реляционная модель баз данных
- •9.3.1Вопросы реляционного проектирования
- •9.3.2Системы баз данных для персональных компьютеров
- •9.3.3Хронологические базы данных
- •9.3.4Реляционные операции
- •9.3.5Вопросы реализации
- •9.3.6Язык sql
- •9.4 Объектно-ориентированные базы данных
- •9.5 Поддержка целостности базы данных
- •9.5.1Пространственные базы данных
- •9.5.2Протоколы фиксации/отката изменений
- •9.5.3Блокировка
- •9.6 Воздействие технологий баз данных на общество
- •10Искусственный интеллект
- •10.1 Интеллект и машины
- •10.1.1Конечный результат или имитация
- •10.1.2Истоки искусственного интеллекта
- •10.1.3Тест Тьюринга
- •10.1.4Машина для решения головоломки из восьми фишек
- •10.2 Распознавание образов
- •10.3 Мышление
- •10.3.1Продукционные системы
- •10.3.2Интеллект, основанный на поведении
- •10.3.3Деревья поиска
- •10.3.4Эвристика
- •10.4 Искусственные нейронные сети
- •10.4.1Основные свойства
- •10.4.2Приложение теории
- •10.4.3Ассоциативная память
- •10.5 Генетические алгоритмы
- •10.6 Прочие области исследования
- •10.6.1Обработка лингвистической информации
- •10.6.2Рекурсия в естественных языках
- •10.6.3Роботы
- •10.6.4Системы баз данных
- •10.6.5Экспертные системы
- •10.7 Обдумывая последствия
- •10.7.1Сильный искусственный интеллект против слабого
- •11Теория вычислений
- •11.1 Функции и их вычисление
- •11.1.1Теория рекурсивных функций
- •11.2 Машины Тьюринга
- •11.2.1Основы машины Тьюринга
- •11.2.2Истоки машины Тьюринга
- •11.2.3Тезис Черча-Тьюринга
- •11.3 Универсальные языки программирования
- •11.3.1Скелетный язык
- •11.3.2Существуют ли инопланетяне?
- •11.3.3Универсальность скелетного языка
- •11.4 Невычислимая функция
- •11.4.1Проблема останова
- •11.4.2Неразрешимость проблемы останова
- •11.5 Сложность задач
- •11.5.1Измерение сложности задачи
- •11.5.2Пространственная сложность
- •11.5.3Полиномиальные и не полиномиальные задачи
- •11.5.5Детерминированность против недетерминированности
- •11.6Шифрование с открытым ключом
- •11.6.1Шифрование при помощи задачи о ранце
- •11.6.2Популярные системы шифрования
- •11.6.3Модульная арифметика
- •11.6.4Обратно к шифрованию
5.4.2Реализация java
В случае веб-страниц с анимацией программное обеспечение, которое управляет анимацией, передается по Интернету вместе со страницей. Если это программное обеспечение поставляется в форме исходной программы, то при просмотре страницы возникнут трудности, поскольку это программное обеспечение нужно преобразовать в машинный язык. Однако если записывать эти программы на машинном языке, то придется создавать разные версии страницы в зависимости от машинного языка, используемого в машине, пытающейся получить доступ к странице.
Компания Sun Microsystems решила эту проблему, создав универсальный «машинный язык», который называется байт-кодом. В этот код преобразуются все исходные программы, написанные на языке Java. Хотя байт-код — не совсем машинный язык, его может быстро выполнить любая машина с помощью соответствующей интерпретирующей программы. Сегодня такие интерпретирующие программы становятся частью программ браузера. Таким образом, если программное обеспечение, управляющее веб-страницей, написано на Java и преобразовано в байт-код, то этот код можно передать браузеру для более эффективного отображения анимации.
В основе процесса синтаксического анализа лежит набор синтаксических правил, которые определяют синтаксис языка программирования. Одним из способов представления этих правил является синтаксическая диаграмма (syntax diagram), то есть графическое изображение грамматической структуры программы. Синтаксическая диаграмма оператора if-then-else представлена на рис. 5.16. Она показывает, что структура if-then-else начинается со слова if, за ним следует Логическое выражение, слово then и Высказывание. После этой комбинации может находиться слово else и Высказывание. Обратите внимание на то, что элементы, которые действительно присутствуют в операторе if-then-else, заключены в овалы, а элементы, которые требуют дальнейшего описания, такие как Логическое выражение и Высказывание, заключены в прямоугольники. Элементы, требующие дальнейшего описания (в прямоугольниках), называются нетерминальными (nonterminals); элементы в овалах, называются терминальными (terminals).
В полном описании синтаксиса языка нетерминальные элементы определяются с помощью дополнительных диаграмм.
В качестве более сложного примера приведем несколько синтаксических диаграмм, описывающих синтаксис структуры Выражение, которая является простым арифметическим выражением (рис. 5.17). На первой диаграмме Выражение состоит из Элемента, за которым может следовать символ + или - и другое Выражение. Вторая диаграмма описывает Элемент, состоящий либо из одного Множителя, либо из Множителя, символов х или -5- и другого Элемента. И наконец, последняя диаграмма описывает Множитель, который является одним из символов х, у или z.
Отдельное арифметическое выражение можно представить с помощью дерева синтаксического анализа (parse tree). Дерево синтаксического анализа (рис. 5.18) для цепочки х + у х z
строится на базе синтаксических диаграмм (см. рис. 5.17). Обратите внимание на то, что в основании дерева находится нетерминальный элемент Выражение, и на каждом последующем уровне нетерминальные элементы разбиваются на составные части до тех пор, пока не будут получены символы цепочки. В частности, дерево
показывает, что цепочка к + у х z состоит из Элемента, который является Множителем х, символа + и Выражения, которое является Элементом у х г.
Процесс синтаксического анализа программы, в сущности, представляет собой построение дерева синтаксического анализа для исходного кода. Синтаксическое дерево отражает то, как синтаксический анализатор понимает грамматическое строение программы. Поэтому синтаксические правила, описывающие грамматическую структуру программы, должны исключать возможность построения двух синтаксических деревьев для одной цепочки, поскольку это приведет к неоднозначности. Ошибки такого рода трудно заметить. Например, диаграмма на рис. 5.16 содержит означенный дефект. Она позволяет построить два синтаксических дерева (рис. 5.19) для одного высказывания if Bl then if В2 then SI else S2
Обратите внимание на то, что эти деревья принципиально отличаются. Первое дерево предполагает, что выражение S2 выполняется, если условие В1 ложно; второе означает, что S2 выполняется, только если условие В1 истинно, а условие В2 ложно.
Синтаксические определения формальных языков программирования создаются так, чтобы избежать неоднозначности. В нашем псевдокоде для этого мы использовали скобки. Например, для того чтобы различать два возможных способа интерпретации приведенного выше выражения, можно записать:
if Bl
then (if B2 then SI)
else S2
и
if Bl
then (if B2 then SI else S2)
Когда синтаксический анализатор обрабатывает операторы описания, он записывает содержащуюся в них информацию в таблицу, которая называется таблицей имен (symbol table). Таблица имен содержит информацию о том, какие переменные объявлены в программе и какие типы данных или структур данных поставлены им в соответствие. С помощью этой информации синтаксический анализатор обрабатывает исполняемые операторы, такие как
Z <- X + Y;
Для того чтобы определить значение символа +, анализатору необходимо знать тип данных переменных X и Y. Если X — вещественная переменная, a Y — сим-иол, тогда их сложение просто бессмысленно, и следует сообщить об ошибке. 1хли X и Y — целочисленные переменные, тогда анализатор предпишет генератору кода создать команду машинного языка с кодом операции сложения двух целых чисел. Если оба слагаемых являются переменными вещественного типа, то генератор кода будет использовать код операции для сложения с плавающей точкой.
Приведенный выше оператор может включать в себя переменные разных типов. Например, если X — целочисленная переменная, a Y — вещественная, то операцию сложения все-таки можно выполнить. В таком случае генератор кода создает команду преобразования типа одного из значений, а затем выполняет сложение. Такое преобразование типа значения называется приведением типов (coercion).
Многие разработчики языков неодобрительно относятся к приведению типов. Они утверждают, что необходимость приведения типов свидетельствует о наличии недостатков в строении программы, и, следовательно, анализатор не должен предоставлять такую операцию. В результате большинство современных языков программирования являются языками со строгим контролем типов (strongly typed), то есть все операции, выполняемые программой, должны включать данные совместимых типов. Синтаксические анализаторы этих языков при возникновении конфликта типов всегда сообщают об ошибке.
Последняя стадия процесса трансляции программы — это генерация кода, то есть создание команд машинного языка, выполняющих выражения, распознанные синтаксическим анализатором. Во время генерации кода возникает множество трудностей, и одна нз них — это создание эффективного кода. Рассмотрим, например, трансляцию последовательности двух операторов
х <- у + z; w <— х + z;
Можно рассматривать эти операторы независимо друг от друга. Однако в этом случае мы не получим эффективного кода. Генератор кода должен распознать, что после выполнения первого оператора значения х и z уже будут находиться в регистрах центрального процессора, и, следовательно, их не нужно повторно загружать из памяти перед выполнением второго оператора. Этот процесс называется оптимизацией программы (code optimization) и является важной задачей генератора кода.
Лексический и синтаксический анализ и генерация кода не выполняются строго друг за другом. Вместо этого все эти процессы протекают одновременно. Лексический анализатор считывает первые символы и определяет первую лексему. Затем он передает эту лексему синтаксическому анализатору. Каждый раз, когда синтаксический анализатор получает лексему, он обрабатывает считываемую грамматическую конструкцию. На данном этапе он либо запрашивает у лексического анализатора еще одну лексему, либо, если он распознает оператор, вызывает генератор кода, чтобы тот создал последовательность соответствующих машинных команд. Затем эти машинные команды добавляются к объектной программе. Трансляция программы соответствует объектно-ориентированной парадигме программирования. Исходная программа, лексический анализатор, синтаксический анализатор, генератор кода и объектная программа являются объектами, которые взаимодействуют между собой, обмениваясь сообщениями, когда какой-либо из объектов приступает к выполнению своей задачи (рис. 5.20).
