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

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

رفتن به کانال در Telegram

Вопросы с собеседований по PHP и ответы на них. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/9f3affba Для обратной связи: @proglibrary_feeedback_bot

نمایش بیشتر
3 152
مشترکین
+124 ساعت
-17 روز
-430 روز
آرشیو پست ها
🧑‍💻 Приглашаем на открытый урок курса «PHP-разработчик. Продвинутый уровень» 19 мая в 20:00 — Работа с очередями в Laravel:
🧑‍💻 Приглашаем на открытый урок курса «PHP-разработчик. Продвинутый уровень» 19 мая в 20:00 — Работа с очередями в Laravel: от настройки до решения типичных проблем Разберём, как очереди помогают ускорить приложение и вынести тяжёлые задачи в фон без потери стабильности. Обсудим настройку и обработку задач, типичные ошибки, повторы при сбоях, защиту от дублирования и мониторинг выполнения. Вы поймёте, как работают фоновые процессы в Laravel, научитесь правильно настраивать очереди и делать приложение быстрее и надёжнее. 🚀Открытый урок проходит в преддверии старта курса «PHP-разработчик. Продвинутый уровень» 19 мая в 20:00 МСК. Регистрация: https://clc.to/6HSSeg Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

Расскажите о паттерне Bridge Bridge — это структурный паттерн, который разделяет абстракцию и реализацию так, чтобы они могли изменяться независимо друг от друга. Простыми словами: вместо одной толстой иерархии наследования вы разбиваете её на две независимые — «что делать» и «как делать» — и связываете их композицией. ▪️ Когда использоватьЕсть две ортогональные оси изменения (тип × реализация)Хотите избежать «взрыва» подклассовНужно переключать реализацию в runtime ▪️ Bridge vs Strategy — Strategy: меняет один алгоритм внутри объекта — Bridge: разделяет целые иерархии абстракции и реализации ▪️ Минус Усложняет код, если оси изменения всего одна — тогда достаточно обычного полиморфизма.

Расскажите о паттерне Builder Builder — это порождающий паттерн, который позволяет создавать сложные объекты пошагово, разделяя процесс конструирования и представление. Простыми словами: вместо конструктора с десятком параметров, вы собираете объект по частям, вызывая понятные методы. ▪️ Когда использоватьОбъект имеет множество параметров (особенно необязательных)Нужна immutable-объект с удобным созданиемХотите избежать telescoping constructor (конструктор в конструкторе) ▪️ Builder vs конструктор — Конструктор: подходит, если параметров 2–3 и все обязательные — Builder: если параметров больше 4 или есть необязательные ▪️ Минус Дублирование полей между классом и билдером. Lombok @Builder решает это автоматически.

Расскажите о паттерне Flyweight Flyweight — это структурный паттерн, который позволяет вместить большее количество объектов в отведённую оперативную память за счёт разделения общего состояния между объектами. Простыми словами: вместо создания тысяч похожих объектов, вы создаёте несколько объектов-легковесов с общими данными и передаёте уникальные данные извне при использовании. ▪️ Когда использоватьПриложение создаёт огромное количество однотипных объектовОбъекты потребляют много памятиБольшую часть состояния можно вынести за пределы объектаПриложение не зависит от идентичности объектов (можно переиспользовать) ▪️ МинусыУсложнение кода из-за разделения состоянияFlyweight должен быть immutable для безопасного переиспользования

🗓 14 мая в 19:00 (Мск) встречаемся в онлайне. Тема: Почему AI-продукты на базе LLM ломаются и как сделать, чтобы работало. В кружке выше Эмиль Сатаев рассказал, какие именно проблемы с LLM в проде будем разбирать. Что в программе:
- Разберем реальные кейсы стартапов и ограничения LLM. - Обсудим рабочие архитектуры: RAG, human-in-the-loop, контроль качества. - Ответим на ваши вопросы и разберем кейсы участников.
🎁 Бонусы: в конце вебинара подарим промокод на скидку 10.000 ₽ на курсы и разыграем подписки на полезные AI-сервисы. 👉 Зарегистрироваться на вебинар

Расскажите о паттерне Prototype Prototype — это порождающий паттерн, который позволяет копировать объекты, не вдаваясь в подробности их реализации. Простыми словами: вместо создания объекта с нуля через конструктор, вы клонируете уже существующий экземпляр. ▪️ Когда использоватьСоздание объекта затратно (сложная инициализация, обращение к БД, парсинг файлов)Нужно избежать привязки к конкретным классам при создании копийОбъекты различаются только состоянием, а не поведением ▪️ Важно: Shallow vs Deep Copy Shallow copy — копируются только примитивы, ссылки на объекты остаются теми же Deep copy — создаются копии вложенных объектов ▪️ Альтернативы clone — Магический __clone() — Статический метод: Report::copy($original) — Сериализация: unserialize(serialize($obj)) ▪️ Минус Клонирование объектов с циклическими ссылками может быть сложным.

Расскажите о паттерне Prototype Prototype — это порождающий паттерн, который позволяет копировать объекты, не вдаваясь в подробности их реализации. Простыми словами: вместо создания объекта с нуля через конструктор, вы клонируете уже существующий экземпляр. ▪️ Когда использоватьСоздание объекта затратно (сложная инициализация, обращение к БД, парсинг файлов)Нужно избежать привязки к конкретным классам при создании копийОбъекты различаются только состоянием, а не поведением ▪️ Важно: Shallow vs Deep Copy Shallow copy — копируются только примитивы, ссылки на объекты остаются теми же Deep copy — создаются копии вложенных объектов ▪️ Альтернативы clone() — Copy constructor: new Report(original) — Статический метод: Report.copy(original) — Сериализация: для очень сложных объектов ▪️ Минус Клонирование объектов с циклическими ссылками может быть сложным.

✔️ PHP-тест: Идемпотентность, которой нет Пользователь нажал «Оплатить» один раз. Деньги списались дважды. 📦 Задание Фича: интеграция с платёжным шлюзом. Платёж создаётся на бэке, пользователь редиректится на страницу шлюза, после оплаты шлюз дёргает webhook. По webhook'у выдаётся доступ к продукту. Жалобы начались через две недели после релиза. Только у части пользователей, только в часы пик. У некоторых списывалось дважды, у других доступ не выдавался вовсе.
// src/Payment/WebhookHandler.php
class WebhookHandler
{
    public function __construct(
        private PaymentRepository $payments,
        private OrderRepository   $orders,
        private AccessService     $access,
        private Mailer            $mailer,
    ) {}

    public function handle(array $payload): void
    {
        $externalId = $payload['payment_id'];
        $status     = $payload['status'];

        if ($status !== 'success') {
            return;
        }

        $payment = $this->payments->findByExternalId($externalId);

        if ($payment === null) {
            return;
        }

        $order = $this->orders->findById($payment->orderId);

        if ($order->status === 'paid') {
            return;
        }

        $this->orders->markAsPaid($payment->orderId);
        $this->access->grantForOrder($order);
        $this->mailer->sendReceipt($order);
    }
}

// src/Repository/OrderRepository.php
class OrderRepository
{
    public function __construct(private PDO $pdo) {}

    public function findById(int $id): Order
    {
        $stmt = $this->pdo->prepare(
            'SELECT * FROM orders WHERE id = ?'
        );
        $stmt->execute([$id]);
        return Order::fromRow($stmt->fetch(PDO::FETCH_ASSOC));
    }

    public function markAsPaid(int $orderId): void
    {
        $stmt = $this->pdo->prepare(
            'UPDATE orders SET status = ? WHERE id = ?'
        );
        $stmt->execute(['paid', $orderId]);
    }
}
🔹 Задачи — Объяснить, как именно возникает двойное списание при одном нажатии пользователя — Исправить WebhookHandler::handle Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

🦾 Почему ваши AI-продукты на базе LLM ломаются (и как это чинить)? Выкатили ИИ-фичу в прод, а она галлюцинирует, падает или
🦾 Почему ваши AI-продукты на базе LLM ломаются (и как это чинить)? Выкатили ИИ-фичу в прод, а она галлюцинирует, падает или выдает мусор? Приглашаем на открытый вебинар, где разберем реальную боль внедрения LLM-агентов и научимся делать так, чтобы «всё работало». 🗓 Когда: 14 мая в 19:00 МСК ⏱️ Формат: 60 минут мяса + 30 минут ответов на ваши вопросы 🧑🏻‍💻 Кто вещает: Эмиль Сатаев — Backend Platform Developer (8+ лет в разработке). Человек, который своими руками внедряет LLM и агентные системы в реальные коммерческие сервисы. 🎁 Главный бонус для онлайна: Только участникам прямого эфира подарим уникальный промокод на скидку 10.000 ₽ на большой курс AgentOps. 👉 Занять место на вебинаре

Расскажите о паттерне Factory Method Factory Method — порождающий паттерн, который определяет общий интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов. 🔹 Когда использовать: Когда заранее неизвестны типы и зависимости объектов, или когда нужно делегировать создание объектов подклассам. 🔹 Как работает: Создается абстрактный метод для создания объектов, а конкретные подклассы переопределяют его, возвращая нужные типы. 🔹 Плюсы:избавляет от привязки к конкретным классам;упрощает добавление новых типов продуктов;следует Open/Closed Principle.

Расскажите о паттерне Adapter Adapter (Адаптер) — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Он выступает в роли "переходника" между двумя интерфейсами. 🔹 Когда использовать: Когда нужно использовать существующий класс, но его интерфейс не соответствует требуемому. Например, при интеграции сторонних библиотек или работе с легаси-кодом.

Расскажите о паттерне Singleton? Singleton — это порождающий паттерн проектирования, который гарантирует, что у класса существует только один экземпляр, и предоставляет глобальную точку доступа к нему. 🔹 Основные характеристики:приватный конструктор запрещает создание экземпляров извне;статический метод getInstance() возвращает единственный экземпляр;статическое поле для хранения экземпляра. 🔹 Когда использовать:объект содержит глобальное состояние;создание объекта ресурсозатратно;нужен единый координатор действий;логически должен быть один экземпляр.

Расскажите о паттерне Strategy? Strategy — это поведенческий паттерн, который позволяет определить семейство алгоритмов, инкапсулировать каждый из них и сделать их взаимозаменяемыми. Когда использовать:есть несколько способов выполнения одной операции;нужно избежать множественных if-else или switch;алгоритмы должны выбираться в runtime. Преимущества: соблюдение Open/Closed Principle, устранение условных операторов, гибкость выбора алгоритма

✔️ PHP-тест: Утечка сессии между пользователями Баг не воспроизводится локально. На проде один юзер видит чужие данные 👇 📦 Задание Стартап запустил SaaS. Первые две недели тишина. А потом в поддержку прилетело: «Я зашёл в кабинет и увидел чужой аккаунт». В коде сессий и авторизации не трогали давно, там всё стабильно.
// src/Auth/UserSession.php
class UserSession
{
    private static ?User $currentUser = null;

    public static function set(User $user): void
    {
        self::$currentUser = $user;
    }

    public static function get(): ?User
    {
        return self::$currentUser;
    }

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

// src/Middleware/AuthMiddleware.php
class AuthMiddleware
{
    public function __construct(
        private readonly UserRepository $userRepository,
        private readonly JWTService     $jwt,
    ) {}

