Системы программирования включают программы

Обновлено: 06.07.2024

Меня не устраивает фраза "системное программирование". Мне всегда казалось, что это ненужное объединение двух идей: низкоуровневое программирование (работа с деталями реализации машины) и проектирование систем (создание сложного набора взаимодействующих компонентов и управление ими). Почему это так? Как давно это было правдой? И что мы могли бы получить от переосмысления идеи систем?

1970-е: улучшение сборки

Давайте вернемся к истокам современных компьютерных систем, чтобы понять, как возник этот термин. Я не знаю, кто изначально придумал эту фразу, но мои поиски показывают, что серьезные усилия по определению «компьютерных систем» начались примерно в начале 70-х годов. В «Языках системного программирования» (Bergeron 1 et al. 1972) авторы говорят:

  1. Проблема, которую необходимо решить, носит широкий характер и состоит из многих и обычно весьма разнообразных подзадач.
  2. Системная программа, скорее всего, будет использоваться для поддержки другого программного обеспечения и приложений, но также может быть полным пакетом приложений.
  3. Он предназначен для постоянного использования в «производственной среде», а не для одноразового решения проблемы с одним приложением.
  4. Скорее всего, количество и типы поддерживаемых функций будут постоянно увеличиваться.
  5. Системная программа требует определенной дисциплины или структуры как внутри модулей, так и между ними (например, «коммуникация») и обычно разрабатывается и реализуется несколькими людьми.

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

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

В то же время исследователи из CMU опубликовали книгу BLISS: A Language for Systems Programming (Wulf et al., 1972), описав ее следующим образом:

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

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

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

Что такое системное программирование? Вы можете представить себе компьютер как некоего зверя, который подчиняется всем командам. Говорят, что компьютеры — это в основном люди, сделанные из металла, или, наоборот, люди — это компьютеры, сделанные из плоти и крови. Однако, как только мы приблизимся к компьютерам, мы увидим, что они в основном являются машинами, которые выполняют очень специфические и примитивные инструкции. На заре компьютеров люди общались с ними с помощью переключателей вкл и выкл, обозначающих примитивные инструкции. Вскоре люди захотели давать более сложные инструкции. Например, они хотели иметь возможность сказать X = 30 * Y; учитывая, что Y = 10, чему равно X?Современные компьютеры не могут понять такой язык без помощи системных программ. Системные программы (например, компиляторы, загрузчики, макропроцессоры, операционные системы) были разработаны, чтобы сделать компьютеры более приспособленными к потребностям их пользователей. Кроме того, людям нужна была дополнительная помощь в механике подготовки их программ.


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

1990-е: расцвет сценариев

В 70-х и 80-х годах большинство исследователей рассматривали системное программирование как противоположность программированию на ассемблере. Других хороших инструментов для построения систем просто не было. (Я не уверен, где во всем этом был Лисп? Ни один из прочитанных мной ресурсов не упоминал Лисп, хотя я смутно знаю, что машины на Лиспе существовали, пусть и недолго.)

Однако в середине 90-х годов в языках программирования произошли кардинальные изменения с появлением языков сценариев с динамической типизацией. Улучшение более ранних систем сценариев оболочки, таких как Bash, таких языков, как Perl (1987 г.), Tcl (1988 г.), Python (1990 г.), Ruby (1995 г.), PHP (1995 г.) и Javascript (1995 г.), пробились в мейнстрим. Кульминацией этого стала влиятельная статья «Сценарии: программирование более высокого уровня для 21 века» (Ousterhout 1998). Это сформулировало «дихотомию Оустерхаута» между «языками системного программирования» и «языками сценариев».

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

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

2010-е годы: стирание границ

В последнее десятилетие грань между языками сценариев и языками системного программирования начала стираться. Такие компании, как Dropbox, смогли построить удивительно большие и масштабируемые системы только на Python. Javascript используется для визуализации сложных пользовательских интерфейсов в реальном времени на миллиардах веб-страниц. Постепенная типизация набрала обороты в Python, Javascript и других языках сценариев, позволяя переходить от «прототипа» кода к «производственному» коду путем постепенного добавления информации о статическом типе.

В то же время огромные инженерные ресурсы, вложенные в JIT-компиляторы как для статических языков (например, HotSpot в Java), так и для динамических языков (например, LuaJIT в Lua, V8 в Javascript, PyPy в Python), сделали их производительность конкурентоспособной по сравнению с традиционными языками системного программирования (C , С++). Крупномасштабные распределенные системы, такие как Spark, написаны на Scala 2. Новые языки программирования, такие как Julia, Swift и Go, продолжают расширять границы производительности языков со сборкой мусора.

