
- •Оглавление
- •Об авторе
- •Благодарности
- •Предисловие
- •Глава 1. Держим оборону
- •На пути к хорошему коду
- •Готовьтесь к худшему
- •Что такое защитное программирование?
- •Этот страшный, ужасный мир
- •Технологии защитного программирования
- •Выберите хороший стиль кодирования и пользуйтесь крепкой архитектурой
- •Пишите код без спешки
- •Не верьте никому
- •Стремитесь к ясности, а не к краткости
- •Не позволяйте никому лезть туда, где ему нечего делать
- •Включайте вывод всех предупреждений при компиляции
- •Пользуйтесь средствами статического анализа
- •Применяйте безопасные структуры данных
- •Проверяйте все возвращаемые значения
- •Аккуратно обращайтесь с памятью (и другими ценными ресурсами)
- •Инициализируйте все переменные там, где вы их объявили
- •Объявляйте переменные как можно позже
- •Пользуйтесь стандартными средствами языка
- •Пользуйтесь хорошими средствами регистрации диагностических сообщений
- •Выполняйте приведение типов с осторожностью
- •Подробности
- •Ограничения
- •Какие ограничения налагать
- •Снятие ограничений
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 2. Тонкий расчет
- •Да в чем проблема?
- •Знайте своих клиентов
- •Что такое хорошее представление?
- •Размещение скобок
- •Скобки в стиле K&R
- •Расширенный стиль скобок
- •Стиль Уайтсмита (с отступами)
- •Другие стили скобок
- •Единственно верный стиль
- •Внутрифирменные стили (и когда их придерживаться)
- •Установка стандарта
- •Религиозные войны?
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 3. Что в имени тебе моем?
- •Зачем нужны хорошие имена?
- •Каким объектам мы даем имена?
- •Игра в названия
- •Описательность
- •Техническая корректность
- •Идиоматичность
- •Тактичность
- •Технические подробности
- •Имена переменных
- •Имена функций
- •Имена типов
- •Пространства имен
- •Имена макросов
- •Имена файлов
- •Роза пахнет розой
- •Соблюдайте единообразие
- •Связывайте имя с содержимым
- •Извлекайте выгоду из выбора имени
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 4. Литературоведение
- •Самодокументируемый код
- •Техника написания самодокументируемого кода
- •Пишите простой код с хорошим форматированием
- •Выбирайте осмысленные имена
- •Разбивайте код на самостоятельные функции
- •Выбирайте содержательные имена типов
- •Применяйте именованные константы
- •Выделяйте важные фрагменты кода
- •Объединяйте взаимосвязанные данные
- •Снабжайте файлы заголовками
- •Правильно обрабатывайте ошибки
- •Пишите осмысленные комментарии
- •Практические методологии самодокументирования
- •Грамотное программирование
- •Инструментарий документирования
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 5. Заметки на полях
- •Что есть комментарий в коде?
- •Как выглядят комментарии?
- •Сколько комментариев требуется?
- •Что помещать в комментарии?
- •Не нужно описывать код
- •Не подменяйте код
- •Как сделать комментарии полезными
- •Не отвлекаться
- •На практике
- •Замечание об эстетичности
- •Единообразие
- •Четкие блочные комментарии
- •Отступы в комментариях
- •Комментарии в конце строки
- •Помощь в чтении кода
- •Стиль должен обеспечивать легкость сопровождения
- •Границы
- •Флажки
- •Комментарии в заголовке файла
- •Работа с комментариями
- •Помощь при написании программ
- •Заметки об исправлении ошибок
- •Устаревание комментариев
- •Сопровождение и бессодержательные комментарии
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 6. Людям свойственно ошибаться
- •Откуда что берется
- •Механизмы сообщения об ошибках
- •Без обработки ошибок
- •Возвращаемые значения
- •Переменные, содержащие состояние ошибки
- •Исключения
- •Сигналы
- •Обнаружение ошибок
- •Обработка ошибок
- •Когда обрабатывать ошибки
- •Варианты реагирования
- •Последствия для кода
- •Подымаем скандал
- •Управление ошибками
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 7. Инструментарий программиста
- •Что такое инструмент программирования?
- •А зачем они нужны – инструменты?
- •Электроинструменты
- •Выясните, каковы его возможности
- •Научитесь им управлять
- •Выясните, для каких задач он пригоден
- •Убедитесь, что он работает
- •Имейте четкие данные о том, как получить дополнительные сведения
- •Узнайте, как получить новые версии
- •Какой инструмент необходим?
- •Средства редактирования исходного кода
- •Средства построения кода
- •Инструменты для отладки и тестирования
- •Средства поддержки языка
- •Инструменты различного назначения
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 8. Время испытаний
- •Проверка на подлинность
- •Кто, что, когда, зачем?
- •Зачем тестировать
- •Кому тестировать
- •В чем состоит тестирование
- •Когда тестировать
- •Типы тестирования
- •Выбор контрольных примеров для блочного тестирования
- •Архитектура и тестирование
- •Руками не трогать!
- •Анатомия провала
- •Справлюсь ли я сам?
- •Система контроля ошибок
- •Обсуждение ошибок
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 9. Поиск ошибок
- •Реальные факты
- •Природа этого зверя
- •Взгляд с высоты птичьего полета
- •Взгляд с поверхности земли
- •Взгляд из глубины
- •Борьба с вредителями
- •Обходная дорога
- •Правильный путь
- •Охота за ошибками
- •Ошибки этапа компиляции
- •Ошибки этапа исполнения
- •Как исправлять ошибки
- •Профилактика
- •Отладчик
- •Средство проверки доступа к памяти
- •Трассировщик системных вызовов
- •Дамп памяти
- •Журналирование
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 10. Код, который построил Джек
- •Языковые барьеры
- •Интерпретируемые языки
- •Компилируемые языки
- •Делаем слона из мухи
- •Выполнение сборки
- •Что должна уметь хорошая система сборки?
- •Простота
- •Единообразие
- •Повторяемость и надежность
- •Атомарность
- •Борьба с ошибками
- •Механика сборки
- •Выбор целей
- •Уборка
- •Зависимости
- •Автоматическая сборка
- •Конфигурация сборки
- •Рекурсивное применение make
- •Мастер на все руки
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 11. Жажда скорости
- •Что такое оптимизация?
- •От чего страдает оптимальность кода?
- •Доводы против оптимизации
- •Альтернативы
- •Нужна ли оптимизация
- •Технические подробности
- •Убедитесь, что нужна оптимизация
- •Определите самую медленную часть кода
- •Тестирование кода
- •Оптимизация кода
- •После оптимизации
- •Методы оптимизации
- •Конструктивные изменения
- •Модификация кода
- •Как писать эффективный код
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 12. Комплекс незащищенности
- •Риски
- •Наши оппоненты
- •Оправдания, оправдания
- •Ощущение незащищенности
- •Опасный проект и архитектура
- •Переполнение буфера
- •Встроенные строки запросов
- •Условия гонки
- •Целочисленное переполнение
- •Дела защитные
- •Технология установки системы
- •Технология конструирования программного обеспечения
- •Технологии реализации кода
- •Технологии процедуры
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 13. Важность проектирования
- •Программирование как конструкторская работа
- •Что нужно проектировать?
- •Хороший проект программного продукта
- •Простота
- •Элегантность
- •Модульность
- •Хорошие интерфейсы
- •Расширяемость
- •Избегайте дублирования
- •Переносимость
- •Идиоматичность
- •Документированность
- •Как проектировать код
- •Методы и процедуры проектирования
- •Инструменты проектирования
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 14. Программная архитектура
- •Что такое программная архитектура?
- •План программы
- •Точки зрения
- •Где и когда этим заниматься?
- •Для чего она применяется?
- •Компоненты и соединения
- •Какими качествами должна обладать архитектура?
- •Архитектурные стили
- •Без архитектуры
- •Многоуровневая архитектура
- •Архитектура с каналами и фильтрами
- •Архитектура клиент/сервер
- •Компонентная архитектура
- •Каркасы
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 15. Программное обеспечение – эволюция или революция?
- •Гниение программного обеспечения
- •Тревожные симптомы
- •Как развивается код?
- •Вера в невозможное
- •Как с этим бороться?
- •Как писать новый код
- •Сопровождение существующего кода
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 16. Кодеры
- •Мартышкин труд
- •Нетерпеливый
- •Кодер (Code Monkey)
- •Гуру
- •Псевдогуру
- •Высокомерный гений
- •Ковбой
- •Плановик
- •Ветеран
- •Фанатик
- •Монокультурный программист
- •Лодырь
- •Руководитель поневоле
- •Идеальный программист
- •И что из этого следует?
- •Для глупцов
- •Резюме
- •План действий
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 17. Вместе мы – сила
- •Команды – общий взгляд
- •Организация команды
- •Методы управления
- •Разделение ответственности
- •Организация и структура кода
- •Инструменты для групповой работы
- •Болезни, которым подвержены команды
- •Вавилонская башня
- •Диктатура
- •Демократия
- •Большой Каньон
- •Зыбучие пески
- •Лемминги
- •Личное мастерство и качества, необходимые для работы в команде
- •Общение
- •Скромность
- •Разрешение конфликтов
- •Обучение и приспособляемость
- •Знание пределов своих возможностей
- •Принципы групповой работы
- •Коллективное владение кодом
- •Нормы кодирования
- •Определите, что считать успехом
- •Установите ответственность
- •Избегайте истощения
- •Жизненный цикл команды
- •Создание команды
- •Рост команды
- •Групповая работа
- •Роспуск команды
- •Резюме
- •План действий
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 18. Защита исходного кода
- •Управление версиями исходного кода
- •Контроль версий
- •Контроль доступа
- •Работа с хранилищем
- •Пусть растут деревья
- •Краткая история систем контроля за исходным кодом
- •Управление конфигурацией
- •Резервное копирование
- •Выпуск исходного кода
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 19. Спецификации
- •Что же это такое, конкретно?
- •Типы спецификаций
- •Спецификация требований
- •Функциональная спецификация
- •Спецификация системной архитектуры
- •Спецификация интерфейса пользователя
- •Проектная спецификация
- •Спецификация тестирования
- •Что должны содержать спецификации?
- •Процесс составления спецификаций
- •Почему мы не пишем спецификации?
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Когда проводить рецензирование?
- •Нужно ли рецензировать
- •Какой код рецензировать
- •Проведение рецензирования кода
- •Рецензирование на собраниях
- •Интеграционное рецензирование
- •Пересмотрите свое отношение
- •Позиция автора
- •Позиция рецензента
- •Идеальный код
- •За пределами рецензирования кода
- •Резюме
- •Контрольный список
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 21. Какой длины веревочка?
- •Выстрел в темноте
- •Почему трудно делать оценки?
- •Под давлением
- •Практические способы оценки
- •Игры с планами
- •Не отставай!
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 22. Рецепт программы
- •Стили программирования
- •Структурное программирование
- •Функциональное программирование
- •Логическое программирование
- •Рецепты: как и что
- •Процессы разработки
- •Каскадная модель
- •SSADM и PRINCE
- •Создание прототипов
- •Итеративная и инкрементная разработка
- •Спиральная модель
- •Другие процессы разработки
- •Спасибо, хватит!
- •Выбор процесса
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 23. За гранью возможного
- •Программирование приложений
- •Коробочные продукты
- •Заказные приложения
- •Программирование игр
- •Системное программирование
- •Встроенное программное обеспечение
- •Программирование масштаба предприятия
- •Численное программирование
- •И что дальше?
- •Резюме
- •Контрольные вопросы
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 24. Что дальше?
- •Но что же дальше?
- •Ответы и обсуждение
- •Глава 1. Держим оборону
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 2. Тонкий расчет
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 3. Что в имени тебе моем?
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 4. Литературоведение
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 5. Заметки на полях
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 6. Людям свойственно ошибаться
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 7. Инструментарий программиста
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 8. Время испытаний
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 9. Поиск ошибок
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 10. Код, который построил Джек
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 11. Жажда скорости
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 12. Комплекс незащищенности
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 13. Важность проектирования
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 14. Программная архитектура
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 15. Программное обеспечение – эволюция или революция?
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 16. Кодеры
- •Вопросы для размышления
- •Глава 17. Вместе мы – сила
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 18. Защита исходного кода
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 19. Спецификации
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 20. Рецензия на отстрел
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 21. Какой длины веревочка?
- •Вопросы для размышления
- •Вопросы личного характера
- •Глава 22. Рецепт программы
- •Вопросы для размышления
- •Глава 23. За гранью возможного
- •Вопросы для размышления
- •Вопросы личного характера
- •Библиография
- •Алфавитный указатель
Какую работу нужно написать?
238 |
Глава 10. Код, который построил Джек |
пропускать наш исходный код через компилятор (или интерпретатор), чтобы получить то, что работает так, как нам хотелось бы. Неизменно оно отказывается это делать. Смыть и повторить.
Задача, состоящая в том, чтобы преобразовать тщательно отшлифо% ванный код на языке высокого уровня в исполняемый модуль, кото% рый можно распространять среди пользователей, обычно называется сборкой кода (building code), хотя в большинстве случаев этот термин используют наравне с компиляцией (making, compiling).
Процедура сборки является базовой – нельзя разрабатывать код, не выполняя сборки. Поэтому важно понимать, что] в нее входит и как ра% ботает ваша система сборки – лишь тогда можно иметь хоть какое%то доверие к генерируемому коду. Здесь играет роль ряд довольно тонких факторов, особенно если базовый код достигает внушительных разме% ров. Любопытно, что почти все учебники программирования благопо% лучно пропускают эту тему; они ограничиваются примерами про% грамм, состоящих из единственного файла, что не отражает реальной сложности процедуры сборки.
Многие разработчики полагаются на систему сборки своей интегриро% ванной среды, но это не снимает с них обязанности разобраться, как она работает. Очень удобно, когда можно нажатием кнопки сгенерировать весь код, но если вы не знаете, какие опции передаются компилятору C или на каком уровне находятся вспомогательные средства, сохраняе% мые в объектных файлах, то вы слабо контролируете ситуацию. То же самое происходит, когда вы вводите в командной строке одну команду сборки. Вы должны понимать, какие скрытые действия производятся, и только тогда сможете многократно осуществлять надежную сборку.
Языковые барьеры
Есть несколько разновидностей языков программирования, в каждой из которых существует своя механическая процедура построения ис% полняемой программы из исходного кода. Модели построения разли% чаются по сложности, и у каждой есть свои сильные и слабые стороны.
Три основных механизма – это интерпретируемые языки, компили# руемые языки и языки, компилируемые в байт#коды. Они представле% ны на рис. 10.1.
Интерпретируемые языки
Коду, написанному на интерпретируемом языке, не требуется прохо% дить через особую фазу сборки. Написав некий код, нужно лишь сооб% щить интерпретатору, где он лежит; интерпретатор станет анализиро% вать код и выполнять инструкции в реальном времени. Распространен% ными интерпретируемыми языками являются Perl, Python и Java% Script. Большинство OO%языков является интерпретируемыми, в основ%

