<?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>Are we really teaching machines to learn, or simply to recognize patterns?

In my opinion, Artificial Intelligence is still far from the level of intelligence and learning capabilities we often expect from it.

Read my article and join the discussion</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Sun, 01 Nov 2026 09:45:56 +0000</pubDate>
      <link>https://dev.to/freitasmp/are-we-really-teaching-machines-to-learn-or-simply-to-recognize-patterns-in-my-opinion-39je</link>
      <guid>https://dev.to/freitasmp/are-we-really-teaching-machines-to-learn-or-simply-to-recognize-patterns-in-my-opinion-39je</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/freitasmp/artificial-intelligence-are-we-teaching-machines-to-learn-or-just-recognize-patterns-43c5" class="crayons-story__hidden-navigation-link"&gt;Artificial Intelligence: Are We Teaching Machines to Learn or Just Recognize Patterns?&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/freitasmp" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F757753%2F8da32153-e936-4070-a5e4-c19123f3f769.jpeg" alt="freitasmp profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/freitasmp" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Freitas-Mp
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Freitas-Mp
                
                
              
              &lt;div id="story-author-preview-content-4956725" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/freitasmp" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F757753%2F8da32153-e936-4070-a5e4-c19123f3f769.jpeg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Freitas-Mp&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/freitasmp/artificial-intelligence-are-we-teaching-machines-to-learn-or-just-recognize-patterns-43c5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Nov 1&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/freitasmp/artificial-intelligence-are-we-teaching-machines-to-learn-or-just-recognize-patterns-43c5" id="article-link-4956725"&gt;
          Artificial Intelligence: Are We Teaching Machines to Learn or Just Recognize Patterns?
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/machinelearning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;machinelearning&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mll"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mll&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/freitasmp/artificial-intelligence-are-we-teaching-machines-to-learn-or-just-recognize-patterns-43c5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
          
          &lt;div class="only-sidebar-menu-item trusted-visible-block print-hidden align-center"&gt;
                
                    
                
          &lt;/div&gt;

        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>discuss</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Artificial Intelligence: Are We Teaching Machines to Learn or Just Recognize Patterns?</title>
      <dc:creator>Freitas-Mp</dc:creator>
      <pubDate>Sun, 01 Nov 2026 09:39:50 +0000</pubDate>
      <link>https://dev.to/freitasmp/artificial-intelligence-are-we-teaching-machines-to-learn-or-just-recognize-patterns-43c5</link>
      <guid>https://dev.to/freitasmp/artificial-intelligence-are-we-teaching-machines-to-learn-or-just-recognize-patterns-43c5</guid>
      <description>&lt;h1&gt;
  
  
  Artificial Intelligence: Are We Teaching Machines to Learn or Just Recognize Patterns?
&lt;/h1&gt;

&lt;p&gt;While exploring Machine Learning, I started questioning something fundamental:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are we really teaching machines to learn, or are we mainly teaching them to recognize patterns from examples?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I believe there is an important distinction between learning individual examples and understanding the fundamental principles behind them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning from examples vs. understanding principles
&lt;/h2&gt;

&lt;p&gt;An example is a specific situation from which we can learn something. A principle, however, is a fundamental truth, relationship, or structure that helps explain why something works.&lt;/p&gt;

&lt;p&gt;These principles are particularly valuable because they can be reused across different contexts. Once we understand the underlying relationship, we can apply that knowledge to situations we have never encountered before.&lt;/p&gt;

&lt;p&gt;This is one of the most powerful aspects of human learning: we don't necessarily need to memorize every possible situation. We can understand a principle and use it to reason about new problems.&lt;/p&gt;

&lt;p&gt;Consider two developers preparing for algorithmic coding interviews:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developer A&lt;/strong&gt; solves 300 coding problems, focusing mainly on practicing individual problems and remembering their solutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer B&lt;/strong&gt; solves 65 carefully selected problems, but focuses on understanding the underlying principles and algorithmic patterns, such as Hash Maps, Two Pointers, Sliding Window, Binary Search, Recursion, and Dynamic Programming.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Who is more likely to solve an unfamiliar problem?&lt;/p&gt;

&lt;p&gt;Developer B may have an advantage because they are developing reusable problem-solving structures rather than relying primarily on familiarity with previously solved examples.&lt;/p&gt;

&lt;p&gt;The point is not that solving 300 problems is wrong, or that 65 is a magic number. Practice is essential. The difference is what each person extracts from that practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One focuses on accumulating solutions. The other focuses on understanding the principles that can generate solutions across different problems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This distinction is what interests me most about the future of Artificial Intelligence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does a Machine Learning model actually do?
&lt;/h2&gt;

&lt;p&gt;Let's use a simple everyday analogy: imagine cooking a pot of food for the first time.&lt;/p&gt;

&lt;p&gt;You taste it and realize it needs more salt. You adjust the seasoning, taste it again, and make another adjustment.&lt;/p&gt;

&lt;p&gt;Each attempt gives you feedback that helps you get closer to the result you want.&lt;/p&gt;

&lt;p&gt;This is learning through trial and error. However, it is not necessarily blind trial and error. The feedback from each attempt guides the next adjustment.&lt;/p&gt;

&lt;p&gt;Many Machine Learning models follow a related mechanism. They make predictions, compare them with actual outcomes, measure the error, and use that information to adjust their internal parameters.&lt;/p&gt;

&lt;p&gt;For example, in Linear Regression, Gradient Descent uses mathematical information about the direction of the error to guide parameter updates.&lt;/p&gt;

&lt;p&gt;This process can be effective. However, repeatedly making adjustments without understanding the underlying relationships can become inefficient.&lt;/p&gt;

&lt;p&gt;In human learning, trial and error is a natural mechanism, but it is not the only one. We can also learn by identifying fundamental principles, understanding relationships, and transferring that knowledge to new situations.&lt;/p&gt;

&lt;p&gt;This brings me back to my original question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can we develop AI systems that go beyond learning statistical patterns from examples and become better at identifying, representing, and reusing fundamental principles?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From theory to practice
&lt;/h2&gt;

&lt;p&gt;To understand one of these learning mechanisms beyond the theory, I implemented a &lt;strong&gt;Linear Regression algorithm from scratch&lt;/strong&gt;, without using Machine Learning libraries.&lt;/p&gt;

&lt;p&gt;This allowed me to explore the mathematics behind the process, including model parameters, the cost function, Mean Squared Error (MSE), and Gradient Descent.&lt;/p&gt;

&lt;p&gt;I started with the mathematical formulation and progressively translated it into code. This experience helped me understand how a model makes predictions, measures its errors, and adjusts its parameters to improve.&lt;/p&gt;

&lt;p&gt;More than implementing an algorithm, this project changed how I look at Machine Learning and reinforced my interest in understanding the mechanisms behind learning itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perhaps the next major challenge in Artificial Intelligence is not simply learning from more data, but learning more from what the data represents — identifying the principles behind examples and making that knowledge reusable across different contexts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is one of the questions I want to keep exploring.&lt;/p&gt;

&lt;p&gt;github: &lt;a href="https://github.com/matondomp/ft_linear_regrassion_42_ecole/tree/master" rel="noopener noreferrer"&gt;my code on github&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  ArtificialIntelligence #MachineLearning #AIEngineering #LinearRegression #GradientDescent
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>mll</category>
    </item>
    <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>
