MidТеория18 min

Критерии оценки

Как оценивают кандидатов на System Design интервью: критерии, шкалы, частые ошибки и что отличает сильных кандидатов

Как работает оценка

Большинство компаний используют рубрику -- структурированную систему оценки с конкретными критериями и шкалой. Это обеспечивает объективность и последовательность оценки между разными интервьюерами.

Типичная шкала

Оценка Описание Решение
Strong Hire Превосходит ожидания для уровня Однозначный офер
Hire Соответствует ожиданиям Офер с высокой вероятностью
Lean Hire Скорее да, с оговорками Зависит от других интервью
Lean No Hire Скорее нет, но есть плюсы Скорее отказ
No Hire Не соответствует уровню Однозначный отказ

Основные критерии оценки

1. Problem Exploration (Исследование проблемы)

Вес: 15-20%

Оценивается способность понять задачу до начала решения.

<?php

declare(strict_types=1);

/**
 * Problem exploration scoring examples
 */

// Score 1-2: Jumps straight to solution
// "OK, let me draw the architecture for the notification system..."

// Score 3: Asks basic questions
// "How many users do we have?"
// "What types of notifications?"

// Score 4: Structured requirement gathering
// "Let me understand the functional requirements first..."
// "What are our SLAs for delivery?"
// "What's the read/write ratio?"

// Score 5: Deep exploration with business context
// "What's the business impact of delayed notifications?"
// "Are there regulatory requirements (GDPR, CAN-SPAM)?"
// "What's our budget for third-party services (Twilio, SendGrid)?"

/**
 * What a score-5 candidate does during problem exploration.
 * They create a structured requirements document.
 */
final readonly class RequirementsDocument
{
    public function __construct(
        // Functional Requirements
        /** @var array<string> */
        public array $mustHave,
        /** @var array<string> */
        public array $niceToHave,
        /** @var array<string> */
        public array $outOfScope,

        // Non-Functional Requirements
        public int $targetLatencyMs,
        public float $availabilityTarget,
        public int $dailyActiveUsers,
        public int $peakQps,

        // Constraints
        public float $budgetPerMonth,
        public array $existingInfrastructure,
        public array $complianceRequirements,
    ) {}
}
### 2. High-Level Design (Высокоуровневый дизайн)

Вес: 20-25%

Способность спроектировать архитектуру с правильным набором компонентов.

Что оценивают:

  • Правильный выбор компонентов
  • Логичные связи между ними
  • Соответствие требованиям
  • Разделение ответственности
<?php

declare(strict_types=1);

/**
 * High-level design scoring
 *
 * Score 1-2: Missing critical components
 *   "We have a web server and a database"
 *   (No caching, no queue, no CDN for a high-traffic system)
 *
 * Score 3: Correct components, weak reasoning
 *   "We need Redis for caching, RabbitMQ for messaging"
 *   (Right choices, but can't explain why)
 *
 * Score 4: Well-reasoned architecture
 *   Explains data flow, failure modes, scaling points
 *
 * Score 5: Anticipates future needs
 *   Designs for evolution, considers operational aspects
 */

// Example: How a strong candidate describes a component
final class NotificationArchitectureNarration
{
    public function describe(): string
    {
        return <<<'TEXT'
        The notification system has 5 major components:

        1. API Gateway - receives notification requests, validates,
           rate-limits, and routes to the ingestion service.
           Why: Decouples clients from internal topology.

        2. Priority Router - classifies notifications by priority
           and routes to appropriate queues.
           Why: Urgent notifications (password reset) should not
           wait behind marketing emails.

        3. Channel Workers - separate worker pools per channel
           (email, SMS, push). Each pool scales independently.
           Why: SMS costs $0.01/msg, email is nearly free.
           Different scaling economics.

        4. User Preference Service - stores delivery preferences,
           opt-outs, quiet hours. Cached in Redis.
           Why: Must check preferences before every send
           to comply with regulations.

        5. Delivery Tracker - records delivery status, handles
           retries, and provides analytics.
           Why: Need to know if notifications actually arrive.
        TEXT;
    }
}
### 3. Detailed Design (Детальный дизайн)

