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
Расскажите о паттерне 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, лучше их настроить, чем воевать в ревью.

Ты деплоишь новую версию. Половина серверов на старом коде, половина на новом. Как не сломать пользователей? Три зоны ответственности — три правила: 🔹 БД — только аддитивные миграции. Не удалять, не переименовывать колонки в том же деплое. Сначала добавь — потом убери старое отдельным деплоем. 🔹 API — не меняй формат ответа, только расширяй. Сломал контракт — версионируй (/v2/). 🔹 Очереди — не меняй свойства Job-классов, только добавляй. Старый воркер может достать джоб от нового кода. Главное: feature flags вместо big bang деплоя. Код едет отдельно от включения фичи.

Что такое WeakReference и WeakMap? WeakReference — ссылка на объект, не увеличивающая счётчик ссылок. Объект может быть уничтожен GC, тогда ->get() вернёт null. WeakMap (PHP 8.0) — map с объектами в роли ключей, тоже не удерживает объекты от GC. При уничтожении объекта-ключа запись автоматически исчезает.
$map = new WeakMap();
$obj = new stdClass();
$map[$obj] = 'data';
unset($obj);
// запись в $map исчезла сама
Можно применять: кэши метаданных об объектах (атрибуты, вычисленные значения), без риска утечки памяти. Активно используется в Symfony, Doctrine.

🔄Вы используете шаблоны, запросы и конфигурации каждый день. Но понимаете ли вы, как они устроены внутри? 📅На открытом урок
🔄Вы используете шаблоны, запросы и конфигурации каждый день. Но понимаете ли вы, как они устроены внутри? 📅На открытом уроке за 60 минут разберём, как работает любой язык — и соберём свой DSL на PHP. Покажем полный конвейер: от исходного текста до результата. Вы увидите, как писать лексер, строить синтаксическое дерево и реализовывать интерпретатор. Всё — на чистом PHP, без магии и скрытых механизмов. Это даёт не просто новый навык, а понимание, как работают инструменты, которыми вы уже пользуетесь: шаблонизаторы, запросы, правила. И как создавать собственные решения под задачи бизнеса — без хардкода и сложных обходных путей. 💡Открытый урок проходит в преддверии старта курса «PHP-разработчик. Продвинутый уровень» 29 апреля в 20:00 МСК. Регистрация: https://clc.to/IA9gbg Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

В чём разница между static и self в PHP? self — ссылается на класс, в котором метод определён (compile-time). static — ссылается на класс, из которого метод вызван (runtime, late static binding).
class A {
    public static function create(): static {
        return new static(); // вернёт экземпляр B, если вызвано из B
    }
}

class B extends A {}

B::create(); // → объект B, не A

Что такое Lazy Collections в Laravel? Обычная Collection загружает всё в память сразу. При работе с большими объёмами данных — это проблема.
// ❌ Загрузит ВСЕ записи в память
$users = User::all()->filter(...)->map(...);

// ✅ Lazy Collection — обрабатывает по одной записи через генератор
User::cursor()->filter(function (User $user) {
    return $user->is_active;
})->each(function (User $user) {
    ProcessUser::dispatch($user);
});
cursor() использует PDO fetchRow под капотом — в памяти одновременно одна запись. Lazy Collection из файла:
// Обработка огромного CSV без OutOfMemoryError
$collection = LazyCollection::make(function () {
    $handle = fopen('huge_file.csv', 'r');
    while ($row = fgetcsv($handle)) {
        yield $row;
    }
});

$collection->skip(1)->chunk(100)->each(function ($rows) {
    ImportBatch::dispatch($rows->toArray());
});
Когда использовать10k+ записей в обработке → cursor() + LazyCollectionФайлы, стримы, внешние API с пагинацией → LazyCollection с генератором Важно: методы типа count() и last() материализуют коллекцию. Их лучше избегать в lazy-контексте.