Языковые барьеры |
239 |
|
|
|
|
|
1. |
Интерпретируемые языки |
|
|
|
|
|
2. |
Компилируемые языки |
|
|
Файлы |
|
|
3. |
Языки, компилируемые в байт7код |
|
|
|
|
4. |
Выполнение с JIT7компиляцией |
|
|
1 |
с исходным |
3 |
|
|
Применение |
|
кодом |
|
|
инструмента сборки |
||
|
|
|
|
|
||
Интерпретатор |
|
2 |
|
|
|
Байт7компилятор |
|
|
|
|
|
|
|
|
Компилятор |
|
|
|
|
|
|
Выполняемый модуль |
4 |
Байт7код |
Выполнение |
JIT7компилятор |
|
Интерпретатор
01010101
Выход
01010101
Рис. 10.1. Методы сборки и выполнения языков программирования
ном потому, что они разработаны не так давно – когда компьютеры смогли выполнять интерпретацию с разумной скоростью.
Главное достоинство интерпретируемых языков – скорость разработ% ки программ, обусловленная отсутствием промежуточной стадии ком# пиляции; все изменения можно очень быстро проверить. Кроме того, достигается независимость от платформы – интерпретаторы популяр% ных языков работают на многих платформах. Ваша программа сможет работать всюду, куда был перенесен интерпретатор.
Но у интерпретируемых программ есть недостатки: они выполняются медленнее, чем компилированные эквиваленты, поскольку на этапе ис% полнения нужно прочесть, проанализировать, интерпретировать и вы% полнить каждую отдельную команду кода. Это большая работа. Совре% менные машины настолько быстры, что проблемы интерпретации воз% никают только в приложениях, требующих особенно интенсивных вы% числений. Существуют также различные технологии интерпретации, увеличивающие производительность кода: в некоторых языках исход% ные тексты компилируются перед выполнением (что увеличивает вре% мя запуска программы) или применяют компиляцию Just#In#Time (JIT), когда каждая функция компилируется непосредственно перед ее исполнением (что замедляет первое обращение к каждой функции). Для большинства программ такие накладные расходы приемлемы, а работа в режиме JIT%компиляции неотличима от выполнения обыч% ного скомпилированного кода.