В панельной дискуссии под названием «Системное программирование в 2014 году и позже» приняли участие крупнейшие умы, стоящие за сегодняшними самопровозглашенными системными языками: Бьярн Страуструп (создатель C++), Роб Пайк (создатель Go), Андрей Александреску (разработчик D) и Нико Мацакис. (разработчик Rust). На вопрос «что такое язык системного программирования в 2014 году?» они ответили (отредактированная транскрипция):

  • Нико Мацакис: Написание клиентских приложений. Полная противоположность тому, для чего разработан Go. В этих приложениях у вас есть потребность в высокой задержке, высокие требования к безопасности, множество требований, которые не возникают на стороне сервера.
  • Бьерн Страуструп: Системное программирование ушло из области, где приходилось иметь дело с аппаратным обеспечением, а затем приложения стали более сложными. Вы должны иметь дело со сложностью. Если у вас есть какие-либо проблемы со значительными ограничениями ресурсов, вы находитесь в области системного программирования. Если вам нужен более тонкий контроль, то вы также находитесь в области системного программирования. Именно ограничения определяют, является ли это системным программированием.У вас заканчивается память? У вас мало времени?
  • Роб Пайк: Когда мы впервые анонсировали Go, мы назвали его языком системного программирования, и я немного сожалею об этом, потому что многие люди полагали, что это язык написания операционных систем. То, что мы должны были назвать, это серверный язык написания, что мы и думали о нем на самом деле. Теперь я понимаю, что у нас есть язык облачной инфраструктуры. Еще одно определение системного программирования – это то, что работает в облаке.
  • Андрей Александреску: У меня есть несколько лакмусовых бумажек для проверки того, является ли что-то языком системного программирования. Языки системного программирования должны позволять вам писать в нем свой собственный распределитель памяти. У вас должна быть возможность преобразовать число в указатель, поскольку так работает аппаратное обеспечение.

Тогда системное программирование связано с высокой производительностью? Ограничения в ресурсах? Аппаратное управление? Облачная инфраструктура? В широком смысле кажется, что языки в категории C, C++, Rust и D отличаются уровнем абстракции от машины. Эти языки раскрывают детали базового оборудования, такие как распределение/разметка памяти и детальное управление ресурсами.

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

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

Сегодня: …так что же такое системное программирование?

Это возвращает меня к моей первоначальной проблеме. То, что многие люди называют системным программированием, я рассматриваю как низкоуровневое программирование — раскрытие деталей машины. Но как быть тогда с системами? Вспомните наше определение 1972 года:

  1. Проблема, которую необходимо решить, носит широкий характер и состоит из многих и обычно весьма разнообразных подзадач.
  2. Системная программа, скорее всего, будет использоваться для поддержки другого программного обеспечения и приложений, но также может быть полным пакетом приложений.
  3. Он предназначен для постоянного использования в «производственной среде», а не для одноразового решения проблемы с одним приложением.
  4. Скорее всего, количество и типы поддерживаемых функций будут постоянно увеличиваться.
  5. Системная программа требует определенной дисциплины или структуры как внутри модулей, так и между ними (например, «коммуникация») и обычно разрабатывается и реализуется несколькими людьми.

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

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

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

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

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

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

Techopedia объясняет системное программирование

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

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

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

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

Назначение системных программ

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

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

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

Типы системных программ

Системные программы можно разделить на семь частей. Они даны следующим образом:

Информация о статусе

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

Общение

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

Работа с файлами

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

Загрузка и выполнение программы

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

Изменение файла

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

Прикладные программы

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

Поддержка языков программирования

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

Раздел 404 Закона Сарбейнса-Оксли (SOX) требует, чтобы все публичные компании установили внутренний контроль и процедуры.

Закон о защите конфиденциальности детей в Интернете от 1998 года (COPPA) – это федеральный закон, который налагает особые требования на операторов доменов .

План North American Electric Reliability Corporation по защите критически важной инфраструктуры (NERC CIP) представляет собой набор стандартов.

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

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

Метаморфное и полиморфное вредоносное ПО – это два типа вредоносных программ (вредоносных программ), код которых может изменяться по мере их распространения.

Медицинская транскрипция (МТ) – это ручная обработка голосовых сообщений, продиктованных врачами и другими медицинскими работниками.

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

Защищенная медицинская информация (PHI), также называемая личной медицинской информацией, представляет собой демографическую информацию, медицинскую .

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

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

Синхронная репликация — это процесс копирования данных по сети хранения, локальной или глобальной сети, поэтому .

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

Интерфейс управления облачными данными (CDMI) – это международный стандарт, определяющий функциональный интерфейс, используемый приложениями.

Износ флэш-памяти NAND — это пробой оксидного слоя внутри транзисторов с плавающим затвором флэш-памяти NAND.

Читайте также: