Введение
О чем задумался, друг? Не о том, как компьютеры понимают код, который пишут программисты? Как удачно, ведь мы как раз хотели об этом рассказать!
Как работают компьютеры?
Сначала узнайте, как работают компьютеры. Вот у нас есть процессор, который в компе самый главный и тут вся инструкция. Он состоит из миллиардов транзисторов, эдаких переключателей, которые могут находиться в двух состояниях - пропускать ток или нет. Условно говоря либо «да», либо «нет», либо единица, либо ноль. Вот мы и получили бит — минимальную единицу информации. В зависимости от того, как построены эти транзисторы, и что на них подано, процессор может выполнять разные операции.
Вспоминай уроки информатики, тебя там учили всяким логическим "и", "или", правда, ложь, булева алгебра и вот это все. Так вот, чтобы процессор сделал то, что мы хотим, надо ему сообщить, какую операцию восстановления в данный момент, но только на языке, понятном ему - на машинном языке. То есть, нам нужно передать ему последовательность нулей и единицу, которую назовем бинарным кодом. Процессор берет эти нулевые значения и отправляет технологический сигнал в нужные транзисторы, таким образом, какой результат дает операция. Короче говоря, машинный язык просто говорит процессору, где какие транзисторы надо переключить - изначально с компьютерами можно было общаться только так.
Абстракция и языки программирования
Но прогресс не стоял на месте, производители старались упихать в процессорах всё больше транзисторов и мерялись тем у кого он…кхм, кхм, меньше, схемы стали сложнее и учёные почесали репу, и поняли, что дальше так дело не пойдёт «мы тут скоро поедем» кукухой, если будем и дальше ноликами и единичками все операции зашифровывать». А представить, какие в те времена кодовые версии были, ух! Поэтому была продумана абстракция над машинным кодом, который называется Ассемблер, где отдельные нулей и единиц заменялись буквами и младшими словами, по типу add, sub и mov и кожаными мешками стало легче.
А как компьютер понимает эти слова, это же не нули и единички? Ну, к тому времени они научились очень хорошо хранить что-то в памяти, и появилась возможность загрузить в них программу, которая переводит эти слова машинным кодом. Вот так просто! Правда есть нюанс - раз процессоры сделаны по-разному, то для каждой архитектуры нужно писать программу на ассемблере по-разному, но такие мелочи не останавливают прогресс.
Ну, а дальше стало понятно, что можно использовать языки, которые будут объединены для программистов и понеслось - Fortran, Algol, LISP, Basic, Pascal, C, Pyton, Java и конечно же JavaScript с его постоянными общедомовыми отключениями. Добавляй конструкции, прикручивай ООП, делай язык максимально близко к моей речи, а главное - в конце переведи в машинный код, и все будет тип-топ.
Компиляция и интерпретация
Есть несколько подходов, чтобы перевести свеженаписанный исходный код в машинный код. Первый - это компиляция. Когда у нас есть исходный код, он пишет в программную часть, которая выполняет роль переводчика, и называется компилятором. Он, в свою очередь, возьмет весь исходный код и начнет пыхтеть, анализировать все, что написали программисты, проверять синтаксис, подтягивать все подключаемые файлы, а затем переводить все это в машинный код, понятный процессор и создавать исполняемый файл. Дальше мы запускаем этот файл, и программа начинает работать, ведь внутри ее инструкции теперь понятные бездушной машины.
Еще важно, что компиляция происходит под определенную архитектуру системы, поэтому, если вам нужно перенести программу на другую систему, то нужно перекомпилировать код под нее или даже использовать другой компилятор. Да, да, на одном языке может быть еще и несколько компиляторов. Но не боись, есть и кросс-компиляторы для нескольких архитектур и языков, например GCC. Используйте компиляцию таких языков, как C, C++, Go, Rust, Swift.
Возможно, у тебя появился вопрос - «а как написать эти самые компиляторы?» На других языках, дружочек! Но после этого можно написать новую версию компилятора, уже на нужном языке, и скомпилировать первым компилятором.
Кстати, пайтон на самом деле тоже компилируется в байт-код. Про то, как это происходит, и про то, как пайтон работает под капотом, мы рассказываем на нашем продвинутом курсе Python Advanced!
Интерпретация
Теперь давай посмотрим на второй вид перевода в этом вашем «бездушно-машинном» - интерпретации. Тут тоже есть специальная программа-переводчик, под названием интерпретатор, но основная замес немножко в другом. В отличие от компилятора, интерпретатор - на диете, и мы вскармливаем ему не весь код, а по ложечке, строчку за строчкой, которую он переводит в машинный и сразу же выполняет, а затем переходит к следующему куску.
Разница с компиляцией в том, что мы заранее генерируем машинный код для всего написанного нами кода и получаем файл, который можно запустить, а тут мы ничего не генерируем, а передаем исходный код в интерпретатор, и он переводит и сразу выполняет код построчно. Последствия и недостатки: интерпретируемые языки и более быстрый запуск, поскольку не нужно каждый раз делать полную компиляцию кода, но от этого зависит производительность, так как код необходимо каждый раз анализировать и выполнять на лету. Да и ошибка сразу могла бы подсветить компилятор, тут получаешь уже во время выполнения, если интерпретатор дойдет до этого места в коде.
Этот язык не зависит от системы, код легко запускается на другой операционной системе, главное, чтобы там был интерпретатор. На самом деле, интерпретаторов на одном языке также может быть несколько. Например, у хрома, мозилы и сафари они свои. Ну и сами интерпретаторы тоже относятся к платформе, где они выполняют код. Интерпретация использует такие языки, как PHP, Python, JavaScript, Ruby.
Сборка «точно в срок»
Еще есть такая штука, которая называется «Just-In-Time Compilation». После того, как мы скомпилировали наш исходный код в байткод или какой-то промежуточный код, его естественно нужно будет восстановить. И это происходит во время выполнения программы, JIT-компилятор анализирует этот байт-код и компилирует его в машинный код. Вот такая вот и компиляция и интерпретация получилась.
Еще JIT-компиляция используется в движках JavaScript. После анализа и преобразования исходного кода браузер может создать промежуточный код для частей, которые, например, часто повторяются, и отправить его через JIT-компилятор для повышения производительности.
Вывод
Так, а какой язык выбрать, с компиляцией или интерпретацией? Все как всегда зависит от твоих целей и от того, находится ли Венера в скорпионе или же в Овне, амиго! Если тебе важна скорость работы программы и ты печешься об оптимизации ресурсов и безопасности, то смотри в сторону компилируемых языков. А если вам важно быстро писать скрипты и легко их обновлять, то в сторону интерпретируемого.
На самом деле любой язык может быть скомпилирован или интерпретирован, если очень захотеть. Просто создатели языка изначально заложили то, что тот или иной метод перевода на язык компьютера будет работать лучше.
Ну вот и все, друг
! Мы немного рассказали о том, как компьютеры понимают код программистов. Надеюсь, тебе было интересно и полезно! Если у тебя остались вопросы или комментарии, пиши нам внизу!