Основы информационных технологий для неспециалистов: что происходит внутри машин — страница 10 из 26

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

Фредерик П. Брукс.

Мифический человеко-месяц[44], 1975

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

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

Жаргонный термин для таких программ – приложение. Он предположительно произошел от фразы «прикладная программа для решения какой-либо задачи на компьютере». Так обычно называются более-менее автономные программы, которые сосредоточены на выполнении одной задачи. Раньше это слово использовалось только в среде программистов, но после ошеломляющего успеха App Store от Apple, где продавались приложения для iPhone, в повседневую речь на английском прочно вошло усеченное «app».

Когда вы приобретаете компьютер или телефон, на нем уже установлены несколько таких программ, и со временем вы пополняете их список, покупая или загружая новые. Приложения в этом смысле важны для нас как пользователей, но они также обладают рядом интересных свойств с технической точки зрения. Мы коротко поговорим о нескольких видах, а затем сосредоточимся на одном из них – браузере. Это показательный пример, ведь с браузерами знаком каждый, но в нем все равно таятся некоторые сюрпризы, включая неожиданные параллели с ОС.

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

6.1. Операционные системы

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

Операционные системы неуклонно усложнялись, не отставая от развития оборудования, которым они управляли. А поскольку «железо» становилось все более мощным и хитроумно устроенным, имело смысл выделять больше ресурсов для управления им. Первые широко используемые ОС возникли на рубеже 1950-1960-х годов. Обычно они предоставлялись той же компанией, которая производила оборудование, и были тесно с ним связаны, поскольку их писали на ассемблерном языке. IBM и более мелкие компании вроде Digital Equipment[45] и Data General[46] выпустили собственные операционные системы для своей аппаратуры. Фредерик Брукс, которого я процитировал в эпиграфе выше, руководил разработкой компьютеров IBM серии System/360 и OS/360 – флагманской ОС его компании с 1965 по 1978 год. Брукс получил премию Тьюринга 1999 года за свой вклад в компьютерную архитектуру, операционные системы и разработку ПО.

ОС также изучали в университетах и промышленных лабораториях. Первопроходцем здесь стал Массачусетский технологический институт, где в 1961 году создали систему под названием CTSS («Совместимая система с разделением времени»). Она получилась действительно передовой на тот момент и, не в пример ее промышленным конкурентам, приятной в использовании. В 1969 году Кен Томпсон и Деннис Ритчи, сотрудники Лабораторий Белла, которые работали над Multics – более сложным и менее успешным продолжением CTSS, – написали ОС Unix. Все современные операционные системы, за исключением Windows от Microsoft, произошли или от оригинальной Unix, или от совместимой с ней, но независимо созданной Linux. Именно за работу над Unix Ритчи и Томпсон в 1983 году совместно удостоились премии Тьюринга59.

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

Единственный способ жонглировать всеми элементами на таком уровне сложности – задействовать еще одну программу, чтобы компьютер сам помогал себе производить операции. Такая программа называется операционной системой. Наиболее распространенная ОС для домашних и рабочих компьютеров – Windows от Microsoft и ее различные исторические версии. Они установлены примерно на 80–90 % машин, которые мы видим в повседневной жизни. Компьютеры от Apple работают на системе macOS. Многие «закулисные» компьютеры (и некоторые на переднем плане) – на Linux. Смартфонами также управляют ОС: изначально под них писали специализированные системы, но сегодня зачастую обходятся облегченными версиями Unix или Linux. Например, на iPhone и iPad установлена iOS, производная от macOS, которая, по сути, вариант Unix. А вот в телефонах на базе Android применяется Linux, как и в моих телевизоре TiVo, читалке Amazon Kindle и устройствах Google Nest. Я даже могу войти в мой телефон на Android и запустить на нем базовые команды Unix.

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

В типичной ОС одновременно работают сотни процессов. Среди них есть и приложения, запущенные пользователями, но большинство из них – системные задачи, невидимые нам. Увидеть, что происходит, вы можете с помощью таких программ, как Activity Monitor на macOS или Task Manager (диспетчер задач) на Windows, или аналогичного средства на телефоне. На рис. 6.1 показано несколько из 300 процессов, которые сейчас запущены на Мас, пока я печатаю. Большинство из них не зависят друг от друга и поэтому хорошо подходят для многоядерной архитектуры.

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

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


