<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Freitas-Mp</title>
    <description>The latest articles on DEV Community by Freitas-Mp (@freitasmp).</description>
    <link>https://dev.to/freitasmp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F757753%2F8da32153-e936-4070-a5e4-c19123f3f769.jpeg</url>
      <title>DEV Community: Freitas-Mp</title>
      <link>https://dev.to/freitasmp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freitasmp"/>
    <language>en</language>
    <item>
      <title>📱 Vamos aprender System Design desenhando o WhatsApp</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Wed, 23 Sep 2026 13:48:22 +0000</pubDate>
      <link>https://dev.to/freitasmp/vamos-aprender-system-design-desenhando-o-whatsapp-1acb</link>
      <guid>https://dev.to/freitasmp/vamos-aprender-system-design-desenhando-o-whatsapp-1acb</guid>
      <description>&lt;p&gt;📱 &lt;strong&gt;System Design do WhatsApp&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neste artigo, mostramos como o WhatsApp pode ser desenhado passo a passo, começando pelos problemas reais do sistema e descobrindo, a partir deles, os conceitos de engenharia necessários para resolvê-los.&lt;/p&gt;

&lt;p&gt;Uma aprendizagem adaptativa através dos problemas&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro &amp;amp; 🤵🏾‍♂️ João&lt;/p&gt;




&lt;p&gt;Introdução&lt;/p&gt;

&lt;p&gt;Esta não é uma aula tradicional de System Design.&lt;/p&gt;

&lt;p&gt;É o registro de uma sessão real de aprendizagem na qual Pedro tentou projetar, passo a passo, um sistema semelhante ao WhatsApp.&lt;/p&gt;

&lt;p&gt;Pedro não recebeu previamente uma lista de conceitos.&lt;/p&gt;

&lt;p&gt;Ele recebeu problemas.&lt;/p&gt;

&lt;p&gt;A cada problema, tentou encontrar uma solução.&lt;/p&gt;

&lt;p&gt;Algumas hipóteses estavam corretas.&lt;/p&gt;

&lt;p&gt;Outras estavam incompletas.&lt;/p&gt;

&lt;p&gt;Outras estavam erradas.&lt;/p&gt;

&lt;p&gt;E foi justamente a partir dessas respostas que João decidiu qual deveria ser a próxima pergunta.&lt;/p&gt;

&lt;p&gt;A sequência foi:&lt;/p&gt;

&lt;p&gt;Problema → hipótese → consequência → dúvida → correção → descoberta → conceito → novo problema.&lt;/p&gt;

&lt;p&gt;O objetivo deste documento é preservar esse processo.&lt;/p&gt;




&lt;p&gt;📱 Começamos pela mensagem&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Pedro, vamos começar pelo mais simples. Temos dois usuários que querem trocar uma mensagem. Como essa mensagem sai do telefone de uma pessoa e chega ao telefone da outra?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: A mensagem sai pela Internet, chega ao nosso servidor e depois vai para o telefone do outro usuário.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Certo. Mas agora temos um problema. Se o usuário estiver constantemente recebendo mensagens, precisamos abrir uma conexão nova para cada mensagem?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Não. Precisamos de uma conexão persistente.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: E qual tecnologia poderia permitir essa comunicação contínua entre o cliente e o servidor?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: WebSocket.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Aqui apareceu o primeiro conceito importante: WebSocket como canal de comunicação persistente e bidirecional.&lt;/p&gt;

&lt;p&gt;Mas a solução imediatamente criou outro problema.&lt;/p&gt;




&lt;p&gt;🖥️ E se tivermos vários servidores?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Agora imagine que temos milhares ou milhões de usuários. Um único servidor não seria suficiente. Teríamos vários servidores WebSocket. Como distribuímos as conexões?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Load Balancer.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Sim. O Load Balancer pode distribuir as novas conexões entre os servidores.&lt;/p&gt;

&lt;p&gt;Mas agora pensa:&lt;/p&gt;

&lt;p&gt;Pedro está conectado ao servidor A.&lt;/p&gt;

&lt;p&gt;Outro servidor recebe uma mensagem destinada a Pedro.&lt;/p&gt;

&lt;p&gt;Como esse servidor sabe onde Pedro está?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Talvez os servidores possam saber uns dos outros?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Poderiam existir mecanismos de comunicação entre eles, mas isso começa a criar um problema de estado distribuído. Se cada servidor guardar apenas na própria memória os usuários conectados, o que acontece quando outro servidor precisar dessa informação?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Então precisamos de alguma informação compartilhada.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;E foi aí que começamos a chegar ao Redis.&lt;/p&gt;




&lt;p&gt;🔴 Onde está o usuário?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Precisamos de alguma coisa que possa ser acessada pelos diferentes servidores. O que poderíamos utilizar?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Redis.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Isso.&lt;/p&gt;

&lt;p&gt;O Redis pode funcionar como uma camada de estado compartilhado.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;p&gt;userId → servidor/conexão atual&lt;/p&gt;

&lt;p&gt;Agora qualquer servidor pode consultar onde está a conexão atual daquele usuário.&lt;/p&gt;

&lt;p&gt;Mas ainda não terminamos.&lt;/p&gt;




&lt;p&gt;⏳ E se o estado ficar velho?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Imagine que Pedro estava conectado ao servidor A. O Redis registra isso. Mas Pedro perde a Internet de repente.&lt;/p&gt;

&lt;p&gt;O que acontece se o Redis continuar acreditando que Pedro está conectado ao servidor A?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: O estado fica errado.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Então como podemos descobrir que aquela conexão já não está viva?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Heartbeat?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Sim.&lt;/p&gt;

&lt;p&gt;E poderíamos combinar isso com um TTL para que informações antigas expirem.&lt;/p&gt;

&lt;p&gt;Agora apareceu outro problema.&lt;/p&gt;




&lt;p&gt;🔄 Reconexão&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Pedro perdeu a conexão e voltou. Só que, desta vez, caiu no servidor B.&lt;/p&gt;

&lt;p&gt;Temos agora uma conexão antiga e uma conexão nova.&lt;/p&gt;

&lt;p&gt;Como sabemos qual é a atual?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Precisamos de algum ID da conexão.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;A ideia de uma geração, versão ou identificador de conexão ajuda a diferenciar:&lt;/p&gt;

&lt;p&gt;conexão antiga&lt;/p&gt;

&lt;p&gt;de:&lt;/p&gt;

&lt;p&gt;conexão atual&lt;/p&gt;

&lt;p&gt;Isso evita que eventos atrasados da conexão antiga sejam tratados como se fossem da conexão atual.&lt;/p&gt;




&lt;p&gt;✅ A mensagem realmente chegou?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Agora temos o caminho da mensagem. Mas o servidor enviou a mensagem para o dispositivo. Como sabemos que ela realmente chegou?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: ACK.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Aqui começamos a distinguir uma coisa importante: o ACK é uma confirmação no nível da aplicação.&lt;/p&gt;

&lt;p&gt;Não é simplesmente uma notificação push.&lt;/p&gt;

&lt;p&gt;Mas agora o ACK criou outro problema.&lt;/p&gt;




&lt;p&gt;🔁 E se o ACK desaparecer?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: O servidor enviou a mensagem.&lt;/p&gt;

&lt;p&gt;O dispositivo recebeu.&lt;/p&gt;

&lt;p&gt;Mas, por algum motivo, o ACK não chegou ao servidor.&lt;/p&gt;

&lt;p&gt;O que o servidor pode pensar?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Que a mensagem não chegou.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: E então?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Ele vai tentar novamente.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: E o que pode acontecer?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: A mensagem pode ser enviada duas vezes.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Agora precisamos de uma maneira de reconhecer que aquela segunda tentativa representa a mesma mensagem.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Message ID.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Isso.&lt;/p&gt;

&lt;p&gt;E aqui aparece outro conceito:&lt;/p&gt;

&lt;p&gt;idempotência.&lt;/p&gt;

&lt;p&gt;Se uma mesma operação for repetida, ela não deve produzir um efeito incorretamente duplicado.&lt;/p&gt;