Чем SplDoublyLinkedList, SplMinHeap и SplFixedArray отличаются от обычного array? PHP array — это хэш-таблица с упорядоченными ключами. Универсальна, но каждый элемент занимает ~400–500 байт в zval + hashtable bucket. SPL-структуры — специализированные контейнеры с фиксированной семантикой и меньшим оверхедом. SplFixedArray — C-массив фиксированного размера. Занимает в 3–4 раза меньше памяти. Оправдан, когда размер известен заранее.
// array: ~400 MB
$arr = array_fill(0, 1_000_000, 0);

// SplFixedArray: ~90 MB
$fixed = new SplFixedArray(1_000_000);
SplDoublyLinkedList / SplStack / SplQueue — двусвязный список под капотом. Выигрывает при частых вставках и удалениях в середину. При случайном доступе по индексу — проигрывает array: O(n) против O(1). SplMinHeap / SplMaxHeap — бинарная куча. Классический кейс — приоритетная очередь с извлечением минимума/максимума за O(log n).
$heap = new SplMinHeap();
$heap->insert(5);
$heap->insert(1);
$heap->insert(3);

// Всегда достаёт минимум за O(log n)
echo $heap->extract(); // 1
echo $heap->extract(); // 3
⚠️ На что обратить внимание на практике → SplFixedArray не поддерживает строковые ключи и array_* функции — только числовые индексы → В PHP 8.1+ SplFixedArray реализует IteratorAggregate — работает в foreach без обёрток → Для задач "top-K элементов" или Dijkstra — SplMinHeap бьёт usort по всем фронтам → В большинстве бизнес-задач обычный array быстрее за счёт CPU-кэша — SPL оправдан при сотнях тысяч элементов

🏃‍♀️ Мы собрали бесплатный мега-гайд по ии-агентам 👇 В первой части постов навалили жесткой базы, чтобы вправить мозги на м
🏃‍♀️ Мы собрали бесплатный мега-гайд по ии-агентам 👇 В первой части постов навалили жесткой базы, чтобы вправить мозги на место. Во второй дали конкретные инструменты, фреймворки и пошаговые инструкции, что нужно кодить прямо сейчас. Часть 1. Введение, юзкейсы и реальность Разбираемся с терминами, снимаем розовые очки и смотрим, где ИИ реально приносит бабки, а где только жжет нервы: 1. «Так что вообще считается AI-агентом?» 2. «Где тут бот, а где уже AI-агент?» 3. «Не надо пихать AI-агента в каждую задачу» 4. «Что уже можно спокойно делать через AI-агентов?» 5. «А что через AI-агентов пока лучше не трогать?» Часть 2. Изнанка, ошибки и архитектура Как всё это устроено под капотом, чтобы не слить бюджет и не наломать дров на старте: 6. «Можно ли просто сесть вечером и собрать себе AI-агента?» 7. «С чего вообще начать, если хочется попробовать AI-агентов» 8. «Почему AI-агент может внезапно начать творить дичь» 9. «Где AI-агенты реально экономят время, а где только добавляют возни» 10. «Почему они жрут столько денег?» Часть 3. Хардкорная практика (Что делать руками) Хватит теории. Открываем ноут, запускаем Cursor и делаем нормальные, отказоустойчивые системы: 11. «Почему одного промпта мало?» 12. «Почему AI-агенту мало просто “дать доступ к данным”» 13. «Если не следить за AI-агентом, он быстро начинает жить своей жизнью» 14. «Собрать демку легко. Но как же сделать нормально» 15. «Как сделать, чтобы это не развалилось через неделю?» 👍 Сохраняйте пост в избранное, чтобы не потерять. 🤫 А завтра стартует наш курс по ии-агентам

PHP использует подсчёт ссылок для сборки мусора. В каком случае это может не сработать? PHP уничтожает объект, когда его refcount падает до 0. Но есть исключение — циклические ссылки: объект A ссылается на B, B — на A. Каждый держит счётчик ≥ 1, хотя оба недостижимы из кода. Для этого существует Cycle Collector (zval garbage collector). Он запускается не сразу, а когда буфер подозрительных zval заполняется (~10 000 узлов по умолчанию). До его запуска объекты в цикле живут в памяти, даже если логически мертвы.

Как правильно протестировать? У вас есть два класса:
class A {
    public function __construct(private B $b) {}
    
    public function doSomething(): string {
        return $this->b->getValue();
    }
}

class B {
    public function getValue(): string {
        return 'real';
    }
}
Нужно написать юнит-тест для A::doSomething(), не трогая класс B. Как это сделать правильно? Создаём мок через PHPUnit, он реализует интерфейс (или наследует класс) и позволяет изолировать зависимость:
$mockB = $this->createMock(B::class);
$mockB->method('getValue')->willReturn('mocked');

$a = new A($mockB);
$this->assertSame('mocked', $a->doSomething());
Почему работает: createMock() генерирует анонимный класс, расширяющий B. PHP позволяет передать его туда, где ожидается B.

Symfony Workflow: конечный автомат для реализации бизнес-логики. Бесплатный урок курса «Symfony Framework» Во многих приложен
Symfony Workflow: конечный автомат для реализации бизнес-логики. Бесплатный урок курса «Symfony Framework» Во многих приложениях бизнес-логика держится на статусах: заказ создан, оплачен, отправлен, доставлен. Пока таких состояний мало, всё кажется простым. Но как только процесс растёт, цепочки if/else начинают расползаться по проекту, логика дублируется, а добавление нового статуса превращается в риск для всей системы. 📅 На открытом уроке 22 апреля: — Разберём, как использовать Symfony Workflow для формализации бизнес-процессов через конечный автомат. — Покажем, чем конечный автомат отличается от рабочего процесса, когда применять каждый подход, как описывать состояния и переходы в YAML и как Symfony умеет автоматически визуализировать процесс. — На практическом примере рассмотрим сущность заказа со статусами new → paid → shipped → delivered, методы can() и apply(), а также построение схемы состояний через workflow:dump.
Урок не для тех, кто считает, что строковое поле status и набор if/else — это нормальная архитектура «на вырост», и не для тех, кто не работает со сложной бизнес-логикой в приложении.
👉 Записаться: https://clc.to/I2zW6A Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

Что такое Job Chaining и Job Batching в Laravel? Оба механизма для организации нескольких фоновых задач, но логика разная. Job Chaining — задачи выполняются строго последовательно. Если одна упала, цепочка останавливается:
Bus::chain([
    new ProcessPayment($order),
    new SendInvoice($order),
    new NotifyWarehouse($order),
])->dispatch();
Job Batching — задачи выполняются параллельно, можно отслеживать прогресс и реагировать на завершение всей группы:
$batch = Bus::batch([
    new ImportRow($rows->chunk(100)[0]),
    new ImportRow($rows->chunk(100)[1]),
    new ImportRow($rows->chunk(100)[2]),
])
->then(fn (Batch $batch) => Log::info('Импорт завершён'))
->catch(fn (Batch $batch, Throwable $e) => Log::error('Ошибка'))
->finally(fn (Batch $batch) => Cache::forget('import-lock'))
->dispatch();

// Можно следить за прогрессом
$batch->progress(); // процент выполнения
Когда что — Независимые задачи, нужна скорость и прогресс → Batch — Зависимость между задачами, порядок важен → Chain

Объясни разницу между Gate и Policy в Laravel? Оба инструмента для авторизации, но с разной областью применения. Gateпростые одиночные проверки, не привязанные к модели:
// Определяем в AuthServiceProvider
Gate::define('access-admin-panel', function (User $user) {
    return $user->is_admin;
});

// Проверяем
if (Gate::allows('access-admin-panel')) { ... }
// или в контроллере
$this->authorize('access-admin-panel');
Policy класс с набором правил для конкретной модели:
// php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id || $user->is_admin;
    }
}

// Использование
$this->authorize('update', $post);
Правило выбора — Нет модели → Gate — Есть модель, несколько действий → Policy