интервьюер: Давайте начнем сегодня с основ,Как вы понимаете, что Java является «кросс-платформенным» языком, что означает «компилировать один раз, запускать где угодно»?
Кандидат: Хорошо понял, ведь у нас JVM.
Кандидат: исходный код Java будет скомпилирован в файлы классов, файлы классов запускаются на JVM.
Кандидат: Когда мы ежедневно разрабатываем и устанавливаем JDK, мы можем обнаружить, что JDK разделен на «разные операционные системы», а JDK содержит JVM, поэтому Java полагается на JVM для достижения «кроссплатформенности».
Кандидат: JVM ориентирована на операционную систему, отвечает за интерпретацию байт-кода класса в инструкции, распознаваемые системой и их выполнение, а также отвечает за управление памятью во время работы программы.
интервьюер:Тогда почему бы вам не рассказать о процессе от файла исходного кода (.java) до выполнения кода?
Кандидат: ну да ладно
Кандидат: Если кратко, я думаю, что есть 4 шага: компиляция->загрузка->интерпретация->выполнение.
Кандидат: Compile: скомпилируйте исходный файл в файл класса, который может интерпретировать JVM.
Кандидат: Процесс компиляции выполнит «синтаксический анализ», «семантический анализ», «обработку аннотаций» и т. д. в программе с исходным кодом и, наконец, сгенерирует файл байт-кода.
Кандидат: Например, стирание дженериков и Lombok, которые мы часто используем, выполняется на этапе компиляции.
Кандидат:load: Загрузите скомпилированный файл класса в JVM.
Кандидат: На этапе загрузки можно уточнить несколько шагов: Загрузка -> Подключение -> Инициализация
Кандидат: Теперь я подробно расскажу об этих шагах.
Кандидат: [Время загрузки] В целях экономии памяти все классы не будут загружаться в JVM одновременно, а будут загружаться по мере «необходимости» (например, новые и отражение и т. д.)
Кандидат:[Происходит загрузка] Файл класса загружается в jvm через "загрузчик классов".Для предотвращения появления в памяти нескольких копий одного и того же байткода используется механизм родительского делегирования (он не будет пытаться загрузить этот класс само собой, а стоит делегировать запрос родительскому загрузчику на завершение, по очереди вверх)
Кандидат: [Правила загрузки] Классы собственных методов в JDK обычно загружаются корневым загрузчиком (загрузчик Bootstrp), классы расширений, реализованные в JDK, обычно загружаются загрузчиком расширений (ExtClassLoader), а файлы классов в программе загружаются системный загрузчик (AppClassLoader ) осуществляет загрузку.
Кандидат: Загрузка того, что он делает на этом этапе, можно резюмировать следующим образом: найти и загрузить двоичные данные класса, создать объект класса java.lang.Class в «куче» JVM и сохранить информацию, связанную с классом, в JVM "область методов" середина
интервьюер:В порядке…
Кандидат: После шага «загрузки» файл класса загружен в JVM, а соответствующий объект класса и информация о классе созданы и сохранены в области методов.
Кандидат: то, что он делает на этапе «подключения», можно резюмировать как: проверка информации о классе, выделение памяти для «переменных класса» и присвоение им значений по умолчанию.
Кандидат: Соединение можно уточнить в несколько этапов: проверка -> подготовка -> разбор
Кандидат: 1. Проверка. Убедитесь, что класс соответствует спецификации Java и спецификации JVM.
Кандидат: 2. Подготовка: выделяем память под статические переменные класса и инициализируем ее начальным значением системы
Кандидат: 3. Парсинг: процесс преобразования символических ссылок в прямые ссылки
интервьюер:В порядке…
Кандидат: После прохождения шага «подключение» информация о классе теперь проверена, а пространство памяти и значения по умолчанию выделены.
Кандидат: Далее следует этап «инициализации», который можно обобщить как: присвоение правильных начальных значений статическим переменным класса.
Кандидат: Процесс, вероятно, заключается в сборе статических переменных класса, статических блоков кода, статических методов в () методов, а затем выполняется сверху вниз.
Кандидат: Если вы «создаете экземпляр объекта», будет вызван метод для инициализации переменной экземпляра, и будет выполнен код в соответствующем конструкторе.
Кандидат: После всего, теперь он фактически завершен до этапа загрузки в (компиляция->загрузка->интерпретация->выполнить), давайте поговорим о том, что делает [этап интерпретации]
Кандидат: после завершения инициализации, когда мы пытаемся выполнить метод класса, мы находим информацию о байт-коде соответствующего метода, а затем интерпретатор интерпретирует информацию о байт-коде в код инструкции, который система может распознать.
Кандидат: то, что он делает на этапе «интерпретации», можно резюмировать следующим образом: преобразование байт-кода в инструкции, распознаваемые операционной системой.
Кандидат: На этапе интерпретации есть два способа интерпретировать информацию байт-кода в код машинных инструкций: один — интерпретатор байт-кода, а другой — JIT-компилятор.
Кандидат: JVM скомпилирует «горячий код», а негорячий код будет интерпретирован напрямую. Когда JVM обнаруживает, что метод или блок кода запускается очень часто, она может идентифицировать эту часть кода как «горячий код».
Кандидат: Используйте «обнаружение горячих точек», чтобы определить, является ли это кодом горячих точек. Обычно существует два способа «обнаружения горячих точек»: счетчик и выборка. HotSpot использует метод «счетчик» для обнаружения, и для каждого метода подготовлены два типа счетчиков: счетчик вызова метода и счетчик возврата.
Кандидат: Эти два счетчика имеют определенный порог. Когда счетчик переполняется за пределы порога, запускается JIT-компиляция.
Кандидат: компилятор реального времени сохраняет код инструкции метода горячей точки и напрямую выполняет кэшированный машинный язык, не повторяя интерпретацию при следующем выполнении.
интервьюер:В порядке…
Кандидат: После завершения фазы интерпретации, наконец, наступает фаза исполнения.
Кандидат: то, что он делает на этапе «выполнения», можно резюмировать следующим образом: операционная система анализирует код инструкции от интерпретатора и вызывает аппаратное обеспечение системы для выполнения окончательной инструкции программы.
Кандидат: вышеизложенное — это мое понимание процесса от файла исходного кода (.java) до выполнения кода.
интервьюер: Ну... Я также хочу спросить о модели родительского делегирования, которую вы только что упомянули...
Кандидат: Обязательно в следующий раз!
В этой статье делается вывод:
-
Кроссплатформенность Java, поскольку JVM защищает базовую операционную систему.
-
С точки зрения JVM процесс от исходного кода Java до исполнения можно свести к четырем этапам: компиляция -> загрузка -> интерпретация -> выполнение.
- «Компиляция» проходит синтаксический анализ, семантический анализ, обработку аннотаций и, наконец, генерирует файл класса.
- «Загрузку» можно разделить на этапы: загрузка -> подключение -> инициализация. При загрузке файл класса загружается в JVM, при компоновке проверяется информация о классе, выделяется место в памяти и присваиваются значения по умолчанию, а при инициализации переменной присваивается правильное начальное значение. Соединение можно уточнить в: проверка, подготовка, разбор
- «Интерпретация» заключается в преобразовании байт-кода в исполняемые инструкции, распознаваемые операционной системой.В JVM будет интерпретатор байт-кода и компилятор в реальном времени. Во время интерпретации код будет проанализирован, чтобы определить, является ли он «горячим кодом».Если это «горячий код», будет запущена JIT-компиляция, и нет необходимости повторять интерпретацию при следующем выполнении, повышение скорости интерпретации.
- «Выполнить» аппаратное обеспечение, которое вызывает систему для выполнения последней инструкции программы.
Добро пожаловать в мой публичный аккаунт WeChat【Java3y] Давайте поговорим о Java-интервью, серия онлайн-интервьюеров постоянно обновляется!
Серия [Онлайн-интервьюер-Мобильный терминал]Продолжаем обновлять два раза в неделю!
【Онлайн-интервьюер-компьютер】СерияПродолжаем обновлять два раза в неделю!
Оригинал это не просто! ! Проси три! !