&lt;p&gt;🖼️ Agora temos uma imagem de 8 MB&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Até aqui falamos principalmente de texto.&lt;/p&gt;

&lt;p&gt;Agora Pedro quer enviar uma imagem de 8 MB.&lt;/p&gt;

&lt;p&gt;Vamos mandar esses 8 MB diretamente pelo WebSocket?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Não parece uma boa ideia.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Então onde podemos armazenar o arquivo?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Object Storage.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: E se quisermos distribuir esse arquivo de forma eficiente?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: CDN.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Começamos então a separar as responsabilidades:&lt;/p&gt;

&lt;p&gt;Mensagem&lt;br&gt;
   ↓&lt;br&gt;
mediaId&lt;br&gt;
   ↓&lt;br&gt;
Object Storage&lt;br&gt;
   ↓&lt;br&gt;
CDN&lt;/p&gt;

&lt;p&gt;O WebSocket transporta a informação da mensagem, enquanto o arquivo físico fica em uma infraestrutura própria para armazenamento e distribuição de mídia.&lt;/p&gt;




&lt;p&gt;🔢 “Mas já temos um ID. Para quê o hash?”&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Agora surge outra questão. Podemos utilizar um hash da imagem para identificar o conteúdo.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Agora aqui fica um pouquinho estranho, visto que já temos um ID. Por que é que precisamos mais do hash? Talvez pudéssemos usar um ID.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Essa dúvida é importante.&lt;/p&gt;

&lt;p&gt;O "mediaId" identifica a entidade lógica.&lt;/p&gt;

&lt;p&gt;O hash tem outra função: representar o conteúdo.&lt;/p&gt;

&lt;p&gt;Se dois arquivos tiverem exatamente o mesmo conteúdo, podemos calcular o mesmo hash para eles.&lt;/p&gt;

&lt;p&gt;Então surge um novo problema.&lt;/p&gt;




&lt;p&gt;♻️ A mesma imagem novamente&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Imagine que Pedro envia uma imagem para uma pessoa.&lt;/p&gt;

&lt;p&gt;Depois envia exatamente a mesma imagem para outra.&lt;/p&gt;

&lt;p&gt;Precisamos armazenar fisicamente duas cópias?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Mas a cada upload é um novo hash, não?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Não necessariamente. O hash depende do conteúdo. Se o conteúdo for exatamente igual, o hash calculado também pode ser igual.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Ah, eu acho que, então, aí entra o conceito de deduplicação, onde evitamos que a mesma imagem seja repetida no nosso servidor, no CDN ou no storage, certo? Então eu acho que aqui a ideia de usar deduplicação é muito interessante.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Aqui o hash deixou de parecer apenas “mais um ID”.&lt;/p&gt;

&lt;p&gt;Ele passou a ter uma função concreta:&lt;/p&gt;

&lt;p&gt;reconhecer conteúdo equivalente e permitir deduplicação.&lt;/p&gt;

&lt;p&gt;Também pode ser utilizado posteriormente para verificar a integridade do arquivo.&lt;/p&gt;




&lt;p&gt;🗑️ Podemos apagar a imagem?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Agora temos uma imagem armazenada.&lt;/p&gt;

&lt;p&gt;Imagine que uma mensagem seja apagada.&lt;/p&gt;

&lt;p&gt;Podemos simplesmente apagar o arquivo físico?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Não, porque talvez outras mensagens ainda estejam usando a mesma imagem.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Claro, a massa física não pode ser eliminada, porque ainda está sendo referenciada pelo M2 e M3.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;O arquivo físico possui várias referências.&lt;/p&gt;

&lt;p&gt;Então precisamos saber quantas referências ainda existem.&lt;/p&gt;

&lt;p&gt;Surge:&lt;/p&gt;

&lt;p&gt;reference_count&lt;/p&gt;

&lt;p&gt;Quando uma mensagem deixa de referenciar a mídia, o contador pode ser reduzido.&lt;/p&gt;

&lt;p&gt;Mas isso trouxe outro problema.&lt;/p&gt;




&lt;p&gt;⚔️ Duas operações ao mesmo tempo&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Imagine duas requisições tentando remover uma referência exatamente ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;O que pode acontecer?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Esse conceito de deadlock, né?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Pode haver deadlock em determinados cenários de concorrência, mas aqui precisamos olhar primeiro para outro problema.&lt;/p&gt;

&lt;p&gt;Duas operações estão tentando alterar o mesmo estado simultaneamente.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Assim, race condition, exatamente. Concorrência de quem vai pegar primeiro.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Isso.&lt;/p&gt;

&lt;p&gt;O problema principal aqui é race condition.&lt;/p&gt;

&lt;p&gt;Agora vamos pensar na operação:&lt;/p&gt;

&lt;p&gt;UPDATE media&lt;br&gt;
SET reference_count = reference_count - 1&lt;br&gt;
WHERE media_id = 'IMG900'&lt;br&gt;
  AND reference_count &amp;gt; 0;&lt;/p&gt;




&lt;p&gt;🧮 “Mas os dois podem tentar fazer a mesma coisa?”&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro:&lt;/p&gt;

&lt;p&gt;UPDATE media&lt;br&gt;
SET reference_count = reference_count - 1&lt;br&gt;
WHERE media_id = 'IMG900'&lt;br&gt;
  AND reference_count &amp;gt; 0;&lt;/p&gt;

&lt;p&gt;Mas é o mesmo problema do if else. Os dois vão tentar acessar a mesma coisa de uma vez?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: A preocupação é exatamente sobre concorrência.&lt;/p&gt;

&lt;p&gt;A diferença é que o banco possui mecanismos para coordenar operações concorrentes sobre a mesma linha.&lt;/p&gt;

&lt;p&gt;Uma operação atômica desse tipo permite que o próprio MySQL faça a alteração de maneira segura, evitando o clássico problema de duas operações lerem o mesmo valor e depois sobrescreverem o resultado uma da outra.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Essa pergunta é interessante porque, mesmo depois de resolver a concorrência, ainda pode haver outro problema, não pode? Não é que ele não possa acessar, mas a questão que analisamos naquela hora já tem aí uma condição: se for maior que zero. Então, nesse caso, essa condição vai impedir isso.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;A condição:&lt;/p&gt;

&lt;p&gt;reference_count &amp;gt; 0&lt;/p&gt;

&lt;p&gt;também impede que o contador seja decrementado abaixo de zero.&lt;/p&gt;




&lt;p&gt;🗄️ MySQL ou Object Storage?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Então, essa concorrência vai ser resolvida no MySQL, no banco, certo? Não no Object Storage. O banco só vai coordenar junto com o Object Storage.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Essa distinção é muito importante.&lt;/p&gt;

&lt;p&gt;O MySQL controla:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;estado;&lt;/li&gt;
&lt;li&gt;metadados;&lt;/li&gt;
&lt;li&gt;referências;&lt;/li&gt;
&lt;li&gt;contadores;&lt;/li&gt;
&lt;li&gt;decisões sobre o ciclo de vida.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O Object Storage mantém:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o arquivo físico.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eles são sistemas diferentes.&lt;/p&gt;

&lt;p&gt;Não podemos assumir que uma operação no MySQL e outra no Object Storage fazem parte automaticamente de uma única transação ACID.&lt;/p&gt;

&lt;p&gt;E isso cria mais um problema.&lt;/p&gt;




&lt;p&gt;🔄 O Object Storage falhou&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: O MySQL indica que o objeto deve ser removido.&lt;/p&gt;

&lt;p&gt;Mas justamente nesse momento o Object Storage está indisponível.&lt;/p&gt;

&lt;p&gt;O que fazemos?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Aqui entramos na questão do retry, certo? Vamos tentar novamente.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Mas agora o retry cria uma nova pergunta:&lt;/p&gt;

&lt;p&gt;«E se a primeira operação tiver sido executada, mas a resposta tiver desaparecido?»&lt;/p&gt;

&lt;p&gt;Se simplesmente repetirmos tudo, podemos executar uma operação duas vezes.&lt;/p&gt;

&lt;p&gt;Voltamos então à:&lt;/p&gt;

&lt;p&gt;idempotência.&lt;/p&gt;




&lt;p&gt;🌊 “Ah, lembrei do streaming”&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Agora vamos pensar em arquivos grandes.&lt;/p&gt;

&lt;p&gt;Precisamos necessariamente enviar todo o arquivo como uma única transferência?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Ah, lembrei do streaming, né?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Sim.&lt;/p&gt;

&lt;p&gt;Streaming permite processar ou transferir dados progressivamente.&lt;/p&gt;

&lt;p&gt;Mas vamos complicar.&lt;/p&gt;

&lt;p&gt;Imagine um arquivo de 100 MB.&lt;/p&gt;

&lt;p&gt;Pedro já enviou 50 MB.&lt;/p&gt;

&lt;p&gt;A conexão cai.&lt;/p&gt;

&lt;p&gt;O que fazemos?&lt;/p&gt;




&lt;p&gt;📍 “Aqui entra checkpoint?”&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Ah, interessante. Não. Acho que aqui devemos começar de onde paramos. Aqui entra, acho, o conceito de checkpoint, certo?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Não queremos necessariamente começar o upload novamente do zero.&lt;/p&gt;

&lt;p&gt;Precisamos saber até onde chegamos.&lt;/p&gt;

&lt;p&gt;O checkpoint permite registrar o progresso e continuar posteriormente.&lt;/p&gt;

&lt;p&gt;Isso nos leva ao conceito de resumable upload.&lt;/p&gt;




&lt;p&gt;📦 E se o chunk for enviado duas vezes?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Agora imagine que o arquivo foi dividido em chunks.&lt;/p&gt;

&lt;p&gt;O cliente envia um chunk.&lt;/p&gt;

&lt;p&gt;O servidor recebe.&lt;/p&gt;

&lt;p&gt;Mas o ACK desse chunk não chega ao cliente.&lt;/p&gt;

&lt;p&gt;O que o cliente pode fazer?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Ele vai tentar novamente.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: E agora temos novamente o problema de duplicação.&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Realmente, aí sim, ele vai tentar duplicar de novo e aí temos que ter a idempotência, né, para evitar que os arquivos sejam duplicados quando já existe.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Exatamente.&lt;/p&gt;

&lt;p&gt;Precisamos identificar cada chunk dentro daquele upload.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;p&gt;uploadId + chunkNumber&lt;/p&gt;

&lt;p&gt;Assim podemos reconhecer uma tentativa repetida.&lt;/p&gt;

&lt;p&gt;Mais uma vez:&lt;/p&gt;

&lt;p&gt;retry → possibilidade de repetição → idempotência.&lt;/p&gt;




&lt;p&gt;✅ ACK não é o mesmo que COMPLETED&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Bom, então aqui também o conceito de ACK pode ajudar, certo? Marcar como concluído.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Sim, se estamos falando do ACK, ele pode confirmar que uma determinada parte foi recebida.&lt;/p&gt;

&lt;p&gt;Mas precisamos separar duas coisas.&lt;/p&gt;

&lt;p&gt;Um ACK pode significar:&lt;/p&gt;

&lt;p&gt;“Recebi este chunk.”&lt;/p&gt;

&lt;p&gt;Enquanto:&lt;/p&gt;

&lt;p&gt;COMPLETED&lt;/p&gt;

&lt;p&gt;pode significar:&lt;/p&gt;

&lt;p&gt;“O upload inteiro terminou.”&lt;/p&gt;

&lt;p&gt;São estados diferentes.&lt;/p&gt;




&lt;p&gt;👨🏾‍💻 Pedro: Como assim? Como é que isso se enquadra aí?&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Porque precisamos distinguir a confirmação de uma parte da confirmação do processo inteiro.&lt;/p&gt;

&lt;p&gt;Se temos 20 chunks:&lt;/p&gt;

&lt;p&gt;Chunk 1  → ACK&lt;br&gt;
Chunk 2  → ACK&lt;br&gt;
Chunk 3  → ACK&lt;br&gt;
...&lt;br&gt;
Chunk 20 → ACK&lt;/p&gt;

&lt;p&gt;isso não significa necessariamente que o processo inteiro já foi finalizado.&lt;/p&gt;

&lt;p&gt;O estado global pode ser atualizado para:&lt;/p&gt;

&lt;p&gt;COMPLETED&lt;/p&gt;

&lt;p&gt;somente quando todas as partes necessárias tiverem sido recebidas e o arquivo tiver sido reconstruído e validado.&lt;/p&gt;

&lt;p&gt;E, nesse momento, o hash pode voltar a ser útil para verificar a integridade do arquivo final.&lt;/p&gt;




&lt;p&gt;🧠 O que aconteceu durante a aprendizagem?&lt;/p&gt;

&lt;p&gt;👨🏾‍💻 Pedro: Muito bom. Então vamos parar por aqui, né? Foi bom.&lt;/p&gt;

&lt;p&gt;🤵🏾‍♂️ João: Foi.&lt;/p&gt;

&lt;p&gt;Mas o mais interessante desta sessão não foi a quantidade de conceitos que apareceram.&lt;/p&gt;

&lt;p&gt;Foi a forma como eles apareceram.&lt;/p&gt;

&lt;p&gt;Pedro não começou dizendo:&lt;/p&gt;

&lt;p&gt;«“Vamos estudar WebSocket.”»&lt;/p&gt;

&lt;p&gt;Ele começou tentando responder:&lt;/p&gt;

&lt;p&gt;«“Como uma mensagem chega ao outro usuário?”»&lt;/p&gt;

&lt;p&gt;Quando apareceu outro problema, surgiu outro conceito.&lt;/p&gt;

&lt;p&gt;Quando uma hipótese não explicava completamente o comportamento do sistema, apareceu uma nova pergunta.&lt;/p&gt;

&lt;p&gt;Quando Pedro confundiu deadlock com race condition, a diferença tornou-se necessária.&lt;/p&gt;

&lt;p&gt;Quando o hash pareceu apenas mais um identificador, surgiu o problema da deduplicação.&lt;/p&gt;

&lt;p&gt;Quando duas operações puderam acontecer simultaneamente, surgiu a necessidade de entender concorrência.&lt;/p&gt;

&lt;p&gt;Quando MySQL e Object Storage passaram a depender um do outro, surgiu retry.&lt;/p&gt;

&lt;p&gt;Quando retry passou a poder repetir operações, surgiu idempotência novamente.&lt;/p&gt;

&lt;p&gt;Quando um upload podia cair no meio, surgiu checkpoint.&lt;/p&gt;

&lt;p&gt;Quando o ACK de um chunk podia desaparecer, a idempotência apareceu novamente em outro contexto.&lt;/p&gt;

&lt;p&gt;Ou seja:&lt;/p&gt;

&lt;p&gt;um conceito não foi estudado isoladamente.&lt;/p&gt;

&lt;p&gt;Ele foi reutilizado quando um novo problema apareceu.&lt;/p&gt;




&lt;p&gt;🔄 O padrão da nossa aprendizagem&lt;/p&gt;

&lt;p&gt;O que aconteceu durante a sessão pode ser representado assim:&lt;/p&gt;

&lt;p&gt;PROBLEMA&lt;br&gt;
   ↓&lt;br&gt;
PEDRO TENTA RESOLVER&lt;br&gt;
   ↓&lt;br&gt;
HIPÓTESE&lt;br&gt;
   ↓&lt;br&gt;
JOÃO QUESTIONA&lt;br&gt;
   ↓&lt;br&gt;
NOVA CONSEQUÊNCIA&lt;br&gt;
   ↓&lt;br&gt;
ERRO OU DESCOBERTA&lt;br&gt;
   ↓&lt;br&gt;
CONCEITO&lt;br&gt;
   ↓&lt;br&gt;
SOLUÇÃO&lt;br&gt;
   ↓&lt;br&gt;
NOVO PROBLEMA&lt;br&gt;
   ↓&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;E isso é importante porque Pedro não acertou tudo.&lt;/p&gt;

