Demonstração com candidatos fictícios

Solicitar piloto grátis
← Voltar ao ranking

Diego Moraes

diego.moraes@example.comAvaliado

Enviado em 17 de out. de 2026, 08:51

Avaliado em 17 de out. de 2026, 09:00

A nota é uma recomendação da IA; a decisão é sua.

Avaliação

Nota final
7.3
Diagrama
6.8
Defesa
8.5

Nota final = 70% diagrama + 30% defesa das perguntas.

Notas por dimensão

Confiabilidade30%5.5
Modelagem de Dados25%6.5
Assincronismo & Desacoplamento20%7.5
Trade-Offs15%5.5
Escalabilidade10%7.0

Pontos fortes

  • Uso adequado de mensageria (Kafka) desacoplando o processamento assíncrono do sistema de pagamentos externo.
  • Separação das regras de campanha em banco relacional com cache no Redis com TTL curto, permitindo alterações dinâmicas pelo marketing sem necessidade de deploy.
  • Adoção de abordagem append-only de lançamentos/transações para compor o histórico financeiro do cliente.

Pontos fracos

  • Tratamento de concorrência e chave de unicidade incompatível: foi afirmado que a tabela de transações possui `purchase_id` único, mas logo em seguida é dito que reembolsos gravam um registro com o mesmo `purchase_id`. Se a restrição única for estrita no `purchase_id`, o estorno falhará por colisão de chave primária/única.
  • Falha em lidar com desordem de eventos (out-of-order delivery): a restrição explicitou que um reembolso pode chegar antes da confirmação da compra, mas o fluxo não descreve como tratar essa inversão cronológica sem gerar inconsistência ou falha de processamento.
  • Condição de corrida no resgate: a validação de saldo seguida de inserção direta no checkout sem bloqueio atômico ou mecanismo de reserva (pessimistic lock, compare-and-swap ou chave de idempotência com saldo condicional no banco) permite que requisições concorrentes deixem o saldo negativo, violando o NFR.

Sugestões

  • Modelar a chave de idempotência composta (ex: `purchase_id` + `event_type` ou `operation_id`), permitindo registrar tanto a compra quanto eventuais reembolsos parciais ou totais para o mesmo pedido.
  • Armazenar um saldo materializado na carteira com verificação atômica (`UPDATE wallet SET balance = balance - amount WHERE balance >= amount`) ou padrão de reserva durante o checkout para garantir atomicidade sob concorrência.
  • Inverter o fluxo no diagrama onde o Redis consulta o Postgres: caches não buscam dados sozinhos; deve ser o 'Serviço de carteira' que busca no banco em caso de cache miss e popula o Redis (padrão Cache-Aside).
  • Definir uma Dead-Letter Queue (DLQ) para mensagens que falharem repetidamente no cálculo ou persistência de regras de cashback.

Sinais de integridade

Registrados pelo navegador do candidato durante o desenho e a defesa. São sinais para revisar, não prova: um segundo monitor, uma notificação ou colar as próprias anotações também geram registros. E a ausência de registros não garante nada, porque outro dispositivo, como um celular, não aparece. Esses registros não mudam a nota.

  • Saiu da aba ou da janela 1× por 12 s no total.

Linha do tempo

Tempo contado desde o início de cada etapa.

  1. Desenho 19:10Saiu da aba por 12 s

Diagrama e explicação

No celular o diagrama aparece reduzido. Dá para usar dois dedos para zoom, mas a leitura fica melhor no computador.

Explicação do candidato

Os pagamentos publicam os eventos de compra no Kafka e um worker consome, calcula o cashback com as regras e grava na tabela de transações com purchase_id único, então se o evento repetir o insert falha e eu ignoro. As regras ficam no Postgres com cache no Redis de 1 minuto, assim o marketing muda sem deploy. Reembolso gera uma transação negativa com o mesmo purchase_id e tipo estorno. Reembolso parcial calcula proporcional ao valor devolvido. O saldo fica no Redis para responder rápido no app. Quando entra transação nova eu invalido a chave e o próximo acesso recalcula somando as transações do cliente. No checkout o serviço de carteira confere o saldo e grava uma transação de resgate negativa. Para a Black Friday escalo os workers horizontalmente pelo número de partições.

Perguntas de defesa

  1. 1. Como sua arquitetura lida com a condição de corrida no checkout para garantir que o saldo nunca fique negativo se o cliente tentar realizar dois resgates simultâneos?

    Do jeito que desenhei, o serviço lê o saldo do Redis, então dois resgates ao mesmo tempo podem passar. Eu mudaria para um UPDATE condicional numa tabela de saldo no Postgres: UPDATE saldos SET saldo = saldo - :valor WHERE cliente = :id AND saldo >= :valor. Se não afetar nenhuma linha, o resgate é recusado. É atômico, e o Redis vira só cache de leitura.

    Avaliação da resposta9.0

    A resposta identifica com precisão a vulnerabilidade da leitura em cache e propõe a solução canônica com UPDATE condicional atômico no banco de dados relacional. Faltou apenas detalhar a reserva temporária versus débito definitivo caso o checkout externo falhe após a dedução.

  2. 2. Você mencionou invalidar a chave do Redis e recalcular o saldo somando todas as transações no Postgres na leitura seguinte; como evitar gargalos no banco e picos de latência (cache stampede) na Black Friday com esse modelo?

    Somar tudo a cada leitura não aguenta a Black Friday. Eu passaria a manter o saldo materializado no Postgres, atualizado na mesma transação do insert, e o Redis com TTL curto. Para o stampede, um lock com SET NX para que só uma requisição recalcule quando a chave expira; as outras leem o valor antigo por alguns segundos.

    Avaliação da resposta8.5

    A solução resolve com eficiência o gargalo ao materializar o saldo na escrita e adotar bloqueio com SET NX para mitigar o cache stampede. Poderia ter especificado uma estratégia de atualização direta do cache (write-through) para dispensar completamente recálculos síncronos na rota de leitura.

  3. 3. Se um evento de reembolso ou estorno chegar antes da confirmação da compra (fora de ordem), como o worker processará o cálculo proporcional e a persistência sem quebrar a restrição de purchase_id único?

    Eu deixaria a unicidade por (purchase_id, tipo). Se o estorno chega antes, o worker não acha a compra e devolve a mensagem para retry com atraso, até a confirmação chegar e o estorno poder ser calculado.

    Avaliação da resposta8.0

    A resposta corrige a chave de unicidade para uma restrição composta e adota fila de retry com atraso para aguardar a confirmação da compra. Deixou de contemplar o tratamento com Dead Letter Queue caso a compra de origem nunca chegue ou seja cancelada.

Quer ver o ranking dos seus candidatos?

O piloto é grátis: 1 processo com até 10 candidatos, sem cartão. Cadastro com e-mail corporativo; revisamos o pedido e liberamos o piloto.