Рис. 6.1. Activity Monitor отображает загрузку процессора в macOS


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

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

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

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

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


Рис. 6.2. Использование памяти в macOS, показанное в программе Activity Monitor


Например, 6-я редакция операционной системы Unix, прародительницы многих современных систем, в 1975 году состояла из 9000 строк на ассемблерном языке и С, написанных двумя коллегами. Современная ОС Linux содержит более 10 миллионов строчек, и над ней работали тысячи людей на протяжении десятилетий. Предполагается, что в Windows 10 содержится 50 миллионов строк, но официальные данные о ее размере пока не опубликованы. Впрочем, эти числа нельзя сравнивать напрямую, поскольку современные компьютеры намного сложнее и имеют дело с более замысловатыми средами и с большим количеством устройств. Кроме того, на этапе обсуждения того, что войдет в ОС, тоже принимаются разные решения.

Поскольку ОС – просто программа, вы, в принципе, можете и сами написать «операционку». Например, история Linux началась в 1991 году, когда финн Линус Торвальдс, будучи студентом колледжа, решил с нуля создать собственную версию» Unix. Разместив первый черновик (чуть менее 10 000 строк) в интернете, он предложил людям попробовать его разработку и помочь улучшить ее. С тех пор Linux стал главной силой в индустрии ПО, его применяют как крупные компании, так и бесчисленное количество мелких игроков. Как упоминалось в предыдущей главе, Linux имеет открытый исходный код, поэтому каждый может его использовать и развивать60. Сегодня в проекте участвуют тысячи человек, хотя костяк составляют специалисты, занятые полный рабочий день. Торвальдс по-прежнему сохраняет общий контроль, и за ним остается окончательный выбор, когда возникают споры по поводу технических решений.

Вы можете использовать на своем оборудовании ОС, отличную от той, что предусмотрена для него. Хороший пример – установка Linux на компьютерах, изначально предназначенных для Windows. Также вы можете хранить на диске несколько ОС и при каждом включении компьютера выбирать любую из них. Такая «мультизагрузка» реализуется, например, через программу Apple Boot Camp, которая позволяет работать на Mac под управлением Windows вместо macOS.

Вы даже можете запустить одну ОС под контролем другой, как виртуальную операционную систему. Программы для работы с виртуальной ОС, такие как VMware, VirtualBox и Хеп (с открытым исходным кодом), позволяют запускать одну операционную систему – скажем, Windows или Linux – в качестве гостевой операционной системы на хосте (например, macOS). Операционная система-«хозяин» перехватывает запросы, созданные «гостем», но для этого ей требуются привилегии вроде доступа к файловой системе или сети. Хост выполняет операции и затем возвращает результат гостевой ОС. Когда обе системы скомпилированы для одного оборудования, то гостевая ОС по большей части работает на полной аппаратной скорости и реагирует почти так же быстро, как если бы она одна стояла на этом компьютере.

На рис. 6.3 схематически показано, как виртуальная ОС выполняется на хосте. С точки зрения системы-«хозяина» го


Рис. 6.3. Организация виртуальной операционной системы


стевая ОС – это типичное приложение.

На рис. 6.4 показан снимок экрана моего Мас, на котором работает VirtualBox. Приложение, в свою очередь, управляет двумя гостевыми ОС: Linux (слева) и Windows 10 (справа).

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


Рис. 6.4. На macOS запущены виртуальные машины Windows и Linux


Самый крупный поставщик облачных вычислений – Amazon Web Services (AWS), за ним следуют Microsoft Azure и Google Cloud Platform. AWS стала особенно успешной, ведь на ее долю приходится более половины операционной прибыли Amazon. Все они предлагают сервис, производительность которого для любого конкретного клиента может увеличиваться или уменьшаться по мере изменения нагрузки. У них есть достаточно ресурсов, чтобы позволить отдельным пользователям мгновенно наращивать или убавлять отведенную им мощность. Многие компании, включая крупного игрока Netflix, полагают, что облачные вычисления более рентабельны, чем поддержание собственных серверов, поскольку они обеспечивают экономию на масштабировании, способны адаптироваться к меняющейся нагрузке и снижают потребность во штатном персонале.

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