&lt;p&gt;Houve momentos em que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a hipótese precisava ser corrigida;&lt;/li&gt;
&lt;li&gt;um conceito foi confundido com outro;&lt;/li&gt;
&lt;li&gt;uma solução parecia suficiente, mas gerou outro problema;&lt;/li&gt;
&lt;li&gt;uma pergunta precisou ser reformulada;&lt;/li&gt;
&lt;li&gt;uma consequência só ficou clara depois da intervenção de João.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esses momentos não devem ser removidos.&lt;/p&gt;

&lt;p&gt;Eles são parte do aprendizado.&lt;/p&gt;




&lt;p&gt;🎯 O verdadeiro objetivo&lt;/p&gt;

&lt;p&gt;O objetivo desta abordagem não é fazer Pedro parecer um especialista.&lt;/p&gt;

&lt;p&gt;É mostrar Pedro se tornando capaz de raciocinar como um engenheiro de sistemas.&lt;/p&gt;

&lt;p&gt;Um engenheiro não recebe todos os problemas antecipadamente.&lt;/p&gt;

&lt;p&gt;Ele encontra problemas.&lt;/p&gt;

&lt;p&gt;Formula hipóteses.&lt;/p&gt;

&lt;p&gt;Testa essas hipóteses.&lt;/p&gt;

&lt;p&gt;Descobre limitações.&lt;/p&gt;

&lt;p&gt;Analisa consequências.&lt;/p&gt;

&lt;p&gt;Escolhe mecanismos.&lt;/p&gt;

&lt;p&gt;E depois descobre que a solução de um problema pode criar outro problema.&lt;/p&gt;

&lt;p&gt;É exatamente isso que aconteceu nesta sessão.&lt;/p&gt;




&lt;p&gt;🧠 Adaptive Inquiry — Aprendizagem Guiada e Adaptativa&lt;/p&gt;

&lt;p&gt;A sessão segue o princípio:&lt;/p&gt;

&lt;p&gt;«O problema cria a necessidade de aprender o conceito.»&lt;/p&gt;

&lt;p&gt;Em vez de:&lt;/p&gt;

&lt;p&gt;Hoje vamos estudar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;WebSocket&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;ACK&lt;/li&gt;
&lt;li&gt;Idempotência&lt;/li&gt;
&lt;li&gt;CDN&lt;/li&gt;
&lt;li&gt;Race Condition&lt;/li&gt;
&lt;li&gt;Checkpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;fazemos:&lt;/p&gt;

&lt;p&gt;Como entregar a mensagem?&lt;br&gt;
        ↓&lt;br&gt;
Precisamos de conexão persistente.&lt;br&gt;
        ↓&lt;br&gt;
WebSocket.&lt;/p&gt;

&lt;p&gt;Como localizar o usuário?&lt;br&gt;
        ↓&lt;br&gt;
Precisamos de estado compartilhado.&lt;br&gt;
        ↓&lt;br&gt;
Redis.&lt;/p&gt;

&lt;p&gt;Como saber que chegou?&lt;br&gt;
        ↓&lt;br&gt;
ACK.&lt;/p&gt;

&lt;p&gt;E se o ACK desaparecer?&lt;br&gt;
        ↓&lt;br&gt;
Retry.&lt;/p&gt;

&lt;p&gt;E se o retry duplicar?&lt;br&gt;
        ↓&lt;br&gt;
Idempotência.&lt;/p&gt;

&lt;p&gt;E se for uma imagem?&lt;br&gt;
        ↓&lt;br&gt;
Object Storage + CDN.&lt;/p&gt;

&lt;p&gt;E se a imagem for repetida?&lt;br&gt;
        ↓&lt;br&gt;
Hash + deduplicação.&lt;/p&gt;

&lt;p&gt;E se duas referências forem removidas simultaneamente?&lt;br&gt;
        ↓&lt;br&gt;
Race Condition.&lt;/p&gt;

&lt;p&gt;Como coordenar?&lt;br&gt;
        ↓&lt;br&gt;
MySQL / atomicidade.&lt;/p&gt;

&lt;p&gt;E se o storage falhar?&lt;br&gt;
        ↓&lt;br&gt;
Retry.&lt;/p&gt;

&lt;p&gt;E se o upload cair no meio?&lt;br&gt;
        ↓&lt;br&gt;
Checkpoint.&lt;/p&gt;

&lt;p&gt;E se um chunk for reenviado?&lt;br&gt;
        ↓&lt;br&gt;
Idempotência novamente.&lt;/p&gt;

&lt;p&gt;O conhecimento vai sendo construído conforme o sistema apresenta novas dificuldades.&lt;/p&gt;




&lt;p&gt;🏁 Conclusão&lt;/p&gt;

&lt;p&gt;Esta sessão não foi apenas sobre desenhar um sistema semelhante ao WhatsApp.&lt;/p&gt;

&lt;p&gt;Foi uma demonstração de como aprender System Design através dos próprios problemas do sistema.&lt;/p&gt;

&lt;p&gt;Pedro errou.&lt;/p&gt;

&lt;p&gt;Pedro fez suposições.&lt;/p&gt;

&lt;p&gt;Pedro confundiu conceitos.&lt;/p&gt;

&lt;p&gt;Pedro voltou atrás.&lt;/p&gt;

&lt;p&gt;Pedro percebeu algumas coisas sozinho.&lt;/p&gt;

&lt;p&gt;João corrigiu outras.&lt;/p&gt;

&lt;p&gt;E, principalmente, cada resposta de Pedro serviu como informação para decidir qual deveria ser a próxima pergunta.&lt;/p&gt;

&lt;p&gt;Essa é a essência do Adaptive Inquiry:&lt;/p&gt;

&lt;p&gt;«Não ensinar primeiro o conceito para depois procurar um problema.&lt;/p&gt;

&lt;p&gt;Apresentar o problema e permitir que a necessidade revele o conceito.»&lt;/p&gt;

&lt;p&gt;Assim, o objetivo não é memorizar:&lt;/p&gt;

&lt;p&gt;“Redis serve para X.”&lt;/p&gt;

&lt;p&gt;É chegar a um ponto em que Pedro pensa:&lt;/p&gt;

&lt;p&gt;«“Temos vários servidores e eles precisam compartilhar o estado da conexão. Então precisamos de alguma coisa compartilhada.”»&lt;/p&gt;

&lt;p&gt;E então o Redis deixa de ser uma palavra decorada.&lt;/p&gt;

&lt;p&gt;Ele passa a ser uma resposta para um problema que Pedro já entendeu.&lt;/p&gt;

&lt;p&gt;Da mesma forma, idempotência deixa de ser uma definição.&lt;/p&gt;

&lt;p&gt;Ela nasce quando Pedro percebe:&lt;/p&gt;

&lt;p&gt;«“Se eu tentar novamente, posso duplicar a operação.”»&lt;/p&gt;

&lt;p&gt;E checkpoint deixa de ser apenas um termo.&lt;/p&gt;

&lt;p&gt;Ele aparece quando Pedro percebe:&lt;/p&gt;

&lt;p&gt;«“Não faz sentido começar novamente de onde já chegamos.”»&lt;/p&gt;

&lt;p&gt;Esse é o tipo de aprendizagem que queremos construir:&lt;/p&gt;

&lt;p&gt;problema → raciocínio → erro → evidência → descoberta → conceito → aplicação → novo problema.&lt;/p&gt;

&lt;p&gt;E é justamente isso que significa aprender System Design através do raciocínio, e não apenas através da memorização de conceitos.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>softwareengineering</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Race Condition Lock</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Mon, 21 Sep 2026 22:39:53 +0000</pubDate>
      <link>https://dev.to/freitasmp/race-condition-lock-2lg5</link>
      <guid>https://dev.to/freitasmp/race-condition-lock-2lg5</guid>
      <description>&lt;p&gt;🧠 Consulta Guiada e Adaptativa&lt;/p&gt;

&lt;p&gt;Uma conversa entre Matondo Pedro e João&lt;/p&gt;

&lt;p&gt;Tema: Race Condition → Lock&lt;/p&gt;

&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Vamos começar com um problema real.&lt;/p&gt;

&lt;p&gt;Imagina uma loja que tem apenas uma unidade de determinado produto.&lt;/p&gt;

&lt;p&gt;O João e a Maria entram na loja exatamente ao mesmo tempo e os dois tentam comprar esse produto.&lt;/p&gt;

&lt;p&gt;O que achas que pode acontecer?&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;Os dois podem tentar comprar o mesmo produto e isso pode gerar um erro.&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Exatamente. Mas vamos olhar com mais cuidado.&lt;/p&gt;

&lt;p&gt;Imagina que o stock é:&lt;/p&gt;

&lt;p&gt;stock = 1&lt;/p&gt;

&lt;p&gt;O João consulta:&lt;/p&gt;

&lt;p&gt;stock &amp;gt; 0 → sim&lt;/p&gt;

&lt;p&gt;Ao mesmo tempo, a Maria também consulta:&lt;/p&gt;

&lt;p&gt;stock &amp;gt; 0 → sim&lt;/p&gt;

&lt;p&gt;Os dois recebem uma resposta válida.&lt;/p&gt;

&lt;p&gt;O que pode acontecer depois?&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;Talvez a Maria fique com "-1"?&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Não necessariamente.&lt;/p&gt;

&lt;p&gt;O problema mais perigoso é que os dois podem confirmar a compra, mesmo existindo apenas uma unidade física do produto.&lt;/p&gt;

&lt;p&gt;Cada operação, isoladamente, parecia válida.&lt;/p&gt;

&lt;p&gt;O problema surgiu porque elas aconteceram ao mesmo tempo sobre o mesmo estado compartilhado.&lt;/p&gt;

&lt;p&gt;É uma Race Condition.&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;É como se os dados fossem replicados para os dois utilizadores.&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;A ideia está próxima, mas pensa de outra forma.&lt;/p&gt;

&lt;p&gt;Imagina uma sala com apenas uma porta.&lt;/p&gt;

&lt;p&gt;Duas pessoas chegam ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;As duas perguntam:&lt;/p&gt;

&lt;p&gt;«“A sala está livre?”»&lt;/p&gt;

&lt;p&gt;As duas recebem:&lt;/p&gt;

&lt;p&gt;«“Sim.”»&lt;/p&gt;

&lt;p&gt;Antes que uma delas entre, a outra também entra.&lt;/p&gt;

&lt;p&gt;O problema não é que a sala foi “replicada”.&lt;/p&gt;

&lt;p&gt;O problema é que duas pessoas observaram o mesmo estado antes de qualquer uma conseguir alterá-lo.&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;Então o "if (stock &amp;gt; 0)" não resolve?&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Porque podemos ter:&lt;/p&gt;

&lt;p&gt;João:   if (stock &amp;gt; 0) → SIM&lt;br&gt;
Maria:  if (stock &amp;gt; 0) → SIM&lt;/p&gt;

&lt;p&gt;Os dois passaram pela condição.&lt;/p&gt;

&lt;p&gt;Então, como poderíamos impedir que duas operações conflitantes trabalhassem simultaneamente sobre o mesmo recurso?&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;Poderíamos colocar numa fila.&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Sim. Uma fila poderia serializar as operações.&lt;/p&gt;

&lt;p&gt;Mas imagina uma loja com 10.000 clientes.&lt;/p&gt;

&lt;p&gt;Seria necessário colocar todos numa única fila?&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;Não. Só os que estão tentando comprar o mesmo produto.&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Então precisamos de uma forma de controlar o acesso ao recurso que está em conflito, e não bloquear o sistema inteiro.&lt;/p&gt;

&lt;p&gt;O que poderíamos usar para isso?&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;Um lock.&lt;/p&gt;

&lt;p&gt;Como colocar um cadeado no produto.&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Perfeito. 🔒&lt;/p&gt;

&lt;p&gt;E onde faria sentido esse lock existir?&lt;/p&gt;




&lt;p&gt;👨‍💻 Matondo Pedro:&lt;/p&gt;

&lt;p&gt;No banco de dados.&lt;/p&gt;




&lt;p&gt;👨‍🏫 João:&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;p&gt;SELECT *&lt;br&gt;
FROM products&lt;br&gt;
WHERE id = 1&lt;br&gt;
FOR UPDATE;&lt;/p&gt;

&lt;p&gt;Esse "FOR UPDATE" permite bloquear a linha que estamos prestes a modificar.&lt;/p&gt;

&lt;p&gt;Assim, outra transação que precise de um lock incompatível nessa mesma linha terá de esperar.&lt;/p&gt;

&lt;p&gt;E agora aparece uma nova pergunta:&lt;/p&gt;

&lt;p&gt;O lock sozinho é suficiente para representar toda a compra?&lt;/p&gt;




&lt;p&gt;🎯 O método&lt;/p&gt;

&lt;p&gt;Nesta conversa, não começámos pela definição de Race Condition ou Lock.&lt;/p&gt;

&lt;p&gt;Começámos por um problema real, fizemos perguntas, testámos hipóteses e fomos descobrindo os conceitos à medida que eles se tornavam necessários.&lt;/p&gt;

&lt;p&gt;🧠 Consulta Guiada e Adaptativa: começar pelo problema e conduzir a pessoa até à descoberta da solução.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>computerscience</category>
      <category>programming</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Aprendendo Angular através de um diálogo</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Mon, 21 Sep 2026 22:32:05 +0000</pubDate>
      <link>https://dev.to/freitasmp/aprendendo-angular-atraves-de-um-dialogo-11i0</link>
      <guid>https://dev.to/freitasmp/aprendendo-angular-atraves-de-um-dialogo-11i0</guid>
      <description>&lt;p&gt;🧠 INVESTIGAÇÃO ADAPTATIVA&lt;/p&gt;

&lt;p&gt;Dia 1 — Aprendendo Angular através de um diálogo&lt;/p&gt;

&lt;p&gt;👨‍💼 João — Entrevistador&lt;/p&gt;

&lt;p&gt;Olá, eu sou o João. Trabalho na empresa X e hoje vou conduzir uma entrevista técnica para uma vaga de Junior Frontend Developer.&lt;/p&gt;

&lt;p&gt;Vamos começar com uma situação real.&lt;/p&gt;

&lt;p&gt;Precisamos desenvolver uma aplicação para uma escola.&lt;/p&gt;

&lt;p&gt;A aplicação deve permitir fazer login, listar estudantes, cadastrar, editar e remover estudantes. Os dados vêm de uma API REST.&lt;/p&gt;

&lt;p&gt;Acabaste de criar o projeto Angular.&lt;/p&gt;

&lt;p&gt;Como começarias a organizar essa aplicação?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro — Candidato&lt;/p&gt;

&lt;p&gt;Certo. Então a primeira coisa que eu vou fazer é criar a estrutura do projeto.&lt;/p&gt;

&lt;p&gt;Vou instalar o Angular com npm, instalar a versão mais recente e o Angular já começa a definir toda a base do projeto, com services, components, HTML e toda essa estrutura inicial.&lt;/p&gt;

&lt;p&gt;Depois vou fazer uma tela de login e cadastro.&lt;/p&gt;

&lt;p&gt;Também vou criar a parte da API de estudantes.&lt;/p&gt;

&lt;p&gt;Depois vou criar uma tela para listar os estudantes, um componente.&lt;/p&gt;

&lt;p&gt;Outra tela para mostrar os detalhes do estudante.&lt;/p&gt;

&lt;p&gt;E na lista vou colocar uma opção para eliminar o estudante.&lt;/p&gt;

&lt;p&gt;Depois vou usar um Service para fazer...&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;O que exatamente colocarias dentro desse Service?&lt;/p&gt;

&lt;p&gt;Imagina que tens um "StudentListComponent" e precisas buscar os estudantes através de:&lt;/p&gt;

&lt;p&gt;"GET /api/students"&lt;/p&gt;

&lt;p&gt;Quem deveria fazer essa chamada HTTP: o componente ou o Service? E por quê?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;O Service.&lt;/p&gt;

&lt;p&gt;Porque normalmente Service é algo compartilhado pela aplicação.&lt;/p&gt;

&lt;p&gt;A chamada HTTP pode ser reutilizada em diferentes partes. Se eu colocasse no componente, teria que replicar esse código sempre que criasse outro componente.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;A ideia principal está correta.&lt;/p&gt;

&lt;p&gt;Mas vamos refinar.&lt;/p&gt;

&lt;p&gt;A razão principal não é simplesmente o Service ser compartilhado.&lt;/p&gt;

&lt;p&gt;É separação de responsabilidades.&lt;/p&gt;

&lt;p&gt;O componente deve preocupar-se principalmente com a interface e interação.&lt;/p&gt;

&lt;p&gt;O Service pode encapsular a responsabilidade de obter e manipular os estudantes.&lt;/p&gt;

&lt;p&gt;Então temos:&lt;/p&gt;

&lt;p&gt;Component → Service → HttpClient → API&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Agora outra pergunta.&lt;/p&gt;

&lt;p&gt;O Service deve conter toda a lógica da aplicação?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Não necessariamente.&lt;/p&gt;

&lt;p&gt;No Service podemos implementar helpers, providers HTTP e lógica de negócio.&lt;/p&gt;

&lt;p&gt;Ele é muito bom para comunicação externa.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Boa. Só precisamos fazer uma precisão.&lt;/p&gt;

&lt;p&gt;Service não significa simplesmente “comunicação externa”.&lt;/p&gt;

&lt;p&gt;Ele serve para encapsular uma responsabilidade que não deveria ficar diretamente no componente.&lt;/p&gt;

&lt;p&gt;Comunicação com API é apenas um dos usos.&lt;/p&gt;

&lt;p&gt;Agora temos outro problema.&lt;/p&gt;

&lt;p&gt;A rota "/students" só pode ser acessada por usuários autenticados.&lt;/p&gt;

&lt;p&gt;O que usarias?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Usaria o recurso do Angular chamado Guard.&lt;/p&gt;

&lt;p&gt;Ele vai proteger a rota e verificar se o acesso está autorizado.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Guard.&lt;/p&gt;

&lt;p&gt;Agora aparece outro problema.&lt;/p&gt;

&lt;p&gt;Todas as requisições precisam enviar o token:&lt;/p&gt;

&lt;p&gt;"Authorization: Bearer "&lt;/p&gt;

&lt;p&gt;Temos:&lt;/p&gt;

&lt;p&gt;"GET /students"&lt;br&gt;
"POST /students"&lt;br&gt;
"PUT /students/1"&lt;br&gt;
"DELETE /students/1"&lt;/p&gt;

&lt;p&gt;Você colocaria o código do token dentro de cada método do Service?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Não.&lt;/p&gt;

&lt;p&gt;Criaria um... um base... alguma coisa que faça esse token.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;A ideia de centralizar está correta.&lt;/p&gt;

&lt;p&gt;O recurso que procuramos é o HTTP Interceptor.&lt;/p&gt;

&lt;p&gt;Ele pode interceptar as requisições HTTP e adicionar automaticamente o token.&lt;/p&gt;

&lt;p&gt;Então agora temos:&lt;/p&gt;

&lt;p&gt;Component&lt;br&gt;
↓&lt;br&gt;
Service&lt;br&gt;
↓&lt;br&gt;
HttpClient&lt;br&gt;
↓&lt;br&gt;
Interceptor&lt;br&gt;
↓&lt;br&gt;
API&lt;/p&gt;




&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;A API devolve:&lt;/p&gt;

&lt;p&gt;"2005-03-15"&lt;/p&gt;

&lt;p&gt;Mas queremos mostrar na tela:&lt;/p&gt;

&lt;p&gt;"15/03/2005"&lt;/p&gt;

&lt;p&gt;Você colocaria essa transformação dentro do Service?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Aqui não me vem à mente...&lt;/p&gt;

&lt;p&gt;Talvez usem Terraform?&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Boa. Não acertaste, e isso é exatamente o que queremos descobrir durante o estudo.&lt;/p&gt;

&lt;p&gt;Aqui o recurso é o Pipe.&lt;/p&gt;

&lt;p&gt;O Pipe é usado para transformar um valor na apresentação.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;p&gt;"{{ student.birthDate | date:'dd/MM/yyyy' }}"&lt;/p&gt;

&lt;p&gt;Resultado:&lt;/p&gt;

&lt;p&gt;15/03/2005&lt;/p&gt;

&lt;p&gt;Então:&lt;/p&gt;

&lt;p&gt;Service → responsabilidade e acesso aos dados.&lt;br&gt;
Pipe → transformação para apresentação.&lt;br&gt;
Component → interface e interação.&lt;/p&gt;




&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Agora temos outro problema.&lt;/p&gt;

&lt;p&gt;Na tela queremos mostrar:&lt;/p&gt;

&lt;p&gt;João — Ativo&lt;br&gt;
Maria — Inativo&lt;br&gt;
Pedro — Ativo&lt;/p&gt;

&lt;p&gt;Queremos aplicar uma classe CSS diferente dependendo do estado.&lt;/p&gt;

&lt;p&gt;Ativo → verde.&lt;br&gt;
Inativo → cinza.&lt;/p&gt;

&lt;p&gt;Que recurso do Angular utilizarias?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Podemos usar a directive "ngModel".&lt;/p&gt;

&lt;p&gt;Ela permite colocar condições dentro do HTML para definir cores.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Estás perto no conceito de Directive, mas confundiste dois recursos.&lt;/p&gt;

&lt;p&gt;"ngModel" é usado principalmente para two-way data binding, especialmente em formulários.&lt;/p&gt;

&lt;p&gt;Para alterar a aparência, podemos utilizar, por exemplo:&lt;/p&gt;

&lt;p&gt;"[class.active]="student.active""&lt;/p&gt;

&lt;p&gt;ou "ngClass".&lt;/p&gt;

&lt;p&gt;Então aprendemos mais uma coisa:&lt;/p&gt;

&lt;p&gt;Directive permite adicionar ou modificar comportamento de elementos no DOM.&lt;/p&gt;

&lt;p&gt;E "ngModel" é uma directive relacionada principalmente ao binding de formulários.&lt;/p&gt;




&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;O projeto cresceu.&lt;/p&gt;

&lt;p&gt;Temos:&lt;/p&gt;

&lt;p&gt;"students/"&lt;br&gt;
→ "student-list"&lt;br&gt;
→ "student-detail"&lt;br&gt;
→ "student-form"&lt;/p&gt;

&lt;p&gt;"auth/"&lt;br&gt;
→ "login"&lt;br&gt;
→ "register"&lt;/p&gt;

&lt;p&gt;Como organizarias e agruparias esses componentes no Angular?&lt;/p&gt;

&lt;p&gt;E qual é a diferença entre NgModule e Standalone?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Entre módulos, nós organizamos os componentes por módulos e depois vamos ter um módulo pai que vai chamar os children.&lt;/p&gt;

&lt;p&gt;E carrega as rotas.&lt;/p&gt;

&lt;p&gt;Isso facilita na eficiência de lazy loading e tudo isso.&lt;/p&gt;

&lt;p&gt;Standalone, acho que é quando temos um único módulo pai que carrega todos os ficheiros.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;A primeira parte está no caminho certo.&lt;/p&gt;

&lt;p&gt;No modelo tradicional, podemos agrupar funcionalidades através de "NgModule".&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;p&gt;"StudentsModule"&lt;br&gt;
→ "StudentListComponent"&lt;br&gt;
→ "StudentDetailComponent"&lt;br&gt;
→ "StudentFormComponent"&lt;/p&gt;

&lt;p&gt;Mas há uma correção importante.&lt;/p&gt;

&lt;p&gt;Standalone é praticamente o contrário daquilo que descreveste.&lt;/p&gt;

&lt;p&gt;Um componente Standalone pode declarar diretamente as suas dependências sem precisar pertencer a um "NgModule".&lt;/p&gt;




&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;Você mencionou lazy loading.&lt;/p&gt;

&lt;p&gt;Por que utilizaria lazy loading?&lt;/p&gt;

&lt;p&gt;Temos:&lt;/p&gt;

&lt;p&gt;"/"&lt;br&gt;
"/login"&lt;br&gt;
"/students"&lt;br&gt;
"/reports"&lt;br&gt;
"/admin"&lt;/p&gt;

