- •Предисловие
- •Введение
- •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.4Пакеты разработки программного обеспечения
Существует тенденция группировать транслятор и другие программы, использующиеся в процессе разработки программного обеспечения, в пакеты, которые функционируют как одна интегрированная система. Такую систему согласно предложенной нами классификации (см. раздел 3.2) можно отнести к прикладному программному обеспечению. Используя такой пакет программ, программист получает доступ к редактору для написания программ, транслятору для перевода программы на машинный язык и большому количеству инструментов отладки, которые позволяют следить за выполнением программы и обнаруживать «глюки».
Использование такой интегрированной системы дает множество преимуществ. Самое очевидное из них заключается в том, что программист в процессе изменения и проверки программы с легкостью может переключаться между редактором и инструментами отладки. Кроме того, большинство пакетов разработки программного обеспечения позволяют связывать зависимые программные единицы, находящиеся в разработке, упрощая тем самым доступ к ним. Некоторые пакеты ведут учет того, какую программную единицу из группы зависимых изменили с момента последней контрольной точки. Такие возможности очень полезны при разработке больших систем программного обеспечения, когда множество взаимосвязанных элементов создаются разными программистами.
Редакторы в пакетах разработки программного обеспечения обычно соответствуют используемому языку программирования. Например, редактор в пакете разработки программного обеспечения обычно структурирует текст программы согласно правилам используемого языка и иногда распознает и автоматически дописывает зарезервированные слова, после того как программист ввел первые несколько символов. Во многих пакетах разработки программного обеспечения используется графический интерфейс, который позволяет программисту создавать программы из заранее написанных блоков, располагающихся на экране в виде значков. Выбранные блоки можно изменять с помощью редактора. Такие пакеты являются следствием всеобщего стремления создавать программы из больших написанных заранее блоков, а не писать их команда за командой.
5.5 Объектно-ориентированное программирование
В разделе 5.1 мы говорили о том, что объектно-ориентированная парадигма программирования подразумевает создание активных программных единиц — объектов, которые состоят из процедур, описывающих, как объект должен отвечать на различные стимулы. При объектно-ориентированном подходе к решению задачи определяются необходимые объекты, которые затем описываются как самостоятельные единицы. В свою очередь объектно-ориентированные языки программирования предоставляют средства для выражения таких идей. В данном разделе мы познакомимся с некоторыми из этих средств и тем, как они представлены в трех наиболее известных объектно-ориентированных языках: C++, Java и С#.
5.5.1Классы и объекты
Рассмотрим процесс разработки компьютерной игры, в которой игрок должен защитить Землю от падающих метеоритов, расстреливая их мощными лазерами. Каждый лазер имеет внутренний запас энергии, который расходуется при выстреле. Когда запас энергии исчерпан, лазер становится бесполезным. Каждый лазер должен уметь направлять луч на цель справа, слева и стрелять.
Согласно объектно-ориентированной парадигме каждый лазер в игре будет реализован как объект, содержащий информацию об оставшемся запасе энергии и процедуры для наведения луча на цель и выстрела. Поскольку свойства всех этих объектов (лазеров) одинаковы, их можно создавать по одному шаблону. В объектно-ориентированном программировании такой шаблон называется классом (class). В языках C++, Java и С# класс описывается с помощью следующего оператора:
class Имя_класса {
}:
где Имя_класса — это имя, по которому к классу обращаются в программе. В фигурных скобках описываются свойства класса.
Class LaserClass
{ int RemainingPower - 100; ~ Описание данных, которые
будут находиться в каждом
объекте данного типа
void turnRight ( )
---------1--------- Методы, описывающие,
{• • ■} как объекты данного типа
должны отвечать void turnteft ( ) на различные сообщения
void fire С )
} Рис. 5.22. Структура класса, описывающего лазерное оружие в компьютерной игре
Например, класс LaserClass, описывающий лазеры в нашей компьютерной игре, изображен на рис. 5.22. (Более детальное описание этого класса приводится позднее на рис. 5.24.) Любой объект, созданный по этому образцу, будет включать в себя
целочисленную переменную RemainingPower и три процедуры — turnRight, turnLeft и f i re, описывающие шаги для выполнения поворота направо, поворота налево и выстрела. Переменная объекта, такая как RemainingPower, называется переменной экземпляра (instance variable), а процедура объекта называется методом (method) (или, согласно терминологии языка C++, функцией-членом (member function)). Обратите внимание на то, что на рис. 5.22 переменная экземпляра RemainingPower объявляется с помощью оператора описания, подобного тому, который мы обсуждали в разделе 5.3, а методы описываются как процедуры и функции, рассматриваемые нами там же. В самом деле, объявление переменных и описание методов, в сущности, являются понятиями императивного программирования.
5.5.2CORBAи RMI
Принципы объектно-ориентированного программирования используются при создании общесетевых систем программного обеспечения. Для таких систем разрабатываются общесетевые инфраструктуры, с помощью которых объекты могут обмениваться сообщениями по сети. Одна из технологий построения распределенных приложений называется CORBA (Common Object Request Broker Architecture — обобщенная архитектура обработчика объектных запросов). Она представляет собой систему инструкций для организации передачи сообщений между объектами. Другая технология называется RMI (Remote Method Invocation — удаленный вызов метода). Эта технология была разработана компанией Sun Microsystems и поддерживается программной средой Java, (более подробно с языком Java мы познакомимся позже в этой главе.) Разработчики программного обеспечения, использующие программную среду Java, находят, что технология RMI очень удобна при создании объектов, которые будут взаимодействовать с другими Java-объектами. Технология же CORBA обычно применяется при создании объектов в других языках программирования.
Описав класс LaserClass, мы можем объявить три переменных типа LaserClass с помощью оператора
LaserClass Laserl. Laser2. Laser3;
Обратите внимание на то, что такая же конструкция используется для описания трех целочисленных переменных х, у и z:
int x. у. 2;
Оба эти оператора состоят из имени типа и списка объявляемых переменных. Различие же заключается в том, что элемент, присвоенный переменной х, создается согласно заранее определенному шаблону целого числа (предопределенный тип данных), в то время как элемент, присвоенный переменной Laserl, создается согласно шаблону, определенному в программе как класс.
В языке C++ в результате выполнения приведенного выше оператора будут созданы три объекта типа LaserClass и присвоены переменным Laserl, Laser2 и Laser3. Однако в языках Java и С# будут просто созданы переменные, которым затем можно присвоить значения. Для того чтобы создать объект типа LaserCl ass и присвоить его переменной Laserl, в этих языках нужно использовать оператор
LaserClass Laserl = new LaserClassO;
Такой оператор не только описывает переменную типа LaserClass, но и создает новый объект, используя для этого шаблон LaserClass, и присваивает его пере-
менной Laserl. В этом случае оператор также похож на тот, который используется для объявления предопределенных типов данных. Например, оператор
int х = 3;
не только описывает тип переменной х, но и присваивает новой переменной значение 3.
Вне зависимости от того, с каким языком мы работаем, создав объекты и назначив им имена Laserl, Laser2 и Laser3, мы можем продолжить нашу программу, вызывая соответствующие методы этих объектов. Например, чтобы объект Laserl выполнил метод fire, нужно использовать оператор
Laserl.fire О:
А для того чтобы объект Laser2 выполнил метод turnLeft, используется оператор
Laser2.turnLeft О:
Прежде чем продолжить, давайте рассмотрим отношение понятий класса и объекта. Класс представляет собой шаблон, по которому создаются объекты: Один класс можно использовать для создания большого количества объектов. Часто объект называют экземпляром класса (instance). Следовательно, в нашей компьютерной игре имена Laserl, Laser2 и Laser3 используются для обозначения экземпляров класса LaserClass.