Здесь следует упомянуть еще одно значение слова «виртуальный». Программу, которая имитирует компьютер, настоящий или выдуманный (как наша Игрушка), часто называют виртуальной машиной (ВМ). То есть компьютер существует только в ПО – программе, симулирующей его работу так, словно он собран из реального оборудования.

Такие виртуальные машины – обычное явление. У браузеров есть ВМ для интерпретации программ на JavaScript, а возможно, и еще одна – отдельно для программ на Java. В смартфонах на Android также есть виртуальная машина для Java. Люди пользуются ВМ, потому что писать и распространять программы легче и удобнее, чем создавать и доставлять физическое оборудование.

6.2. Как работает операционная система

Процессор устроен таким образом, что, когда компьютер включается, ЦПУ запускает на выполнение несколько инструкций, хранящихся в постоянной памяти. Затем уже они считывают другие инструкции из небольшой флеш-памяти, которая содержит достаточно кода, чтобы прочитать еще больше инструкций из определенного места на диске, USB-памяти или сетевого подключения. Те, в свою очередь, прочитают еще больше инструкций, и так до тех пор, пока не будет загружено достаточно кода для выполнения полезной работы. Такой процесс начального запуска когда-то называли boot-strapping (буквально «тянуть за ушко ботинка») – по старому присловью о людях, которые сами всего добились с нуля[47], а сейчас говорят просто booting (загрузка). Детали различаются, но основная идея не меняется: хватает нескольких инструкций, чтобы обратиться к другим, которые, в свою очередь, запустят третьи и т. д.

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

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

Система реагирует на такие события, как окончание музыки, получение письма, открытие веб-страницы или нажатие клавиши. В каждом случае она делает все необходимое, часто сообщая, что с приложением произошло нечто, требующее каких-либо действий. Если я захочу перенести окошко на моем экране, ОС сообщит дисплею, куда нужно его поместить, и скажет всем приложениям, что части их окон сейчас станут видимыми, чтобы они могли их заново отобразить. Если я выхожу из приложения через File Exit (Файл Закрыть) или нажимаю на маленький × в верхнем углу окна, система уведомляет приложение, что оно вот-вот умрет, и тогда у него появляется шанс привести свои дела в порядок – например, спросить пользователя: «Хотите ли вы сохранить файл?» Затем ОС восстанавливает все ресурсы, которые использовала программа, и сообщает приложениям с открытыми окнами, что они должны их перерисовать.

6.2.1. Системные вызовы

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

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

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

6.2.2. Драйверы устройств

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

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

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

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

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

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


Рис. 6.5. Интерфейсы операционной системы, системного вызова и драйвера устройства

6.3. Другие операционные системы

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

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

Итак, мы можем сделать общий вывод, что сейчас устройства приобретают черты обычных компьютеров общего назначения, о которых мы говорили в главе 1. В них встраивают мощный процессор, много памяти и несколько периферийных устройств (например, объективы и дисплей в камере). У них бывают сложные пользовательские интерфейсы. Часто у этих устройств есть выход в сеть, и они могут общаться с другими системами: смартфоны используют телефонные каналы и Wi-Fi, а игровые контроллеры – инфракрасное излучение и Bluetooth. Также всевозможное оборудование можно подключать через USB при нерегулярных ситуативных соединениях. «Интернет вещей» основан на том же принципе: термостаты, освещение, системы безопасности и тому подобное управляются встроенными компьютерами и подсоединяются к Всемирной паутине.

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

6.4. Файловые системы

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

