Библиотека собеса по PHP | вопросы с собеседований
3.39K subscribers
140 photos
2 videos
70 links
Вопросы с собеседований по PHP и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/9f3affba

Работать у нас: https://job.proglib.io/

Наши каналы: https://yangx.top/proglibrary/9197
加入频道
В чем разница между include, require, include_once и require_once на уровне производительности?

​В PHP конструкции include, require, include_once и require_once используются для включения содержимого одного файла в другой. Основные различия между ними связаны с обработкой ошибок и повторным включением файлов. С точки зрения производительности различия минимальны, но некоторые нюансы стоит учитывать.​

Обзор конструкций:

include: Включает указанный файл. Если файл не найден, генерируется предупреждение (E_WARNING), и выполнение скрипта продолжается.​

require: Аналогично include, но при отсутствии файла вызывает фатальную ошибку (E_COMPILE_ERROR), останавливая выполнение скрипта.​

include_once: Действует как include, но проверяет, был ли файл уже включен ранее; если да, повторное включение не происходит.​

require_once: Работает аналогично require, с дополнительной проверкой на предыдущее включение файла, предотвращая повторное его подключение.​

Различия в производительности:

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

include и require: Каждый раз при вызове происходит повторное включение и выполнение кода из указанного файла, что может привести к избыточным операциям и увеличению времени выполнения, особенно если файл содержит ресурсоемкий код.​

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

Практические рекомендации:

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

🔸 Для менее критичных файлов можно использовать include или include_once, в зависимости от необходимости проверки на повторное включение.​

🔸 Избегайте многократного включения одного и того же файла в рамках одного запроса без необходимости, чтобы минимизировать накладные расходы и потенциальные ошибки.
Что такое JIT? Как он работает?

JIT (Just-In-Time) компиляция представляет собой метод оптимизации выполнения кода, при котором код не компилируется заранее в процессе разработки, а только перед фактическим его выполнением во время работы программы. Это позволяет улучшить производительность программы за счет оптимизаций, которые могут быть применены с учетом конкретных условий выполнения.

Как это работает:

Исходный код на PHP: Начинаем с написания нашего кода на PHP, который является языком сценариев с динамической типизацией.

Компиляция в промежуточный код (opcode): Исходный код PHP компилируется в промежуточный байт-код, который представляет собой некий промежуточный представитель нашего кода, близкий к машинному коду, но все еще независимый от конкретной аппаратной платформы.

Исполнение байт-кода: Этот байт-код может быть интерпретирован непосредственно виртуальной машиной PHP (Zend VM), что происходит по умолчанию. Однако, в контексте JIT, в определенный момент, когда интерпретатор PHP обнаруживает, что некий участок кода используется достаточно часто, он может решить скомпилировать этот участок кода в машинный код «на лету».

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

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

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

​Принцип инверсии управления (Inversion of Control, IoC) в Laravel реализуется с помощью сервис-контейнера, который управляет зависимостями между классами и их внедрением. Это позволяет создавать гибкую и тестируемую архитектуру приложений.

В нашем примере:

Определяется интерфейс PaymentGatewayInterface с методом charge, который должен быть реализован любым платежным шлюзом.

Класс StripePaymentGateway реализует этот интерфейс, предоставляя конкретную логику для обработки платежей через Stripe.

Класс OrderProcessor зависит от PaymentGatewayInterface. Вместо создания экземпляра конкретного платежного шлюза внутри себя, он получает его через конструктор, что соответствует принципу инверсии управления.

В сервис-контейнере Laravel регистрируется связь между PaymentGatewayInterface и его реализацией StripePaymentGateway с помощью метода $app->bind().

Создание экземпляра OrderProcessor осуществляется через сервис-контейнер с помощью метода $app->make(), который автоматически внедрит необходимые зависимости.

Использование IoC в Laravel позволяет:​

🔸 Разделить ответственность между классами, делая их более независимыми и удобными для тестирования.

🔸 Легко заменять реализации зависимостей, например, для использования другого платежного шлюза, достаточно зарегистрировать новую реализацию в контейнере.

🔸 Упрощает тестирование, позволяя подменять реальные реализации зависимостей на заглушки или моки.
Как можно выполнить PHP-код через eval() без явного использования eval()?

