es
Feedback
Библиотека собеса по PHP | вопросы с собеседований

Библиотека собеса по PHP | вопросы с собеседований

Ir al canal en Telegram

Вопросы с собеседований по PHP и ответы на них. По рекламе: @proglib_adv Учиться у нас: clc.to/5JWKxA Для обратной связи: @proglibrary_feeedback_bot

Mostrar más
3 114
Suscriptores
-324 horas
-67 días
-1930 días
Archivo de publicaciones
Что такое Covering Index и как он ускоряет запрос? Covering Index — индекс, который содержит все столбцы, необходимые для выполнения запроса. MySQL отвечает прямо из индекса, не обращаясь к основной таблице (heap/clustered index).
  CREATE INDEX idx_user_status ON orders(user_id, status, created_at);
 
  SELECT status, created_at FROM orders WHERE user_id = 5;
Все три поля запроса есть в индексе → MySQL читает только индекс. В EXPLAIN увидишь: Using index. Без covering index: MySQL находит строки через индекс, затем делает дополнительный lookup в основную таблицу за остальными столбцами (random I/O). При большом количестве строк это медленно. Правило проектирования индексов: сначала столбцы из WHERE и JOIN, потом из ORDER BY, потом из SELECT. Порядок в составном индексе критичен — MySQL использует индекс слева направо и останавливается на первом неиспользованном столбце.

Объясни разницу между индексом B-Tree и Hash? B-Tree (сбалансированное дерево) — стандартный тип индекса в InnoDB. Узлы дерева хранят ключи в отсортированном порядке. Поддерживает: — точный поиск: WHERE id = 5 — диапазоны: WHERE id BETWEEN 5 AND 10 — сортировку: ORDER BY id — префиксный поиск: WHERE name LIKE 'Ali%' Hash-индекс — хранит хэш значения ключа. Поиск O(1), но только точное равенство. Не поддерживает диапазоны, сортировку, LIKE.

Чем отличается Optimistic Lock от Pessimistic Lock? Pessimistic Lock — блокируем строку в БД на время транзакции. Никто другой не может её изменить до снятия блокировки.
  SELECT * FROM orders WHERE id = 1 FOR UPDATE;
Применять когда: высокая вероятность конфликта, критичные финансовые операции, короткие транзакции. Минус: снижает throughput, риск дедлоков при блокировке нескольких строк в разном порядке. Optimistic Lock — блокировки нет. У записи есть поле version. При обновлении проверяем, что версия не изменилась:
  UPDATE orders SET status = 'paid', version = 6
  WHERE id = 1 AND version = 5;
Если affected_rows = 0 — кто-то успел раньше, делаем retry или возвращаем ошибку. Применять когда: конфликты редки, операции долгие (нельзя держать блокировку), высокий параллелизм. Минус: нужен retry-механизм, сложнее реализовать корректно.

Как предотвратить SQL-инъекции? SQL-инъекция — подстановка вредоносного SQL через пользовательский ввод.
Плохо:
  $query = "SELECT * FROM users WHERE name = '$name'";
  // name = "' OR '1'='1" → сломает всё
Правильно — подготовленные выражения (prepared statements):
// PDO:
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);

// MySQLi:
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$stmt->execute();
Параметры никогда не попадают в SQL-текст — они передаются отдельно. Дополнительно: • Никогда не доверяй пользовательскому вводу • Принцип минимальных привилегий для DB-пользователя • ORM (Eloquent, Doctrine) использует prepared statements под капотом

Что такое сессии в PHP и какие у них уязвимости? Сессия — механизм хранения данных между HTTP-запросами. PHP создаёт уникальный session_id, передаёт его клиенту в cookie (PHPSESSID), а данные хранит на сервере (файлы, Redis, DB).
session_start();
$_SESSION['user_id'] = $user->id;
Уязвимости: ⚠️ Session Fixation — атакующий подсовывает жертве известный session_id. Решение: session_regenerate_id(true) после логина. ⚠️ Session Hijacking — кража session_id через XSS или сниффинг. Решение: HTTPS, httponly cookie, SameSite. ⚠️ Предсказуемый session_id — в старых PHP. В современных — криптографически безопасный генератор.