Большинство читателей, вероятно, использовали Проводник Windows или Finder в macOS, которые отображают упомянутую иерархию, начиная с самого верха (например, диск С: в Windows). Папки содержат имена других папок и файлов. Просматривая какую-нибудь папку, мы обнаруживаем в ней еще больше папок и файлов. (В системах семейства Unix обычно используется слово «каталог», а не «папка».) Папки обеспечивают организационную структуру, а в файлах размещается само содержимое документов, изображений, музыки, электронных таблиц, веб-страниц и так далее. Вся информация в компьютере хранится в файловой системе, через которую вы получаете доступ к сведениям, когда что-то ищете. ФС содержит не только ваши данные, но и исполняемые формы программ вроде Word и Chrome, библиотеки, информацию о конфигурации, драйверы устройств и файлы, которые составляют саму ОС. Их количество поражает: я с удивлением узнал, что мой скромный MacBook хранит более 900 тысяч файлов, а ПК с Windows у друга – около 800 тысяч. На рис. 6.6 показана часть иерархии из пяти уровней на моем компьютере, внизу которой находятся несколько фотографий в моем корневом каталоге.


Рис. 6.6. Иерархия файловой системы


Несмотря на свои названия, Finder («Искатель») и Проводник наиболее полезны, только если вам известно местоположение ваших файлов: вы всегда можете двигаться к ним от корня или верхней части иерархии ФС. Однако если вы не знаете, где располагается то, что нужно, возможно, вам придется задействовать инструмент поиска – например, Spotlight на macOS.

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

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

6.4.1. Файловые системы внешней памяти

ФС – отличный пример того, как на основе крайне разнообразных физических систем создать единое логическое отображение – иерархию папок и файлов. Как это работает?

Диск объемом 500 Гб содержит 500 миллиардов байт, но его ПО, скорее всего, представит это в виде 500 миллионов фрагментов или блоков по 1000 байт. (В настоящих компьютерах все величины измерялись бы степенями двойки, но сейчас я указываю десятичные числа, чтобы вы отчетливо видели все связи.) Файл объемом в 2500 байт – например, небольшое сообщение в почте – будет сохранен в трех таких блоках. Для двух он слишком велик, а вот трех достаточно.

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

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

Кроме того, запись в папке указывает, где файл хранится на диске, то есть в каком из 500 миллионов блоков содержатся его байты. Управление этими сведениями о местоположении ведется множеством различных способов. Запись папки или содержит список номеров блоков, или ссылается на блок, который сам содержит такой список, или указывает номер первого блока, а тот – второго и т. д.

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

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

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


Рис. 6.7. Организация файловой системы на жестком диске


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

Когда программа хочет получить доступ к имеющемуся файлу, ФС должна выполнить его поиск, начиная от корня иерархии, то есть просмотреть каждый компонент имени пути к файлу в соответствующей папке. Например, если нам нужен файл /Users/bwk/book/book. txt на Мас, ФС будет искать в корне файловой системы каталог Users, затем уже в нем – bwk, далее book и book. txt. В Windows имя может выглядеть как C: \My Documents\book\book. txt, но поиск будет вестись аналогично.

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

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

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

6.4.2. Удаление файлов

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

При удалении файла в Windows или macOS он переходит в Корзину или Trash («мусорное ведро»), которые выглядят просто как очередная папка, хотя и с несколько другими свойствами. Вообще говоря, так оно и есть. Когда файл удаляется, его запись в папке и полное имя (путь к нему) копируются в папку под названием Корзина или Trash, а первоначальная запись очищается. Блоки файла и все его содержимое нисколько не меняются! Восстановление файла из «мусорки» – это обратная процедура, при которой запись возвращается в исходную папку.

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

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

Из-за такой задержки та информация, которую вы считаете удаленной, все еще существует, к ней легко могут получить доступ те, кто знает, как ее найти. Любая программа, которая считывает диск через физические блоки, то есть без прохождения через систему иерархии, способна увидеть их старое содержимое. В середине 2020 года Microsoft анонсировала выпуск Windows File Recovery – бесплатного инструмента, выполняющего восстановление именно такого рода для широкого спектра файловых систем и носителей61.

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

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

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