    public function handle(Request $request, callable $next): Response
    {
        $token = $request->headers->get('Authorization');

        if (!$token) {
            return new Response(status: 401);
        }

        $payload = $this->jwt->decode(str_replace('Bearer ', '', $token));
        $user    = $this->userRepository->find($payload['sub']);

        UserSession::set($user);

        return $next($request);
    }
}

// src/Controller/DashboardController.php
class DashboardController
{
    public function index(): Response
    {
        $user = UserSession::get();

        return new Response(
            body: $this->renderDashboard($user),
        );
    }
}

// src/Console/CacheWarmupCommand.php
class CacheWarmupCommand
{
    public function execute(): void
    {
        $users = $this->userRepository->findAll();

        foreach ($users as $user) {
            UserSession::set($user);
            $this->warmupForUser($user);
        }

        // прогрев завершён
    }
}
🔹 Задачи — Объяснить механизм утечки — Объяснить, как CacheWarmupCommand триггерит баг и при каком race window — Переписать UserSession так, чтобы устранить проблему архитектурно, а не патчем Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

Что такое Bundles в Symfony? В Symfony, Bundle — это структурированный набор файлов и директорий, реализующих определённую функцию или набор связанных функций. Бандлы являются основными единицами организации, позволяя упаковывать повторно используемый код и делиться им между несколькими проектами. Ключевые аспекты 1️⃣ Структура и организация Бандлы предоставляют способ организовать код в логические единицы. Каждый бандл обычно включает: — Контроллеры — Модели/Сущности — Сервисы — Конфигурационные файлы — Шаблоны (файлы Twig) — Информацию о маршрутах 2️⃣ Повторное использование Бандлы могут быть повторно использованы в разных проектах. Это упрощает совместное использование и распространение функций и функциональных возможностей, способствуя модульности и поддерживаемости. 3️⃣ Разделение Бандлы помогают разделить различные части приложения. Это разделение гарантирует, что изменения в одном бандле не влияют на функциональность других, что облегчает обслуживание и разработку. 4️⃣ Сторонние бандлы У Symfony есть богатая экосистема сторонних бандлов, доступных через такие платформы, как Packagist. Эти бандлы можно легко интегрировать в проект для добавления различных функций, таких как аутентификация пользователей, обработка платежей или интеграция с API.

Что такое Bundles в Symfony? В Symfony, Bundle — это структурированный набор файлов и директорий, реализующих определённую функцию или набор связанных функций. Бандлы являются основными единицами организации, позволяя упаковывать повторно используемый код и делиться им между несколькими проектами. Некоторые ключевые аспекты: 1. Структура и организация Бандлы предоставляют способ организовать код в логические единицы. Каждый бандл обычно включает: ✔️Контроллеры ✔️Модели/Сущности ✔️Сервисы ✔️Конфигурационные файлы ✔️Шаблоны (файлы Twig) ✔️Информацию о маршрутах 2. Повторное использование Бандлы могут быть повторно использованы в разных проектах Symfony. Это упрощает совместное использование и распространение функций и функциональных возможностей, способствуя модульности и поддерживаемости. 3. Разделение Бандлы помогают разделить различные части приложения. Это разделение гарантирует, что изменения в одном бандле не влияют на функциональность других, что облегчает обслуживание и разработку. 4. Сторонние бандлы У Symfony есть богатая экосистема сторонних бандлов, доступных через такие платформы, как Packagist. Эти бандлы можно легко интегрировать в ваш проект для добавления различных функций, таких как аутентификация пользователей, обработка платежей или интеграция с API. 5. Конфигурация Бандлы могут быть настроены с помощью файлов конфигурации YAML, XML или PHP. Это позволяет настроить поведение бандла в соответствии с потребностями вашего приложения. 6. Лучшие практики Symfony рекомендует использовать стандартную структуру директорий для бандлов, которая включает: Controller/: Содержит классы контроллеров. Resources/config/: Содержит конфигурационные файлы. Resources/views/: Содержит шаблоны Twig. Resources/public/: Содержит общедоступные ресурсы, такие как CSS и JavaScript файлы. DependencyInjection/: Содержит классы и конфигурации, связанные с внедрением зависимостей. Entity/: Содержит классы сущностей Doctrine.

Осталось всего 4 места на курс по ИИ-агентам. 30 апреля закрываем набор окончательно. В ГС честно рассказали: — Кому курс не подойдет; — Какой хардкор в программе (LangGraph, AutoGen, CrewAI); — Как мы даем токены, чтобы вы не тратили свои деньги. 🏃‍♀️ Записаться, пока есть места

Symfony основан на конфигурации или соглашениях? Symfony — это фреймворк, основанный на соглашениях. Документ Coding Standards иллюстрирует нормы кодирования для проектов Symfony, а также внутренних и сторонних пакетов. Он определяет стандарты кодирования и соглашения, используемые в ядре фреймворка, чтобы сделать его более единообразным и предсказуемым.

Как отревьюить большой PR? Большой PR — это архитектурная проблема, но раз он уже есть, вот стратегия: 🔹 Начинать не с первого файла в списке, а с точки входа — контроллера, команды или сервиса, где меняется логика. 🔹 До открытия первого файла — ответить на три вопроса: что должно измениться в поведении системы, что не должно, и где граница между старым и новым. 🔹 Тесты читать первыми, т.к. они документируют намерение автора лучше, чем любой комментарий. 🔹 Искать не ошибки, а допущения. Где код предполагает, что данные всегда валидны? Что очередь не упадёт? Что транзакция атомарна? Именно здесь прячутся баги, которые выстреливают через месяц. 🔹 Замечания по стилю без линтера — не тема для PR-комментариев. Если в проекте нет phpcs или php-cs-fixer, лучше их настроить, чем воевать в ревью.