From 472e8891326556429eca94a301f3eb62277edcf3 Mon Sep 17 00:00:00 2001 From: egorzhurov Date: Sat, 11 May 2024 15:58:29 +0300 Subject: [PATCH] Move 35 article to markdown format --- .../Compilation and interpretation in Java.md | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 lessons/java-core/035/Compilation and interpretation in Java.md diff --git a/lessons/java-core/035/Compilation and interpretation in Java.md b/lessons/java-core/035/Compilation and interpretation in Java.md new file mode 100644 index 0000000..3854be3 --- /dev/null +++ b/lessons/java-core/035/Compilation and interpretation in Java.md @@ -0,0 +1,109 @@ +# Компиляция и интерпретация в Java + +Сегодняшний урок будет ознакомительным. В нем мы поверхностно познакомимся с механизмами JVM, превращающими Java-код в +работающую программу. + +**Высокоуровневые языки программирования** (в той или иной степени, сюда можно отнести почти все широко известные языки, +кроме **ассемблера**) обладают высокой степенью абстракции над **машинным кодом** – условно говоря, нулями и единицами, +воспринимаемыми процессором. + +Отсюда рождается необходимость в механизме «перевода» программного кода на высокоуровневом языке в то, что будет понятно +условному процессору, который будет исполнять программу. Такой процесс называется **компиляцией**. + +Справедливости ради, программы на высокоуровневых языках не превращаются в **бинарный код** напрямую (те самые нули и +единицы), вместо этого они компилируются в эквивалентные программы на языке, понятном конкретному процессору. Таким +языком может выступать ассемблер. Главное, что нужно вынести на текущем этапе – результатом компиляции программы на +условном C++ является программа на не менее условном ассемблере. + +Если копнуть ниже, каждая программная инструкция низкоуровневого языка будет оберткой над нулями и единицами. Но это +выходит далеко за пределы данного урока. + +Итак, мы имеем некий процесс компиляции, который из понятного разработчику кода сделает непонятный разработчику код. Но +во многих языках на этом решили не останавливаться и появился еще один термин – **интерпретация**. + +**Интерпретация** – построчный анализ, обработку и выполнение программного кода. В рамках определения не играет роли +язык, на котором написана программа. + +Важным отличием компиляции от интерпретации является то, что компиляция обрабатывает весь текст программы целиком, +интерпретация – это всегда про построчную обработку. Второе важное отличие – компиляция не выполняет программу, это лишь +процесс «перевода». + +**Интерпретируемые языки программирования** – достаточно обширная тема, нас же интересует интерпретируемость в рамках +Java (в целом, для ряда других языков, вроде Python или Basic, описанное тоже будет, отчасти, верно). + +Проблема компилируемых языков в том, что они зависят от конкретного процессора. Как более верхнеуровневая надстройка, +они зависят от операционной системы. Скажем, не любая программа, написанная на C и работающая на Linux, будет работать +на Windows. + +Java, в свою очередь, была создана под лозунгом _«Write Once, Run Anywhere»_. Наиболее популярный, хоть и не совсем +корректный русский перевод – _«Написано однажды – работает везде»_. Таким образом, Java гарантирует, что программа, +написанная на Java будет работать одинаково вне зависимости от архитектуры процессора, операционной системы и +политических тенденций. На самом деле, в любом правиле есть свои исключения, но сегодня не об этом. + +Как бы там ни было, подход, направленный на универсальность кода привел к рождению **JVM – Java Virtual Machine**, +которая является прослойкой между Java-кодом и всем тем, что влияет на исполнение программы (от операционной системы до +процессора). + +По сути, в этом контексте JVM является интерфейсом, который с одной стороны принимает Java-код, с другой – имеет +различные реализации под различные операционные системы, что и позволяет программе иметь одинаковое поведение. + +Однако для JVM потребовался некий аналог машинного кода, понятный интерпретатору виртуальной машины. Такой аналог +называется **байткодом**. Байткод не является чем-то характерным только для Java – он существует во многих +интерпретируемых языках. + +На данном этапе мы можем описать путь от Java-кода до выполнения программы следующим образом: Java-код компилируется в +байткод, байткод выполняется интерпретатором. Общий термин, объединяющий компиляцию и интерпретацию – **трансляция**. +Его тоже стоит запомнить, ибо в рамках данной темы он частоупотребим. + +Безусловно, на практике все немного сложнее, но есть и плюс – Java-разработчику редко приходится даже работать с +настройкой JVM, не говоря о практическом применении информации о более глубоких механизмах, связанных с компиляцией и +интерпретацией. Но кое-что знать, все же стоит. + +Предлагаю обратить внимание на данную +[статью](https://javarush.com/groups/posts/2256-kompiljacija-i-ispolnenie-java-prilozheniy-pod-kapotom) + +В ней достаточно лаконично пересказывается изложенное выше и немного описываются более низкоуровневые механизмы. Также +она знакомит с компилятором в bytecode – _javac_ и интерпретатором – _java_. Как итог, демонстрирует запуск +Java-программы без помощи IDE. + +К сожалению, автор обошел стороной несколько важных моментов, но их постараюсь подсветить я. В подробности вдаваться не +будем, боюсь, тема и так получилась нелегкой. + +Продемонстрированная в статье компиляцией одного единственного класса – это хорошо в рамках примера. Но в реальных +условиях все было бы немного сложнее. + +Предлагаю обратить внимание на следующую [статью](https://javarush.com/groups/posts/2318-kompiljacija-v-java). +Рекомендую дочитать до раздела _«Создание JAR-файлов»_, с ним и тем, что после – ознакомимся в свое время. + +К сожалению, в данной статье примеры компиляции и запуска приводятся только для Windows, но кардинальных отличий для +других ОС не будет. + +Кроме того, в рамках первой статьи была упомянута и достаточно неплохо описана, насколько позволял формат, * +*JIT-компиляция** (она также называется **динамической**). Однако в рамках Java такой подход является не единственно +возможным. С Java 9 существует также **AOT – Ahead-of-Time** – компиляция. Она же – **статическая компиляция**. Именно +этот тип компиляции используется в классических **компилируемых языках** (например, C++). + +Основная разница заключается в том, что JIT компилирует байткод в машинный код (да, интерпретация тоже подразумевает +компиляцию внутри себя), но поскольку JIT отрабатывает прямо по ходу выполнения программы, это достаточно дорого и +долго, в том числе поэтому приложения на Java (и интерпретируемых языках в целом) работают медленнее, чем приложения, +написанные на компилируемых языках. + +В это время AOT компилирует байткод в машинный код заранее. Тем самым делает процесс запуска и работы приложения +быстрее. Как показывает практика, это нужно далеко не всегда, но сам факт наличия такой возможности в Java был +определенным шагом вперед. + +Тема JIT и AOT компиляций достаточно сложная и требует определенного уровня экспертизы. В рамках данной статьи она +дается очень поверхностно - по сути, на уровне базовых определений. Но вы можете попытаться разобраться в ней +самостоятельно, если данная тема кажется интересной, поскольку в рамках курса мы нырять в это не будем. + +#### На сегодня все! + +![img.png](../../../commonmedia/justTheoryFooter.png) + +> Если что-то непонятно или не получается – welcome в комменты к посту или в лс:) +> +> Канал: https://t.me/ViamSupervadetVadens +> +> Мой тг: https://t.me/ironicMotherfucker +> +> **Дорогу осилит идущий!** \ No newline at end of file