Библиотека собеса по PHP | вопросы с собеседований
3.16K subscribers
191 photos
6 videos
126 links
Вопросы с собеседований по PHP и ответы на них.

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

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

Для обратной связи: @proglibrary_feeedback_bot
Download Telegram
Что такое preloading в PHP и какие у него ограничения?

Preloading (PHP 7.4+) — механизм, при котором PHP загружает файлы в память один раз при старте PHP-FPM и держит их там на весь срок жизни процесса. Последующие запросы используют уже скомпилированный opcode без обращения к диску.

▪️ Что даёт

— Устраняет overhead на парсинг и компиляцию горячих классов
— Реальный прирост на больших фреймворках (Laravel, Symfony) — 10–30% к RPS

▪️ Ограничения

— При любом изменении файла нужен рестарт PHP-FPM, иначе изменения не подхватятся.
— Preloaded классы нельзя пересоздать или переопределить в рантайме
— Если preloaded класс зависит от другого файла, тот тоже должен быть preloaded, иначе ошибка при старте
— Не работает с circular dependencies между файлами
— Работает только с OPcache
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1🤔1
✔️ PHP-тест: Fibers + замыкания в Laravel

Классическая ловушка с утечкой состояния 👇

📦 Задание

Написали систему обработки платёжных webhook'ов. В логах периодически замечают, что у одной транзакции записывается merchant_id другой. Баг плавающий, воспроизводится только под нагрузкой. Найдите проблему и исправьте:

class MerchantContext
{
private static ?string $currentMerchantId = null;

public static function set(string $id): void
{
self::$currentMerchantId = $id;
}

public static function get(): ?string
{
return self::$currentMerchantId;
}

public static function clear(): void
{
self::$currentMerchantId = null;
}
}

class WebhookProcessor
{
public function handle(WebhookPayload $payload): void
{
MerchantContext::set($payload->merchantId);

$fiber = new Fiber(function () use ($payload): void {
$result = $this->validateSignature($payload);

// симулируем I/O — запрос к внешнему сервису
Fiber::suspend();

$this->auditLogger->log(
'Webhook processed for: ' . MerchantContext::get(),
['amount' => $payload->amount]
);
});

$fiber->start();
// ... другие файберы запускаются здесь
$fiber->resume();
}
}


🔹 Задачи

— Объяснить, почему MerchantContext::get() после resume() может вернуть merchant_id другого запроса
— Исправить так, чтобы контекст не терялся при переключении между файберами

Ставьте → 🔥 если нравится формат. Если нет → 🌚

💬 Решения пишите в комменты под спойлер — сравним подходы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍1🤔1
Что такое Closure и зачем нужен use?

Closure — это анонимная функция. Объект класса Closure под капотом.
use захватывает переменные из внешнего скоупа внутрь замыкания.

$discount = 10;

$price = fn($amount) => $amount - $discount; // не работает

$price = function($amount) use ($discount) {
return $amount - $discount; // работает
};
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1😢1🥱1👾1
Какие HTTP-методы есть?

GET: этот метод используется для запроса содержимого указанного ресурса.

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

PUT: используется для создания или обновления ресурса на сервере.

DELETE: удалить указанный ресурс с сервера.

PATCH: используется для частичного обновления ресурса.

HEAD: метод полезен, когда клиенту нужны только заголовки, а не фактическое содержимое.

OPTIONS: получить информацию о возможностях сервера относительно ресурса или сервера в целом. Это может включать доступные методы, поддерживаемые заголовки и другую метаинформацию.

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

CONNECT: используется для установки виртуального соединения с сервером, обеспечивая прозрачное шифрование SSL через промежуточный узел.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
В чем разница между '==' и '===' ?

Нестрогое сравнение («==»): При использовании двойного знака равенства PHP сравнивает значения операндов после их преобразования в общий тип данных. Например, 5 == '5' вернет true, потому что PHP преобразует строку '5' в целое число 5 перед сравнением.

Строгое сравнение («===»): При использовании тройного знака равенства PHP сравнивает не только значения операндов, но и их типы данных. Это означает, что для того чтобы выражение было истинным, значения операндов должны быть одинаковыми и одного типа. Например, 5 === '5' вернет false, потому что типы операндов различны.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
☝️ Уже сегодня: ИИ-агенты в продакшене — инженерный подход к интеграции LLM

Индустрия активно обсуждает потенциал нейросетей, способных автоматизировать бизнес-процессы и заменить целые отделы. Однако реальное внедрение агентов в production вскрывает серьёзные проблемы: разработчикам приходится бороться с непредсказуемыми галлюцинациями моделей, нестабильными API и сложной интеграцией в существующую архитектуру.

Сегодня в 19:00 МСК в рамках нашего курса «Разработка AI-агентов» мы проведём открытый вебинар «ИИ-агенты в продакшене: от хайпа к деньгам». Спикер — Полина Полунина, руководитель AI-направления в Альфа-Банке. Будем говорить о нейросетях с позиции жёсткой инженерии.

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

Тем, кто придёт на эфир, дадим промокод AGENTS на скидку 10 000 ₽ на любой тариф курса.

👉 Занять место на вебинаре
🥱1
Часовая готовность: создаём ИИ-агента в прямом эфире

В 19:00 МСК в рамках нашего курса «Разработка AI-агентов» стартует вебинар «ИИ-агенты в продакшене: от хайпа к деньгам». Спикер — Полина Полунина, руководитель AI-направления в Альфа-Банке.

Будет live-демо работающего агента, реальные метрики из корпоративной среды и честный разбор архитектурных граблей — без воды и «успешного успеха».

Всем зрителям эфира дадим эксклюзивный промокод AGENTS на скидку 10 000 ₽ на любой тариф курса.

👉 Занять место на вебинаре
🥱1
Чем отличается абстрактный класс от интерфейса?

Интерфейс — чистый контракт. Только сигнатуры методов и константы, никакой реализации. Класс может реализовывать сколько угодно интерфейсов.

Абстрактный класс — уже частичная реализация: может содержать конкретные методы, свойства, конструктор. Наследоваться можно только от одного.

Правило выбора простое: если нужно описать что умеет объект — интерфейс. Если нужно вынести общую логику и состояние — абстрактный класс.

В хорошей архитектуре они часто работают вместе: абстрактный класс реализует интерфейс частично, потомки добивают остальное.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Что такое trait и зачем он нужен, если есть абстрактные классы?

Trait — механизм горизонтального переиспользования кода. PHP не поддерживает множественное наследование, trait это обходит: он буквально копирует методы в класс на этапе компиляции. Класс может использовать несколько трейтов одновременно.

Хорошо подходит для сквозной функциональности: логирование, soft delete, timestamps, работа с UUID. Плохо — когда трейт начинает зависеть от свойств класса, которые в нём не объявлены. Это скрытая связанность, и трейтами легко злоупотребить. Если видишь трейт с $this->connection без объявления свойства — это запах.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🥱2🔥1😁1
Что такое PSR-4?

Стандарт автозагрузки классов от PHP-FIG. Описывает как неймспейс маппится на структуру директорий. Composer реализует его из коробки через секцию autoload в composer.json.

Суть: App\Services\PaymentService должен лежать в src/Services/PaymentService.php, если корневой неймспейс App\ смаплен на src/. Без этого стандарта каждый фреймворк изобретал свой автолоадер. PSR-4 заменил устаревший PSR-0 и сейчас де-факто обязателен в любом современном PHP-проекте.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3
✔️ PHP-тест: Static state + OPcache + Preloading

Классический баг, который ломает прод и не воспроизводится локально 👇

📦 Задание

Команда добавила preloading в production для ускорения.

Через день в логах появились странные ошибки: у разных пользователей в одном запросе перемешиваются данные — кто-то видит чужие настройки, кто-то получает null там, где не должен.

На dev-машинах не воспроизводится. Найдите проблему в коде:
// preload.php 
require_once 'src/Config.php';
require_once 'src/UserContext.php';
require_once 'src/RequestPipeline.php';

// config/app.php
class Config
{
private static array $data = [];
private static bool $loaded = false;

public static function load(string $env): void
{
if (self::$loaded) {
return;
}
self::$data = parse_ini_file("config/{$env}.ini");
self::$loaded = true;
}

public static function get(string $key): mixed
{
return self::$data[$key] ?? null;
}
}

// src/UserContext.php
class UserContext
{
private static ?array $current = null;

public static function set(array $user): void
{
self::$current = $user;
}

public static function get(): ?array
{
return self::$current;
}

public static function clear(): void
{
self::$current = null;
}
}

// src/RequestPipeline.php
class RequestPipeline
{
private static array $middlewareResults = [];

public static function addResult(string $key, mixed $value): void
{
self::$middlewareResults[$key] = $value;
}

public static function getResult(string $key): mixed
{
return self::$middlewareResults[$key] ?? null;
}

public static function reset(): void
{
self::$middlewareResults = [];
}
}

// public/index.php
Config::load($_ENV['APP_ENV'] ?? 'production');

$user = Auth::check($_SERVER['HTTP_AUTHORIZATION'] ?? '');
UserContext::set($user);

RequestPipeline::addResult('ip', $_SERVER['REMOTE_ADDR']);
RequestPipeline::addResult('ua', $_SERVER['HTTP_USER_AGENT'] ?? '');

$app->handle(ServerRequest::fromGlobals());


🔹 Задачи

— Объяснить, почему при preloading статические свойства классов ведут себя иначе, чем без него, и как это связано с жизненным циклом worker-процесса.
— Объяснить, чем классы отличаются по характеру утечки
— Предложить архитектурное решение: как правильно управлять request-scoped состоянием в long-running процессах

Ставьте → 🔥 если нравится формат. Если нет → 🌚

💬 Решения пишите в комменты под спойлер — сравним подходы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍2🤔2🥱1
Самый востребованный навык в ИТ в 2026-м — навык создания ИИ-агентов

Мы полностью переработали курс «Разработка AI-агентов» под реалии 2026 года. Никакой долгой теории — с самого начала пишем код. Обучать и делиться набитыми шишками будут эксперты-практики из Газпромбанка, Альфа-Банка и других бигтехов.

В программе:

— архитектура автономных систем с тестированием, ReAct-циклами и контролем токенов;
— практическая работа с актуальными фреймворками LangGraph, AutoGen, MCP и CrewAI;
— настройка продвинутого RAG для парсинга документов и точного поиска;
— внедрение решений с учётом действующего законодательства (152-ФЗ);
— дипломная работа, за основу которой можно взять свой рабочий проект или задачу, которую предложим мы.

Эксперты поделятся инсайтами из реального продакшна — тем, о чём вам никогда не расскажет ни одна нейросеть.

Запись первого открытого вебинара, на котором мы вместе с руководителем AI-направления в Альфа-Банке Полиной Полуниной пилили агента в прямом эфире.


Ах да, чуть не забыли! Дарим промокод AGENTSWEB на скидку 10 000 рублей и два курса сверху при покупке до 15 марта 🎁

Стать AI-инженером
🥱21
Что такое Composer?

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

🔹 Основные функции Composer

▪️ Установка зависимостей: Composer позволяет определить необходимые библиотеки и их версии в файле composer.json, а затем установить их с помощью команды composer install.

▪️ Обновление зависимостей: после установки библиотек, можно обновить их до последних версий, указанных в файле composer.json, с помощью команды composer update.

▪️ Автозагрузка классов: Composer автоматически создает файл автозагрузки, который позволяет использовать классы из установленных зависимостей без необходимости явного подключения файлов.

▪️ Автоматическое разрешение зависимостей: Composer управляет разрешением зависимостей, учитывая совместимость версий между различными библиотеками.

▪️ Создание собственных пакетов: Composer позволяет создавать собственные пакеты для повторного использования в различных проектах и их публикации в репозитории Packagist для общего использования.
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1🔥1
Зачем использовать yield вместо return с массивом?

yield превращает функцию в генератор. Вместо того чтобы собрать все данные в массив и вернуть целиком, функция отдаёт значения по одному, по мере запроса.

Главный профит — память. Если обрабатываешь CSV на 500 тысяч строк, с массивом ты загрузишь всё в RAM разом. С генератором в памяти живёт одна строка. Генератор реализует интерфейс Iterator, с ним работает foreach. Минус — нельзя перемотать назад, обойти можно только один раз. Используй когда данных много, порядок линейный, и случайный доступ не нужен.
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3🔥1
Кажется, мы окончательно перешли от игрушек к суровому AgentOps