240 |
Глава 10. Код, который построил Джек |
Действительно ли мы собираем программы?
«Сборка» часто используется в качестве метафоры программиро% вания, равносильной тому, что происходит в «нормальной» сбо% рочной промышленности. Между ними есть много глубоких па% раллелей, поскольку в том и другом случае мы имеем дело со строительными процессами. И мы действительно наблюдали в известной мере частичное совпадение и сотрудничество между двумя отраслями в виде движения «паттернов программирова% ния» (см. «Шаблоны проектирования» на стр. 334), примером чего служит книга Кристофера Александра (Christopher Alexan% der) об архитектуре (Alexander 79).
Важно понять пределы этой метафоры и ее реальную ценность. В конце концов, нет идеальных метафор. Хотя это абстрактный вопрос, лежащий несколько в стороне, он важен, поскольку срав% нение неизбежно вызовет предвзятость нашего подхода к разра% ботке. Метафора хороша к месту; в иных случаях она может быть неудачна и даже вредна.
Положительное
Как и в физическом процессе строительства здания, мы начи% наем с нуля и осуществляем строительство, помещая слои структуры один на другой. До начала строительства должны быть выполнены сбор технических требований и тщательное проектирование и разработка архитектуры. Можно особенно не заниматься планированием, если нужно построить садовую беседку, но было бы безумием рассчитывать на то, что без предварительного планирования может вырасти небоскреб; для его появления необходимы серьезные предварительные усилия по проектированию и планированию. Здесь параллель с созданием программного обеспечения достаточно близка.
Отрицательное
В остальных областях метафора оказывается довольно сла% бой. Например, базовые уровни программной конструкции модифицировать значительно легче, чем фундамент здания. Гораздо дешевле разрушить программное сооружение, чем физическое. Это говорит о том, что в области программирова% ния возможности создания прототипов и исследования шире, чем в физическом мире.
Строительство реальных сооружений основано на твердых инженерных принципах: они отражены в законодательных актах и предполагают легальную ответственность. Многие фирмы%производители программного обеспечения в глаза не видели никаких инженерных принципов.