Несколько похожая ситуация происходит с самой записью в папке. Когда вы удаляете файл, ФС отмечает, что его запись в папке больше не указывает на действительный файл. Для этого она задает в папке бит, означающий «эта запись не используется». При таком методе возможно затем восстановить исходную информацию о файле, включая содержимое всех блоков, которые еще не перераспределены. Но сделать это получится лишь до тех пор, пока сама запись в папке еще не использована повторно. В 1980-х годах этот механизм лежал в основе коммерческой программы по восстановлению файлов для MS-DOS от Microsoft, которая отмечала свободные записи, присваивая первому символу в имени файла специальное значение. Тем самым облегчалось восстановление целого файла, если оно проводилось не слишком поздно.

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

6.4.3. Другие файловые системы

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

На компакт-дисках и DVD доступ к информации предоставляется так, словно на них тоже организована ФС, опять же с иерархией папок и файлов. Повсеместно распространены ФС флеш-памяти на дисках USB и SD (Secure Digital, рис. 6.8). Когда мы подключаем такой носитель к компьютеру с Windows, флешка или карта отображаются как еще один дисковый накопитель. Его можно просматривать через Проводник, а файлы читаются и записываются точно так же, как со встроенного диска. Единственное отличие в том, что пропускная способность бывает ниже, а доступ – несколько медленнее.


Рис. 6.8. Флеш-память SD-карты


Если то же самое устройство подключить к Мас, оно тоже будет отображаться как папка, которую можно открыть с помощью Finder, а файлы с него – перекидывать в разные места. Его можно подсоединить к компьютерам на Unix или Linux, и оно снова появится в файловой системе. Благодаря ПО физическое устройство отображается в различных операционных системах как ФС, с такой же абстракцией папок и файлов. Внутри, скорее всего, применяется файловая система Microsoft FAT – широко используемая, де-факто стандартная, – но точно мы не знаем, да нам этого и не нужно. Абстракция совершенна. (FAT расшифровывается как File Allocation Table, то есть «таблица распределения файлов», и тут нет никаких намеков на качество реализации[48].) Это возможно благодаря стандартизации структуры интерфейса аппаратного и программного обеспечения.

Моя первая цифровая камера хранила снимки во внутренней файловой системе. Чтобы извлечь их, мне приходилось подключать ее к компьютеру и запускать патентованную программу, чтобы извлечь их. С тех пор у каждой камеры появилась съемная карта памяти SD вроде той, что показана на рис. 6.8, и я могу загружать фотографии, переставляя ее из аппарата в компьютер. Это намного быстрее, чем раньше, и к тому же с неожиданной побочной выгодой: мне больше не нужно пользоваться ужасно неуклюжим и ненадежным ПО от производителя камеры. Знакомый и единообразный интерфейс стандартных носителей заменяет громоздкое и разнородное обеспечение, как программное, так и аппаратное. Полагаю, производитель тоже доволен тем, что ему больше не нужно предоставлять специализированное приложение для передачи файлов.

Стоит упомянуть еще одну версию реализации этой идеи – сетевую ФС, распространенную в школах и на предприятиях. С помощью ПО создается доступ к файловой системе на каком-либо другом компьютере так, словно вы работаете за этой машиной. При этом для доступа к информации мы снова используем Проводник, Finder или другие программы. При этом неважно, какая ФС на дальнем конце подключения – такая же (когда на обоих компьютера стоит Windows, например) или другая – скажем, macOS или Linux. Как и в случае с устройствами флеш-памяти, ПО скрывает различия и предоставляет единый интерфейс, поэтому все выглядит как обычная файловая система на локальном компьютере.

Сетевые ФС часто используются в качестве как резервного, так и основного хранилища файлов. Многочисленные старые экземпляры файлов могут копироваться на архивный носитель для хранения в другом месте. Это помогает защитить важные записи от разрушительных событий вроде атаки программы-вымогателя или пожара, поскольку в таком случае погибнут только копии. Некоторые дисковые системы полагаются на технологию под названием «массив независимых дисков с избыточностью», или RAID (redundant array of independent disks): данные записываются на несколько дисков с применением алгоритма исправления ошибок, что позволит восстановить информацию даже при поломке одного из дисков. Естественно, при использовании таких систем сложнее гарантировать, что информация стерта бесследно.

Системы облачных вычислений, о которых мы будем говорить в главе 11, обладают некоторыми из перечисленных свойств, но обычно не показывают свое содержимое в интерфейсе ФС.

6.5. Приложения

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

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

В качестве примера элементарного приложения рассмотрим программу в Unix под названием date, которая выводит текущую дату и время:


$ date

Fri Nov 27 16:50:00 EST 2020


Программа date ведет себя одинаково во всех системах, подобных Unix, в том числе macOS, и похожим образом в Windows. Реализация date крошечная, потому что она создана на основе системного вызова (time), который предоставляет текущую дату и время во внутреннем формате, а также на библиотеках для форматирования дат (сtime) и вывода текста (printf). Ниже представлена полная реализация на языке С – посмотрите, насколько она короткая:



В системах семейства Unix есть программа под названием Is, которая составляет списки файлов и папок в каталоге. Это простой текстовый аналог Проводника Windows и Finder в macOS. Другие приложения копируют, перемещают, переименовывают файлы и т. д. (Как в Finder, так и в Проводнике аналогичные операции реализованы через графический интерфейс.) И, опять же, эти программы используют системные вызовы для получения доступа к базовой информации о содержимом папок и полагаются на библиотеки для чтения, записи, форматирования и отображения данных.

Такое приложение, как Word, гораздо объемнее любой программы для просмотра файловой системы. Очевидно, что в него потребовалось встроить некий код ФС, чтобы пользователи смогли открывать файлы, читать их содержимое и сохранять документы. В Word включены сложные алгоритмы – например, чтобы отображение непрерывно обновлялось по мере изменения текста. Приложение обладает продуманным пользовательским интерфейсом, который выводит информацию на экран и предоставляет способы настраивать размер и тип шрифта, цвет, слои и т. д. Его можно назвать основной частью программы. Word и другие большие приложения, имеющие значительную коммерческую ценность, постоянно развиваются, получая новые функции. Не знаю, насколько объемный у Word код, но не удивлюсь, если он содержит десять миллионов строк на языках С, C++ и других, особенно если в пакет включены версии для Windows, Мас, телефонов и браузеров.

Любой браузер – это пример объемного бесплатного приложения, иногда с открытым исходным кодом, которое по некоторым параметрам еще сложнее Word. Среди них Firefox, Safari, Edge, Chrome, и вы наверняка применяли хотя бы один из них, а многие люди регулярно используют несколько. В главе 10 мы более подробно поговорим о Сети и о том, как браузеры извлекают информацию, тогда как здесь я хочу сосредоточиться на принципах работы больших сложных программ.

Если посмотреть со стороны, браузер отправляет запрос веб-сервисам и получает от них данные для отображения. В чем сложность?

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

Им полагается поддерживать много разных видов контента: от статического текста до интерактивных программ, которые меняют содержимое страницы. Часть задач браузер может передать вспомогательным приложениям, как обычно и поступает со стандартными форматами – например, PDF[49] и фильмами. Но при этом он обязан предоставлять механизмы для запуска таких вспомогательных программ, для отправки и получения их данных и запросов, а также их интеграции в общее отображение.

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

Помимо того, браузер обеспечивает платформу для расширений на нескольких уровнях: плагинов вроде QuickTime, виртуальных машин JavaScript и надстроек (например, Adblock Plus и Ghostery). К тому же он должен работать на нескольких версиях различных ОС, в том числе для мобильных устройств.

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

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

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

6.6. Уровни программного обеспечения

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

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

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

Это верно для интерфейса операционных систем Unix и Linux, которые работают на всех видах ЦПУ и обеспечивают на них выполнение одинаковых служб ОС. По сути, сама ОС стала предметом потребления: мы уже не особо обращаем внимания на тип оборудования, разве что на цену и производительность, поскольку ПО «наверху» от него не зависит. (Это очевидно в том числе потому, что я часто упоминаю системы Unix и Linux как взаимозаменяемые, так как в большинстве аспектов различия между ними несущественны.) Всё, что необходимо для переноса какого-либо программы на новый процессор, – скомпилировать ее с помощью подходящего компилятора. Конечно, чем сильнее приложение зависит от определенных свойств оборудования, тем сложнее станет эта работа, но она вполне выполнима для многих программ.

Вот пример такого процесса в крупных масштабах: компания Apple меньше чем за год (с 2005 по 2006) перевела свое ПО с процессора IBM PowerPC на Intel. В середине 2020 года Apple объявила, что планирует снова проделать эту работу, поскольку собирается теперь использовать на всех телефонах, планшетах и компьютерах процессоры ARM, а не Intel. Это еще одна демонстрация того, как программное обеспечение может существенно не зависеть от конкретной архитектуры процессора.

Это в меньшей степени относится к Windows, которая на протяжении многих лет поддерживала довольно тесную связь с архитектурой Intel, начиная с процессора Intel 8086 в 1978 году и заканчивая его последующими версиями. (Данное семейство ЦПУ часто называют «х86», поскольку названия процессоров Intel долгие годы заканчивались на 86, включая 80286, 80386 и 80486.) Сотрудничество велось настолько плотно, что Windows, работающую на Intel, иногда называли Wintel. Однако сегодня Windows также выполняется на процессорах ARM63.

Следующий уровень над ОС – это набор библиотек, которые предоставляют основные полезные сервисы, чтобы отдельным программистам не приходилось писать их с нуля. Доступ к ним осуществляется через API. Одни библиотеки относятся к низким уровням, потому что работают с базовой функциональностью (например, обрабатывают математические функции вроде квадратного корня или логарифма, или высчитывают дату и время, как в команде date выше), тогда как другие гораздо более сложны и отвечают за криптографию, графику, сжатие и т. п. Компоненты графического пользовательского интерфейса (диалоговые окна, меню, кнопки, ячейки-флажки, полосы прокрутки, панели с вкладками и проч.) требуют объемного кода, но, как только они попадают в библиотеку, любой может ими воспользоваться, что помогает обеспечивать единообразный внешний вид. Вот почему большинство приложений Windows – или, по крайней мере, их базовые компоненты – выглядят одинаково. На устройствах Mac это проявляется даже в большей степени. Для большинства поставщиков ПО слишком трудозатратно изобретать или внедрять что-то новое, тем более что бессмысленные отличия в визуальном дизайне сбивают пользователей с толку.

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

Как же их разделять? Вот полезное, хотя и не исчерпывающее указание: к ОС относится всё, необходимое для того, чтобы одно приложение не мешало другому. Управление памятью, то есть принятие решений о том, в какой части RAM держать программу, пока она работает, – это часть ОС. Файловая система, которая определяет, где хранить информацию во внешней памяти, – тоже ключевая функция. Это же относится к контролю устройств: два приложения не должны одновременно запускать принтер или что-то выводить на дисплей безо всякой координации. Фактически и руководство процессорами – функция ОС, поскольку оно необходимо для обеспечения всех остальных свойств.

Браузер – не часть ОС, поскольку можно запустить любой браузер или даже несколько одновременно, не вмешиваясь в общие ресурсы или управление. Возможно, вы решите, что это технический нюанс, но он привел к серьезным юридическим последствиям. Антимонопольный судебный процесс Министерства юстиции США против Microsoft, тянувшийся с 1998 по 2011 год, частично касался того, является ли браузер Internet Explorer (IE) от Microsoft частью операционной системы или просто приложением. Microsoft утверждала, что верно первое, а значит, его невозможно удалить без последствий, и компания вправе требовать, чтобы покупатель использовал IE. Если же правильно второе, то получается, что Microsoft незаконно принуждает клиентов пользоваться IE, хотя в этом нет необходимости. Разумеется, суть дела гораздо сложнее, но важная его часть заключалась в споре о том, где провести эту черту. Для справки, суд решил, что браузер – это приложение, а не часть ОС. Выражаясь словами окружного судьи Томаса Джексона, «веб-браузеры и операционные системы – это отдельные продукты»64.

6.7. Краткие выводы

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

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

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

7. Учимся программировать