Вес: 25-30%

Глубина понимания критических компонентов.

<?php

declare(strict_types=1);

/**
 * Detailed design: strong candidate dives deep into one component
 *
 * Example: Priority queue routing with dead letter handling
 */
final class PriorityRouter
{
    /** @var array<string, QueueConfig> */
    private array $queues;

    public function __construct(
        private readonly MessageBroker $broker,
        private readonly MetricsCollector $metrics,
    ) {
        $this->queues = [
            'urgent' => new QueueConfig(
                name: 'notifications.urgent',
                workers: 20,
                maxRetries: 5,
                retryDelayMs: 1000,
                deadLetterQueue: 'notifications.urgent.dlq',
            ),
            'high' => new QueueConfig(
                name: 'notifications.high',
                workers: 10,
                maxRetries: 3,
                retryDelayMs: 5000,
                deadLetterQueue: 'notifications.high.dlq',
            ),
            'normal' => new QueueConfig(
                name: 'notifications.normal',
                workers: 5,
                maxRetries: 3,
                retryDelayMs: 30000,
                deadLetterQueue: 'notifications.normal.dlq',
            ),
            'low' => new QueueConfig(
                name: 'notifications.low',
                workers: 2,
                maxRetries: 2,
                retryDelayMs: 60000,
                deadLetterQueue: 'notifications.low.dlq',
            ),
        ];
    }

    public function route(NotificationMessage $message): void
    {
        $queue = $this->queues[$message->priority->value]
            ?? $this->queues['normal'];

        $this->broker->publish($queue->name, $message->serialize(), [
            'max_retries' => $queue->maxRetries,
            'retry_delay' => $queue->retryDelayMs,
            'dead_letter' => $queue->deadLetterQueue,
            'message_id' => $message->id, // For deduplication
        ]);

        $this->metrics->record('notification.routed', 1, [
            'priority' => $message->priority->value,
            'channel' => $message->channel->value,
        ]);
    }
}

final readonly class QueueConfig
{
    public function __construct(
        public string $name,
        public int $workers,
        public int $maxRetries,
        public int $retryDelayMs,
        public string $deadLetterQueue,
    ) {}
}
### 4. Trade-off Analysis (Анализ компромиссов)

Вес: 15-20%

Способность видеть альтернативы и обосновывать выбор.

Признаки сильного кандидата:

  • Сам называет альтернативы без подсказок
  • Объясняет, ПОЧЕМУ выбрал конкретное решение
  • Понимает, при каких условиях выбор изменится
  • Обсуждает операционные аспекты (стоимость, сложность)

Признаки слабого кандидата:

  • Называет только одно решение
  • Не может объяснить выбор
  • Отвечает "потому что так делают все"
  • Не знает ограничений выбранного решения

5. Communication (Коммуникация)

Вес: 10-15%

<?php

declare(strict_types=1);

/**
 * Communication scoring rubric
 */
final class CommunicationEvaluation
{
    // Score 1-2: Poor communication
    // - Long pauses without explanation
    // - Jumps between topics randomly
    // - Doesn't respond to interviewer's hints
    // - Uses jargon without explaining

    // Score 3: Adequate communication
    // - Explains decisions when asked
    // - Some structure in presentation
    // - Responds to questions

    // Score 4: Good communication
    // - Thinks aloud consistently
    // - Clear structure and transitions
    // - Proactively discusses alternatives
    // - Engages with interviewer feedback

    // Score 5: Excellent communication
    // - Like a collaborative design session with a colleague
    // - Draws interviewer into discussion
    // - Summarizes before moving to next topic
    // - Adjusts depth based on interviewer's interest
}
## Частые ошибки кандидатов

Ошибка 1: Resume-Driven Design

Кандидат проектирует систему на основе технологий из своего резюме, а не требований задачи.

"Давайте используем Kubernetes, потому что на моем текущем проекте мы его используем."

Ошибка 2: Over-Engineering

Кандидат добавляет сложные компоненты без обоснования.

<?php

