Entrevista de Design de Sistemas: Projete o Uber
"Projete o Uber" é um dos pedidos de design de sistemas mais comuns porque envolve indexação geoespacial, streaming de localização em tempo real, correspondência (matching) e alto throughput de escrita, tudo ao mesmo tempo. O entrevistador não está procurando a arquitetura real do Uber — ele quer ver você delimitar o problema, tomar decisões defensáveis e raciocinar sobre escala em voz alta.
Siga uma ordem deliberada: esclareça os requisitos, estime a escala, esboce as entidades e APIs principais, projete os dados e o caminho de correspondência, e então discuta os pontos de estrangulamento e os trade-offs. O guia abaixo segue essa ordem para que você pratique a estrutura, não apenas a resposta.
1. Esclarecer os requisitos
Separe o funcional do não funcional e defina o escopo antes de projetar. Passageiros solicitam uma corrida e veem o motorista se aproximando em tempo real; motoristas ficam online e recebem solicitações próximas; o sistema os combina e acompanha a corrida até a conclusão.
- Funcional: solicitar uma corrida, combinar com um motorista próximo, rastrear a corrida em tempo real, calcular a tarifa, histórico de corridas.
- Não funcional: correspondência de baixa latência (segundos), alta disponibilidade, atualizações de localização em tempo real, consistência de que um motorista seja atribuído a exatamente um passageiro.
- Fora do escopo (diga isso): a parte interna do processamento de pagamentos, avaliações, ML de tarifa dinâmica — mencione-os e depois os deixe de lado.
2. Estimar a escala
Números aproximados justificam decisões posteriores. Suponha ~10 milhões de motoristas ativos diários enviando um ping de localização a cada 4 segundos — isso dá ~2,5 milhões de gravações por segundo de dados de localização, uma carga dominada por escrita que descarta de imediato uma tabela relacional ingênua como caminho de maior tráfego.
3. Componentes principais e APIs
Esboce os serviços e o fluxo de requisições. Mantenha o caminho de correspondência independente do armazenamento durável de corridas, para que cada um escale segundo suas próprias características.
- Serviço de localização: ingere os pings dos motoristas e mantém as posições atuais em um índice geoespacial em memória.
- Serviço de correspondência: ao receber uma solicitação de corrida, consulta motoristas online próximos e atribui um deles.
- Serviço de corridas: registro durável do ciclo de vida da corrida (solicitada → combinada → em andamento → concluída).
- Notificação/streaming: envia a posição do motorista em tempo real ao passageiro (WebSocket/long-poll).
4. Correspondência geoespacial — o cerne do problema
É isso que o entrevistador mais quer ouvir. Armazenar lat/long em bruto e percorrer tudo é O(n); você precisa de um índice espacial. Explique quadtrees ou geohashing: dividir o mapa em células para que 'encontrar motoristas perto deste ponto' se torne uma busca em algumas células, não uma varredura completa.
O geohashing codifica uma região em uma string curta onde prefixos compartilhados indicam proximidade espacial, o que transforma 'próximo' em uma consulta por prefixo. As células atuais dos motoristas ficam em um armazenamento em memória (ex.: Redis) para leituras rápidas e atualizações frequentes; o tamanho da célula é um trade-off ajustável entre precisão e abrangência da consulta.
5. Escalabilidade e pontos de estrangulamento
Nomeie os pontos de pressão e como você os aliviaria. O fluxo de 2,5 milhões de gravações por segundo de localização é o dominante.
- Particione o índice de localização geograficamente — motoristas e passageiros de uma cidade são atendidos pela mesma partição, mantendo a correspondência local.
- Absorva o pico de escrita com um armazenamento em memória e gravações duráveis assíncronas; você não precisa de cada ping em um banco de dados durável.
- Garanta um motorista por passageiro com uma atribuição atômica (um lock ou uma atualização condicional) para evitar reservas duplicadas.
- Use uma fila de mensagens (Kafka) entre a ingestão de localização e os consumidores downstream para desacoplar os picos.
6. Trade-offs a verbalizar
Encerre nomeando as tensões que um entrevistador valoriza: consistência forte vs. eventual (a atribuição do motorista precisa ser forte; a exibição de localização pode ser eventual), velocidade em memória vs. durabilidade, e precisão do tamanho da célula vs. abrangência da consulta. Afirmar isso explicitamente é a diferença entre uma resposta aprovada e uma resposta forte.
Pratique o design de sistemas do Uber com ajuda em tempo real
O assistente de entrevistas de design de sistemas da Natively pode te manter estruturado durante uma rodada em tempo real — sugerindo a próxima dimensão a cobrir e mostrando os trade-offs em tempo real, tudo no seu próprio dispositivo.