&lt;p&gt;Por que não simplesmente carregar tudo quando a aplicação começa?&lt;/p&gt;

&lt;p&gt;👨‍💻 Matando Pedro&lt;/p&gt;

&lt;p&gt;Porque à medida que o projeto vai crescer, vai ficar muito lento o Angular fazer um build e descarregar todo o projeto.&lt;/p&gt;

&lt;p&gt;Isso pode matar a eficiência da aplicação.&lt;/p&gt;

&lt;p&gt;👨‍💼 João&lt;/p&gt;

&lt;p&gt;O raciocínio está correto.&lt;/p&gt;

&lt;p&gt;Só precisamos fazer uma precisão.&lt;/p&gt;

&lt;p&gt;O problema principal para o usuário não é o build ficar lento. O build acontece durante desenvolvimento ou CI.&lt;/p&gt;

&lt;p&gt;O problema é o carregamento inicial da aplicação.&lt;/p&gt;

&lt;p&gt;Sem lazy loading, o usuário pode acabar carregando recursos que ainda nem precisa.&lt;/p&gt;

&lt;p&gt;Com lazy loading, partes da aplicação podem ser carregadas quando forem necessárias.&lt;/p&gt;




&lt;p&gt;🧠 O que aconteceu nesta entrevista?&lt;/p&gt;

&lt;p&gt;Nós não começámos decorando definições.&lt;/p&gt;

&lt;p&gt;Começámos com um problema.&lt;/p&gt;

&lt;p&gt;Uma resposta gerou uma nova pergunta.&lt;/p&gt;

&lt;p&gt;A pergunta revelou uma lacuna.&lt;/p&gt;

&lt;p&gt;A lacuna levou à investigação.&lt;/p&gt;

&lt;p&gt;A investigação revelou o conceito.&lt;/p&gt;

&lt;p&gt;E o conceito foi colocado diante de outro problema.&lt;/p&gt;

&lt;p&gt;Problema → Hipótese → Pergunta → Investigação → Conceito → Aplicação → Transferência&lt;/p&gt;

&lt;p&gt;Essa é a ideia por trás da Investigação Adaptativa.&lt;/p&gt;

&lt;p&gt;«Aprender não precisa começar pela definição.&lt;/p&gt;

&lt;p&gt;Às vezes, começa por uma pergunta que revela aquilo que ainda não sabemos.»&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Capítulo 21 — Deadlock: Quando o Sistema Fica Esperando por Ele Mesmo</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Mon, 21 Sep 2026 22:27:17 +0000</pubDate>
      <link>https://dev.to/freitasmp/capitulo-21-deadlock-quando-o-sistema-fica-esperando-por-ele-mesmo-359n</link>
      <guid>https://dev.to/freitasmp/capitulo-21-deadlock-quando-o-sistema-fica-esperando-por-ele-mesmo-359n</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi6rpq5fbt83kpwnmmbiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi6rpq5fbt83kpwnmmbiy.png" alt=" " width="662" height="512"&gt;&lt;/a&gt;Capítulo 21 — Deadlock: Quando o Sistema Fica Esperando por Ele Mesmo&lt;/p&gt;

&lt;p&gt;Uma falha que nos obrigou a parar tudo&lt;/p&gt;

&lt;p&gt;Estávamos construindo o sistema.&lt;/p&gt;

&lt;p&gt;Tudo parecia funcionar.&lt;/p&gt;

&lt;p&gt;Até que, durante um teste de concorrência, colocamos cinco execuções fazendo a mesma operação praticamente ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;E então apareceu:&lt;/p&gt;

&lt;p&gt;ER_LOCK_DEADLOCK&lt;/p&gt;

&lt;p&gt;A princípio, parece apenas mais um erro técnico.&lt;/p&gt;

&lt;p&gt;Mas a pergunta é muito mais interessante:&lt;/p&gt;

&lt;p&gt;«O que significa, de verdade, um sistema entrar em deadlock?»&lt;/p&gt;

&lt;p&gt;Foi assim que começou a nossa investigação.&lt;/p&gt;




&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;João, afinal, o que aconteceu aqui?&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Antes de falar de banco de dados, vamos esquecer programação por um momento.&lt;/p&gt;

&lt;p&gt;Imagina duas pessoas organizando documentos.&lt;/p&gt;

&lt;p&gt;👨 A está segurando um documento que B precisa.&lt;/p&gt;

&lt;p&gt;👩 B está segurando outro documento que A precisa.&lt;/p&gt;

&lt;p&gt;Então:&lt;/p&gt;

&lt;p&gt;👨 A → espera B&lt;br&gt;
👩 B → espera A&lt;/p&gt;

&lt;p&gt;Quem continua?&lt;/p&gt;

&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Ninguém.&lt;/p&gt;

&lt;p&gt;A está esperando B.&lt;/p&gt;

&lt;p&gt;B está esperando A.&lt;/p&gt;

&lt;p&gt;Então fica tudo travado.&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Agora temos uma descoberta.&lt;/p&gt;

&lt;p&gt;Não é simplesmente esperar que causa o problema.&lt;/p&gt;

&lt;p&gt;Se B estivesse esperando A, mas A pudesse terminar sozinho:&lt;/p&gt;

&lt;p&gt;👩 B → espera 👨 A&lt;/p&gt;

&lt;p&gt;👨 A → termina&lt;br&gt;
       ↓&lt;br&gt;
👩 B → continua&lt;/p&gt;

&lt;p&gt;Tudo ficaria bem.&lt;/p&gt;

&lt;p&gt;O problema aparece quando a espera volta para o início.&lt;/p&gt;

&lt;p&gt;👨 A → espera 👩 B&lt;br&gt;
        ↑       ↓&lt;br&gt;
        └───────┘&lt;/p&gt;

&lt;p&gt;Temos um círculo.&lt;/p&gt;




&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Então, se tivermos cinco pessoas, pode ficar ainda pior?&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Pode.&lt;/p&gt;

&lt;p&gt;Imagina:&lt;/p&gt;

&lt;p&gt;👨 A espera 👩 B&lt;br&gt;
👩 B espera 👨 C&lt;br&gt;
👨 C espera 👩 D&lt;br&gt;
👩 D espera 👨 E&lt;br&gt;
👨 E espera 👩 A&lt;/p&gt;

&lt;p&gt;Agora ninguém consegue avançar.&lt;/p&gt;

&lt;p&gt;E olha uma coisa interessante:&lt;/p&gt;

&lt;p&gt;nenhuma pessoa necessariamente fez algo errado.&lt;/p&gt;

&lt;p&gt;Cada uma simplesmente está esperando outra pessoa.&lt;/p&gt;

&lt;p&gt;O problema só aparece quando olhamos para o conjunto inteiro.&lt;/p&gt;




&lt;p&gt;Voltando para o nosso sistema&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Agora vamos voltar para o S04.&lt;/p&gt;

&lt;p&gt;Tínhamos cinco execuções acontecendo simultaneamente:&lt;/p&gt;

&lt;p&gt;Execução A ─┐&lt;br&gt;
Execução B ─┤&lt;br&gt;
Execução C ─┼──→ mesma interactionId&lt;br&gt;
Execução D ─┤&lt;br&gt;
Execução E ─┘&lt;/p&gt;

&lt;p&gt;O cursor daquela interação ainda não existia.&lt;/p&gt;

&lt;p&gt;Então todas chegaram praticamente à mesma conclusão:&lt;/p&gt;

&lt;p&gt;«"Não existe cursor. Preciso criá-lo."»&lt;/p&gt;

&lt;p&gt;E todas tentaram fazer isso.&lt;/p&gt;

&lt;p&gt;Foi aí que apareceu o nosso:&lt;/p&gt;

&lt;p&gt;ER_LOCK_DEADLOCK&lt;/p&gt;

&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Ah! Então o problema que encontramos no nosso projeto é o mesmo padrão.&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Mas com uma precisão importante:&lt;/p&gt;

&lt;p&gt;não significa que o banco de dados inteiro parou.&lt;/p&gt;