// Over-engineered for a system with 1000 users
// "We need event sourcing, CQRS, Kafka, Elasticsearch,
//  Kubernetes, service mesh, and a custom CDC pipeline"

// Appropriate for 1000 users
final class SimpleOrderService
{
    public function __construct(
        private readonly \PDO $db,
        private readonly MailerInterface $mailer,
    ) {}

    public function createOrder(array $items, string $userId): int
    {
        $this->db->beginTransaction();

        try {
            $stmt = $this->db->prepare(
                'INSERT INTO orders (user_id, total, status, created_at)
                 VALUES (:userId, :total, :status, NOW())
                 RETURNING id'
            );
            $total = array_sum(array_column($items, 'price'));
            $stmt->execute([
                'userId' => $userId,
                'total' => $total,
                'status' => 'pending',
            ]);

            $orderId = (int) $stmt->fetchColumn();

            foreach ($items as $item) {
                $this->db->prepare(
                    'INSERT INTO order_items (order_id, product_id, quantity, price)
                     VALUES (:orderId, :productId, :quantity, :price)'
                )->execute([
                    'orderId' => $orderId,
                    'productId' => $item['product_id'],
                    'quantity' => $item['quantity'],
                    'price' => $item['price'],
                ]);
            }

            $this->db->commit();

            // Simple email notification
            $this->mailer->send($userId, 'Order confirmed', "Order #$orderId");

            return $orderId;
        } catch (\Throwable $e) {
            $this->db->rollBack();
            throw $e;
        }
    }
}
### Ошибка 3: Игнорирование нефункциональных требований

Кандидат фокусируется только на функциональности и забывает про:

  • Мониторинг и алертинг
  • Обработку ошибок
  • Graceful degradation
  • Observability (логи, метрики, трейсы)

Ошибка 4: Неумение управлять временем

Проблема Последствие
20 минут на requirements Не успели обсудить детали
25 минут на один компонент Другие компоненты не покрыты
Нет плана Хаотичное переключение между темами

Ошибка 5: Оборонительная позиция

Когда интервьюер указывает на проблему в дизайне, слабый кандидат начинает защищать свое решение. Сильный кандидат говорит: "Хорошее замечание. Давайте рассмотрим альтернативу."

Что отличает Strong Hire

Характеристики

  1. Ведет интервью как технический лид на design review
  2. Предвидит проблемы до того, как интервьюер их поднимет
  3. Обосновывает каждое решение числами и опытом
  4. Гибко адаптирует дизайн при изменении требований
  5. Знает пределы своих знаний и честно об этом говорит

Пример: как обсуждать ограничения

<?php

declare(strict_types=1);

/**
 * Strong candidate discusses limitations honestly
 *
 * "The current design has these limitations:
 *
 * 1. Single region - if the region goes down, entire system is offline.
 *    To fix: multi-region with cross-region replication.
 *    Trade-off: 2-3x infrastructure cost.
 *
 * 2. No message ordering across partitions.
 *    Users in the same conversation might see messages
 *    in slightly different order under high load.
 *    To fix: per-conversation sequence numbers.
 *
 * 3. File uploads are synchronous.
 *    For large files, this blocks the API thread.
 *    To fix: presigned URLs for direct S3 upload.
 *
 * If I had more time, I would focus on #1 first,
 * as availability is our primary non-functional requirement."
 */
## Самооценка после практики

Используйте этот чек-лист для оценки своих тренировочных сессий:

  • Задал ли я 5+ уточняющих вопросов?
  • Сделал ли я оценку нагрузки?
  • Нарисовал ли я понятную высокоуровневую архитектуру?
  • Описал ли я API и модель данных?
  • Углубился ли я в 2-3 компонента?
  • Обсудил ли я trade-offs для ключевых решений?
  • Упомянул ли я мониторинг и обработку ошибок?
  • Уложился ли я в 45 минут?

Выводы

Понимание критериев оценки позволяет целенаправленно готовиться. Тренируйте не только технические знания, но и навыки коммуникации, тайм-менеджмент и способность обосновывать решения.