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

Компилируемый и интерпретируемый языки Изучение

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

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

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

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

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

Символы в двоичном формате

A 01000001

a 01100001

B 01000010

b 01100010

C 01000011

c 01100011

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

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

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

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

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

#include<stdio.h>
int main() {
    printf("Hello World\n");
    return 0;
}

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

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

Что такое компилируемый язык?

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

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

Некоторые примеры скомпилированных языков включают:

  • C, C++, and C#
  • Go
  • Rust
  • Haskell
  • Cobol

Что такое интерпретируемый язык?

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

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

Некоторые примеры интерпретируемых языков включают:

  • Python
  • JavaScript
  • PHP
  • MATLAB
  • Perl
  • Ruby

Скомпилированные и интерпретированные: сравнение

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

Compilers

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

Interpreters

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

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

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

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

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

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

Начните с языков программирования

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

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

Читайте также:  10 обязательных функций для успешного банковского приложения
Оцените статью
bestprogrammer.ru
Добавить комментарий