Начать рассказывать интервьюеру, как вы ловко дёргаете ручки API через базовый LangChain. Звучит как отличный план, да? Нет, это мгновенный отказ. В свежем отчёте по рынку GPU говорится, что 54% компаний стопают ИИ-внедрения тупо из-за конских затрат на инфраструктуру. На серверах более 70% стоимости — это видеокарты. Поэтому на собесах сейчас спрашивают не про красивые промпты, а про жёсткую экономику агентов. По сути, от вас ждут понимания, как лимитировать ресурсы на лету, роутить запросы и дебажить отказы через механизм time-travel в LangGraph. Если вы до сих пор собираете ботов в ноутбуках, гляньте обновлённый курс «Разработка ИИ-агентов» — фокус там смещён с игрушечных концепций на суровый энтерпрайз. Что требуют от мидлов и выше: — интеграция мультиагентных систем по стандарту MCP; — суровый AgentOps: метрики, трейсинг, защита от деградации пайплайнов; — локальный деплой Open Source под 152-ФЗ (без этого в финтех можно даже не стучаться). Прямо сейчас можно урвать курс с увесистой скидкой (49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек), но стоит поторопиться — на потоке осталось всего 5 мест. 👉 Подтянуть архитектуру до уровня прода

✔️ PHP-тест: Typed Properties + Lazy Initialization + Объект в статике Баг, который живёт в проде месяцами и проявляется только под нагрузкой 👇 📦 Задание Команда пишет модуль биллинга. Ты написал быстрый класс-обёртку для работы с тарифами. Код прошёл ревью, всё работало на стейджинге. В проде через неделю начались жалобы: у части пользователей неправильно считается стоимость. Причём только в пиковые часы.
// src/Billing/TariffCalculator.php
class TariffCalculator
{
    private static TariffConfig $config;
    private static array $cache = [];

    public static function init(array $rawConfig): void
    {
        self::$config = new TariffConfig($rawConfig);
    }

    public static function calculate(int $userId, int $units): float
    {
        $key = $userId . ':' . $units;

        if (isset(self::$cache[$key])) {
            return self::$cache[$key];
        }

        $price = self::$config->getBasePrice()
            * $units
            * self::$config->getUserMultiplier($userId);

        self::$cache[$key] = $price;

        return $price;
    }

    public static function resetCache(): void
    {
        self::$cache = [];
    }
}

// src/Billing/TariffConfig.php
class TariffConfig
{
    private float $basePrice;
    private array $multipliers;

    public function __construct(array $config)
    {
        $this->basePrice   = (float) $config['base_price'];
        $this->multipliers = $config['multipliers'] ?? [];
    }

    public function getBasePrice(): float
    {
        return $this->basePrice;
    }

    public function getUserMultiplier(int $userId): float
    {
        return $this->multipliers[$userId] ?? 1.0;
    }
}

// bootstrap.php — вызывается один раз при старте воркера
TariffCalculator::init(loadConfigFromDB());

// Где-то в обработчике запроса
$price = TariffCalculator::calculate($user->id, $request->units);
🔹 Задачи — Найти все архитектурные и логические проблемы в коде (их несколько) — Объяснить, почему баг проявляется только под нагрузкой и не воспроизводится на стейджинге — Предложить правильное решение Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

Как работают генераторы? Генератор — функция с 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, потоковая генерация данных.

Что такое магические методы? Назови основные. Магические методы — методы с двойным подчёркиванием, которые 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()

Что такое 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) автоматизирует создание объектов и внедрение зависимостей по всему приложению.

Что такое 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-экосистемы.

Кажется, мы окончательно перешли от игрушек к суровому AgentOps Приглашаем на наш обновлённый курс по разработке ИИ-агентов. Никакой воды про «будущее нейросетей», только инженерный подход. На курсе мы: — пошагово строим готовые системы на LangGraph, CrewAI и MCP; — настраиваем кэширование и роутинг, чтобы бот не сожрал токены; — разбираемся со стейтом, учимся дебажить через time-travel и прикручиваем human-in-the-loop; — выводим RAG в прод так, чтобы безопасники не завернули архитектуру из-за 152-ФЗ. В пекло скучные лекции про общую инфраструктуру — сразу фокусируемся на агентных фреймворках и написании кода. Занятия ведут бывалые лиды из Газпромбанка и Альфы, набившие шишки на реальных задачах.
Кстати, на днях мы пилили агента в прямом эфире, если пропустили — есть запись вебинара.
Сегодня последний день, когда можно забрать курс по старым ценам. Базовый тариф сейчас стоит 49 000 ₽ (вместо 62 990 ₽), продвинутый трек — 99 000 ₽ (вместо 124 990 ₽). Если не хочется отдавать всю сумму сразу, есть рассрочка. Торопитесь — на потоке осталось всего 5 мест! → Зафиксировать цену и перейти к сборке своих агентов

Зачем использовать yield вместо return с массивом? yield превращает функцию в генератор. Вместо того чтобы собрать все данные в массив и вернуть целиком, функция отдаёт значения по одному, по мере запроса. Главный профит — память. Если обрабатываешь CSV на 500 тысяч строк, с массивом ты загрузишь всё в RAM разом. С генератором в памяти живёт одна строка. Генератор реализует интерфейс Iterator, с ним работает foreach. Минус — нельзя перемотать назад, обойти можно только один раз. Используй когда данных много, порядок линейный, и случайный доступ не нужен.

