Как пройти собеседование по PHP: топ вопросов продвинутого уровня
Собеседование на позицию Senior PHP-разработчика — это проверка не только синтаксиса, но и глубины понимания архитектуры, производительности и современных стандартов. В этой статье мы разберем продвинутые вопросы, которые часто задают на технических интервью, и дадим развернутые ответы с примерами кода. Статья будет полезна как для подготовки к собеседованию, так и для прокачки своих навыков.
1. Принципы SOLID в PHP: от теории к практике
Один из самых популярных блоков вопросов — знание и умение применять принципы SOLID. Интервьюер хочет увидеть, как вы проектируете гибкую и поддерживаемую архитектуру.
Вопрос: "Расскажите о принципе открытости/закрытости (OCP) на примере PHP."
Ответ: Классы должны быть открыты для расширения, но закрыты для модификации. Вместо изменения существующего кода мы добавляем новый.
Пример нарушения OCP:
<?php
class ReportGenerator {
public function generate($type) {
if ($type === 'pdf') {
// генерация PDF
} elseif ($type === 'csv') {
// генерация CSV
}
}
}
Решение с соблюдением OCP:
<?php
interface ReportInterface {
public function generate(): string;
}
class PdfReport implements ReportInterface {
public function generate(): string {
return 'PDF content';
}
}
class CsvReport implements ReportInterface {
public function generate(): string {
return 'CSV content';
}
}
class ReportGenerator {
public function generate(ReportInterface $report): string {
return $report->generate();
}
}
Такой подход позволяет добавлять новые форматы отчетов без изменения существующего кода ReportGenerator.
2. Паттерны проектирования: Singleton, Factory и Dependency Injection
Знание паттернов — обязательное требование для senior-позиции. Чаще всего спрашивают про Singleton, Factory и Dependency Injection.
Вопрос: "Реализуйте паттерн Singleton в PHP и объясните, когда его использовать."
Ответ: Singleton гарантирует, что у класса есть только один экземпляр. Используется для подключения к БД, логгера или конфигурации.
<?php
class Database {
private static $instance = null;
private $connection;
private function __construct() {
$this->connection = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
}
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getConnection(): PDO {
return $this->connection;
}
// Запрещаем клонирование и десериализацию
private function __clone() {}
public function __wakeup() {
throw new \Exception("Cannot unserialize singleton");
}
}
// Использование
$db = Database::getInstance();
Вопрос: "Что такое Dependency Injection и как его реализовать без фреймворка?"
Ответ: DI — это передача зависимостей в класс через конструктор или сеттеры, а не создание их внутри класса.
<?php
class Logger {
public function log(string $message): void {
echo $message;
}
}
class UserService {
private Logger $logger;
// Внедрение зависимости через конструктор
public function __construct(Logger $logger) {
$this->logger = $logger;
}
public function createUser(array $data): void {
// логика создания пользователя
$this->logger->log('User created');
}
}
// Использование
$logger = new Logger();
$service = new UserService($logger);
3. Стандарты PSR и автозагрузка классов
Современный PHP-разработчик обязан знать PSR-4 и PSR-12. Часто спрашивают про разницу между PSR-0 и PSR-4, а также про механизм автозагрузки.
Вопрос: "Как работает PSR-4 автозагрузка? Напишите пример реализации."
Ответ: PSR-4 связывает пространства имен с директориями. Пример автозагрузчика:
<?php
spl_autoload_register(function (string $class) {
// Префикс проекта
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
// Проверяем, начинается ли класс с префикса
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
// Относительное имя класса
$relativeClass = substr($class, $len);
// Преобразуем пространство имен в путь к файлу
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
});
// Класс App\Models\User будет загружен из src/Models/User.php
Вопрос: "Какие основные правила PSR-12 вы соблюдаете в коде?"
Ответ: PSR-12 — это расширение PSR-2. Основные правила:
- Отступы — 4 пробела, не табуляция.
- Открывающая фигурная скобка для классов и методов — на новой строке.
- Для управляющих конструкций (if, foreach) — скобка на той же строке.
- Одна пустая строка между методами.
- Строгая типизация:
declare(strict_types=1);в начале файла.
4. Асинхронность и оптимизация производительности PHP
Продвинутые вопросы часто касаются работы с памятью, кэшированием и асинхронными задачами.
Вопрос: "Как обработать 10 000 писем в PHP без тайм-аута?"
Ответ: Использовать очереди (RabbitMQ, Redis) и воркеры. Пример с Redis и PHP:
<?php
// Producer (отправка в очередь)
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
for ($i = 0; $i < 10000; $i++) {
$redis->lPush('email_queue', json_encode(['to' => "user{$i}@example.com", 'subject' => 'Hello']));
}
// Worker (обработка)
while ($data =