​Выполнение динамически сформированного PHP-кода без явного использования функции eval() возможно через альтернативные методы, каждый из которых имеет свои особенности и области применения. Ниже рассмотрены основные подходы:​

1. Использование функции create_function()

Ранее в PHP существовала функция create_function(), позволяющая создавать анонимные функции из строковых выражений. Однако начиная с PHP 7.2.0 эта функция объявлена устаревшей, а в PHP 8.0.0 удалена. Поэтому её использование не рекомендуется.​

2. Динамическое создание и подключение файлов

Другой подход заключается в создании временного PHP-файла с необходимым кодом и его последующем подключении с помощью конструкции include или require.​

Пример:

$code = '';$tempFile = tempnam(sys_get_temp_dir(), 'php');file_put_contents($tempFile, $code);include $tempFile;unlink($tempFile); // Удаляем временный файл после выполнения


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

3. Использование шаблонизаторов

Если цель заключается в динамическом формировании и отображении контента, рекомендуется использовать шаблонизаторы, такие как Twig или Smarty. Они обеспечивают безопасность и гибкость при работе с динамическими данными, избегая прямого выполнения кода.​

Пример с использованием Twig:
require_once '/path/to/vendor/autoload.php';$loader = new \Twig\Loader\ArrayLoader(['index' => 'Привет, {{ name }}!',]);$twig = new \Twig\Environment($loader);echo $twig->render('index', ['name' => 'мир']);
Опишите поведение при использовании traits с одинаковыми именами полей и / или методов?

При использовании traits с одинаковыми именами полей и/или методов, возникает конфликт имен, который не позволяет PHP однозначно определить, какое поле или метод должны использоваться.

Если в классе используется несколько traits, и в этих traits есть поля или методы с одинаковыми именами, возникает ошибка компиляции «trait method has not been applied», или «trait field has not been applied». По сути, PHP не знает, из какого trait следует взять поле или метод.

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

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

Для масштабирования PHP-приложения можно использовать горизонтальное масштабирование, при котором несколько экземпляров приложения могут работать на разных серверах за балансировщиком нагрузки. Это поможет справиться с высокой нагрузкой. Одной из проблем является обеспечение согласованности данных в нескольких экземплярах приложения.

Другая задача — обеспечить эффективную связь между экземплярами приложения и гарантировать, что каждый экземпляр имеет достаточно ресурсов, чтобы справиться с нагрузкой. Для снижения нагрузки на серверы можно также использовать методы кэширования и оптимизации.
Влияет ли unset() на потребление памяти в PHP?

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

Присвоение переменной значения null также разрывает связь с её данными, но, в отличие от unset(), оставляет переменную в области видимости со значением null. Оба подхода сигнализируют сборщику мусора о возможности освобождения памяти, но фактическое время освобождения определяется внутренними механизмами PHP. ​

В большинстве случаев явное использование unset() или присвоение null не требуется, так как PHP автоматически управляет памятью. Однако в сценариях с длительно работающими скриптами или при обработке больших объемов данных явное освобождение памяти может быть полезным для предотвращения её исчерпания. ​

Важно отметить, что unset() удаляет только ссылку на данные. Если другие переменные ссылаются на те же данные, они останутся в памяти до тех пор, пока все ссылки не будут удалены. ​

Таким образом, хотя unset() может помочь в управлении памятью, его использование не всегда приводит к немедленному освобождению памяти. PHP полагается на сборщик мусора для эффективного управления ресурсами, и в большинстве случаев ручное вмешательство не требуется.
Как настроить мониторинг с помощью Grafana для PHP-приложений?

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

На открытом вебинаре 15 апреля в 20:00 мск вы научитесь:

- Подключать различные источники данных, такие как Graphite и PostgreSQL.
- Визуализировать данные с помощью гибких и информативных графиков.
- Настраивать алерты, чтобы получать уведомления о критических событиях.

Присоединяйтесь к вебинару и получите скидку на большое обучение «PHP Developer. Professional.

Регистрируйтесь прямо сейчас: https://clc.to/i9PBbw

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, erid 2VtzqxTYPyj
Что такое gap locks в MySQL?

Gap locks в MySQL — это блокировки, применяемые на диапазоне значений индексов таблицы, но не на конкретную запись. Они используются для решения проблем с возможными фантомными чтениями и уровнем изоляции транзакций.

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

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

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