Языковые барьеры |
241 |
Самое страшное
В целом процедура разработки похожа на процесс физическо% го строительства, включая в себя замысел системы, проекти% рование, реализацию и пробную эксплуатацию. Но в данной главе мы озабочены несколько иным – компиляцией и проце% дурами, входящими в такого рода строительные задачи. Здесь метафора тоже оказывается не вполне удачной. Каж% дый раз, взяв новый экземпляр исходного кода, вы «строите» его, создавая выполняемую программу – об этом здесь и идет речь. Обратите внимание на два разных употребления терми% на «build» (сборка, строительство).
Процесс построения программного продукта подчинен своим правилам: если вы модифицируете функцию, то должны по% том заново построить систему. В противоположность этому, если вы покрасили двери, вам не нужно заново возводить сте% ны своего дома.
Языки сценариев часто являются интерпретируемыми. У этих языков очень быстрый цикл разработки благодаря терпимому отношению к сомнительному коду (в языке нет строгих правил и слабая типизация) и отсутствию сложных функций. Языки сценариев часто используют% ся в качестве связующей среды для более удобного вызова других ути% лит. Примерами языков сценариев служат сценарии оболочки UNIX, пакетные файлы Windows и Tcl.
Компилируемые языки
В компилируемых языках для преобразования файлов исходного кода
вмашинные инструкции на целевой платформе применяется после% довательность инструментов. Обычно целевая платформа совпадает с платформой разработки, однако разработчики встроенного ПО часто работают на ПК, а целевыми могут быть самые разные машины, для чего применяются кросс#компиляторы. Крупные проекты компилиру% ются поэтапно: отдельные файлы с исходным кодом компилируются
впромежуточные объектные файлы, а затем эти объекты компонуются
вокончательный исполняемый модуль. Эту модель иллюстрирует мета% фора выпекания пирога, показанная на рис. 10.2, где отдельные ингре% диенты (исходные файлы) перемешиваются (компилируются) и нако% нец запекаются все вместе (компонуются).
Из компилируемых языков наиболее популярны C и C++, хотя компи% лируется большинство структурированных языков. Совершенно естест% венно, что скомпилированное приложение будет выполняться быстрее, чем его интерпретируемый аналог (по крайней мере, в отсутствие JIT% компиляции), хотя на практике вы этого не заметите; большинство

242 |
Глава 10. Код, который построил Джек |
Рис. 10.2. Кухня компиляции
приложений не требует интенсивных вычислений и большую часть вре% мени стоит в ожидании данных от пользователя, с диска или от сети.
Для компилируемых языков процедура сборки сложнее, чем при ин% терпретации, поэтому возможностей для возникновения сбоев в них больше. Для каждой платформы, на которой планируется выполнять приложение, оно должно быть скомпилировано отдельно.1
Языки, компилируемые в байтNкоды
Компилируемые в байт%коды языки занимают промежуточное поло% жение между интерпретируемыми и компилируемыми языками. Они предполагают этап компиляции, но не создают обычной исполняемой программы. Результатом является файл, содержащий байт#коды: псевдомашинный язык, который может выполняться на виртуальной машине. Примером таких языков служат Java и C#.
1Целевые платформы различаются по типам процессоров и операционных систем. Могут иметь значение и другие факторы, такие как имеющееся пе% риферийное оборудование.