PHP PHP  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Кэширование, очереди и фоновые задачи

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

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. Предполагайте повторный запуск и сбой между любыми двумя действиями. На тест отведено 85 минут.
Вопрос 1 из 30
Что такое cache-aside?
PHP
function profile(int $id, Cache $cache, UserRepository $users): User
{
    $key = "profile:$id";
    $user = $cache->get($key);
    if ($user === null) {
        $user = $users->get($id);
        $cache->set($key, $user, 300);
    }
    return $user;
}
Вопрос 2 из 30
Почему нельзя считать кэш источником истины без специального дизайна?
PHP
$user = $repository->get($id);
$cache->set("user:$id", $user, 60);
Вопрос 3 из 30
Что такое cache stampede?
PHP
$value = $cache->get($key);
if ($value === null && $lock->acquire("rebuild:$key", 10)) {
    try {
        $value = rebuildExpensiveValue();
        $cache->set($key, $value, 300);
    } finally {
        $lock->release("rebuild:$key");
    }
}
Вопрос 4 из 30
Что неверно в ключе profile:42 для локализованного профиля?
Вопрос 5 из 30
Как избежать вечного одинакового истечения тысяч ключей?
Вопрос 6 из 30
Что должно быть в сообщении задания?
PHP
final readonly class GenerateInvoice
{
    public function __construct(
        public int $invoiceId,
        public string $operationId,
    ) {}
}
Вопрос 7 из 30
Когда producer может считать сообщение надёжно поставленным?
PHP
$pdo->beginTransaction();
$outbox->add($event);
$orders->save($order);
$pdo->commit();
Вопрос 8 из 30
Что означает visibility timeout?
PHP
$message = $queue->reserve(visibilityTimeout: 60);
try {
    handle($message);
    $queue->ack($message);
} catch (Throwable $error) {
    $queue->releaseAfter($message, 30);
}
Вопрос 9 из 30
Почему ack выполняют после успешного эффекта?
Вопрос 10 из 30
Как graceful shutdown помогает worker?
Вопрос 11 из 30
Что значит идемпотентный handler?
PHP
function handle(PaymentRequested $message, PaymentStore $store): void
{
    if ($store->exists($message->operationId)) {
        return;
    }
    $store->createOnce($message->operationId, $message->amount);
}
Вопрос 12 из 30
Как защитить создание выплаты?
PHP
$stmt = $pdo->prepare(
    'INSERT INTO payouts (operation_id, amount) VALUES (?, ?)'
);
$stmt->execute([$operationId, $amount]);
Вопрос 13 из 30
Почему SELECT «ещё не обработано» затем INSERT без ограничения недостаточен?
PHP
$exists = $pdo->prepare('SELECT 1 FROM payouts WHERE operation_id = ?');
$exists->execute([$operationId]);
if (!$exists->fetchColumn()) {
    $pdo->prepare('INSERT INTO payouts VALUES (?, ?)')
        ->execute([$operationId, $amount]);
}
Вопрос 14 из 30
Что делать при неизвестном исходе внешнего API?
Вопрос 15 из 30
Какая операция естественно идемпотентна?
Вопрос 16 из 30
Что означает at-least-once?
PHP
$message = $broker->receive();
$handler->handle($message);
$broker->ack($message);
Вопрос 17 из 30
Какие ошибки повторять?
PHP
try {
    $api->send($request);
} catch (TimeoutException|ServiceUnavailable $error) {
    $queue->retryWithBackoff($message);
} catch (InvalidPayload $error) {
    $queue->reject($message);
}
Вопрос 18 из 30
Для чего dead-letter queue?
PHP
if ($message->attempts >= 5) {
    $deadLetterQueue->publish($message, reason: $lastError::class);
    $queue->ack($message);
}
Вопрос 19 из 30
Почему backoff с jitter лучше фиксированной паузы?
Вопрос 20 из 30
Что записать в retry metadata?
Вопрос 21 из 30
Как unit-тестировать producer?
PHP
$queue = new FakeQueue();
$service = new InvoiceService($queue);
$service->requestInvoice(42);

assert($queue->lastMessage() instanceof GenerateInvoice);
assert($queue->lastMessage()->invoiceId === 42);
Вопрос 22 из 30
Как проверить идемпотентность?
PHP
$handler($message);
$handler($message);

assert($payments->countByOperationId($message->operationId) === 1);
Вопрос 23 из 30
Как тестировать TTL без sleep?
PHP
$clock = new FrozenClock('2026-07-14T10:00:00Z');
$cache = new InMemoryCache($clock);
$cache->set('report', $value, 60);
$clock->advance('+61 seconds');
assert($cache->get('report') === null);
Вопрос 24 из 30
Что связывает producer и worker в трассировке?
Вопрос 25 из 30
Как воспроизвести падение после внешнего эффекта до ack?
Вопрос 26 из 30
Почему не стоит класть access token в payload?
PHP
$queue->publish([
    'user_id' => $userId,
    'access_token' => $accessToken,
]);
Вопрос 27 из 30
Как выпускать новую схему сообщения?
PHP
$queue->publish([
    'type' => 'InvoiceRequested',
    'version' => 2,
    'invoice_id' => $invoiceId,
    'locale' => $locale,
]);
Вопрос 28 из 30
Какие метрики важны?
PHP
$metrics->gauge('queue_oldest_message_seconds', $queue->oldestAge());
$metrics->counter('queue_retry_total')->add($retryCount);
$metrics->counter('queue_dead_letter_total')->add($deadLetterCount);
$metrics->counter('queue_duplicate_total')->add($duplicateCount);
Вопрос 29 из 30
Что делать worker при SIGTERM?
Вопрос 30 из 30
Как ограничить права worker?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу