Б керниган р пайк практика программирования: Книга «Практика программирования» – купить книгу ISBN 978-5-8459-2005-8 с быстрой доставкой в интернет-магазине OZON

Содержание

Практика программирования (Керниган, Б.)

Керниган, Б.

Брайан Керниган и Роб Пайк вложили в книгу «Практика программирования» концентрированный опыт многих лет программирования, преподавания и совместной работы с коллегами. Книга содержит множество практических советов и реальных примеров на языках C, C++, Java и других. Всякий, кому приходится писать программы, почерпнет немало полезного из принципов и рекомендаций, приведенных в книге.

Полная информация о книге

  • Вид товара:Книги
  • Рубрика:Теория и технология программирования
  • Целевое назначение:Производств.
    -практич.изд.,практич.рук-во
  • ISBN:978-5-907144-46-0
  • Серия:Программирование для профессионалов
  • Издательство: Диалектика
  • Год издания:2019
  • Количество страниц:287
  • Формат:70х100/16
  • УДК:681. 3.07
  • Штрихкод:9785907144460
  • Доп. сведения:пер. с англ.
  • Переплет:обл.
  • Сведения об ответственности:Б. Керниган, Р. Пайк
  • Код товара:2451861

СписокЛитературы

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


  • распределить книги и статьи по категориям;
  • определиться с форматом библиографических ссылок (в т. ч. для книжек на английском).

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

Формировать список вручную чрезвычайно утомительное занятие. Стоит подумать над тем, как приспособить для этих нужд существующие препроцессоры библиографических ссылок (refer(1), lookbib(1), indxbib(1) и т. п.), или же написать свой препроцессор, возможно, специфичный для этой вики. Здесь есть над чем подумать.


  • В: Что делать если хочется указать и оригинал и перевод? Указывать дважды?
    • O: В библиографическом описании помимо основного заглавия книги или статьи может присутствовать параллельное заглавие.
      Это заглавие на другом языке. Например, Язык программирования Си = The C Programming Language.

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