&lt;p&gt;Algumas operações ficaram envolvidas numa dependência circular.&lt;/p&gt;

&lt;p&gt;O banco detectou a situação e escolheu uma ou mais transações como vítimas, desfazendo aquela operação para permitir que o sistema continuasse.&lt;/p&gt;




&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Então o banco precisa "matar" alguns processos?&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;De forma simplificada, podemos dizer isso.&lt;/p&gt;

&lt;p&gt;Tecnicamente, ele pode abortar uma transação e fazer rollback.&lt;/p&gt;

&lt;p&gt;E isso produz uma descoberta interessante:&lt;/p&gt;

&lt;p&gt;«Às vezes, o erro é justamente o mecanismo que impede o sistema de ficar bloqueado para sempre.»&lt;/p&gt;




&lt;p&gt;Mas isso só acontece em bancos de dados?&lt;/p&gt;

&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Essa é uma coisa que fiquei curioso.&lt;/p&gt;

&lt;p&gt;Deadlock só acontece em banco de dados?&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Não.&lt;/p&gt;

&lt;p&gt;O banco é apenas um dos lugares onde esse problema aparece.&lt;/p&gt;

&lt;p&gt;O padrão é muito mais amplo.&lt;/p&gt;

&lt;p&gt;Pode acontecer quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👥 pessoas esperam umas pelas outras;&lt;/li&gt;
&lt;li&gt;🏭 máquinas dependem umas das outras;&lt;/li&gt;
&lt;li&gt;🚗 veículos ficam presos em uma passagem;&lt;/li&gt;
&lt;li&gt;💻 programas aguardam recursos;&lt;/li&gt;
&lt;li&gt;🗄️ transações aguardam recursos do banco.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A estrutura é sempre parecida:&lt;/p&gt;

&lt;p&gt;A possui X&lt;br&gt;
A precisa de Y&lt;/p&gt;

&lt;p&gt;B possui Y&lt;br&gt;
B precisa de X&lt;/p&gt;

&lt;p&gt;E então:&lt;/p&gt;

&lt;p&gt;A → espera B&lt;br&gt;
↑       ↓&lt;br&gt;
└───────┘&lt;/p&gt;




&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Então, quando estamos projetando um sistema, precisamos levantar essas situações e tentar prever esses problemas?&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Sim.&lt;/p&gt;

&lt;p&gt;Não conseguimos prever todos os problemas antes de construir um sistema.&lt;/p&gt;

&lt;p&gt;Mas podemos investigar:&lt;/p&gt;

&lt;p&gt;O que é compartilhado?&lt;/p&gt;

&lt;p&gt;Quem pode utilizar?&lt;/p&gt;

&lt;p&gt;Quem pode precisar esperar?&lt;/p&gt;

&lt;p&gt;Enquanto espera, o que continua segurando?&lt;/p&gt;

&lt;p&gt;Existe possibilidade de formar um ciclo?&lt;/p&gt;

&lt;p&gt;Essa análise pode revelar riscos de concorrência antes que eles apareçam em produção.&lt;/p&gt;




&lt;p&gt;Uma pequena experiência&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Agora olha para duas situações.&lt;/p&gt;

&lt;p&gt;Primeira:&lt;/p&gt;

&lt;p&gt;👨 A → X → Y&lt;br&gt;
👩 B → Y → X&lt;/p&gt;

&lt;p&gt;Existe possibilidade de formar um ciclo.&lt;/p&gt;

&lt;p&gt;Agora mudamos a ordem:&lt;/p&gt;

&lt;p&gt;👨 A → X → Y&lt;br&gt;
👩 B → X → Y&lt;/p&gt;

&lt;p&gt;O que acontece?&lt;/p&gt;

&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Aí não temos círculo.&lt;/p&gt;

&lt;p&gt;B pode esperar A.&lt;/p&gt;

&lt;p&gt;Mas A não está esperando B.&lt;/p&gt;

&lt;p&gt;Quando A terminar, B continua.&lt;/p&gt;

&lt;p&gt;Então não temos deadlock.&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Exatamente.&lt;/p&gt;

&lt;p&gt;Acabaste de descobrir uma das estratégias fundamentais para reduzir deadlocks:&lt;/p&gt;

&lt;p&gt;«estabelecer uma ordem consistente para adquirir recursos.»&lt;/p&gt;




&lt;p&gt;E se o banco não detectasse?&lt;/p&gt;

&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Mas o que aconteceria se o banco nunca detectasse aquele deadlock?&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;Imagina:&lt;/p&gt;

&lt;p&gt;A ⏳&lt;br&gt;
B ⏳&lt;/p&gt;

&lt;p&gt;Se nenhuma pudesse sair da situação, poderiam ficar esperando indefinidamente.&lt;/p&gt;

&lt;p&gt;E outras operações poderiam começar a esperar também:&lt;/p&gt;

&lt;p&gt;A ⏳&lt;br&gt;
B ⏳&lt;br&gt;
C ⏳&lt;br&gt;
D ⏳&lt;br&gt;
E ⏳&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;Isso poderia consumir conexões e outros recursos, aumentar os tempos de resposta, provocar timeouts e degradar o sistema.&lt;/p&gt;

&lt;p&gt;O sistema estaria gastando recursos sem produzir progresso útil.&lt;/p&gt;




&lt;p&gt;🧑‍💻 Matondo Pedro&lt;/p&gt;

&lt;p&gt;Agora lembrei de uma coisa!&lt;/p&gt;

&lt;p&gt;Na 42 Luanda estudamos um problema chamado Dining Philosophers — O Jantar dos Filósofos.&lt;/p&gt;

&lt;p&gt;👨‍💻 João&lt;/p&gt;

&lt;p&gt;E agora a conexão fica muito interessante.&lt;/p&gt;

&lt;p&gt;Nós não começamos pelos filósofos.&lt;/p&gt;

&lt;p&gt;Encontramos o problema primeiro no nosso sistema.&lt;/p&gt;

&lt;p&gt;Depois percebemos que existia um problema clássico que representa exatamente essa classe de situação.&lt;/p&gt;

&lt;p&gt;🍝 Dining Philosophers      Nosso sistema&lt;/p&gt;

&lt;p&gt;🧑 Filósofo                 Execução&lt;br&gt;
🍴 Garfo                    Recurso&lt;br&gt;
⏳ Espera                   Espera&lt;br&gt;
🔄 Ciclo                    Dependência circular&lt;br&gt;
🔒 Bloqueio                 Deadlock&lt;/p&gt;

&lt;p&gt;E essa é talvez a parte mais interessante da investigação.&lt;/p&gt;

&lt;p&gt;Não estudamos deadlock porque alguém começou dizendo:&lt;/p&gt;

&lt;p&gt;«"Deadlock é X."»&lt;/p&gt;

&lt;p&gt;Nós começamos com:&lt;/p&gt;

&lt;p&gt;«"Por que o nosso sistema travou?"»&lt;/p&gt;

&lt;p&gt;Investigamos.&lt;/p&gt;

&lt;p&gt;Fizemos perguntas.&lt;/p&gt;

&lt;p&gt;Criamos hipóteses.&lt;/p&gt;

&lt;p&gt;Simplificamos o problema.&lt;/p&gt;

&lt;p&gt;Encontramos o padrão.&lt;/p&gt;

&lt;p&gt;E só depois demos nome ao que havíamos descoberto:&lt;/p&gt;

&lt;p&gt;«Deadlock.»&lt;/p&gt;

&lt;p&gt;Esse é o espírito do Adaptive Inquiry: começar pelo problema real, investigar através de perguntas, descobrir o conceito e só então aprender o termo técnico.&lt;/p&gt;

&lt;p&gt;A teoria veio depois da necessidade de entendê-la.&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>Coming soon !</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Sun, 21 Nov 2021 16:21:27 +0000</pubDate>
      <link>https://dev.to/freitasmp/coming-soon--j22</link>
      <guid>https://dev.to/freitasmp/coming-soon--j22</guid>
      <description>&lt;p&gt;I will develop this application ,coming soon.&lt;br&gt;
Using Nodejs,DDD,TDD and react js&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