Приглашаем на наш обновлённый курс по разработке ИИ-агентов. Никакой воды про «будущее нейросетей», только инженерный подход.

На курсе мы:

— пошагово строим готовые системы на LangGraph, CrewAI и MCP;
— настраиваем кэширование и роутинг, чтобы бот не сожрал токены;
— разбираемся со стейтом, учимся дебажить через time-travel и прикручиваем human-in-the-loop;
— выводим RAG в прод так, чтобы безопасники не завернули архитектуру из-за 152-ФЗ.

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

Кстати, на днях мы пилили агента в прямом эфире, если пропустили — есть запись вебинара.


Сегодня последний день, когда можно забрать курс по старым ценам. Базовый тариф сейчас стоит 49 000 ₽ (вместо 62 990 ₽), продвинутый трек — 99 000 ₽ (вместо 124 990 ₽). Если не хочется отдавать всю сумму сразу, есть рассрочка. Торопитесь — на потоке осталось всего 5 мест!

Зафиксировать цену и перейти к сборке своих агентов
Что такое PSR и зачем это нужно?

PSR (PHP Standards Recommendations) — набор стандартов от PHP-FIG, которые обеспечивают совместимость кода между проектами и пакетами.

Ключевые стандарты:

• PSR-1 / PSR-12 — стиль кода (отступы, имена классов, методов)
• PSR-4 — автозагрузка: пространство имён → путь к файлу
• PSR-3 — интерфейс логгера (LoggerInterface)
• PSR-7 — HTTP-сообщения (Request / Response)
• PSR-11 — контейнер зависимостей (ContainerInterface)
• PSR-15 — HTTP middleware

Без PSR библиотеки несовместимы, composer не может их объединить, а команды пишут в разных стилях. PSR — это общий язык PHP-экосистемы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Что такое Dependency Injection?

DI — паттерн, при котором зависимости класса передаются извне, а не создаются внутри.

// Плохо — жёсткая связанность:
class OrderService {
private $mailer;
public function __construct() {
$this->mailer = new SmtpMailer(); // зависимость зашита внутри
}
}

// Хорошо — DI:
class OrderService {
public function __construct(private MailerInterface $mailer) {}
}


Зачем:


✔️ Легко подменить реализацию (например, для тестов — MockMailer)
✔️ Классы не знают о конкретных реализациях (зависимость от абстракции)
✔️ Код легче тестировать, поддерживать, расширять

DI Container (Symfony, Laravel) автоматизирует создание объектов и внедрение зависимостей по всему приложению.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31🔥1
Что такое магические методы? Назови основные.

Магические методы — методы с двойным подчёркиванием, которые PHP вызывает автоматически в определённых ситуациях.

__construct() / __destruct() — создание и уничтожение объекта
__get($name) / __set($name, $value) — обращение к несуществующему свойству
__isset($name) / __unset($name) — isset() / unset() на несуществующем свойстве
__call($name, $args) — вызов несуществующего метода экземпляра
__callStatic($name, $args) — вызов несуществующего статического метода
__toString() — приведение объекта к строке
__invoke() — вызов объекта как функции
__clone() — после clone()
__sleep() / __wakeup() — перед serialize() / после unserialize()
__debugInfo() — что показывать в var_dump()
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
Как работают генераторы?

Генератор — функция с yield, которая возвращает значения по одному, не загружая всё в память.

function readLargeFile(string $file): \Generator {
$handle = fopen($file, 'r');
while (!feof($handle)) {
yield fgets($handle);
}
fclose($handle);
}

foreach (readLargeFile('10gb.log') as $line) {
process($line);
}


Без генератора file() загрузил бы весь файл в массив → OutOfMemoryError.

Генератор реализует интерфейс Iterator. Ключевые отличия от обычной функции:

• Выполнение приостанавливается на yield
• Возобновляется при следующем обращении к итератору
• yield from позволяет делегировать другому генератору

Применение: обработка больших файлов, пагинация из DB, потоковая генерация данных.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3😁3🔥2