При обучении очень важно найти хорошую книгу по теме. На этой странице будут собираться разделённые по тематикам книжки (часть из них доступна в электронном варианте на страничке группы https://vk.com/amplab, часть можно найти в интернете).

  1. Керниган, Б. В. Язык программирования C / Б. В. Керниган, Д.М. Ричи.
  2. Керниган, Б. В. Практика программирования / Б. В. Керниган, Р. Пайк.
  3. Kernighan, B. W. Unix Programming Environment / B. W. Kernighan, R. Pike. — New Jersey : Englewood Cliffs, 1984. — 357 p.
  1. Linden, P. Expert C Programming: Deep C Secrets / P. Linden. — Prentice Hall, 1994. — 353 p.
  1. Marshall, K. M. The Design and Implementation of the 4. 4 BSD Operating System / Kirk Mckusick Marshall, Bostic Keith, J. Karels Michael, S. Quarterman John. — Addison-Wesley, 1996. — 580 p.
  2. Maurice, J. B. The Design of the UNIX Operating System / J. Bach Maurice. — Prentice Hall, 1986. — 471 p.
  1. Parziale, L. TCP/IP Tutorial and Technical Overview / L. Parziale, D. T. Britt, C. Davis. — 2006. — 974 p.
  2. Internetworking Technologies Handbook, 4th Edition / Cisco System Inc. — Cisco Press, 2003. — 1128 p.
  1. Сато, Ю. Цифровая обработка сигналов / Юкио Сато.
  2. Smith, S. W. The Scientist and Engineer’s Guide to Digital Signal Processing. Second edition / S. W. Smith. — San Diego, 1999. — 650 p.
  1. Васильев, А. А. Математикарь. От элементарной математики к высшей / А. А. Васильев, В. Л. Никитенков. — Сыктывкар : Изд-во Сыктывкарского ун-та, 2011. — 110 c.



  • В: предложите свое название для этого подраздела. Исселдование операций — это очень неудачная калька с англ.
    «Operations Research» (амер.) или «Operational Research» (брит.). Сюда запихивают всё: и методы оптимизации, и теорию игр, и теорию расписаний, и теорию графов, etc. —АтрашкевичАндрей
  • О: может быть методы оптимизации? А прочие математически насыщенные темы сделать подразделами Математики. —ЛипинБорис
    • К: сделал, добавил ТИгр как отдельный раздел. А остальное: теорию расписаний, теорию графов и прочие приятные и полезные вещи будем доделывать в процессе. —АтрашкевичАндрей

Разговор не о теории, а о практике | Мир ПК

05.04.2005 Автор: Г.И. Рузайкин

Обучение программированию обычно связывают с овладением приемами написания текстов на том или ином языке программирования. По существу это равносильно ремесленным навыкам перевода с алгоритмического языка на язык программирования. Но даже беглого взгляда на проблемы использования программ достаточно, чтобы обратить внимание на предъявляемые к ним требования, без удовлетворения которых не достичь эффективности в управлении компьютерами. Брайан Керниган и Роб Пайк, авторы книги «Практика программирования», предлагаемой вниманию читателей, считают, что при написании программ необходим следующий подход: соблюдение принципа простоты, т. е. программа должна быть краткой и удобной для доработки; ясности, гарантирующей, что ни у программиста при чтении программы, ни у компьютера при ее исполнении не должно возникать сомнений и двусмысленности; общности, заключающейся в способности программы правильно реагировать на изменение ситуаций в широком диапазоне и при этом адаптироваться к новой обстановке; программа должна служить автоматизации, освобождающей человека от трудоемких рутинных операций. «Практика программирования» — книга, в которой авторы рассматривают искусство программирования — на разных языках и в диапазоне от текста, описывающего алгоритмы и структуры данных, до архитектуры, включая отладку программ, тестирование и повышение быстродействия, — как совокупность универсальных инженерных концепций, независимых от конкретного языка, операционной системы или среды программирования.

Б. Керниган, Р. Пайк Практика программирования М.: Издательский дом «Вильямс». 2004, 288 с.: ил.

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

http://tpop.awl.com, посвященном книге.

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

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

В третьей главе, «Проектирование и реализация», Б. Керниган и Р. Пайк обращают внимание читателей на то, что «проектирование структуры данных является решающим элементом при разработке программ». Здесь рассмотрена архитектура и реализация программы и показана алгоритмизация и структуризация данных в манере, приближенной к практической.

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

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

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

В оставшихся трех главах книги читатель познакомится с практическими приемами повышения быстродействия программ за счет выявления узких мест, настройки кода, оптимизации использования памяти. Делать это, по мнению авторов книги, «стоит, но только если проблема действительно существует: программа работает слишком медленно и есть надежда сделать ее быстрее, при этом сохранив правильность, понятность и надежность». Далее авторы обсуждают проблемы переносимости разработанных программ на другой процессор, компилятор или ОС. Идеальный случай, когда у программы таких проблем не возникает. Практически довольствуются переносимостью, если достаточно модификации программы. Основная мысль, развиваемая авторами относительно переносимости программ: «Постарайтесь писать программу так, чтобы она работала на пересечении нескольких различных стандартов, интерфейсов и сред, к которым она должна приспособиться».

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

«Практика програмирования» написана, по замыслу авторов, для студентов, прослушавших несколько курсов по программированию и вычислительной технике и желающих поднять свой статус в программировании практических задач. Также она может оказаться полезной и для тех, кто пишет программы лишь время от времени. Дело в том, что приведенные в книге сведения позволят повысить эффективность программирования и в этом случае.

Думается, что и широкий круг читателей русского перевода получит несомненную пользу от данной книги.

АЯ, Примат СПбПУ — Лекции

3.21. Объединения

Составной тип — объединения, его назначение. Определение и инициализация, обращение к отдельным элементам. Частичная инициализация. Расположение в памяти, операция sizeof. Варианты использования объединений.

3.22. Сборка программы из нескольких файлов

Стадии трансляции программы на Си: предобработка, компиляция и компоновка. Объявления и определения. Области видимости. Пространства имен. Доступ к переменным и функциям из других файлов, ключевые слова extern и static, внешнее и внутреннее связывание. Заголовочные файлы в Си, проблема повторного включения и её решение. Классы памяти для размещения локальных переменных, ключевые слова auto, register и static.

Глава 4. Практика программирования

Список литературы

  • Керниган, Б. Практика программирования. / Б. Керниган, Р. Пайк. — Вильямс, 2016. — 288 с.

  • Макконнелл, С. Совершенный код. / С. Макконнелл. — Русская Редакция, Microsoft Press, 2017. — 896 с.

  • Ван Тассел, Д. Стиль, разработка, эффективность, отладка и испытание программ. / Д. Ван Тассел. — М.: Мир, 1985. — 334 с.

  • Тэллес, М. Наука отладки. / М. Тэллес, Ю. Хсих — КУДИЦ-Образ, 2003. — 560 с.

4.01*. Искусство программирования и профессиональный подход

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

4.02. Стиль программирования

Программы пишутся не только для машины, но и для человека. Необходимость повышения читаемости программ: совместная разработка, отладка, модификация, повторное использование, поддержка, развитие. Правило №1 при редактировании кода. Визуальные составляющие стиля: форматирование кода, именование идентификаторов, комментирование. Смысловые составляющие стиля: паттерны (шаблоны) для решения стандартных задач. Соглашение об именовании: передача назначения объекта и дополнительных сведений. Способы объединения нескольких слов. Регистр букв, префиксы и суффиксы для передачи мета-информации (тип, вид, область видимости идентификаторов). Комментарий как конструкция языка для внедрения дополнительной информации в исходный код. Зачем? Почему? Как? Что? Краткое изложение кода, объяснение сложных конструкций, алгоритмов, намерений программиста. PDL (Program Design Language) и программирование «сверху вниз». Комментарии как метаданные для инструментария разработки, автодокументация.

4.03. Модульное программирование

Независимые компоненты большой системы. Изоляция частей программы, уменьшение точек соприкосновения: упрощение понимания, уменьшение числа ошибок. Возможность независимого изменения и подмены. Модульность на уровне блоков, функций, файлов. Поддержка модульности в Си.

4.04. Абстрактные типы данных и их реализация в Си

Понятия абстрактного типа данных (АТД) и структуры данных (СД). Техника использования непрозрачных (opaque) типов данных в Си. АТД «стек» и «очередь», интерфейс на языке Си и возможная реализация на массиве.

4.05. Обработка ошибок

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

4.06. Ошибки программиста

Причина ошибок. Статический анализ кода, программа lint и ее аналоги. Семантические проверки во время выполнения: assertions (утверждения) как проверка предположений программиста. Их назначение, стандартные реализации, синтаксис при использовании. Примеры применения, design by contract. Отладочная и финальная конфигурации проекта. Compile-time (static) assertions как проверка предположений во время компиляции программы. Их назначение, стандартная реализация, синтаксис при использовании.

4.07. Собственная реализация механизма утверждений в Си

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

_

4.08. Тестирование и отладка

Классификация видов тестирования по действующему лицу, по виду ошибок, по целевой части программы. Модульное тестирование. Понятие нестабильности и примеры, процесс отладки. Интерактивный отладчик и его возможности. Библиотека crtdbg в Visual Studio.

_

4.09. Профилирование и оптимизация

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

Глава 5. Введение в алгоритмы

Список литературы

  • Кормен, Т. Алгоритмы. Построение и анализ. / Т. Кормен, Ч. Лейзерсон, Р. Ривест, К. Штайн —

  • Вильямс, 2016. — 1328 с.

5.01. Cложность задач и алгоритмов

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

_

5.

02. Задача возведения в целую степень

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

5.03. Задача поиска в массиве

Поиск минимального и максимального элемента. Поиск заданного элемента. Упорядоченные массивы.

_

5.04. Простейшие квадратичные сортировки

Задача сортировки. Свойства и метрики алгоритмов. Сортировка перебором. Сортировка выбором (selection sort) и вариации. Сортировка вставками (insertion sort) и вариации. Сортировка пузырьком (bubble sort) и вариации.

_

5.05. Улучшенные субквадратичные сортировки

Сортировка Шелла (Shell sort) и вариации. Сортировка прочесыванием (гребнем, comb sort). Библиотечная сортировка*** (library sort).

5.

06. Квазилинейные в среднем сортировки

Сортировка слиянием (merge sort) и вариации. Быстрая сортировка (Хоара, quicksort) и вариации. Пирамидальная сортировка (кучей, heapsort) и вариации. Случайные перестановки и их роль в сортировке.

_

5.07. Сортировки за линейное время

Сортировка подсчетом (counting sort). Поразрядная сортировка (цифровая, radix sort). Сортировка вычерпыванием (черпаком, bucket sort).

_

5.08. Cвязный список

Структура данных «связный список». Линейный односвязный список, основные операции и их вычислительная сложность. Альтернативная реализация интерфейса стека и очереди на связных списках. Другие динамически связные структуры: двусвязные списки, бинарные деревья и деревья с произвольным числом детей. Совпадение структур Си для разных структур данных.

_

5.09. Рекурсия и её реализация

Общее понятие рекурсии. Прямая и косвенная рекурсия в математике, пример с факториалом и числами Фибоначчи. Поддержка в языках программирования, возможная реализация, стек вызовов. Достоинства и недостатки рекурсии. Особый вид — хвостовая рекурсия.

Глава 6. Другие языки программирования

6.00. Развитие языков программирования

Язык программирования и исполнитель. Рейтинги языков программирования, востребованные языки. Любимые языки. Интересные языки. Полиглот, квайн, уроборос.

6.01. Многоязычные программы

Программно-аппаратная среда выполнения программ. Компоновка объектного кода в исполняемую программу. Статические и динамические библиотеки. Проблемы совместимости. Преобразование имен, порядок вызова функций и передачи параметров. Типы данных, различия в представлении массивов и строк.

_

_

6.02.

Язык программирования Forth

Виртуальная машина языка Forth. Базовые слова управления стеком. Определение новых слов. Управляющие структуры.

6.03. Язык программирования Scheme

6.04. Куда двигаться дальше

3.23. Существование объектов во времени и в пространстве

Объявления и определения. Области видимости объявлений. Пространства имен. Время и место жизни объектов. Спецификаторы и модификаторы классов памяти.

БОНУС. Контроль версий

Системы контроля версий…

_

📌 Программное окружение UNIX. 🎓 Керниган Б. 🪐

  • — Это список популярных программ, работающих в операционных системах основанных на UNIX (POSIX совместимых). Некоторые из этих программ являются стандартными для UNIX подобных систем. Содержание 1 Системный софт 1.1 Общего назначения …   Википедия

  • Операционное окружение — Возможно, эта статья содержит оригинальное исследование. Добавьте ссылки на источники, в противном случае она может быть выставлена на удаление. Дополнительные сведения могут быть на странице обсуждения. (4 ноября 2011) Операционное окружение… …   Википедия

  • Пайк, Роб — В Википедии есть статьи о других людях с такой фамилией, см. Пайк. Роб Пайк англ. Rob Pike …   Википедия

  • Пайк Р. — Роб Пайк англ. Rob Pike Роб Пайк один из создателей оригинальной Unix Дата рождения: 1956 …   Википедия

  • Пайк Роб — Роб Пайк англ. Rob Pike Роб Пайк один из создателей оригинальной Unix Дата рождения: 1956 …   Википедия

  • Роб Пайк — англ. Rob Pike Роб Пайк один из создателей оригинальной Unix Дата рождения: 1956 …   Википедия

  • Керниган, Брайан — Брайан Уилсон Керниган Brian Wilson Kernighan Место рождения: Торонто, Онтарио, Канада Страна …   Википедия

  • Кёрниган, Брайан — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Брайан Керниган — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Брайан Уильям Керниган — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Брайен Керниган — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Керниган — Керниган, Брайан Брайан Уилсон Керниган (англ. Brian Wilson Kernighan; январь 1942, Торонто, Онтарио, Канада) соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Деннисом Ритчи). Соавтор языка AWK (Alfred Aho,… …   Википедия

  • Керниган, Брайан Уильям — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Керниган Б. — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Керниган Брайан — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • Керниган Брайан Уильям — Брайан Вильсон Керниган (Brian Wilson Kernighan; род. 1942)  соавтор знаменитого руководства «Язык программирования Си» (совместно с автором языка Денисом Ритчи). Соавтор языка Ахо, Питер Вейнбергер, и Брайан Керниган). В соавторстве с Робом… …   Википедия

  • DariaEmacs

    Б. Керниган, Д. Ритчи «Язык C»

    Стивен Прата «Язык программирования С»

    Б. Керниган, Р. Пайк «Практика программирования»

    Брюс Эккель «Философия С++. Введение в стандартный С++»

    Брюс Эккель, Чак Эллисон «Философия С++. Практическое программирование»

    Скотт Майерс » Эффективное использование C++. 50 рекомендаций по улучшению ваших программ и проектов. «

    Скотт Майерс «Эффективное использование STL»

    Скотт Майерс «Эффективный и современный С++: 42 рекомендации по использованию C++11 и C++14»

    Роберт Лафоре «Объектно-ориентированное программирование в С++»

    Б. Страуструп «Программирование. Принципы и практика с использованием C++ «

    Б. Страуструп «Язык программирования C++»

    А. Александреску «Современное проектирование на С++»

    Г. Саттер, А. Александреску «Стандарты программирования на С++. 101 правило и рекомендация»

    Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес «Приемы объектно-ориентированного проектирования. Паттерны проектирования»

    Б. Страуструп «Дизайн и эволюция С++»

    Стивен Прата «Язык программирования С++»

    «Искусство программирования. Основные алгоритмы» Д. Кнут, Том 1

    «Искусство программирования. Получисленные алгоритмы» Д. Кнут, Том 2

    «Искусство программирования. Сортировка и поиск» Д. Кнут, Том 3

    «Искусство программирования. Комбинаторные алгоритмы. Часть 1» Д. Кнут, Том 4А

    «Алгоритмы: построение и анализ», Т. Кормен, Ч. Лейзерсон, Р. Ривест

    «Введение в теорию автоматов, языков и вычислений», Д. Хопкрофт, Р. Мотвани, Дж. Ульман

    «Компиляторы. Принципы, технологии, инструменты», А. Ахо, Р. Сати, Дж. Ульман

    «Философия Java», Брюс Эккель

    «Криптография», Н. Смарт

    «Полный справочник по JavaScript», Т. Пауэл, Ф. Шнайдер

    «Введение в системы Баз Данных», К. Дж. Дейт

    «Операционная система Unix», А. Робачевский

    Э. Таненбаум «Современные операционные системы»

    «Ядро Pnux», Д. Бовет, М. Чезати

    Грейди Буч «UML. Руководство пользователя»

    Шон Уолтон «Создание сетевых приложений в среде Pnux. Руководство разработчика»

    С.В. Зубков «Assembler для DOS, Windows и UNIX»

    Фредерик Брукс «Мифический человеко-месяц»

    Гради Буч «Объектно-ориентированный анализ и проектирование с примерами приложений на С++»

    Что же читать? — Codeforces

    В наши дни существует необычайной количество прекрасных книг о программировании, которые стали классикой, традиционными учебниками для программистов. Так что же все-таки стоит прочитать и в какой последовательности?
    Сейчас я сам столкнулся с тем, что не знаю за что взяться, потому что количество книг, которые я хочу прочитать плавно перевалило за 20…
    Вот, что рекомендует Санкт-Петербургский тренировочный центр:
    • Кормен, Т., Лейзерсон, Ч. , Ривест Р., Штайн К. «Алгоритмы: построение и анализ».
    • Кнут Д. «Искусство программирования».
    • Шень А. А. «Программирование. Теоремы и задачи».
    • Керниган Б., Пайк Р. «Практика программирования».
    • Романовский И. В. «Дискретный анализ».
    • Уоррен Г. «Алгоритмические трюки для программистов».
    • Грехем Р., Кнут Д., Паташник О. «Конкретная математика».
    • Скиена С. С., Ревилла М. А. «Олимпиадные задачи по программированию. Руководство по подготовке к соревнованиям».
    • Меньшиков Ф. В. «Олимпиадные задачи по программированию».
    • Асанов М. О., Баранский В. А., Расин В. В. «Дискретная математика: графы, матроиды, алгоритмы».
    • Гасфилд. Д. «Строки, деревья и последовательности в алгоритмах».
    • Вирт. Н. «Алгоритмы и структуры данных».
    Но есть еще много интересных книг, которые стоило бы почитать:
    • Роберт Седжвик «Фундаментальные алгоритмы на C++».
    • Steven Skiena «The algorithm design manual». Если честно, то именно эта книга и ввела меня в задумчивость. Потому что, немного просмотрев ее, я увидел какое-то сходство с творением Кормена (CLRS, «Алгоритмы: построение и анализ»).
    • И великое множество книг по математике. Ведь математика тоже очень полезна. Этот пункт тоже ввел меня в задумчивость. Литература по линейной алгебре и по аналитической геометрии. По высшей математике.
    Чем больше список, тем больше он дезориентирует.
    Поэтому я рекомендую всем остановиться для начала на списке тренировочного центра. Можно, конечно, добавить к нему Седжвика и еще одну книгу Стивена Скиены, только она полностью на английском.
    Если смотреть только на первый список, то я могу определиться, что читать следующим. Но если добавить еще пару книг, то я в замешательстве.
    Сложно добавить еще что-то к этому звездному составу. Книги по языкам программирования не в счет. Мне больше интересно, может ли кто-нибудь высказаться по поводу моих добавлений к списку. Потому что они сбивают меня с толку и я не могу взять наконец книгу и читать ее.
    Если кто-то хочет, может высказаться о книгах и сказать, в каком порядке он советовал бы их читать.
    Думаю, тем, кто собрался здесь, все эти книги знакомы. Но всегда есть люди, которые только начинают свое знакомство с программированием. В итоге, может получиться неплохое руководство.
    Я, в свою очередь, рекомендую прочитать Кормена, «Конкретную математику» и Стивена Скиену. Ну и все остальное) Потому что все книги очень интересные. Правда, одни сложнее, а другие проще.

    Практика программирования

  • Задание 1: Прочтите главу 1 и ответьте на вопросы 1-1, 1-2, 1-4, 1-5, 1-6, 1-7, 1-9, 1-11. (Для 1-6 сделайте только первая часть, т.е. не экспериментируйте с разными компиляторы.) Решение

    Некоторые комментарии к главе 1.

    Звездный кредит: прокомментируйте данную библиотеку C, которая реализует тип bitvector в стиле doxygen. Детали: Звезда 1

    Срок погашения 7 июня .

  • Назначение 2: Прочтите главу 2 и ответьте на вопросы 2-2, 2-3, 2-5, 2-6, 2-9, 2-12, 2-14, 2-16. (Для 2-9, реализовать его только на C.) Решение 1, Решение 2,

    Некоторые комментарии к главе 2.

    Звездный кредит: напишите код для группировки вершин в неориентированный граф на два непересекающихся множества A и B равного размера при минимальном количестве ребер, которые иметь одну конечную точку в A и одну в B. алгоритм к приведенным примерам. Детали: Звезда 2

    Срок погашения 18 июня .

  • Назначение 3: Прочтите главу 3 и ответьте на вопросы 3-2, 3-3, 3-5, 3-6.Решение

    Некоторые комментарии к главе 3.

    Срок погашения 25 июня .

  • Задание 4: Прочтите главу 4 и ответьте на вопросы 4-8, и напишите критический отзыв о библиотеке CSV реализации в разделе 4.2, и как реализация в Разделе 4.3 касается вашего критика. Решение

    Некоторые комментарии к главе 4.

    Срок погашения июля 2 .

  • Задания 5/6: Прочтите главы 5 и 6. По каждому фрагменту сомнительный код в разделе 5.2 и 5.4, объясните что с этим не так. Сдать ответ на вопрос 6-1. Прочтите экстремальный взгляд на программирование тестирования на http://www.extremeprogramming.org/rules.html и критикуйте это. Решение

    Некоторые комментарии к главе 5-6.

    Срок погашения 9 июля .

    Звездный кредит: напишите набор тестов для универсального массива пакет, который будет предоставлен. Детали: Звезда 3

  • Назначение 7/8: Прочтите главы 7 и 8. Опишите шаги, предпринятые K&P для улучшить производительность примера спам-фильтра в Глава 7.Сдайте ответ к упражнению 7-3. За каждый фрагмент сомнительного кода в главе 8 напишите 1-3 предложения, объясняющие, что с этим не так. (Есть 15 экземпляров сомнительного кода; вы не нужно копировать весь список.)

    Некоторые комментарии к Главе 7-8.

    Звездный кредит: вам будет предоставлен код для реализации хеширования и потребуется для определения узкие места в коде. Детали: Звезда 4

    Срок погашения 23 июля .

  • Назначение 9: Отменено : Прочтите главу 9 и сдайте ответы на вопросы 9-1, 9-3, 9-9, 9-18. Новое задание : Достигните главы 9 и напишите краткое изложение того, что вы узнали — с 1 по 3. абзацев в разделе. Некоторые комментарии.

    Срок погашения 30 июля .

  • Расценки на CS1

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

    Проблема с этим [создание именно того, что вам нужно, вместо того, чтобы планировать заранее] заключается в том, что эти системы начинают сильно усложняться. Пришло время исправить ошибку, добавить функцию, что-то заменить, и вы обнаружить, что все связано с все остальное так, как вы даже не можете понять. Потому что вы делаете что-то более амбициозное, чем первоначальная академическая prototype, он достаточно большой, чтобы его нужно было разделить между командой.Члены команды должны иметь четкое представление о том, как их работа связана с всех остальных, и они должны иметь возможность общаться с тестировщиками, чьи работа — найти ошибки. В противном случае [другими словами] вы делаете пациенту пересадку почки и его сердце внезапно перестает работать; затем вы даете ему сердечное лекарство, но это заставляет его коллапс легких. Вы не знаете почему, но вы облажались.

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

    С каждым новым выпуском эти проблемы усугубляются. К тому времени, как вы выйдете на пятый выпуск, решение сделать свой первый продукт быстрым и грязным способом, вероятно, стоил вам в десять раз больше, чем он изначально сохранен.Программа, подобная Microsoft Windows 98, состоит из десятков миллионов строк кода. Никто не может держать в голове столько сложностей или надеяться справиться с ними эффективно. Итак, вам нужна архитектура, которая говорит всем: «Вот как эта штука работает, и чтобы внести свой вклад, вам нужно понять только эти пять вещей, и не смей трогать ничего другого «.

    — К. Фергюсон (Высокие ставки, без заключенных; Times Business Press, стр. 107-109)

    CPSC 215 — Марк Смотерман

    CPSC 215 — Марк Смотерман

    Этот документ можно найти по адресу http: // www. cs.clemson.edu/~mark/215.html
    Программу факультета можно найти в http://www.cs.clemson.edu/html/syllabi/cpsc215.shtml


    Целей: Изучите разработку программного обеспечения с использованием императивного языка.

    Основные концепции:

    • Императивное программирование на C, включая глобальные функции, автоматические данные и препроцессор
    • Использование указателей и явное выделение / освобождение динамической памяти
    • Методы разработки и тестирования программного обеспечения, такие как отдельные компиляция, заглушки, драйверы и инкрементальная разработка
    • Инструменты разработки программ, такие как отладчики и make-файлы
    • сценарии оболочки UNIX и утилиты, такие как grep
    • Файловый ввод-вывод, включая текстовый, двоичный и случайный ввод-вывод
    • Возможности C ++ недоступны в Java

    Предварительное условие: C или выше в CPSC 212 (CPSC 241)


    Встречи: 12: 20–1: 10 MW в Daniel Hall комната 408
    Позднее прибытие: пожалуйста, подождите до 15 минут, если я опаздываю на занятия.

    Необходимые учебники:
    1. Дейтель Х., Дейтель П., C: Как программировать, 3-е изд., Прентис Холл, 2001, ISBN: 0-13-089572-5. (сайт книги)
    2. С. Сарвар, Р. Корецкий, С. Сарвар, Unix: Учебник, Эддисон-Уэсли Лонгман, 2001, ISBN: 0-201-61260-7. (сайт книги)

    Рекомендуемые профессиональные справочники:
    1. С. Макконнелл, Code Complete, Microsoft Press, 1993, ISBN: 1-55615-484-4. (Оглавление и выдержки)
    2. Б. Керниган, Р.Пайк, Практика программирования, Эддисон-Уэсли, 1999, ISBN 0-201-61586-X. (сайт книги)
    3. Б. Керниган и Д. Ричи, Язык программирования C, 2-е изд. (ANSI-C), Прентис Холл, 1988, ISBN: 0-13-110362-8. (сайт книги)
    4. Б. Страуструп, Язык программирования C ++, 3-е изд., Addison-Wesley Longman, Inc., 1997, ISBN: 0-201-88954-4. (сайт книги)
    5. П. Плаугер, Стандартная библиотека Си, Прентис Холл, 1992, ISBN 0-13-131509-9.

    Инструктор: Mark Smotherman, 441 Edwards Hall, mark @ cs.clemson. edu, 656-5878
    часы работы: 11: 00-12: 00 Пн, Вт, по предварительной записи

    Лабораторий:

    Оценка:

    • Составляющие итоговой оценки:
      • Лабораторная оценка (30%)
      • Программы (7 при 5% = 35%)
      • Экзамены в классе (2 из 10% = 20%)
      • Заключительный экзамен (15%)
    • А 7.Для итоговых оценок будет использоваться пятибалльная шкала для буквенных оценок.
      • от 100 до 93 — А
      • 92 по 85 — B
      • от 84 до 78 — C
      • от 77 до 70 — D
      • ниже 70 — F
    • Кривая может применяться или не применяться к окончательным оценкам.
    • Плохая оценка в лабораторных условиях приведет к плохой оценке по курсу.

    Программ:

    • Программы должны быть отправлены в электронном виде с помощью команды handin. 2-1, где n — количество дней опоздания. Таким образом, программа то есть опоздание на 4 дня будет иметь максимально возможное количество очков 69.

    Посещаемость: Посещаемость занятий не оценивается.

    Дней выпадения: Последний день без записи — 24 января; Последний день без оценок — 2 марта.

    Академическая честность: «Как члены сообщества Университета Клемсона мы унаследовали Взгляд Томаса Грина Клемсона на это учреждение как на высшую семинарию обучения.«В основе этого видения лежит взаимная приверженность правдивость, честь и ответственность, без которых мы не можем заработать доверие и уважение окружающих. Кроме того, мы признаем, что академические нечестность снижает ценность степени Клемсона. Поэтому мы не потерпит лжи, обмана или воровства в любой форме ».

    из Политика академической честности

    • Любое нарушение принципов, изложенных в Академической честности Заявление считается актом академической нечестности.
    • Академическая нечестность далее определяется как:
      • Предоставление, получение или использование несанкционированной помощи в любой учебной работе;
      • Плагиат, включающий копирование языка, структуры или идеи других и приписывание работы своим собственным усилиям;
      • Попытки скопировать, отредактировать или удалить компьютерные файлы, принадлежащие другое лицо или использование номеров учетных записей Компьютерного центра, которые принадлежать другому лицу без разрешения владельца файла, владелец аккаунта или владелец номера файла;
    • Все академические работы, представленные на оценку, содержат неявное обещание и может содержать, по запросу инструктора, явное обязательство со стороны студент, что не было получено посторонней помощи.
    • Ответственность за это несет каждый член Университета Клемсона. сообщества, чтобы обеспечить соблюдение Политики академической честности.

    См. Также заявление отдела.

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


    Весна 2001 г. Примерное расписание

    месяц M W класс категория тема (текст) лаборатория тема (текст)
    Янв 10 Класс 01 C введение, UNIX, C, C ++, Java (DD 1,2) (без лаборатории)
    15 без класса, день MLK
    17 Класс 02 C ввод / вывод, функции (DD 2,5) Lab 01 Команды UNIX (SKS 4,9)
    22 Класс 03 C массивы, указатели (DD 6,7)
    24 Класс 04 SW-1 разработка программного обеспечения, тестирование Lab 02 редакторы (СКС 5)
    29 Класс 05 SW-1 отдельная компиляция, make-файлы (SKS 20)
    ПРОГРАММА 1 ВЫПОЛНЕНА: реализация стека на основе массива с использованием тестового драйвера (используйте handin. 215.2 1 имя файла) схема оценок
    31 Класс 06 C обработка строк, ввод / вывод (DD 8,9) Lab 03 электронная почта (SKS 6)
    фев 5 Класс 07 C структура, объединение (DD 10)
    7 Класс 08 C распределение динамической памяти, связанные списки (DD 12) Lab 04 Файловая система UNIX (SKS 7,8)
    ПРОГРАММА 2 ДО 2/12/01: калькулятор со стеком с использованием makefile (используйте handin.215.2 2 файла) схема оценок
    12 Класс 09 C cpp, va_arg (), параметры командной строки (DD 13,14)
    14 Класс 10 C другие стандартные библиотечные процедуры (DD 14) Lab 05 оболочка, труба, перенаправление (SKS 4,12)
    ПРОГРАММА 3 ОТ 23. 02.01: диспетчер очередей с использованием двусвязных списков и тестового драйвера (используйте handin.215.2 3 файла)
    19 11 ** ПЕРВЫЙ ЭКЗАМЕН ** Учебное пособие
    21 Класс 12 GUI Графические интерфейсы, программы, управляемые событиями, GTK + (Интернет) Lab 06 доп.обработка файлов, регулярное выражение (SKS 10)
    26 Класс 13 GUI упаковочные коробки, этикетки, краски (рулон)
    28 Класс 14 GUI нажатие клавиш, дополнительные виджеты (Интернет) Лаборатория 07 процессов (SKS 13)
    ПРОГРАММА 4, ВЫПОЛНЕННАЯ 3/2/01: калькулятор с использованием администратора очередей (используйте handin. 215.2 4 файла)
    мар 5 Класс 15 SW-2 отладка
    7 Класс 16 SW-2 снаряды (СКС 4,17,18) Lab 08 отладчики (SKS 20)
    12 Класс 17 SW-2 версионирование, упаковка (СКС 20)
    14 Класс 18 IO Файлы UNIX, потоковый ввод-вывод, перенаправление (SKS 7,8,12) Lab 09 снарядов (СКС 15-18)
    ПРОГРАММА 5 ОТ 16.03.01: Калькулятор GUI (используйте handin.215.2 5 имя файла) схема оценок
    19 без класса, Пружинный перерыв
    21 без класса, Пружинный перерыв
    26 Класс 19 IO форматированный vs. двоичный ввод / вывод (DD 11)
    28 Класс 20 IO последовательный и случайный ввод / вывод (DD 11) Лаборатория 10 Удаленное использование (SKS 14)
    апр 2 Класс 21 IO низкоуровневый (небуферизованный) ввод / вывод (DD 11)
    4 Класс 22 ** ВТОРОЙ ЭКЗАМЕН ** учебное пособие Lab 11 упаковка / конфигурация / установка (SKS 19)
    9 Класс 23 C ++ введение в C ++, классы (DD 15,16)
    11 Класс 24 C ++ константа, друг, новое / удаление, контейнеры, итераторы, STL (DD 17) Lab 12 версиями (SKS 20)
    ПРОГРАММА 6 ОТ 13. 04.01: Просмотрщик изображений GUI (используйте handin.215.2 6 имя файла) схема оценок
    16 Класс 25 C ++ перегрузочные, конструкторы (ДД 18)
    18 Класс 26 C ++ наследование, полиморфизм (DD 19,20) Лаборатория 13 Xwindows (SKS 21)
    23 Класс 27 C ++ потоки, шаблоны, исключения (DD 21,22,23)
    25 Класс 28 оценка, обзор Lab 14 ** LAB FINAL **
    (ДОПОЛНИТЕЛЬНЫЙ КРЕДИТ) ПРОГРАММА 7 ОТ 27. 04.01: калькулятор на C ++ (используйте handin.215.2 7 имя файла) схема оценок
    30 Класс 29 ** ЗАКЛЮЧИТЕЛЬНЫЙ ЭКЗАМЕН — понедельник, 30 апреля, 1-4 апреля ** Учебное пособие

    Изучение C после Java ...
     
            Представьте, что нет классов,
            Сделать это несложно.
            Нет объектов для отправки сообщений
            Ссылок тоже нет
            Представьте себе все методы
            Статический, и у вас есть C.О-хо, ты можешь сказать, что это кошмар
            И ты не единственный
            Но у языка есть свои применения
            И как Java может быть весело.
    
    Дэвид Арноу ([email protected])
    (с: http://www.cs.columbia.edu/~evs/songs/othersongs.html)
     

    Веб-страницы на vi


    Веб-страницы на C


    Веб-страницы с рекомендациями по кодированию


    веб-страниц на C99


    веб-страниц на C ++


    веб-страниц на C ++ STL


    Веб-страницы по сравнению Java и C / C ++


    веб-страниц, посвященных графическому интерфейсу пользователя и особенноGTK +


    Веб-страниц на языках сценариев


    Интернет-страниц по истории


    [Домашняя страница Марка] [Домашняя страница CPSC] [Clemson Univ. домашняя страница]

    [email protected]

    CS 251: Список книг

    CS 251: Список книг

    Необходимые книги

    Бентли, Джон Луи. Жемчуг программирования . Чтение, Массачусетс: Эддисон-Уэсли, 2000.
    Доступен прекрасный обзор принципов и практики программирования. мелкими кусочками.Для курса требуется только часть I. вы можете предпочесть прочитать это в библиотеке.

    Керниган, Брайан В. и Пайк, Роб. Практика программирования . Ридинг, Массачусетс: Эддисон-Уэсли, c1999.
    Лучшая доступная книга « глубины » — она ​​выбирает несколько важных темы и раскрывает их подробно. Написано мастером программисты из Bell Labs (иногда называемые Умный канадец Программисты).

    Хант, Эндрю и Томас, Дэвид. Прагматичный программист: от подмастерья до мастера .Ридинг, Массачусетс: Эддисон-Уэсли, c2000.
    Прекрасная « обширная » книга, в которой больше внимания уделяется процессу и отношениям, чем подробности программирования. Я выбрал его из-за множества полезных принципов и грамотный и практический подход к программным средствам .

    Рекомендуемые книги

    Бек, Кент. Объяснение экстремального программирования: примите изменения . Ридинг, Массачусетс: Эддисон-Уэсли, c2000.
    Манифест нынешнего увлечения программным процессом. Я воспринимаю экстремальное программирование как негативную реакцию против супертяжеловеса, неэффективный программный процесс 1970-х и 1980-х годов.Есть несколько интересных практики программирования, один или два из которых мы подадим в классе. В сети много материала, но книга все еще Рекомендовано для тех, кто интересуется процессом программирования.

    Хэнсон, Дэвид Р. Интерфейсы C и реализация: методы создания программного обеспечения многократного использования . Addison-Wesley Longman, Incorporated, август 1996 г.
    Настоятельно рекомендуется для всех, кто будет использовать C, и может быть полезным и для C ++. Все советуют использовать код повторно.Советую повторно использовать код Хэнсона.

    Гамма, Хелм, Влиссидес и Джонсон. Паттерны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования . Ридинг, Массачусетс: Эддисон-Уэсли, c1995.
    Сочетание хорошей практики программирования, нового словаря и пластыри от бородавок на C ++. Рекомендуется для тех, кто использует C ++ или Java. (Словарь стал неотъемлемой частью объектно-ориентированного сообщества.)

    Керниган, Брайан В. и Пайк, Роб. Среда программирования UNIX .Энглвуд Клиффс, Нью-Джерси: Прентис-Холл, c1984.
    Еще содержательные советы мастеров. Лучшее краткое введение в Unix. Настоятельно рекомендуется для тех, у кого ограниченный опыт работы с Unix.

    Лисков, Б. и Гуттаг, Джон. Разработка программ на Java: абстракция, спецификации и объектно-ориентированный дизайн . Бостон: Аддисон-Уэсли, c2001.
    Не так много интересных вещей, как в предыдущей книге, но все же очень хорошая и лучшая обработка абстракции данных, которую я знаю в печати. Рекомендуется для тех, кто использует Java или C ++ или не уверен в их навыки.

    Другие рекомендуемые книги

    Бентли, Джон Луи. Еще жемчужины программирования: признания программиста . Чтение, Массачусетс: Аддисон-Уэсли Паб. Co, c 1988 г.
    Еще колонки Bentley от CACM.

    Брукс, Фредерик П. Мифический человеко-месяц: очерки программной инженерии . Чтение, Массачусетс: Аддисон-Уэсли Паб. Co, [1975].
    Классическая книга о том, почему программные проекты терпят неудачу.

    Джексон, Майкл. Требования и спецификации к программному обеспечению: Практический словарь, Принципы и предрассудки . Addison-Wesley Longman, Incorporated, август 1995 г.
    Что происходит перед кодированием? Что происходит в реальных магазинах программного обеспечения? Как нам думать о программном обеспечении? В этом сборнике коротких эссе, Джексон отвечает на эти и многие другие вопросы. Настоятельно рекомендуется для тех, кто хочет узнать больше о программная инженерия.

    Керниган, Брайан В. и Плаугер, П.Дж. Элементы стиля программирования . Нью-Йорк: Макгроу-Хилл, c1978.
    Отличная классика, использующая улучшение плохих примеров для иллюстрируют неподвластные времени принципы построения программы. Распечатано, но Керниган, возможно, сможет поставить это в сети.

    Лисков, Барбара и Джон Гуттаг. 1986 г. Абстракция и конкретизация в разработке программ . MIT Press / McGraw-Hill.
    Лучшее введение в абстрактные типы данных. Также хороший введение в соответствующие формальные методы.к несчастью из печати. Приведенная выше книга по Java — лучшая альтернатива.

    Стив МакКоннелл, Код завершен. Microsoft Press, 1992 ?.
    (Отказ от ответственности: я не прочитал всю книгу.) Я не уверен, что согласен с презентацией (начиная с процедур а не модули или данные), но эта книга очень тщательная и конкретный, хотя и довольно длинный. Книгу очень рекомендуют люди, которых я уважаю, и я рекомендую для тех, кто прилагает много усилий, чтобы получить просто плохие или адекватные результаты, особенно если вы не уверены, что что нужно делать, чтобы стать лучше. Также рекомендовал для тех, кому нравится все прописанное шаг шаг за шагом.

    Ван дер Линден, Питер. Эксперт C-программирование: глубокие секреты C . Энглвуд Клиффс, Нью-Джерси: SunSoft Press, 1994.
    Одна из самых забавных компьютерных книг, которые я когда-либо читал. Настоятельно рекомендуется , если вы не уверены в своих навыках C.

    Справочный материал

    Керниган, Брайан В. и Деннис М. Ричи. Язык программирования C . Второе издание. Энглвуд Клиффс, Нью-Джерси: Прентис-Холл, 1988.
    Чтобы познакомиться с C, прочтите оригинал (и все еще лучший).

    Харбисон, Сэмюэл П. и Гай Л. Стил-младший. C: Справочное руководство . Четвертый выпуск. Энглвуд Клиффс, Нью-Джерси: Prentice Hall, 1995.
    Любимый справочник серьезных программистов на C.

    Джонс, Ричард и Рафаэль Линс. Сборка мусора: алгоритмы автоматического управления динамической памятью . Нью-Йорк, Нью-Йорк, США: Wiley, 1996. Перепечатано в 1999 году с улучшенным индексом и исправленными опечатками.
    Прекрасный справочник по сборке мусора.

    Левин, Джон Р. Линкеры и загрузчики . Сан-Франциско: Морган Кауфманн, c2000.
    Неизменные принципы, лежащие в основе линкеров и загрузчиков.

    Плаугер, П. Дж. Стандартная библиотека C . Энглвуд Клиффс, Нью-Джерси: Prentice Hall, 1992.
    Справочник по библиотеке — с кодом!

    Книги по разработке программного обеспечения

    Гленфорд Дж. Майерс, Композитный / Структурированный дизайн, Ван Ностранд Рейнхольд, 1978.
    Менее известная работа по структурированному дизайну.

    Гленфорд Дж. Майерс, Надежное программное обеспечение через композитный дизайн, Van Ностранд Рейнхольд, 1975.
    Ранняя работа Майерса, которая есть у нас в Гарварде.

    Эд Юрдон и Ларри Л. Константин. Структурированный дизайн: основы Дисциплины компьютерных программ и системного проектирования . Энглвудские скалы, Нью-Джерси: Prentice Hall, 1979.
    Наиболее известная работа по структурированному дизайну.

    Магистерские работы мастеров-программистов

    Кнут, Стэнфордская база данных GraphBase.
    Коллекция алгоритмов графа и вспомогательных библиотек, все написаны как грамотные программы. Самый доступный из грамотных программ Кнута. Рекомендуем для тех, кто хочет проникнуться взглядом Кнута на мир.

    Кнут, TeX: Программа.
    Полный исходный код TeX, написанный грамотно. Наверное, наиболее поучительно из-за очень внимательного отношения к портативность; этот код работает на удивительном разнообразии компьютеров и операционные системы, включая машины, которые даже не поддерживают ASCII! Рекомендуем для тех, кто любит стиль Кнута и хочет проект.

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

    Фрейзер, Кристофер В. и Дэвид Р. Хэнсон. Перенастраиваемый компилятор C: разработка и реализация . Редвуд-Сити, Калифорния: Бенджамин / Каммингс, 1991.
    Очень почти полная картина производственного компилятора C. Этот компилятор активно использовался до прихода Linux и gcc. мир.Использует те же методы грамотного программирования, которые мы используем в классе. Настоятельно рекомендуется для тех, кто будет писать компилятор в C или кто хочет глубокого понимания того, как работает C.

    Интервью с Деннисом Ричи, Бьярном Страуструпом, Джеймсом Гослингом

    Семейство языков C: Интервью с Деннисом Ричи, Бьярном Страуструпом и Джеймсом Гослингом

    Эта статья появилась в Java Report, 5 (7), июль 2000 г. и C ++ Report, 12 (7), июль / август 2000 г. .

    Семейство языков C — C, C ++ и Java — доминирует в коммерческом программировании более 30 лет. Сегодня все три языка переживают поворотный момент:

    o Второй стандарт ISO / ANSI C был только что опубликован (C99 был официально выпущен в декабре 1999 года). C продолжает оставаться одним из самых влиятельных языков в мире, особенно в области встроенных систем.

    o Первое официальное обновление стандарта ISO / ANSI C ++ будет завершено в октябре 2000 года.C ++ — один из наиболее широко используемых коммерческих языков программирования в мире, с беспрецедентной поддержкой как объектно-ориентированного, так и универсального программирования, и продолжает стабильно расти.

    o Популярность Java продолжает расти в различных областях, от программирования на стороне клиента до программирования на стороне сервера. Sun недавно решила, что Java может лучше всего развиваться как стандарт де-факто, а не как формальный стандарт ISO / ANSI или ECMA, и отказалась от формальных усилий по стандартизации.

    Что сделало семейство языков C таким доминирующим? Что мы можем ожидать в ближайшем будущем в этих и родственных им языках? Это знаковое интервью о «состоянии союза», опубликованное одновременно в этом месяце в отчетах C ++ Report и Java Report , объединяет трех легенд, которые вряд ли нуждаются в представлении: Денниса Ричи, Бьярна Страуструпа и Джеймса Гослинга, создателей C , C ++ и Java.

    Оглядываясь назад: откуда мы?

    В: Почему семейство языков C стало настолько успешным и широко используемым?

    Деннис Ричи: Для меня всегда было загадкой, чтобы я мог разбираться в деталях. Очевидно, что использование C [1] в ранние времена (имеется в виду 1970-е и большая часть 80-х) значительно поощрялось его использованием в качестве lingua franca Unix в период, когда Unix рос в исследовательское и академическое сообщество, а затем, когда Unix была принята в качестве основы программного обеспечения для индустрии рабочих станций в 80-х.Это, в свою очередь, было отчасти связано с неполитической природой C и Unix (не привязанной к мощи компьютерного оборудования до 1984 года). Были также технические и полутехнические аспекты: язык оказался подходящим как для описания вещей на достаточно высоком уровне, так что переносимость между аппаратными средствами была возможной, но достаточно простой в своих требованиях, чтобы сделать его дешевым в реализации.

    Бьярн Страуструп: C и C ++ стали популярными, потому что они были гибкими, дешевыми и более эффективными, чем альтернативы.Своей первоначальной популярностью C во многом обязан популярности Unix. C ++ во многом обязан своей первоначальной популярностью своей высокой степени совместимости с C.

    Очень важным успехом C и C ++ было то, что AT&T не пыталась монополизировать эти языки, но позволила своим исследователям поддержать создание альтернативных реализаций. Кроме того, AT&T полностью поддержала стандартизацию ANSI и ISO для C и C ++, как только эти усилия были начаты. Систематического маркетинга C или C ++ не существовало до того, как они стали устоявшимися языками, и несколько поставщиков не начали конкурировать.Это некоммерческое распространение C и C ++ сильно привлекло многих программистов.

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

    Я подозреваю, что корень многих различий между C / C ++ и Java заключается в том, что AT&T в первую очередь является пользователем (потребителем) компьютеров, языков и инструментов, тогда как Sun в первую очередь является поставщиком таких вещей.

    Напомню: C и C ++ были изобретены в Исследовательском центре компьютерных наук Bell Labs в Мюррей-Хилле и нашли свое первоначальное серьезное применение в Bell Labs и AT&T. Тогда Bell labs была отделением исследований и разработок AT&T. Теперь часть Bell Labs является отделом исследований и разработок Lucent, а часть осталась в AT&T под названием «AT&T Labs».»

    Ни один из этих языков не отличался радикально или значительно лучше других современных языков. Однако они были достаточно хороши и выиграли от удачи и» социальных «факторов, таких как Unix, низкая цена, маркетинг (только Java) и т. Д.

    Среди технических факторов преимущества C и C ++ заключаются в их близости к машине и отсутствии искусственных ограничений на то, что может быть выражено. Это позволяет выполнять работу низкоуровневых систем на этих языках и обеспечивать полную производительность машины. своим пользователям.Java выиграла от работы на собственной виртуальной машине и от наличия большого набора библиотек, которые сокращают время, необходимое программисту, чтобы стать продуктивным. Unix дала аналогичный импульс развитию C. В отличие от этого, мир C ++ страдает от фрагментации своей огромной базы библиотек, многие из которых являются собственными и поставляются конкурирующими поставщиками.

    Джеймс Гослинг: Я думаю, что причина номер один в том, что это вообще очень прагматичная семья языков. По большому счету, это не были эксперименты в области языкового дизайна; они были собраны как инструменты людьми, которые хотели сделать что-то еще.C был в значительной степени обусловлен написанием операционной системы Unix и всех утилит в ней, поэтому многие вещи, которые есть в C, напрямую связаны с тем, что требуется для создания эффективной операционной системы, а также с тем, что требуется для сделайте это на машине с 32К.

    В: Каковы были ваши основные первоначальные цели при разработке [C / C ++ / Java]? Какие проблемы должен был решать язык? Какие проблемы не предназначался для решения языка?

    Ritchie: Суть C (в отличие от своего непосредственного предшественника B) заключалась в том, чтобы взять язык, который был разработан с учетом машин, ориентированных на слова, и адаптировать его к более новому аппаратному обеспечению, которое стало доступным, в частности, PDP -11.Не потребовалось много времени, чтобы понять, что те вещи, которые были введены на раннем этапе, также сделают его адаптируемым к самым разным машинам.

    Страуструп: Моей первоначальной целью для C ++ был язык, на котором я мог бы писать программы, такие же элегантные, как программы Simula, но столь же эффективные, как программы на C.

    Проекты, которые я рассматривал в то время, были связаны с распределением функций и приложений операционных систем между несколькими компьютерами в локальной сети. Я должен был учитывать как сложность всей системы, так и эффективность объектов самого низкого уровня.Объектно-ориентированные средства Simula помогли с первым, а средства системного программирования C — со вторым.

    Gosling: Как и C, цели Java на самом деле заключались в том, чтобы создавать относительно определенные виды программного обеспечения, и мы действительно стремились к очень распределенным, очень надежным программам, взаимодействующим с людьми, — таким, где такие вещи, как Надежность имела огромное значение, такие вещи, как безопасность, имели огромное значение, и все они имели достаточно большое значение, чтобы было желание понизить производительность для них.

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

    И все же, если вы попытаетесь сделать что-то вроде того, что делает Java, где очень строгое отношение к модели памяти, вы получите некоторое снижение производительности. Оказывается, с достаточно хорошими оптимизирующими компиляторами потери производительности могут стать почти неизмеримо маленькими, но для этого требуется высококачественный компилятор, а 20 лет назад никто не создавал компиляторы, которые выполняли бы такую ​​оптимизацию, как сегодня. Цели в отношении безопасности и надежности привели к различиям, которые вызвали проблемы с производительностью, которые можно было восстановить только с помощью высококачественных компиляторов, и большая часть оригинального дизайна C была мотивирована тем, что «из чего можно получить код хорошего качества без действительно великолепных? оптимизирующий компилятор. «

    Вопрос: Как эти цели для [C / C ++ / Java] изменились с течением времени, если вообще изменились? Почему?

    Ричи: Мои собственные цели для C не сильно изменились в много лет, и я не был центральным игроком в изменениях стандартов 1989 или 1999. Стандарт ANSI и ISO 1989 года кодифицировал вещи значительно лучше, чем наш исходный документ; наиболее важным введением было то, что я должен был сделать раньше on (прототипы функций).Между прочим, самая ранняя работа Бьярна над тем, что стало C ++, вероятно, оказала самое важное прямое влияние на это.

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

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

    Более общий ответ: я попытался задокументировать свои цели и соображения по дизайну для C ++ в The Design and Evolution of C ++ . [2] Здесь можно задать вопросы о том, почему C ++ такой, какой он есть, и почему он не пошел по другому правдоподобному пути.

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

    Q: Когда вы проектировали [C / C ++ / Java], какие функции было сложнее всего реализовать правильно или какие функции сложнее всего создать так, чтобы их приняли ваши первоначальные пользователи?

    Ричи: В общем, возникает вопрос, что вставить, а что оставить.Вероятно, самым странным аспектом C по сравнению с другими языками, не входящими в его непосредственное семейство, является синтаксис объявления, в котором (в некотором роде из Фортрана) упоминается тип, а затем переменные оформляются таким образом, чтобы отражать их использование в выражениях. Многим это не нравится, поэтому вопрос о том, правильно ли я понял.

    Тесно связанным аспектом является обработка массивов и указателей. Учитывая постоянство вопросов по этому поводу и искажения, через которые проходит C ++, чтобы отойти от C в этом вопросе, это вполне может быть сочтено ошибкой.

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

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

    Шаблоны потребовалось много времени, чтобы получить правильные и достаточно полные формы. В некотором смысле, их разработка началась с моих (в основном неудачных) экспериментов с макросами в «C с классами».«Легко спроектировать средство параметризованного типа, которое удовлетворяет базовую потребность в статической типобезопасности контейнеров. Обеспечить гибкость и эффективность, которые я считаю необходимыми, гораздо сложнее и требует экспериментов и обратной связи от реального использования. Общее программирование, как в настоящее время практикуется в Стандартном C ++, выходит за рамки того, что большинство людей считало возможным (особенно в языке, который нацелен на бескомпромиссную эффективность). Я предполагаю, что в этой области мы увидим значительный прогресс в следующие несколько лет — и где языковые возможности могут быть необходимо для поддержки новых методов.

    Gosling: Было много действительно серьезных проблем с дизайном, и они были повсюду. К примеру, те, которые действительно интересовали людей, включали идею о том, что в Java есть такая вещь, которая называется интерфейсом. Большая часть дизайна интерфейсов была довольно просто заимствована из Objective C, и у нее есть свои плюсы и минусы, и это был действительно сложный баланс.

    Вопрос: Вы когда-нибудь добавляли функции, которые ваши пользователи не ценили так сильно, как вы, а затем вынуждены были отказаться от них или удалить их позже? Что вы узнали из опыта?

    Ritchie: Я добавил некоторые вещи под давлением пользователей, которые, как мне кажется, были выполнены плохо.Типы перечисления немного странные, битовые поля более странные. Ключевое слово static очень странно, оно выражает как время жизни хранилища, так и то, что в стандарте называется «привязкой» (внешней видимостью). Здесь и там есть много странностей.

    Я не могу вспомнить функции, которые я добавил, которые мне пришлось удалить, за исключением некоторых крошечных битов, таких как ключевое слово «entry».

    Страуструп: Когда я разрабатывал C с классами и C ++, мне очень нравилась идея, что класс определяет среду, в которой работает код его функций-членов (я все еще так считаю). Это привело к понятию конструкторов, которые устанавливают эту среду (инвариантную) и получают необходимые ресурсы. Деструкторы обращают этот процесс вспять (высвобождая ресурсы). Эти идеи лежат в основе дизайна исключений и управления ресурсами. Например, см. Новое Приложение E: «Безопасность исключений стандартной библиотеки» к Язык программирования C ++ . [3] Это приложение можно загрузить с моих домашних страниц. [4]

    Основываясь на этом образе мышления, C с классами также позволил вам определить функцию call (), которая вызывалась перед входом в функцию-член, и функцию return (), которая вызывалась после выхода из функция-член.Механизм call () / return () был разработан, чтобы позволить программисту управлять ресурсами, необходимыми для вызова отдельной функции-члена. Это позволило мне реализовать мониторы для первой библиотеки задач. Вызов задачи () захватил блокировку, а соответствующий ей return () снял блокировку. Идея частично пришла из методов Lisp: before и: after. Однако это понятие не было совершенно общим — например, вы не могли получить доступ к аргументам для вызова функции-члена из call (). Хуже того, мне совершенно не удалось убедить людей в полезности этого понятия, поэтому я удалил call () и return () при определении C ++.

    Недавно я повторно рассмотрел эту проблему и написал шаблон на стандартном C ++, который обертывает вызовы объекта произвольным префиксом и суффиксом. Документ, описывающий это, Обертывание вызовов функций-членов C ++ , появился в прошлом месяце в выпуске отчета C ++ Report . [5]

    Я попытался что-то сделать с синтаксисом декларатора. Я рассматривал возможность использования postfix -> как альтернативу postfix * и экспериментировал с тем, чтобы имя появлялось в альтернативных местах в последовательности декларатора.Например:

    int (* p) [10]; // указатель на массив int
    int p -> [10]; // альтернатива
    int -> [10] p; // альтернатива
    -> [10] int p; // альтернатива
    p: -> [10] int; // альтернатива

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

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

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

    В: Если бы вы могли вернуться в прошлое, зная то, что знаете сейчас, что бы вы сделали по-другому при проектировании [C / C ++ / Java]? Почему?

    Ричи: Очевидно, не было никаких гигантских ошибок. Конечно, есть много аспектов, которые я бы по крайней мере переосмыслил (некоторые подробно описаны выше).

    Страуструп: Вы никогда не сможете вернуться, и делать что-то снова бессмысленно.

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

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

    Гослинг: Есть много вещей, которые я бы сделал иначе. Есть ряд вещей, которые меня не совсем устраивают, и неясно, какой ответ правильный. Я не очень доволен расколом между интерфейсами и классами; во многих отношениях кажется, что правильное решение не помешает.

    Было много вещей — например, множественные возвращаемые значения — которые в наши дни я как бы хотел добавить. Это был тот момент, когда мне действительно понравилась эта функция, и большинство людей просто сказали: «А?» Еще одно, что вроде как пошло по этому пути, заключалось в том, что я шел по этому пути, имея кучу вещей, связанных с предусловиями, постусловиями и утверждениями в стиле Эйфеля, и фактически в сообществе людей, которые использовали его в в то время средний ответ был: «А? Зачем мне вообще это?» Я думаю, что средний разработчик сегодня тоже так сказал бы. Но есть довольно разумная толпа людей, которые верят в такие вещи, как Дизайн по контракту, и это одна из тех вещей, где многие люди думают: «Если бы только остальной мир был достаточно образован, чтобы понять, о чем идет речь, им будет лучше «. И я действительно с этим согласен. Проблема в том, что большая часть мира на самом деле меньше заботится.

    Есть некоторые вещи, которые меня беспокоят, например, перегрузка оператора. Я не стал рассматривать перегрузку операторов как довольно личный выбор, потому что видел слишком много людей, злоупотребляющих ею в C ++.За последние пять-шесть лет я провел много времени, опрашивая людей о перегрузке операторов, и это действительно увлекательно, потому что вы разбиваете сообщество на три части: примерно от 20 до 30 процентов населения считают перегрузку операторов порождение дьявола; кто-то сделал что-то с перегрузкой операторов, что их просто помешало, потому что они использовали что-то вроде + для вставки списка, и это действительно очень запутало жизнь. Большая часть этой проблемы проистекает из того факта, что есть только около полдюжины операторов, которые можно разумно перегрузить, и все же есть тысячи или миллионы операторов, которые люди хотели бы определить, поэтому вам нужно выбирать, и часто выбор противоречит вашей интуиции.Кроме того, есть около 10% сообщества, которое на самом деле использовало перегрузку операторов должным образом и действительно заботится об этом, и для кого это действительно важно; это почти исключительно люди, которые работают с числами, где обозначения очень важны для обращения к интуиции людей, потому что они приходят к ним с интуицией о том, что означает +, и способностью сказать «a + b», где a и b комплексные числа или матрицы, или что-то действительно имеет смысл. Когда вы дойдете до таких вещей, как умножение, вы почувствуете себя немного шатко, потому что на самом деле существует несколько видов операторов умножения — есть векторное произведение и скалярное произведение, которые в корне очень разные. А оператор только один, так что же делать? И нет оператора для извлечения квадратного корня. Эти два лагеря — полюса, а еще есть каша в середине 60 с лишним процентов, которым все равно. Лагерь людей, которые думают, что перегрузка операторов — это плохая идея, просто по моей неофициальной статистической выборке был значительно больше и, безусловно, более громким, чем числители. Итак, учитывая то, как все пошло сегодня, когда некоторые функции языка голосуются сообществом — это не просто какой-то небольшой комитет по стандартам, это действительно масштабно — было бы довольно сложно добиться перегрузки оператора в.И все же это оставляет это единственное сообщество довольно важных людей полностью закрытым. Это оттенок трагедии общественной проблемы.

    Использование языков

    В: По вашему опыту, какие ошибки чаще всего допускают разработчики в [C / C ++ / Java]?

    Ричи: Я действительно не знаю ответа на этот вопрос. Я бы предположил, что ошибки низкого уровня связаны с ошибками типов, особенно с индексами массива и ссылками на указатели. Хотя правила о том, что вы можете делать, довольно ясны, реализации обычно мало проверяют ..

    Я также рискну предположить, что действительно большие проблемы связаны с не продумыванием крупномасштабной структуры больших систем: что видно где, наименование вещей, кто что может изменить. Сам по себе C очень мало помогает вам здесь; вам нужно разработать схему.

    Страуструп: Использование C ++ так же, как если бы это был C или Smalltalk. Это приводит к серьезно неоптимальному C ++.Чтобы правильно использовать C ++, вы должны принять некоторые собственные стили C ++. Их обычно выделяют небольшие конкретные классы и шаблоны. Стиль программирования, на который слишком сильно влияет C, имеет тенденцию использовать множество массивов, умные манипуляции с указателями, приведение типов и макросы, а не стандартные библиотечные средства (такие как векторы, строки и карты). Стиль программирования, на который слишком сильно влияет Smalltalk, пытается втиснуть каждый класс в иерархию и чрезмерно использовать приведение типов (и часто макросы). В любом случае ключевые абстракции имеют тенденцию исчезать в беспорядке деталей реализации, и люди (без надобности) связывают себя узлами с распределением, указателями, приведениями и макросами.

    Одна распространенная ошибка, которая меня особенно раздражает, — это использование сложных базовых классов с большим количеством элементов данных в качестве части интерфейсов, предлагаемых разработчикам приложений (пользователям). Абстрактные базовые классы значительно улучшают интерфейсы для служб. Я пытался искоренить такие злоупотребления более десяти лет: я добавил абстрактные классы в 1989 году после того, как не смог донести идею без поддержки явной языковой функции.

    Идея действительно проста:

    интерфейс класса {// видят пользователи
    // чистые виртуальные функции
    };

    class my_implementation: открытый интерфейс {
    // данные
    // функции
    // замещающие функции
    };

    Когда пользовательский код видит только «интерфейс», он невосприимчив к изменениям в «my_implementation. «

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

    класс общий {// виден разработчикам
    // данные
    // функции
    };

    class my_implementation: открытый интерфейс, защищенный общий {
    // данные
    // функции
    // замещающие функции
    };

    класс your_implementation: открытый интерфейс, защищенный общий {
    // данные
    // функции
    // замещающие функции
    };

    Это одно из простейших и наиболее фундаментальных применений множественного наследования.

    То, что многим людям нужно, чтобы получить намного больше от C ++, — это не новые функции, это просто более подходящий стиль дизайна и программирования. Я написал несколько статей по этому поводу (см. Мою страницу с «бумагами» среди моих домашних страниц). В частности, Изучение стандартного C ++ как нового языка [6] сравнивает простые упражнения, выполненные в стилях C и C ++.

    Gosling: Вероятно, самая распространенная ошибка — не делать со вкусом объектно-ориентированного программирования.Есть люди, которые этого совсем не понимают, которые просто выполняют какие-то процедурные вещи и пишут свою программу как один огромный класс с множеством методов; они пытаются сделать это в стиле C. Еще есть люди, которые говорят: «Ооо, объекты! Они классные! Давайте сделаем из них миллионы!» На самом деле, это кажется почти ошибкой образовательной системы, потому что если вы посмотрите, чему учили много детей, только что окончивших колледж, это: «Объекты хороши, определите многие из них!» Итак, вы получаете программы с бесчисленным множеством маленьких адаптеров, с методами длиной в одну или две строки, вы начинаете их профилировать, а они все свое время тратят на диспетчеризацию методов.Тогда единственные виды оптимизирующих компиляторов, которые приносят хоть какую-то пользу, — это те, которые тратят почти все свое время, пытаясь исключить отправку методов и выполняя много полного встраивания.

    Вопрос: По вашему опыту, сколько времени нужно начинающему программисту, чтобы стать достаточно опытным разработчиком [C / C ++ / Java], способным писать нетривиальный производственный код? Как долго программист с опытом работы на одном или нескольких других языках? Как можно сократить это время?

    Ричи: Я тоже не знаю ответа на этот вопрос — моя обычная шутка по поводу подобных: «Ну, мне никогда не приходилось учить C…. «

    Stroustrup: Это в значительной степени зависит от опыта новичка, сложности задачи, которая была впервые решена с помощью C ++, и от подхода к преподаванию / обучению.

    Для начинающего программиста год и половина кажется подходящей; для программиста, который не знаком с C ++ и поддерживаемыми им методами, полгода кажется более вероятным. Ясно, что я говорю о времени, необходимом для реального использования возможностей языка в важном приложении. напишите «Hello world», и его кузенов, очевидно, можно будет сделать за несколько минут.

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

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

    Gosling: Я знаю, что для кого-то, кто является довольно талантливым программистом на C ++, день в значительной степени делает это для многих людей. Вы, вероятно, потратите много времени на изучение руководства по библиотеке. Сам язык выучить несложно; это все библиотечные вещи, которые требуют времени, и лучший способ сделать это — просто начать писать и использовать это, а когда вам что-то нужно, ищите это.

    Для людей, которые никогда раньше не писали программы, я не знаю. Произошел интересный феномен: раньше стандартным первым языком, которому людей учили в колледже, был Паскаль. Во многом это связано с тем, что Паскаль был относительно простым и чистым, но также и потому, что, когда что-то идет не так в Паскале, они имеют тенденцию идти не так, как надо, более очевидным образом.Простая проверка указателей и проверка границ массива составляет огромную часть ошибок, которые допускают начинающие программисты, поэтому на курсах первого года обучения, как правило, в значительной степени преобладает Паскаль. C появился позже только потому, что в C так легко делать глупые вещи; так легко иметь массив и писать «for (i = 1; i <= length; . ..)», и вы должны объяснять: «нет, это не меньше или равно length, и это не 1, это 0 и это меньше. » Но, конечно, ваш цикл работает нормально, только, может быть, иногда вы обнаружите, что вы ударяете по заголовку malloc блока, следующего за массивом, и никто никогда вам об этом не сказал.Система вас не преследовала, но программа выйдет из строя по-разному, потому что очень легко повредить чужие структуры данных, и поэтому этот фрагмент программы выглядит так, как будто он работает нормально, этот фрагмент выглядит так, как будто он сломан, но этот фрагмент работает со структурами данных, которые были повреждены первым фрагментом. Это невероятно распространено в C и C ++ или в любом языке, не имеющем действительно строгой модели памяти. В последние несколько лет люди на самом деле много обучают Java в качестве первого курса, потому что он обладает большой безопасностью, что упрощает преподавание начального курса, плюс, в отличие от Паскаля, это то, что действительно коммерчески актуально как карьера. .

    Взгляд в будущее: куда мы идем?

    Вопрос: Отсутствуют ли какие-либо важные функции в семействе языков C? Из [C / C ++ / Java]?

    Страуструп: В каком смысле C, C ++ и Java составляют семейство языков? C и C ++ имеют большое общее подмножество, и на протяжении многих лет были предприняты серьезные усилия, чтобы минимизировать неизбежную тенденцию двух языков к разделению, поскольку они контролируются отдельными органами по стандартизации.Однако Java не обеспечивает реальной совместимости, и аналогичные синтаксические конструкции имеют семантику, отличную от версий C и C ++. Ясно, что Java заимствует C и C ++, но внутренне сходство с Modula-3 кажется большим.

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

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

    Если вы посмотрите журналы RFE для Java, на самом деле есть только две функции, которые люди просят, чтобы они появлялись с какой-либо частотой: одна — это утверждения, и на самом деле есть группа, работающая над добавлением утверждений в Java прямо сейчас.Другой — полиморфизм типов, что-то вроде шаблонов, а в Java прямо сейчас есть что-то вроде системы шаблонов для бедняков, в которой иерархия типов имеет общий корень для всего и вся, а именно Object, но есть также группа, работающая над правильным работа полиморфизма типов в Java. Оказывается, это действительно сложная проблема. Одна из причин, по которой я упустил полиморфизм типов в Java, хотя я считаю это хорошей идеей, заключается в том, что в академических кругах было много споров о том, как это сделать.Вы найдете множество людей, у которых есть очень твердые мнения, и очень сложно найти что-то вроде консенсуса. Другие проблемы яснее: сборка мусора — хорошая идея; goto — плохая идея.

    Я думаю, что сами языки для общего применения на самом деле довольно полны. Я думаю, что интересными областями являются более специализированные, и у этого есть две развилки: одна — это специализация с точки зрения создания большего количества библиотек, и сегодня для Java создается больше библиотек, которые любой может перечислить.Другой — языковые особенности для определенных сообществ. На самом деле я думаю о перегрузке операторов, которая очень важна для людей, выполняющих числовую работу. Люди, занимающиеся бизнесом, могут действительно привести достаточно веские аргументы в пользу функций, которые выглядят немного в стиле COBOL, например, связанных с запросами к базе данных. Если вы создаете запросы к базе данных с использованием JDBC API, это будет немного неуклюже, так же как создание арифметических выражений становится немного неуклюжим.В некотором смысле, чтобы сделать его неуклюжим более глубоким, система должна понимать обозначения для баз данных и математики.

    В: Все языки меняются со временем, и наличие большой установленной базы пользователей может как стимулировать, так и сдерживать такие изменения. Как [C / C ++ / Java] удалось изменить от выпуска к выпуску? Что вы узнали о ключевых моментах или методах успешного создания улучшений, если у вас есть большая установленная база программистов?

    Ritchie: Я узнал, что это ужасно сложно, и что люди, связанные с успешными языками, могут стать безумно консервативными независимо от их общих наклонностей.Проблема в том, что после того, как есть установленная база, даже «совместимое снизу вверх» расширение может стать настоящей проблемой для многих. Программы, использующие расширение, не могут обрабатываться теми, кто еще не был вынужден обновиться. Если им повезет, новый синтаксис, по крайней мере, укажет на проблемы, потому что старый компилятор его не примет. Если им не повезет, они столкнутся с загадочными проблемами, потому что новый язык точно определяет то, что раньше не было определено, и новая программа зависит от этой определенности поведения.

    Страуструп: Я думаю, что идеальная стратегия для эволюции — это провести обширные эксперименты перед внесением изменений, точно определить новые функции таким образом, чтобы не сделать старый код недействительным, и сделать их доступными повсюду. Затем, через год или два предупредите о старых (запрещенных или устаревших) функциях, а через год или два удалите эти функции. К сожалению, эта стратегия требует координации между всеми поставщиками.

    Старые реализации были серьезным препятствием для стиля программирования C ++, потому что они не позволяли людям, которым нужен переносимый код, использовать новейшие средства (в этом контексте «недавний» иногда означает «изобретенный менее 10 лет назад»). Похоже, что стандарт и желание основных пользователей использовать стандартную библиотеку теперь создают значительные стимулы для разработчиков, чтобы они соответствовали требованиям, а для пользователей — для перехода на современные реализации.

    Развитие языка программирования и его реализаций по своей сути затруднено, потому что разные люди придают разное значение запуску старого кода без изменений. Раньше я считал совместимость ссылок гораздо более важной, чем совместимость источников. Я не так уверен. У многих организаций нет ресурсов, чтобы исправить сломанный старый код (даже там, где он всегда был сломан).Это говорит в пользу использования параметров компилятора для управления вариациями совместимости.

    Я не поклонник опций компилятора для управления вариациями совместимости и предупреждений, но для некоторых они необходимы. Однако настройка по умолчанию для всех компиляторов C ++ должна полностью соответствовать ISO C ++, и отклонения от этого должны быть несколько неприятными. К сожалению, люди, которые больше заботятся о сроках доставки, чем о качестве кода и подлинной переносимости, склонны выступать за язык, который можно бесконечно изменять с помощью параметров, при этом по умолчанию используется совместимость с ошибками с некоторыми основными поставщиками.

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

    Затем есть несовместимые изменения, которые меняют смысл существующего кода. Если изменение меняет значение чего-либо в библиотеке, почти всегда ответом будет изменение имени. Самые первые библиотеки ввода-вывода читали и записывали байты, и это было главным образом потому, что у нас не было много времени, чтобы делать это правильно. На самом деле им следовало работать с символами, а не с байтами; существует огромная разница между символом и байтом, и они связаны с интернационализацией и кодировками файлов, а также с ISO this или ANSI that, или UTF-7, или UTF-8 и всем остальным, что делает его намного более сложным.Поэтому вместо того, чтобы изменять семантику входных и выходных потоков, мы фактически создали новые классы, называемые читателями и писателями, и оставили старые там для людей, которые хотели их использовать, а новые — для людей, которые хотели к ним адаптироваться.

    С библиотеками это в большинстве случаев сойдет с рук. Есть места, где это сделать действительно сложно. В потоках возникали все эти вопросы: «Что значит остановить поток? Убить поток?» и есть много кандидатских диссертаций, которые нужно написать на тему «Что такое thread.kill () означает? «, потому что он затрагивает самую суть целого ряда действительно острых проблем. И многие системы, включая Java прямо из коробки, имели это определение того, что значит убить поток, которое было довольно целесообразным и добрым. of проигнорировал кучу проблем. По мере поступления сообщений об ошибках стало действительно ясно, что вся идея уничтожения потока — плохая идея.

    Q: Какие вещи вы бы хотели видеть частью [C / C ++ / Java] в ближайшие 2–5 лет? В следующие 10 лет? Почему?

    Ritchie: Для C новый стандарт 1999 г. существует, но не стал легкодоступным, и в нем есть несколько изменений по сравнению с более ранние, но не революционные.Я думаю, ему нужно на некоторое время остановиться.

    Страуструп: Я думаю, что упор при развитии C ++ должен быть сделан на создании библиотек. Я надеюсь, что следующий стандарт будет в первую очередь касаться предоставления дополнительных возможностей в стандартной библиотеке, и что изменения языка возникнут в первую очередь из-за потребностей таких возможностей.

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

    Очевидно, что многих беспокоит параллелизм и интерфейсы с различными системами (например, графический интерфейс, базы данных, операционные системы, другие языки, модели компонентов). Это [] наиболее вероятная область работы, и создание и поддержание согласованности будет основной проблемой.Например, будет важно обеспечить единообразное представление текста из C ++. Если одни интерфейсы используют строки в стиле C, другие — строку стандартной библиотеки, а третьи — представления строк, полученных из систем, к которым осуществляется интерфейс, — это рецепт хаоса. Я предлагаю сделать стандартную библиотечную строку основой для всех привязок C ++ к «другим системам». В общем, нам нужен согласованный взгляд на управление ресурсами, чтобы пронизывать стандартную библиотеку.

    В: Есть ли место и / или рыночный спрос на новый язык в семействе C?

    Ritchie: Сложно представить язык, который был бы почти похож на C, но достаточно лучше, чтобы его заменить.Это зависит от того, что подразумевается под «семейством C». Означает ли это «использует {}»? «Называет тип в начале объявления»?

    Stroustrup: Я думаю, что сообществу пользователей лучше всего будет обслуживать единый язык, обеспечивающий низкоуровневую поддержку системного программирования. Я думаю, что C ++ здесь будет хорошо работать, и я не вижу технических проблем при слиянии C и C ++. Но я вижу много политических проблем. Продавцы / поставщики любят множество языков и диалектов, так что они могут претендовать на преимущества для своего варианта и закреплять своих пользователей. Кроме того, каждая организация стремится увековечить себя, поэтому я не вижу, чтобы ни один из языков, диалектов и вариантов мирно умирал.

    Java не поддерживает низкоуровневое системное программирование, поэтому она должна полагаться на другие языки (например, ассемблер, C или C ++). И наоборот, чтобы C или C ++ были полезны для безопасной загрузки на другую машину, нам нужна либо поддержка оборудования (мое предпочтительное долгосрочное решение для всех языков), либо виртуальная машина C ++ (да, такие звери существуют), либо прорыв в программе. проверка (я не задерживаю дыхание).

    Итак, есть ли место для другого языка помимо C, C ++ и Java? Конечно, есть место для большего количества языков. Вопрос в том, следует ли считать такие языки частью семьи. Кроме того, новый язык следует создавать только при наличии серьезных проблем, которые нельзя решить с помощью существующих языков. Языки и диалекты, которые предоставляют пользователям лишь незначительные удобства, просто фрагментируют сообщество и отвлекают ресурсы, которые можно было бы использовать для общего блага.

    Гослинг: Да, конечно.Я не знаю, что вы называете «языком в этой семье». Есть ли язык, в котором используются фигурные скобки, в семействе C? AWK принадлежит семейству C? Вы можете назвать AWK в семействе C. И мне бы хотелось думать, что есть место для большего количества языков; принадлежат ли они к семейству C или нет, почти не имеет значения.

    Одной из настоящих трагедий за годы до появления Java было то, что исследования языков программирования почти прекратились во всем мире. Затем появилась Java, и она действительно имела успех. Когда я учился в университетах, я получил много комментариев: «Ого, вы действительно узаконили все изучение языков программирования.«Я думаю, что это было бы трагическим заявлением о вселенной, если бы Java была последним языком, который пронесся мимо. Я надеюсь, что появятся некоторые новые, более интересные парадигмы, и буду ли я участвовать в этом или нет, кто знает. Было бы хорошо, если бы мир не ждал еще 20 лет. Может быть, еще пять лет было бы неплохо, чтобы получить некоторую стабильность, потому что изменение языка программирования похоже на изменение базовой генетической структуры организма. Это примерно так же глубоко в ядре ремесла программирования, так что это действительно сложно изменить.

    Вопрос: Какие типы приложений лучше всего подходят для [C / C ++ / Java]? Какие нет?

    Страуструп: Без поддержки библиотек большинство серьезных приложений на C ++ излишне сложно. С подходящими библиотеками большинство из них довольно просто. C ++ имеет неотъемлемую силу в приложениях с системным компонентом, особенно там, где есть ограничения на ресурсы (такие как время выполнения и память). Исходя из этого, C ++ обеспечивает значительную поддержку для организации более крупных программ для упрощения обслуживания и развития.

    При соответствующей поддержке библиотеками C ++ может стать отличным языком обучения. В концепции обучения важно начинать с современного C ++, а не увлекать студентов старыми стилями. См. «Изучение стандартного C ++ как нового языка» (этот документ можно загрузить с моих домашних страниц). В преподавании величайшая сила C ++, вероятно, состоит в том, что он позволяет студенту познакомиться с множеством техник, которые могут быть применены к реальным проблемам.

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

    Вопрос: Становятся ли языки легче или сложнее в изучении и использовании? Видите ли вы какие-либо тенденции к прогрессивному использованию C, C ++ и Java по мере появления этих языков и / или добавления новых функций с течением времени?

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

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

    Мне кажется, что С ++ и Java проходят разные курсы в том, что касается эволюции стиля и языка.Можно было ожидать, что интенсивное использование библиотек сведет к минимуму это расхождение, но с современными библиотеками C ++, делающими упор на сложное использование шаблонов, и современными библиотеками Java, делающими упор на внутренние классы, это, похоже, не так.

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

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

    Для меня важнее всего то, что сложность систем, которые мы все создаем, с каждым днем ​​становится все больше и больше.Безусловно, все оборудование, на котором мы строим эти вещи, управляется каким-то видом или производным от закона Мура. Создаваемые нами программные системы не имеют ничего подобного, но они определенно становятся более сложными — и довольно быстро. Как вы строите большие сложные системы? Есть много вещей, которые мы не очень хорошо понимаем, и я думаю, что на самом деле многие из них выходят за рамки того, что люди обычно считают языком программирования.

    Один из моих любимых примеров в наши дни — алгоритм рисования линий Брезенхема.Вы берете любую книгу по графике первого года, и в ней описывается алгоритм Брезенхэма для рисования линии, он состоит примерно из пяти утверждений, делает то, что делает, и это довольно просто. Вы идете и смотрите на любую промышленную реализацию алгоритма Брезенхема, и это тысячи, если не десятки тысяч строк. Почему он такой большой? Почему такая сложность заключается в том, что на самом деле очень простой алгоритм? Многое связано с различными частными случаями, с пониманием того, что происходит под машиной, таких как размер строки кэша; у этой машины есть строки кэша шириной 16 байт? Шириной 8 байт? 32 байта в ширину? В конечном итоге вы захотите по-другому оптимизировать внутренний цикл. Какая разрядность пикселя? Вы про 1-битные пиксели? 8-битные пиксели? 16-битные пиксели? 15-битные пиксели? Вы рисуете пиксель? XOR для пикселя? альфа-смешивание пикселя? Многие из этих вещей на самом деле могут быть выражены в терминах преобразований алгоритмов, и около 10 лет назад я выполнил проект, построив систему, которая была своего рода макро-препроцессором для C, но больше походила на средство доказательства теорем. Это был своего рода препроцессор макросов на семантическом графе, и вы могли писать макросы на семантическом графе.Вы могли написать преобразования алгоритмов, и поэтому вы действительно могли написать алгоритм Брезенхема в пять строк, выразить преобразования и довести его до промышленной версии. Одним из больших преимуществ такого подхода является то, что вы лучше понимаете, правильно это или нет, и вся проблема тестирования и настройки становится намного проще. И все же, это вопрос языка программирования или среды программирования? В некотором смысле вы вообще не изменили семантику языка с точки зрения того, что вы можете делать. Вы изменили то, как вы это говорите, и манипулируете не столько текстом программы, сколько семантическим графом. В подобных вещах просто огромная территория. Эта система, которую я построил, использовалась для многих графических алгоритмов Sun, но у меня была огромная проблема: я не мог заставить людей понять, что она делает. Это было очень странно, и с его помощью можно было написать несколько очень крутых программ, но заставить людей понять, что значит проводить доказательство теорем как часть построения нового алгоритма, было довольно сложно.При разработке многих языков программирования речь идет не столько о том, «Что такое крутая функция? Что соответствует каким-то модным академическим критериям?». Это действительно вопрос: «Что подходит разработчикам?»

    Персональные настройки

    В: У всех нас разные причины, по которым мы решили работать в индустрии программного обеспечения. Что привлекло вас в области программного обеспечения? Что делает его крутым?

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

    Страуструп: Я не совсем уверен, что привело меня к компьютерам. Я рассматривал компьютеры как практический и полезный выход для научных интересов. Мне очень нравится строить. Когда вы строите, вы получаете отзывы от инструментов, от программы / системы и от пользователей. Это то, что выталкивает воображение за пределы очевидного и предвзятого мнения и доктрины отдельного человека, академической области или организации. Мне нравится идея Кристен Найгаард о программировании как о средстве понимания чего-либо.

    Gosling: Я не знаю, что такое моя генетическая структура, но мне просто нравится строить вещи. В некотором смысле, создаю ли я программное обеспечение, создаю стул или готовлю обед — также известный как кулинария — я получаю удовольствие от простого создания вещей. Одна из замечательных особенностей программного обеспечения заключается в том, что вы можете создавать самые удивительно сложные сложные вещи, и вы можете делать это довольно быстро. Если бы я был часовщиком, уверен, я бы разочаровался в том, насколько сложно было создавать вещи с большим количеством шестерен и шкивов; И все же, просто глядя на хорошие часы, снимаешь заднюю часть, и это так здорово.Я не знаю, почему это круто, мне просто кажется, что это круто. С помощью программного обеспечения вы можете поместить туда столько шестерен, кулачков и всего, что вам нужно, и все становится просто сложным. В некотором смысле то, что мне больше всего нравится в программном обеспечении, — это то, с чем я в конечном итоге трачу большую часть своего времени на борьбу, а именно на сложность.

    В: Какой язык программирования вы использовали в первую очередь?

    Ричи: Я не могу точно определить время. Более или менее одновременно, примерно в 1962 году, я пошел на лекцию о Коболе (написанную Джин Саммет) и прошел курс, который включал программирование аналоговых компьютеров с использованием коммутационной панели и написание машинного языка Univac I (без ассемблера).Примерно в это же время я посетил офис IBM в Кембридже (Массачусетс), и они дали мне руководства по Фортрану, которые я с удовольствием прочитал.

    Страуструп: Моим первым языком программирования был Algol60 на компьютере GIER. GIER был датским компьютером 1960-х годов с 1K 42-битными (я думаю, плюс несколько дополнительных битов для тестирования оборудования) словами.

    Gosling: Первым языком программирования, который я когда-либо использовал, был язык под названием Focal 5. Focal расшифровывалось как «вычисление формул». Это был язык сценариев для PDP-8. Я писал большинство своих первых программ, используя Focal 5. Это язык, полный компилятор и исполняющая система которого могут быть реализованы менее чем за 24 часа. На самом деле это хороший маленький язык, намного проще, чем Basic.

    В: Какие языки или особенности языков вдохновили вас?

    Stroustrup: Помимо Simula67, моим любимым языком в то время был Algol68. Я думаю, что «Алгол68 с классами» был бы лучшим языком, чем «Си с классами».«Однако это было бы мертворожденным.

    Gosling: Они повсюду. При использовании Lisp больше всего на меня повлияла невероятная разница в сборке мусора. Используя Simula и будучи местным сопровождающим Компилятор Simula был тем, что познакомил меня с объектами и заставил задуматься об объектах. Использование таких языков, как Паскаль, заставило меня серьезно задуматься о моделировании. Такие языки, как Modula-3, действительно подтолкнули меня к таким вещам, как механизмы исключения. Я использовал множество языков, и многие из них оказали влияние. Вы можете просмотреть все на Java и сказать: «это пришло оттуда, а это пришло оттуда».

    В: Какую первую программу вы написали? На каком железе?

    Ritchie: Как и выше, первой на реальном компьютере была программа Univac I. (Как я узнал через год или около того, на самом деле упражнения заключались в реализации некоторых операторов APL — примерно в то время был Айверсон).

    Страуструп: Я не припомню, но это должно быть какое-то 101 упражнение по информатике в Algol60 на компьютере GIER.Первые программы, которые я сделал по-настоящему, то есть для использования другими, были бизнес-программами, написанными на ассемблере для офисных компьютеров Burroughs. Так я профинансировал большую часть датской степени магистра.

    В: Существует ли язык программирования, который лучше всего подходит для разработки всех (или почти всех) приложений? Если да, то на каком это языке и что лучше всего? Если нет, то что нужно для создания такого языка?

    Ричи: Нет, это глупо.

    Страуструп: No.Люди слишком различаются для этого и их приложения слишком разнятся. Идея идеального и почти идеального языка — мечта незрелых программистов и маркетологов. Естественно, каждый разработчик языков старается как укрепить свой язык, чтобы лучше служить основному сообществу, так и расширить его привлекательность, но быть всем для всех — не разумный идеал. Есть подлинный выбор дизайна и компромиссы, которые необходимо сделать.

    В: Программисты часто говорят о преимуществах и недостатках программирования на «простом языке».«Что эта фраза означает для вас, и является ли [C / C ++ / Java] простым языком, с вашей точки зрения?

    Ritchie: C (и другие в этом отношении) в некотором смысле просты, хотя они также тонкий; другие, несколько похожие языки, такие как Паскаль, возможно, проще. Стало ясно, что такие аспекты среды, как библиотеки, которые не являются частью основного языка, намного больше и сложнее. Стандарт C 1999 года значительно вырос в часть библиотеки, чем в языке; C ++ STL и другие вещи большие; AWT и другие вещи, связанные с Java, тоже.

    Страуструп: Я вижу три очевидных понятия «простой»: быть легким для изучения, облегчить выражение идей и иметь однозначное соответствие некоторой математической форме. В этом смысле ни один из трех языков не является простым. Однако после освоения C и C ++ можно легко выражать довольно сложные и продвинутые идеи, особенно когда эти идеи должны быть выражены в условиях реальных ограничений ресурсов.

    Вопрос: Какие темы, по вашему мнению, отсутствуют в университетских программах по информатике и инженерии по всему миру, которые помогли бы улучшить качество программного обеспечения?

    Страуструп: На некоторых уважаемых факультетах информатики вы можете получить высшее образование, не написав никакого кода.Это невозможно. Никто не должен получать диплом по информатике или компьютерной инженерии, не выполнив значительного проекта по программированию. Код — это основа вычислений, и люди, не «разбирающиеся» в коде, склонны серьезно недооценивать, какие навыки, инструменты и время необходимы для создания хороших систем.

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

    Нет, я не утверждаю, что надо просто учить хакерству. Я выступаю за баланс между теоретическими и практическими навыками. Другая часть образовательного учреждения сталкивается с противоположной проблемой. Они обучают людей (только) практическим навыкам, а не обучают их.

    В: Какие языки, помимо семейства C, вам нравятся больше всего? Что, в частности, делает их интересными для вас?

    Ритчи: Я восхищаюсь языками вроде Лиспа. Но, как и в предыдущем вопросе о «простом» языке, на практике удивительно простой язык превращается во что-то устрашающее.

    Страуструп: На ум приходят Algol68, CLOS и ML. В каждом случае меня привлекает гибкость и несколько очень элегантных примеров кода.

    В: Какие ваши любимые книги по программному обеспечению?

    Ритчи: Это подержанное самообслуживание, но работы Кернигана и Пайка (по отдельности или вместе) хороши. [7] [8] В некотором смысле мне нравятся старые Керниган и Плаугер по стилю программирования [9] лучше всего, хотя бы по той простой причине, что брать программы, опубликованные в других местах, и показывать, насколько они плохи.Больше всего мне понравилась книга Бена Росса Шнайдера «Путешествие в компьютерную страну» , [10] , которая тоже устарела, и сейчас ее трудно достать.

    Страуструп: Брукс Месяц мифического человека , [11] Объектно-ориентированный дизайн Booch , [12] и шаблоны дизайна Gamma et. al. . [13]

    В: Если бы вы могли порекомендовать две книги по [C / C ++ / Java] помимо вашей, что бы это были и почему?

    Страуструп: Шаблоны проектирования снова для людей, стремящихся к гибкости.В дополнение, я хотел бы порекомендовать книгу, посвященную эффективности, но я не знаю той, которая мне полностью подходит. Для многих людей Ruminations on C ++ [16] Кенига и Му окажут ценную услугу, поколебав их предубеждения о том, что такое C ++ и чем может быть.

    Стандарты языков программирования

    В: Важно ли иметь формальный стандарт (например, ISO / ANSI) для языка программирования? Каковы преимущества? Недостатки?

    Ritchie: В какой-то момент становится необходимым формальный стандарт, особенно для языков, которые развились неформально (конечно, C, но также C ++ и Java).Процесс действительно имеет тенденцию несколько уточнить, а также вносит в таблицу некоторые изменения или расширения, которые могли предвидеть другие, помимо дизайнеров. Письменный стандарт также дает организациям (во всех секторах) определенную уверенность в том, что их технический персонал, который может быть увлечен языком или другим программным обеспечением, не просто следует какой-то волеизъявлению. Этот процесс имеет определенную серьезность.

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

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

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

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

    Вопрос: Важно ли иметь фактический стандарт для языка программирования? Каковы преимущества? Недостатки?

    Stroustrup: Стандарт де-факто является большим преимуществом для его владельца и его друзей / союзников.Это также может принести пользу третьим сторонам, таким как профессора, студенты и небольшие компании. Пока корпорация, владеющая «стандартом» де-факто, находится в процессе устранения альтернатив, инструменты и поддержка, как правило, дешевы, а влияние маркетинга влияет на интеллектуальную и деловую атмосферу. Позже цена повышается.

    Вопрос: Что вы узнали, изучая стандарты [C / C ++ / Java]?

    Страуструп: Достижение консенсуса утомительно и необходимо. Люди и организации действительно хотят поступать «правильно», учитывая половину шанса. Политические проблемы не решаются. Способ решения политической проблемы состоит в том, чтобы найти техническую проблему в ее основе и вместо этого решить ее. Тогда политическая проблема исчезнет.

    Индустрия программного обеспечения «Century 21»

    В: Прогнозирование сложно, но ценно, даже если оно никогда не может быть точным на 100%. На ваш взгляд, каковы основные движущие силы того программного обеспечения, которое мы будем писать в будущем? и как мы будем писать это программное обеспечение?

    Ritchie: Наиболее очевидное изменение, которое произошло в последнее время, — это рост использования «языков сценариев», которые обычно интерпретируются.Они варьируются от базовых, таких как HTML, до Perl, Tcl / Tk и Javascript, а затем до пакетов презентационной графики для создания WWW-страниц или слайдов.

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

    Страуструп: Будущее? в наши дни почти невозможно даже описать настоящее.

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

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

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

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

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

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

    Примечания

    1. Б. Керниган и Д. Ричи. Язык программирования C, 2-е издание (Прентис Холл, 1998) ISBN 0131103709.

    2. Б. Страуструп. Дизайн и развитие C ++ (Аддисон-Уэсли, 1994) ISBN 0201543303.

    3. Б. Страуструп. Язык программирования C ++, специальный выпуск (Addison-Wesley, 2000) ISBN 0201700735.

    4. http://www.research.att.com/~bs.

    5. Б. Страуструп. «Обертка вызовов функций-членов C ++» ( Отчет о C ++ , 12 (6), июнь 2000 г.).

    6. Б. Страуструп. «Изучение стандартного C ++ как нового языка» ( C / C ++ Users Journal , май 1999; также в CVu 12 (1) январь 2000).

    7.Б. Керниган и Р. Пайк. Практика программирования (Аддисон-Уэсли, 1999) ISBN 020161586X.

    8. Б. Керниган и Р. Пайк. Среда программирования UNIX (Прентис Холл, 1984) ISBN 013937681X.

    9. Б. Керниган и П. Дж. Плаугер. Элементы стиля программирования (Макгроу-Хилл, 1988) ISBN 0070342075.

    10. Б. Шнайдер. Путешествия в компьютерной сфере: Или несовместимости и интерфейсы: полный и достоверный отчет о реализации Лондонского информационного банка Stage , ASIN 0201067374.

    11. Ф. Брукс. Мифический человеко-месяц: Очерки программной инженерии (Аддисон-Уэсли, 1995) ISBN 0201835959.

    12. Г. Буч. Объектно-ориентированный анализ и дизайн с приложениями (Аддисон-Уэсли, 1994) ISBN 0805353402.

    13. Э. Гамма, Р. Хелм, Р. Джонсон и Дж. Влиссидес. Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования (Аддисон-Уэсли, 1995) ISBN 0201633612.

    14. Дж. Бентли. Programming Pearls, Second Edition (Addison-Wesley, 1999) ISBN 0201657880.

    15. Р. Седжвик. Алгоритмы на языке C, 3-е издание (Addison-Wesley, 2000) ISBN 0201849372. (Седжвик выпустил не менее десяти книг «Алгоритмы», охватывающих различные области применения или специализированных для разных языков программирования. Это одна из недавно написанных / обновл.)

    16. А. Кениг и Б. Му. Размышления о C ++ (Аддисон-Уэсли, 1996) ISBN 0201423391.

    % PDF-1.3 % 2 0 obj > endobj 3755 0 объект > поток 2013-08-01T14: 35: 41-08: 002013-08-02T11: 29: 38-07: 002013-08-02T11: 29: 38-07: 00Adobe Acrobat 9.55 Подключаемый модуль захвата бумаги / pdfuuid: 786afc82-c7dd-8d42-bad6-68bd4c9989d5uuid: 50e498f7-2829-2d48-8fa6-c5c74c18c520 конечный поток endobj 9 0 объект > endobj 1 0 obj > endobj 4 0 obj >>> / Тип / Страница >> endobj 11 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 17 0 объект >>> / Тип / Страница >> endobj 23 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 29 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 35 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 41 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 47 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 53 0 объект >>> / Тип / Страница >> endobj 59 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 65 0 объект >>> / Тип / Страница >> endobj 71 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 77 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 83 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 89 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 95 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 101 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 107 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 113 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 119 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 125 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 131 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 137 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 143 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 149 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 155 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 161 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 167 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 173 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 179 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 185 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 191 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 197 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 203 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 209 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 215 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 221 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 227 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 233 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 239 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 245 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 251 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 257 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 263 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 269 ​​0 объект >>> / Тип / Страница >> endobj 275 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 281 0 объект >>> / Тип / Страница >> endobj 287 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 293 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 299 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 305 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 311 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 317 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 323 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 329 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 335 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 341 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 347 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 353 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 359 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 365 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 371 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 377 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 383 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 389 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 395 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 401 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 407 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 413 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 419 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 425 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 431 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 437 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 443 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 449 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 455 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 461 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 467 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 473 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 479 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 485 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 491 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 497 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 503 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 509 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 515 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 521 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 527 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 533 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 539 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 545 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 551 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 557 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 563 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 569 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 575 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 581 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 587 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 593 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 599 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 605 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 611 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 617 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 623 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 629 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 635 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 641 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 647 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 653 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 659 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 665 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 671 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 677 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 683 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 689 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 695 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 701 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 707 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 713 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 719 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 725 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 731 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 737 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 743 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 749 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 755 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 761 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 767 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 773 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 779 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 785 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 791 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 797 0 объект >>> / Тип / Страница >> endobj 803 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 809 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 815 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 821 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 827 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 833 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 839 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 845 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 851 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 857 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 863 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 869 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 875 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 881 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 887 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 893 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 899 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 905 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 911 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 917 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 923 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 929 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 935 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 941 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 947 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 953 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 959 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 965 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 971 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 977 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 983 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 989 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 995 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1001 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1007 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1013 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1019 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1025 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1031 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1037 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1043 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1049 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1055 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1061 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1067 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1073 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1079 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1085 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1091 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1097 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1103 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1109 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1115 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1121 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1127 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1133 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1139 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1145 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1151 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1157 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1163 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1169 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1175 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1181 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1187 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1193 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1199 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1205 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1211 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1217 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1223 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1229 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1235 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1241 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1247 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1253 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1259 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1265 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1271 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1277 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1283 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1289 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1295 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1301 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1307 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1313 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1319 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1325 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1331 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1337 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1343 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1349 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1355 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1361 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1367 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1373 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1379 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1385 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1391 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1397 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1403 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1409 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1415 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1421 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1427 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1433 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1439 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1445 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1451 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1457 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1463 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1469 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1475 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1481 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1487 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1493 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1499 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1505 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1511 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1517 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1523 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1529 0 объект >>> / Тип / Страница >> endobj 1535 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1541 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1547 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1553 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1559 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1565 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1571 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1577 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1583 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1589 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1595 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1601 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1607 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1613 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1619 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1625 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1631 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1637 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1643 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1649 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1655 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1661 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1667 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1673 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1679 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1685 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1691 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1697 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1703 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1709 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1715 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1721 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1727 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1733 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1739 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1745 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1751 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1757 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1763 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1769 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1775 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1781 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1787 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1793 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1799 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1805 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1811 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1817 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1823 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1829 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1835 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1841 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1847 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1853 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1859 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1865 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1871 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1877 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1883 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1889 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1895 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1901 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1907 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1913 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1919 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1925 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1931 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1937 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1943 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1949 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1955 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1961 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1967 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1973 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1979 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1985 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1991 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 1997 0 obj > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2003 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2009 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2015 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2021 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2027 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2033 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2039 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2045 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2051 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2057 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2063 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2069 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2075 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2081 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2087 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2093 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2099 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2105 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2111 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2117 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2123 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2129 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2135 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2141 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2147 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2153 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2159 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2165 0 объект >>> / Тип / Страница >> endobj 2171 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2177 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2183 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2189 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2195 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2201 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2207 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2213 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2219 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2225 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2231 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2237 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2243 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2249 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2255 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2261 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2267 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2273 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2279 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2285 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2291 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2297 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2303 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2309 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2315 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2321 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2327 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2333 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2339 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2345 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2351 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2357 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2363 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2369 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2375 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2381 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2387 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2393 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2399 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2405 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2411 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2417 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2423 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2429 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2435 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2441 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2447 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2453 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2459 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2465 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2471 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2477 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2483 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2489 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2495 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2501 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2507 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2513 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2519 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2525 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2531 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2537 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2543 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2549 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2555 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2561 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2567 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2573 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2579 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2585 ​​0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2591 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2597 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2603 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2609 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2615 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2621 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2627 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2633 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2639 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2645 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2651 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2657 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2663 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2669 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2675 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2681 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2687 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2693 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2699 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2705 ​​0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2711 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2717 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2723 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2729 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2735 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2741 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2747 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2753 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2759 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2765 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2771 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2777 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2783 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2789 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2795 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2801 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2807 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2813 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2819 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2825 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2831 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2837 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2843 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2849 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2855 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2861 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2867 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2873 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2879 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2885 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2891 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2897 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2903 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2909 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2915 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2921 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2927 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2933 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2939 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2945 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2951 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2957 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2963 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2969 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2975 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2981 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2987 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2993 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 2999 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3005 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3011 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3017 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3023 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3029 0 объект >>> / Тип / Страница >> endobj 3035 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3041 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3047 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3053 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3059 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3065 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3071 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3077 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3083 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3089 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3095 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3101 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3107 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3113 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3119 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3125 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3131 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3137 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3143 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3149 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3155 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3161 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3167 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3173 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3179 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3185 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3191 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3197 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3203 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3209 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3215 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3221 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3227 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3233 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3239 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3245 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3251 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3257 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3263 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3269 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3275 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3281 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3287 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3293 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3299 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3305 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3311 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3317 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3323 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3329 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3335 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3341 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3347 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3353 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3359 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3365 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3371 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3377 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3383 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3389 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3395 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3401 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3407 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3413 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3419 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3425 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3431 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3437 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3443 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3449 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3455 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3461 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3467 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3473 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3479 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3485 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3491 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3497 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3503 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3509 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3515 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3521 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3527 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3533 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3539 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3545 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3551 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3557 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3563 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3569 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3575 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3581 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3587 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3593 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3599 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3605 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3611 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3617 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3623 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3629 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3635 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3641 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3647 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3653 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3659 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3665 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3671 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3677 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3683 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3689 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3695 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3701 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3707 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3713 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3719 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3725 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3731 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3737 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3743 0 объект > / ProcSet [/ PDF / Text / ImageB] / XObject >>> / Type / Page >> endobj 3749 0 объект >>> / Тип / Страница >> endobj 8043 0 объект > поток H * 203720004R0

    (PDF) Использование языка программирования Go на практике

    3. Обсуждение

    мы чувствуем, что Go имеет преимущество перед любым другим языком в том смысле, насколько легко выучить

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

    был разработан с философией простоты и ортогональности, стандартная библиотека

    не сложна, и научиться ею пользоваться также легко. Тем не менее, это имеет некоторое влияние, например,

    достаточно, что Go предоставляет только небольшой набор структур данных, в отличие, например, от Java

    Collection Framework.Это означает, что когда требуется специализированная структура данных, например

    хэш-карта с предсказуемым порядком итераций, как LinkedHashMap в Java, Go-way

    — это реализовать вручную. Из-за того, что сообщество, стоящее за Go, состоит из

    разработчиков, пришедших из разных языков программирования с разным мировоззрением, вероятно,

    структура данных уже была реализована кем-то другим. Первоначальная идея

    о простоте и ортогональности очень важна для команды Go, и для цели

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

    , доступных в стандартной библиотеке, по крайней мере, в ближайшем будущем.

    Go был разработан для решения конкретных проблем, которые есть у Google, как описано в разделе

    , пункт 1.2.2, который включает в себя цель сделать весь процесс разработки более плавным

    и быстрее. Чтобы достичь этого, основное внимание уделялось конструкции самого языка, и поэтому

    отнюдь не оптимизировали компиляторы, поскольку это можно сделать позже.

    Go — не медленный язык программирования, но и не самый быстрый. Существует проект

    , в котором сравнивается время выполнения, использование памяти и строки кода, необходимые для программ

    , написанных на разных языках. На этом сайте мы видим, что Go в среднем на

    примерно в три раза медленнее, чем C и C ++, но требует взамен несколько строк кода [113]. Эта

    — это то, над чем в настоящее время работает команда Go, и они надеются, что Go будет одним из главных претендентов на

    , когда дело доходит до времени выполнения в будущем. Более конкретно, они

    стремятся быть в целом быстрее, чем C ++ после выпуска Go 1.3, который будет выпущен

    в июне 2014 года [114, 12:08].

    Имея дело с молодым языком, хорошо подготовиться к тому, чтобы наткнуться на

    вещей, которые не совсем такие, какими должны быть. Go не стал исключением и в ходе работы

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

    и некорректной работой системных функций.Здесь пригодится Go с открытым исходным кодом

    , единственное, что нужно сделать, — это сообщить о проблеме на домашней странице проекта

    Go, и если желательно быстрое исправление (если источник проблемы известен ),

    представить решение задачи [115].

    3.1.2 Синтаксис и типы

    В Go есть несколько конструкций, которые, после некоторого использования, мы поняли, что они делают

    не только проще для разработчика, но и делают код кратким и многое другое.