Что такое Composer? Composer — это инструмент для управления зависимостями в PHP-приложениях. Он позволяет легко устанавливать, обновлять и управлять библиотеками и фреймворками, которые используются в проекте. 🔹 Основные функции Composer ▪️ Установка зависимостей: Composer позволяет определить необходимые библиотеки и их версии в файле composer.json, а затем установить их с помощью команды composer install. ▪️ Обновление зависимостей: после установки библиотек, можно обновить их до последних версий, указанных в файле composer.json, с помощью команды composer update. ▪️ Автозагрузка классов: Composer автоматически создает файл автозагрузки, который позволяет использовать классы из установленных зависимостей без необходимости явного подключения файлов. ▪️ Автоматическое разрешение зависимостей: Composer управляет разрешением зависимостей, учитывая совместимость версий между различными библиотеками. ▪️ Создание собственных пакетов: Composer позволяет создавать собственные пакеты для повторного использования в различных проектах и их публикации в репозитории Packagist для общего использования.

Самый востребованный навык в ИТ в 2026-м — навык создания ИИ-агентов Мы полностью переработали курс «Разработка AI-агентов» под реалии 2026 года. Никакой долгой теории — с самого начала пишем код. Обучать и делиться набитыми шишками будут эксперты-практики из Газпромбанка, Альфа-Банка и других бигтехов. В программе: — архитектура автономных систем с тестированием, ReAct-циклами и контролем токенов; — практическая работа с актуальными фреймворками LangGraph, AutoGen, MCP и CrewAI; — настройка продвинутого RAG для парсинга документов и точного поиска; — внедрение решений с учётом действующего законодательства (152-ФЗ); — дипломная работа, за основу которой можно взять свой рабочий проект или задачу, которую предложим мы. Эксперты поделятся инсайтами из реального продакшна — тем, о чём вам никогда не расскажет ни одна нейросеть.
Запись первого открытого вебинара, на котором мы вместе с руководителем AI-направления в Альфа-Банке Полиной Полуниной пилили агента в прямом эфире.
Ах да, чуть не забыли! Дарим промокод AGENTSWEB на скидку 10 000 рублей и два курса сверху при покупке до 15 марта 🎁 Стать AI-инженером

✔️ 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 процессах Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

Что такое PSR-4? Стандарт автозагрузки классов от PHP-FIG. Описывает как неймспейс маппится на структуру директорий. Composer реализует его из коробки через секцию autoload в composer.json. Суть: App\Services\PaymentService должен лежать в src/Services/PaymentService.php, если корневой неймспейс App\ смаплен на src/. Без этого стандарта каждый фреймворк изобретал свой автолоадер. PSR-4 заменил устаревший PSR-0 и сейчас де-факто обязателен в любом современном PHP-проекте.

Что такое trait и зачем он нужен, если есть абстрактные классы? Trait — механизм горизонтального переиспользования кода. PHP не поддерживает множественное наследование, trait это обходит: он буквально копирует методы в класс на этапе компиляции. Класс может использовать несколько трейтов одновременно. Хорошо подходит для сквозной функциональности: логирование, soft delete, timestamps, работа с UUID. Плохо — когда трейт начинает зависеть от свойств класса, которые в нём не объявлены. Это скрытая связанность, и трейтами легко злоупотребить. Если видишь трейт с $this->connection без объявления свойства — это запах.

Чем отличается абстрактный класс от интерфейса? Интерфейс — чистый контракт. Только сигнатуры методов и константы, никакой реализации. Класс может реализовывать сколько угодно интерфейсов. Абстрактный класс — уже частичная реализация: может содержать конкретные методы, свойства, конструктор. Наследоваться можно только от одного. Правило выбора простое: если нужно описать что умеет объект — интерфейс. Если нужно вынести общую логику и состояние — абстрактный класс. В хорошей архитектуре они часто работают вместе: абстрактный класс реализует интерфейс частично, потомки добивают остальное.

Часовая готовность: создаём ИИ-агента в прямом эфире В 19:00 МСК в рамках нашего курса «Разработка AI-агентов» стартует вебинар «ИИ-агенты в продакшене: от хайпа к деньгам». Спикер — Полина Полунина, руководитель AI-направления в Альфа-Банке. Будет live-демо работающего агента, реальные метрики из корпоративной среды и честный разбор архитектурных граблей — без воды и «успешного успеха». Всем зрителям эфира дадим эксклюзивный промокод AGENTS на скидку 10 000 ₽ на любой тариф курса. 👉 Занять место на вебинаре