<?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>Forem: Alex Reis</title>
    <description>The latest articles on Forem by Alex Reis (@alexreis).</description>
    <link>https://forem.com/alexreis</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1217593%2F6a99750b-e369-4209-99b7-f712ce3ae07a.jpeg</url>
      <title>Forem: Alex Reis</title>
      <link>https://forem.com/alexreis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alexreis"/>
    <language>en</language>
    <item>
      <title>O que são generics?</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Thu, 12 Feb 2026 11:00:00 +0000</pubDate>
      <link>https://forem.com/alexreis/o-que-sao-generics-id4</link>
      <guid>https://forem.com/alexreis/o-que-sao-generics-id4</guid>
      <description>&lt;p&gt;Generics são uma funcionalidade introduzida no Java 5 que permite criar classes, interfaces e métodos que trabalham com diferentes tipos de dados. Eles eliminam a necessidade de conversões explícitas (casts) e ajudam a detectar erros em tempo de compilação.&lt;/p&gt;

&lt;p&gt;Antes do Java 5, as coleções tratavam tudo como &lt;code&gt;Object&lt;/code&gt;. Isso gerava dois problemas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Casting Excessivo:&lt;/strong&gt; Você tinha que fazer cast &lt;code&gt;(String)&lt;/code&gt; toda vez que tirava algo da lista.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insegurança:&lt;/strong&gt; Nada impedia você de colocar um &lt;code&gt;Integer&lt;/code&gt; numa lista que deveria ser só de &lt;code&gt;String&lt;/code&gt;. O erro só estourava na cara do usuário (Runtime).
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Código antigo&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Lista "crua" (Raw Type)&lt;/span&gt;
&lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// O compilador deixa passar!&lt;/span&gt;

&lt;span class="c1"&gt;// O erro só acontece AQUI, quando o programa está rodando:&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ClassCastException!&lt;/span&gt;

&lt;span class="c1"&gt;// Código novo com Generics&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// lista.add(10); // O compilador NEM DEIXA compilar. Erro na hora!&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Sem necessidade de cast manual.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Variáveis de tipo
&lt;/h3&gt;

&lt;p&gt;Generics permitem que classes e métodos operem em objetos de vários tipos, garantindo a segurança em tempo de compilação (Compile-time safety).&lt;/p&gt;

&lt;p&gt;Usamos letras maiúsculas por convenção para representar esses tipos genéricos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;T&lt;/code&gt;&lt;/strong&gt;: Type (Tipo genérico)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;E&lt;/code&gt;&lt;/strong&gt;: Element (usado em Collections)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;K&lt;/code&gt;, &lt;code&gt;V&lt;/code&gt;&lt;/strong&gt;: Key, Value (usado em Maps)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Classe Genérica
&lt;/h3&gt;

&lt;p&gt;Uma classe genérica utiliza um &lt;strong&gt;parâmetro de tipo&lt;/strong&gt; representado por &lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt;, que funciona como um placeholder para o tipo real.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// &amp;lt;T&amp;gt; define que esta classe aceita um parâmetro de tipo&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Caixa&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;conteudo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;guardar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;conteudo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;conteudo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conteudo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;abrir&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;conteudo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AulaGenerics&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Caixa que só aceita Strings&lt;/span&gt;
        &lt;span class="nc"&gt;Caixa&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;caixaDeTexto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Caixa&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;caixaDeTexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;guardar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Segredo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// caixaDeTexto.guardar(123); // Erro de compilação!&lt;/span&gt;

        &lt;span class="c1"&gt;// Caixa que só aceita Inteiros&lt;/span&gt;
        &lt;span class="nc"&gt;Caixa&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;caixaDeNumeros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Caixa&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;caixaDeNumeros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;guardar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt; é substituído por &lt;code&gt;String&lt;/code&gt; ou &lt;code&gt;Integer&lt;/code&gt; no momento da criação do objeto.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Wildcards
&lt;/h3&gt;

&lt;p&gt;Os &lt;strong&gt;wildcards&lt;/strong&gt; (&lt;code&gt;?&lt;/code&gt;) são usados para representar tipos desconhecidos em generics. Eles são úteis para criar métodos que aceitam diferentes tipos de coleções.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;?&amp;gt;&lt;/code&gt;&lt;/strong&gt;: Qualquer coisa.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;? extends T&amp;gt;&lt;/code&gt; (Upper Bounded)&lt;/strong&gt;: Aceita T ou qualquer &lt;strong&gt;filho&lt;/strong&gt; de T.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Uso:&lt;/em&gt; Quando você quer apenas &lt;strong&gt;LER&lt;/strong&gt; dados (Get).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;&lt;code&gt;&amp;lt;? super T&amp;gt;&lt;/code&gt; (Lower Bounded)&lt;/strong&gt;: Aceita T ou qualquer &lt;strong&gt;pai&lt;/strong&gt; de T.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Uso:&lt;/em&gt; Quando você quer &lt;strong&gt;ESCREVER&lt;/strong&gt; dados (Add).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exemplo Prático
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Wildcards&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Aceita lista de Number OU QUALQUER FILHO (Integer, Double...)&lt;/span&gt;
    &lt;span class="c1"&gt;// Só consigo LER com segurança (sei que tudo ali é Number)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;somarLista&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;soma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Posso ler como Number&lt;/span&gt;
            &lt;span class="n"&gt;soma&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doubleValue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// lista.add(10); // ERRO! Não posso adicionar nada (não sei se é lista de Double ou Integer)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;soma&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inteiros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;inteiros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;inteiros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doubles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doubles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doubles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// O método aceita ambos!&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;somarLista&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inteiros&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;somarLista&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doubles&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type Erasure
&lt;/h3&gt;

&lt;p&gt;Generics só existem para o &lt;strong&gt;Compilador&lt;/strong&gt;. Depois que o código vira &lt;code&gt;.class&lt;/code&gt; (Bytecode), o Java &lt;strong&gt;apaga&lt;/strong&gt; todas as informações de Generics e substitui por &lt;code&gt;Object&lt;/code&gt; (ou pelo limite superior) e insere os casts automaticamente.&lt;/p&gt;

&lt;p&gt;Isso significa que, em tempo de execução, &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt; e &lt;code&gt;List&amp;lt;Integer&amp;gt;&lt;/code&gt; são a mesma classe (&lt;code&gt;List&lt;/code&gt;). Isso foi feito para manter compatibilidade com versões antigas do Java.&lt;/p&gt;

</description>
      <category>java</category>
      <category>backend</category>
      <category>braziliandevs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Interfaces Funcionais</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Wed, 11 Feb 2026 11:38:56 +0000</pubDate>
      <link>https://forem.com/alexreis/interfaces-funcionais-4pg0</link>
      <guid>https://forem.com/alexreis/interfaces-funcionais-4pg0</guid>
      <description>&lt;p&gt;Uma &lt;strong&gt;interface funcional&lt;/strong&gt; é definida como uma interface que &lt;strong&gt;não é declarada como selada (sealed)&lt;/strong&gt; e pode conter métodos &lt;code&gt;default&lt;/code&gt; e &lt;code&gt;static&lt;/code&gt; mas possui &lt;strong&gt;exatamente um método abstrato&lt;/strong&gt; (além dos métodos da classe &lt;code&gt;Object&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Além da maneira tradicional (declarando e instanciando uma classe), instâncias de interfaces funcionais podem ser criadas de forma mais concisa utilizando &lt;strong&gt;expressões lambda&lt;/strong&gt; e &lt;strong&gt;referências de método&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Existe ainda a anotação &lt;code&gt;@FunctionalInterface&lt;/code&gt; que serve para indicar que uma interface deve ser funcional. Se uma interface for anotada dessa forma, mas não atender aos requisitos (como ter mais de um método abstrato), o compilador gerará um erro. No entanto, ela é opcional.&lt;/p&gt;

&lt;p&gt;Para evitar que tenhamos que criar uma nova interface toda vez que precisarmos de uma função simples, o Java fornece um pacote padrão com as interfaces funcionais mais comuns (&lt;code&gt;java.util.function&lt;/code&gt;). As quatro principais são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Predicate&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/strong&gt;: Recebe um argumento e retorna um &lt;code&gt;boolean&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Uso:&lt;/em&gt; Filtros e condicionais.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Método abstrato:&lt;/em&gt; &lt;code&gt;test(T t)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Consumer&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/strong&gt;: Recebe um argumento e não retorna nada (&lt;code&gt;void&lt;/code&gt;).

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Uso:&lt;/em&gt; Impressão de dados, gravação em banco, efeitos colaterais.
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Método abstrato:&lt;/em&gt; &lt;code&gt;accept(T t)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Function&amp;lt;T, R&amp;gt;&lt;/code&gt;&lt;/strong&gt;: Recebe um argumento do tipo T e retorna um resultado do tipo R.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Uso:&lt;/em&gt; Transformação de dados (mapeamento).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Método abstrato:&lt;/em&gt; &lt;code&gt;apply(T t)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Supplier&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/strong&gt;: Não recebe argumentos e retorna um resultado do tipo T.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Uso:&lt;/em&gt; Factories, geração preguiçosa (lazy) de dados.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Método abstrato:&lt;/em&gt; &lt;code&gt;get()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Exemplo prático
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.function.Predicate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Definindo uma Interface Funcional Customizada&lt;/span&gt;
&lt;span class="nd"&gt;@FunctionalInterface&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ConversorTexto&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;converter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Único método abstrato&lt;/span&gt;

    &lt;span class="c1"&gt;// Método default não quebra a regra de interface funcional&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;imprimirLog&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando conversão..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AulaInterfaces&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// --- USO DA INTERFACE CUSTOMIZADA ---&lt;/span&gt;

        &lt;span class="c1"&gt;// Implementação clássica (Classe Anônima) - O jeito antigo&lt;/span&gt;
        &lt;span class="nc"&gt;ConversorTexto&lt;/span&gt; &lt;span class="n"&gt;gritarClassico&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ConversorTexto&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;@Override&lt;/span&gt;
            &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;converter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"!!!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Implementação com Lambda - O jeito moderno&lt;/span&gt;
        &lt;span class="c1"&gt;// O compilador infere que 's' é o argumento de 'converter'&lt;/span&gt;
        &lt;span class="nc"&gt;ConversorTexto&lt;/span&gt; &lt;span class="n"&gt;gritarLambda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"!!!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gritarLambda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;converter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bom dia"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; 
        &lt;span class="c1"&gt;// Saída: BOM DIA!!!&lt;/span&gt;


        &lt;span class="c1"&gt;// --- USO DE INTERFACE PADRÃO (Predicate) ---&lt;/span&gt;

        &lt;span class="c1"&gt;// Predicate verifica uma condição&lt;/span&gt;
        &lt;span class="nc"&gt;Predicate&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;isPar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;validarNumero&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isPar&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Passando comportamento como argumento&lt;/span&gt;
        &lt;span class="n"&gt;validarNumero&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isPar&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Método que aceita um comportamento (Predicate) como parâmetro&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;validarNumero&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Predicate&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" passou na regra."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" não passou na regra."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Leituras Complementares
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documentação Oficial Oracle:&lt;/strong&gt; Pacote java.util.function.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Livro&lt;/strong&gt;: "Java 8 in Action" (Raoul-Gabriel Urma) - Capítulo sobre Lambdas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artigo:&lt;/strong&gt; "Functional Interfaces in Java" no Baeldung.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>java</category>
      <category>programming</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>O que são Expressões Lambdas?</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Tue, 10 Feb 2026 11:34:59 +0000</pubDate>
      <link>https://forem.com/alexreis/o-que-sao-expressoes-lambdas-5gcd</link>
      <guid>https://forem.com/alexreis/o-que-sao-expressoes-lambdas-5gcd</guid>
      <description>&lt;p&gt;Você sabe o que são Expressões Lambdas (Lambda Expressions)?  As Expressões Lambda, introduzidas no Java 8, permitem que você trate "comportamento" como se fosse um dado.&lt;/p&gt;

&lt;p&gt;Segunda a Java Language Specification: As &lt;strong&gt;expressões lambda&lt;/strong&gt; são estruturas semelhantes a métodos que fornecem uma lista de parâmetros formais e um corpo (que pode ser uma expressão ou um bloco de código) expressos em termos desses parâmetros&lt;/p&gt;

&lt;p&gt;Antes do Java 8, se você quisesse passar um pedaço de código para ser executado (ex: num clique de botão ou numa Thread), você precisava criar uma &lt;strong&gt;Classe Anônima&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Jeito velho:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Criando uma Thread antiga&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando tarefa..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}).&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jeito novo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// "() -&amp;gt;" significa: Sem argumentos, execute isso.&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando tarefa..."&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;O principal objetivo de uma expressão lambda é produzir uma instância de uma &lt;strong&gt;interface funcional&lt;/strong&gt; (uma interface que possui exatamente um método abstrato).&lt;/li&gt;
&lt;li&gt;Elas oferecem uma sintaxe muito mais concisa do que as declarações de classes anônimas.
### Sintaxe e estrutura
Uma expressão lambda é composta de três partes. Pense nela como uma função sem nome.
A sintaxe básica é composta por: &lt;code&gt;(Parâmetros) -&amp;gt; { Corpo }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sem parâmetros:&lt;/strong&gt; &lt;code&gt;() -&amp;gt; System.out.println("Oi");&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Um parâmetro:&lt;/strong&gt; &lt;code&gt;(s) -&amp;gt; System.out.println(s);&lt;/code&gt; (Pode omitir parênteses se for só um).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Múltiplos parâmetros:&lt;/strong&gt; Devem estar entre parênteses. Exemplo: &lt;code&gt;(x, y) -&amp;gt; x + y&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parâmetros não nomeados:&lt;/strong&gt; É possível usar o caractere &lt;code&gt;_&lt;/code&gt; (underscore) para declarar um parâmetro cujo valor não será utilizado no corpo da lambda.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Com retorno:&lt;/strong&gt; &lt;code&gt;(a, b) -&amp;gt; { return a + b; }&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplificado:&lt;/strong&gt; &lt;code&gt;(a, b) -&amp;gt; a + b&lt;/code&gt; (Se só tiver uma linha, não precisa de &lt;code&gt;{}&lt;/code&gt; nem da palavra &lt;code&gt;return&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Você pode declarar os tipos dos parâmetros (exclusivamente para todos ou nenhum) ou deixar que o compilador os infira a partir do contexto da interface funcional.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Regras de Uso e Contexto
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Onde usar:&lt;/strong&gt; Devem ocorrer apenas em contextos de &lt;strong&gt;atribuição&lt;/strong&gt;, de &lt;strong&gt;invocação&lt;/strong&gt; (como argumentos de métodos) ou de &lt;strong&gt;cast&lt;/strong&gt; (conversão explícita). O Java só permite Lambda quando o tipo esperado é uma &lt;strong&gt;Interface Funcional&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Captura de Variáveis:&lt;/strong&gt; Uma lambda pode acessar variáveis locais do escopo ao seu redor, desde que essas variáveis sejam &lt;strong&gt;finais ou efetivamente finais&lt;/strong&gt; (ou seja, seu valor nunca mude após a inicialização).&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo prático
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nomes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ana"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Pedro"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ze"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Maria"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Jeito Antigo (Classe Anônima)&lt;/span&gt;
&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nomes&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compare&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Jeito Novo&lt;/span&gt;
&lt;span class="c1"&gt;// O Java sabe que s1 e s2 são Strings (Inferência de Tipo)&lt;/span&gt;
&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nomes&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compare&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method Reference
&lt;/h3&gt;

&lt;p&gt;Muitas vezes, uma expressão Lambda não faz nada além de chamar um método que já existe, você pode deixar o código ainda mais limpo usando o operador "quatro pontos" (&lt;code&gt;::&lt;/code&gt;). &lt;br&gt;
Por exemplo: &lt;code&gt;s -&amp;gt; System.out.println(s)&lt;/code&gt;. Perceba que o parâmetro &lt;code&gt;s&lt;/code&gt; é apenas repassado para o método &lt;code&gt;println&lt;/code&gt;. Não há lógica adicional.&lt;/p&gt;

&lt;h4&gt;
  
  
  Exemplos:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Lambda: numero -&amp;gt; Math.abs(numero)&lt;/span&gt;
&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;valorAbsoluto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;Math:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;abs&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// O objeto 'System.out' já existe.&lt;/span&gt;
&lt;span class="c1"&gt;// Lambda: s -&amp;gt; System.out.println(s)&lt;/span&gt;
&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;impressora&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Aqui, o método toUpperCase é chamado NA instância da String passada&lt;/span&gt;
&lt;span class="c1"&gt;// Lambda: s -&amp;gt; s.toUpperCase()&lt;/span&gt;
&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maiuscula&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Exemplo composto:&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nomes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"java"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"python"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// A String "java" chama o método compareTo passando "python"&lt;/span&gt;
&lt;span class="n"&gt;nomes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// Lambda: () -&amp;gt; new String()&lt;/span&gt;
&lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;novaString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Referência
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://docs.oracle.com/javase/specs/jls/se24/jls24.pdf" rel="noopener noreferrer"&gt;The Java Language Specification, Java SE 24 Edition&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>braziliandevs</category>
      <category>backend</category>
    </item>
    <item>
      <title>Entendendo Flyway</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Mon, 27 Oct 2025 10:30:00 +0000</pubDate>
      <link>https://forem.com/alexreis/flyway-4cbn</link>
      <guid>https://forem.com/alexreis/flyway-4cbn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Nota: Isto não é um artigo, são minhas anotações de estudo sobre o que é o Flyway, que resolvi postar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O Flyway é uma ferramenta de versionamento de banco de dados.&lt;br&gt;
Ele ajuda a controlar e aplicar mudanças no esquema do banco (migrations) de forma segura e automatizada — assim como o Git controla versões de código. Ele é específico para banco de dados relacionais.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scripts
&lt;/h3&gt;

&lt;p&gt;Você cria arquivos SQL chamados migrations. Cada um representa uma mudança no banco. Eles seguem uma convenção de nome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;V1__create_message_table.sql
V2__create_room_table.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;V&lt;/code&gt; é de versão e o número (&lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;) diz a ordem em que devem ser executados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tabela de controle
&lt;/h3&gt;

&lt;p&gt;Quando o Flyway roda pela primeira vez, ele cria uma tabela dentro do seu banco, chamada por padrão de:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;flyway_schema_history&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa tabela guarda o histórico de todas as migrações aplicadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Execução
&lt;/h3&gt;

&lt;p&gt;Quando a aplicação inicia (ou quando você roda o comando flyway migrate), o Flyway faz o seguinte:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lê todos os arquivos de migração disponíveis na pasta configurada (por exemplo, db/migration/);&lt;/li&gt;
&lt;li&gt;Compara com a tabela flyway_schema_history do banco;&lt;/li&gt;
&lt;li&gt;Executa apenas os scripts que ainda não foram aplicados, em ordem crescente de versão.
### Controle de integridade
O Flyway guarda também um checksum (hash) de cada script. Se alguém altera um script antigo (por exemplo, muda &lt;code&gt;V2__create_room_table.sql&lt;/code&gt; depois de aplicado), o Flyway detecta a diferença e gera erro — pra evitar inconsistência entre versões do banco.
### Repetição e rollback
As migrations são pensadas para serem irreversíveis (você cria novas versões em vez de apagar ou alterar antigas). Se precisar “voltar atrás”, cria um novo script que desfaz a alteração anterior (em vez de alterar o antigo).
## Spring Boot
O Spring Boot detecta automaticamente o Flyway durante a inicialização se o projeto tiver a dependência no &lt;code&gt;pom.xml&lt;/code&gt;.
### Inicialização
Quando o Spring Boot inicia, ele faz algo nesta ordem:&lt;/li&gt;
&lt;li&gt;Cria a conexão com o banco (DataSource).&lt;/li&gt;
&lt;li&gt;Antes de carregar seus repositórios, entidades JPA, etc., ele chama o Flyway.&lt;/li&gt;
&lt;li&gt;O Flyway:

&lt;ul&gt;
&lt;li&gt;Cria (se não existir) a tabela flyway_schema_history.&lt;/li&gt;
&lt;li&gt;Procura por scripts na pasta padrão classpath:db/migration/.&lt;/li&gt;
&lt;li&gt;Aplica os que ainda não estão marcados como executados.&lt;/li&gt;
&lt;li&gt;Só depois disso o Spring continua inicializando o restante da aplicação.
Isso garante que o banco já esteja na versão certa antes de qualquer entidade JPA tentar interagir com ele.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dentro do projeto você cria algo assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;src&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;main&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;java&lt;/span&gt;&lt;span class="o"&gt;/...&lt;/span&gt;
    &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;resources&lt;/span&gt;
        &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;db&lt;/span&gt;
            &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;migration&lt;/span&gt;
                &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;V1__create_table_users&lt;/span&gt;&lt;span class="nc"&gt;.sql&lt;/span&gt;
                &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;V2__add_column_email&lt;/span&gt;&lt;span class="nc"&gt;.sql&lt;/span&gt;
                &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;V3__insert_initial_data&lt;/span&gt;&lt;span class="nc"&gt;.sql&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada arquivo é uma migration. Quando a aplicação sobe, o Flyway lê esses arquivos e aplica o que falta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuração do &lt;code&gt;application.properties&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Você pode personalizar a configuração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.flyway.enabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.flyway.locations&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;classpath:db/migration&lt;/span&gt;
&lt;span class="py"&gt;spring.flyway.baseline-on-migrate&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.flyway.user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;spring.flyway.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1234&lt;/span&gt;
&lt;span class="py"&gt;spring.flyway.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:postgresql://localhost:5432/meubanco&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>sql</category>
      <category>database</category>
      <category>springboot</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Relacionamentos Bidirecionais vs Unidirecionais no Spring JPA</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Thu, 21 Aug 2025 11:52:04 +0000</pubDate>
      <link>https://forem.com/alexreis/relacionamentos-bidirecionais-vs-unidirecionais-no-spring-jpa-48b4</link>
      <guid>https://forem.com/alexreis/relacionamentos-bidirecionais-vs-unidirecionais-no-spring-jpa-48b4</guid>
      <description>&lt;p&gt;Recentemente eu estava desenvolvendo um projeto pessoal de API para gerenciamento de lojas, mas tive dificuldasde ao tentar modelar os relacionamentos entre as entidades. O problema estava em entender qual melhor abordagem bidirecional ou unidirecional. Este artigo demonstra as conclusões que tive ao estudar vantagens e casos de uso dos tipos de relacionamento e o uso de &lt;code&gt;fetch&lt;/code&gt; do Spring Data JPA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relacionamentos: Navegação e Complexidade
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Relacionamentos Bidirecionais: Flexibilidade com Responsabilidade
&lt;/h3&gt;

&lt;p&gt;Os relacionamentos bidirecionais permitem navegação em ambas as direções, criando uma conexão completa entre entidades. Por exemplo, em um sistema de e-commerce, tanto um &lt;code&gt;Pedido&lt;/code&gt; pode acessar seu &lt;code&gt;Cliente&lt;/code&gt; quanto um &lt;code&gt;Cliente&lt;/code&gt; pode listar todos os seus &lt;code&gt;Pedidos&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vantagens dos relacionamentos bidirecionais:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Navegação intuitiva&lt;/strong&gt;: Facilita a escrita de código mais legível e expressivo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade de consultas&lt;/strong&gt;: Permite acessar dados relacionados de qualquer direção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adequado para interfaces ricas&lt;/strong&gt;: Ideal para dashboards e sistemas que exigem contexto completo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Desvantagens:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complexidade no mapeamento&lt;/strong&gt;: Requer atenção especial ao definir o lado proprietário da relação usando &lt;code&gt;mappedBy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risco de inconsistências&lt;/strong&gt;: Necessita sincronização cuidadosa quando ambos os lados são modificados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Possível impacto na performance&lt;/strong&gt;: Pode gerar joins desnecessários se não for bem configurado&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Relacionamentos Unidirecionais: Simplicidade e Performance
&lt;/h3&gt;

&lt;p&gt;Os relacionamentos unidirecionais oferecem uma abordagem mais simples, onde apenas uma entidade conhece a outra. Um &lt;code&gt;Produto&lt;/code&gt; pode conhecer sua &lt;code&gt;Categoria&lt;/code&gt;, mas a &lt;code&gt;Categoria&lt;/code&gt; não mantém referência direta aos produtos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vantagens dos relacionamentos unidirecionais:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicidade arquitetural&lt;/strong&gt;: Menor complexidade de implementação e manutenção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance otimizada&lt;/strong&gt;: Redução de joins automáticos desnecessários&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhor encapsulamento&lt;/strong&gt;: Evita exposição desnecessárias de entidades&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitações:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Navegação restrita&lt;/strong&gt;: Consultas reversas exigem joins manuais ou queries customizadas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Menos flexibilidade&lt;/strong&gt;: Pode requerer refatoração se novos casos de uso surgirem&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estratégias de Carregamento: Eager vs Lazy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  FetchType.EAGER: Carregamento Imediato
&lt;/h3&gt;

&lt;p&gt;O carregamento eager traz os dados relacionados junto com a consulta principal, usando joins SQL ou múltiplas consultas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@OneToMany&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetchType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAGER&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Pedido&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cenários adequados para EAGER:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Relações pequenas que são sempre utilizadas&lt;/li&gt;
&lt;li&gt;Casos onde a &lt;code&gt;LazyInitializationException&lt;/code&gt; seria problemática&lt;/li&gt;
&lt;li&gt;Entidades com poucos relacionamentos&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  FetchType.LAZY: Carregamento Sob Demanda
&lt;/h3&gt;

&lt;p&gt;O carregamento lazy utiliza proxies que são resolvidos apenas quando os dados são efetivamente acessados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@OneToMany&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetchType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LAZY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Pedido&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pedidos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cenários adequados para LAZY:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Relações grandes ou que não são sempre utilizadas&lt;/li&gt;
&lt;li&gt;Sistemas com foco em performance&lt;/li&gt;
&lt;li&gt;APIs REST que utilizam DTOs para controle de dados expostos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tomada de Decisão
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Escolhendo a Direção do Relacionamento
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cenário&lt;/th&gt;
&lt;th&gt;Recomendação&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Navegação frequente em ambas as direções&lt;/td&gt;
&lt;td&gt;Bidirecional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domínios fortemente conectados (Aluno ↔ Curso)&lt;/td&gt;
&lt;td&gt;Bidirecional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APIs com consumo unidirecional&lt;/td&gt;
&lt;td&gt;Unidirecional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foco em performance e simplicidade&lt;/td&gt;
&lt;td&gt;Unidirecional&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Definindo a Estratégia de Fetch
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situação&lt;/th&gt;
&lt;th&gt;Estratégia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Entidades com muitas relações&lt;/td&gt;
&lt;td&gt;LAZY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relações sempre utilizadas&lt;/td&gt;
&lt;td&gt;EAGER (com cuidado)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APIs REST com DTOs&lt;/td&gt;
&lt;td&gt;LAZY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operações em batch&lt;/td&gt;
&lt;td&gt;LAZY com JOIN FETCH controlado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Abordagem Recomendada: Evolução Gradual
&lt;/h2&gt;

&lt;p&gt;A melhor prática é começar com relacionamentos unidirecionais e fetch LAZY, evoluindo conforme necessário:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Inicie simples&lt;/strong&gt;: Implemente relacionamentos unidirecionais com LAZY loading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitore o uso&lt;/strong&gt;: Identifique padrões de acesso aos dados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evolua quando necessário&lt;/strong&gt;: Adicione navegação bidirecional apenas quando houver justificativa concreta&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Otimize seletivamente&lt;/strong&gt;: Use EAGER apenas para relações comprovadamente críticas&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A modelagem de relacionamentos no Spring JPA é uma arte que equilibra flexibilidade, performance e manutenibilidade. Relacionamentos unidirecionais com carregamento lazy oferecem um ponto de partida sólido, permitindo evolução baseada em necessidades reais do sistema.&lt;/p&gt;

&lt;p&gt;A chave está em evitar &lt;em&gt;over-engineering&lt;/em&gt; inicialmente, para sim construir uma base sólida que possa crescer organicamente com os requisitos do projeto. Monitore a performance, documente as decisões arquiteturais e mantenha a flexibilidade para ajustes futuros.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>sql</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>O que é JWT?</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Mon, 09 Jun 2025 11:00:00 +0000</pubDate>
      <link>https://forem.com/alexreis/o-que-e-jwt-2o65</link>
      <guid>https://forem.com/alexreis/o-que-e-jwt-2o65</guid>
      <description>&lt;h2&gt;
  
  
  JWT
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JSON Web Token (JWT)&lt;/strong&gt; é um padrão (&lt;a href="https://datatracker.ietf.org/doc/html/rfc7519" rel="noopener noreferrer"&gt;RFC 7519&lt;/a&gt;) para transmitir informações de forma segura entre partes como um objeto JSON. Ele é compacto e autoassinado. As informações contidas nele são assinadas digitalmente, garantindo que os dados não sejam alterados durante a transmissão. A estrutura de um JSON Web Token normalmente é &lt;strong&gt;Header.Payload.Signature&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Header (Cabeçalho)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Contém os metadados do token.&lt;/li&gt;
&lt;li&gt;Tipicamente, consiste em duas partes: o tipo do token, que é sempre &lt;code&gt;"JWT"&lt;/code&gt;, e o algoritmo de assinatura que está sendo usado (HS256, RS256 ou ECDSA).&lt;/li&gt;
&lt;li&gt;É codificado em &lt;strong&gt;Base64Url&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Payload (Carga)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Contém as claims, que são declarações sobre a entidade (geralmente o usuário) e dados adicionais.&lt;/li&gt;
&lt;li&gt;As informações no payload, embora protegidas contra adulteração, são legíveis por qualquer pessoa que possua o token decodificado.&lt;/li&gt;
&lt;li&gt;O payload é codificado em &lt;strong&gt;Base64Url&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Signature (Assinatura)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Garante integridade e autenticidade do token.&lt;/li&gt;
&lt;li&gt;É gerada utilizando o cabeçalho (já codificado), o payload codificado, uma chave secreta (para algoritmos simétricos como HMAC) ou um par de chaves pública/privada (para algoritmos assimétricos como RSA ou ECDSA) e o algoritmo especificado no cabeçalho.&lt;/li&gt;
&lt;li&gt;O processo envolve aplicar o algoritmo escolhido à concatenação de cabeçalho e payload codificados, usando a chave.&lt;/li&gt;
&lt;li&gt;Também é codificada em &lt;strong&gt;Base64Url&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A concatenação dessas três partes codificadas em Base64Url, separadas por pontos, forma o JSON Web Token.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fluxo de funcionamento do JWT
&lt;/h2&gt;

&lt;p&gt;O fluxo de funcionamento do JWT geralmente ocorre da seguinte forma:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Login do Usuário&lt;/strong&gt;: O cliente envia as credenciais de login do usuário (geralmente via navegador) para o servidor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geração do JWT pelo servidor&lt;/strong&gt;: Se as credenciais são válidas, o servidor faz a verificação das credenciais. Então, o servidor cria um JWT contendo dados sobre o usuário (conhecidos como "claims" no payload) e assina usando uma chave secreta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Envio do token para o cliente&lt;/strong&gt;: O JWT é enviado de volta para o cliente e armazenado geralmente em localStorage ou em um cookie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cliente inclui o token em requisições subsequentes&lt;/strong&gt;: Sempre que o cliente deseja acessar rotas protegidas ou recursos restritos, ele inclui o JWT no cabeçalho HTTP da requisição, mais comumente no cabeçalho &lt;code&gt;Authorization&lt;/code&gt; usando o esquema &lt;code&gt;Bearer token&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificação do Token pelo Servidor&lt;/strong&gt;: Ao receber uma requisição com um JWT no cabeçalho &lt;code&gt;Authorization&lt;/code&gt;, o servidor (ou as rotas protegidas) verifica a validade do token JWT. A verificação inclui validar a estrutura,o formato, e conteúdo do token (validação) e confirma a autenticidade e integridade do token através da verificação da assinatura (verificação).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Boas práticas com JWT
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use HTTPS&lt;/strong&gt;: Transmita JWTs apenas por conexões seguras para prevenir ataques &lt;em&gt;man-in-the-middle&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defina tempo de expiração&lt;/strong&gt;: Evite tokens de longa duração que possam ser explorados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use armazenamento seguro&lt;/strong&gt;: Armazene JWTs de forma segura (por exemplo, cookies HttpOnly em vez de localStorage).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jwt.io/introduction" rel="noopener noreferrer"&gt;Introduction to JSON Web Token&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/json-web-token-jwt/" rel="noopener noreferrer"&gt;JSON Web Token&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.javaguides.net/2021/03/what-is-jwt-json-web-token-and-how-it.html" rel="noopener noreferrer"&gt;What is JWT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
      <category>webdev</category>
      <category>api</category>
      <category>learning</category>
    </item>
    <item>
      <title>Como funciona o DNS?</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Wed, 04 Jun 2025 11:00:00 +0000</pubDate>
      <link>https://forem.com/alexreis/como-funciona-o-dns-203o</link>
      <guid>https://forem.com/alexreis/como-funciona-o-dns-203o</guid>
      <description>&lt;h2&gt;
  
  
  O que é DNS
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Domain Name System (DNS)&lt;/strong&gt; é a lista telefônica da Internet. O DNS converte os nomes de domínio (legíveis por humanos, como &lt;code&gt;www.google.com&lt;/code&gt;) em endereços IP (que os computadores usam para se comunicar).&lt;/p&gt;

&lt;p&gt;Cada dispositivo conectado à Internet tem um IP único que as outras máquinas usam para localizar o dispositivo. Os servidores DNS eliminam a necessidade de humanos terem de memorizar endereços IP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Servidores de DNS envolvidos no carregamento de uma página da Internet
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recursor de DNS&lt;/strong&gt;: O recursor é responsável por fazer solicitações adicionais para atender à consulta de DNS do cliente. Pode ser imaginado como uma bibliotecária que foi solicitada a procurar um livro específico.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Servidor raiz&lt;/strong&gt;: Primeira etapa da tradução (resolução) do host. Pode ser imaginado como um índice em uma biblioteca que aponta para as estantes de livros.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nameserver TLD&lt;/strong&gt;: Pense no servidor de domínio de nível superior (TLD) como uma estante de livros específica em uma biblioteca. É o próximo passo se não busca de um endereço IP específico e hospeda a última parte de um hostname.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nameserver autoritativo&lt;/strong&gt;: Pode ser imaginado como um dicionário em uma estante de livros, no qual um nome específico pode ser traduzido em sua definição. Se tiver acesso ao registro solicitado, o nameserver autoritativo retorna o endereço IP do hostname solicitado de volta ao recursor de DNS que fez a solicitação inicial.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Etapas de uma pesquisa de DNS
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Quando o usuário digita uma URL no navegador, o sistema verifica se o IP do domínio já está salvo em cache (no navegador, no sistema operacional ou no roteador). Se já estiver em cache, ele usa o IP diretamente e o processo termina aqui. Senão a consulta parte para a próxima etapa.&lt;/li&gt;
&lt;li&gt;A consulta é recebida por um &lt;strong&gt;resolvedor de DNS recursivo&lt;/strong&gt;, que pode ter o IP em cache e então responde direto. Caso contrário, consulta o &lt;strong&gt;servidor raiz&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;O &lt;strong&gt;servidor raiz&lt;/strong&gt; responde ao resolvedor com o endereço de um servidor de &lt;strong&gt;TLD&lt;/strong&gt;, como &lt;code&gt;.com&lt;/code&gt;, &lt;code&gt;.org&lt;/code&gt;, &lt;code&gt;.br&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;O resolvedor faz uma solicitação ao TLD.&lt;/li&gt;
&lt;li&gt;O &lt;strong&gt;servidor de TLD&lt;/strong&gt; responde com o endereço IP do &lt;strong&gt;servidor autoritativo&lt;/strong&gt;, o &lt;strong&gt;nameserver do domínio&lt;/strong&gt; (como &lt;code&gt;google.com&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;O resolvedor recursivo envia uma consulta ao &lt;strong&gt;nameserver do domínio&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;O &lt;strong&gt;endereço IP&lt;/strong&gt; é então retornado ao resolvedor partindo do nameserver.&lt;/li&gt;
&lt;li&gt;O &lt;strong&gt;resolvedor de DNS&lt;/strong&gt; responde ao navegador com o endereço IP do site.&lt;/li&gt;
&lt;li&gt;A conexão com o site é realizada via &lt;strong&gt;HTTP&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Referência
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cloudflare.com/pt-br/learning/dns/what-is-dns/" rel="noopener noreferrer"&gt;What is dns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>braziliandevs</category>
      <category>network</category>
    </item>
    <item>
      <title>Como o protocolo HTTP funciona?</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Wed, 21 May 2025 11:00:00 +0000</pubDate>
      <link>https://forem.com/alexreis/como-o-protocolo-http-funciona-55oc</link>
      <guid>https://forem.com/alexreis/como-o-protocolo-http-funciona-55oc</guid>
      <description>&lt;p&gt;Sempre que você acessa um site pode notar que a URL exibida no navegador é algo como &lt;code&gt;https://dev.to&lt;/code&gt;, você sabe que &lt;code&gt;dev.to&lt;/code&gt; é o endereço do site, a localização dele na web. Mas o que são as letrinhas &lt;em&gt;HTTPS&lt;/em&gt; ou &lt;em&gt;HTTP&lt;/em&gt; antes do endereço? Neste artigo vamos entender o que é o HTTP, para quê serve e como funciona.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é HTTP
&lt;/h2&gt;

&lt;p&gt;O Hyper Transfer Text Protocol, ou HTPP, é um protocolo de transferência de documentos de hipermídia da &lt;a href="https://pt.wikipedia.org/wiki/Camada_de_aplica%C3%A7%C3%A3o" rel="noopener noreferrer"&gt;camada de aplicação&lt;/a&gt;. Ele foi projeto para comunicação entre clientes e servidores, mas também pode ser usado para outros fins, como comunicação máquina a máquina, acesso programático a APIs e muito mais. Ele é enviado por TCP ou por conexção TCP criptografada por TLS ou SSL, o HTTPS utiliza esta camada adicional de segurança. &lt;a href="https://pt.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Hist%C3%B3ria" rel="noopener noreferrer"&gt;Confira mais detalhes da história do HTTP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aspectos do HTTP
&lt;/h2&gt;

&lt;p&gt;O HTTP segue o modelo cliente-servidor, no qual clientes (na maioria das vezes um navegador web) e servidores se comunicam por meio de mensagens individuais. As mensagens enviadas pelo cliente, as solicitações ou requisições, são chamadas de &lt;em&gt;requests&lt;/em&gt; e as mensagens enviadas como resposta pelo servidor são chamadas &lt;em&gt;responses&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O HTTP é &lt;em&gt;stateless&lt;/em&gt;, isso significa que ele não guarda qualquer dado entre requisições, cada requisição do cliente é tratada de forma independente. Porém ele não é &lt;em&gt;sesionless&lt;/em&gt;, a adição de cookies HTTP permitem que os aplicações web armazenem quantidades limitadas de dados e lembrem informações de estado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como funciona o HTTP
&lt;/h2&gt;

&lt;p&gt;O cliente, um navegador web geralmente, faz uma requisição a um servidor para obter um recurso como uma página HTML, imagens ou arquivos. Neste momento é aberta uma conexão ente os dois. Na requisição HTTP é explicitado o método pretendido e o caminho do recurso desejado. &lt;/p&gt;

&lt;p&gt;O servidor recebe essa solicitação, busca o recurso e ao encontrar responde ao navegador uma mensagem contendo o recurso e informações adicionais no cabeçalho da mensagem HTTP.&lt;/p&gt;

&lt;p&gt;O cliente recebe a resposta do servior, e encerra a conexão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mensagens HTTP
&lt;/h2&gt;

&lt;p&gt;As mensagens HTTP, conforme definido em HTTP/1.1 e anteriores, são legíveis por humanos. No HTTP/2, essas mensagens são incorporadas em uma estrutura binária, um quadro, permitindo otimizações como compactação de cabeçalhos e multiplexação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requisições
&lt;/h3&gt;

&lt;p&gt;Exemplo de requisição HTTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET / HTTP/1.1
Host: meusite.com
Accept-Language: en-US
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; é o método HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; é o caminho do recurso a ser buscado.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HTTP/1.1&lt;/code&gt; a versão do protocolo.&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Host&lt;/code&gt;e &lt;code&gt;Accept-Language&lt;/code&gt; são parte do cabeçalho HTTP e fornecem informações adicionais sobre navegador e preferências de conteúdo.&lt;/li&gt;
&lt;li&gt;Ainda pode conter um corpo para alguns métodos como o &lt;code&gt;POST&lt;/code&gt;, que contém o recurso enviado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Respostas
&lt;/h3&gt;

&lt;p&gt;Exemplo de resposta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 200 OK
Date: Wed, 09 MAY 2025 01:58:00 GMT
Content-Length: 1999
Content-Type: text/html; charset=UTF-8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HTTP/1.1&lt;/code&gt; a versão do protocolo HTTP que eles seguem.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;200&lt;/code&gt; um código de status, indicando que a solicitação foi bem-sucedida.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OK&lt;/code&gt; uma mensagem de status, uma breve descrição não autorizada do código de status.&lt;/li&gt;
&lt;li&gt;Cabeçalhos HTTP, como aqueles para solicitações.&lt;/li&gt;
&lt;li&gt;Opcionalmente, um corpo que contém o recurso buscado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Métodos HTTP
&lt;/h2&gt;

&lt;p&gt;O HTTP define um conjunto de certos métodos de solicitação para enviar mensagens indicando a finalidade da solicitação e o que é esperado em caso de sucesso.&lt;/p&gt;

&lt;h3&gt;
  
  
  GET
&lt;/h3&gt;

&lt;p&gt;Este método tem finalidade de solicitar um recurso especifico. É usado para recuperar dados e não deve conter conteúdo no corpo da solicitação.&lt;/p&gt;

&lt;h3&gt;
  
  
  POST
&lt;/h3&gt;

&lt;p&gt;Este método indica que a solicitação faz a publicação de um recurso no servidor.&lt;/p&gt;

&lt;h3&gt;
  
  
  PUT
&lt;/h3&gt;

&lt;p&gt;Substitui todas as entidades do recurso alvo pelo conteúdo do corpo da solicitação.&lt;/p&gt;

&lt;h3&gt;
  
  
  PATCH
&lt;/h3&gt;

&lt;p&gt;Faz modificações parciais em um recurso, que ao contrário do &lt;code&gt;PUT&lt;/code&gt; substituí um recurso por inteiro.&lt;/p&gt;

&lt;h3&gt;
  
  
  DELETE
&lt;/h3&gt;

&lt;p&gt;Este método excluí o recurso.&lt;/p&gt;

&lt;h3&gt;
  
  
  CONNECT
&lt;/h3&gt;

&lt;p&gt;Estabele um túnel para o servidor identificado pelo recurso alvo.&lt;/p&gt;

&lt;h3&gt;
  
  
  OPTIONS
&lt;/h3&gt;

&lt;p&gt;Descreve opções de comunição para o recurso alvo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;E então chegamos ao fim deste texto, espero que eu tenha conseguido explicar minimamente o que é o HTTP e que tenha ajudado a você leitor. Abraços.&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.alura.com.br/artigos/http" rel="noopener noreferrer"&gt;https://www.alura.com.br/artigos/http&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>network</category>
      <category>computerscience</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Hi brazilian people, I wrote this shell script begginers tutorial and I hope you like it.</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Mon, 03 Mar 2025 13:56:19 +0000</pubDate>
      <link>https://forem.com/alexreis/hi-brazilian-people-i-wrote-this-shell-script-begginers-tutorial-and-i-hope-you-like-it-5624</link>
      <guid>https://forem.com/alexreis/hi-brazilian-people-i-wrote-this-shell-script-begginers-tutorial-and-i-hope-you-like-it-5624</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/alexreis" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1217593%2F6a99750b-e369-4209-99b7-f712ce3ae07a.jpeg" alt="alexreis"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/alexreis/introducao-ao-shell-script-3me3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Introdução ao Shell Script&lt;/h2&gt;
      &lt;h3&gt;Alex Reis ・ Mar 3 '25&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#linux&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#braziliandevs&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>programming</category>
      <category>devops</category>
      <category>linux</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Introdução ao Shell Script</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Mon, 03 Mar 2025 11:00:00 +0000</pubDate>
      <link>https://forem.com/alexreis/introducao-ao-shell-script-3me3</link>
      <guid>https://forem.com/alexreis/introducao-ao-shell-script-3me3</guid>
      <description>&lt;p&gt;Shell Script é uma linguagem de script usada para automatizar tarefas no terminal do Linux/Unix.&lt;/p&gt;

&lt;p&gt;Um &lt;strong&gt;Shell Script&lt;/strong&gt; é um arquivo contendo comandos do terminal que podem ser executados como um programa. Ele usa interpretadores como &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;sh&lt;/code&gt; ou &lt;code&gt;zsh&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um shell script
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Crie um arquivo arquivo &lt;code&gt;.sh&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;meu_script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Abra o arquivo no editor.&lt;/li&gt;
&lt;li&gt;Adicione o código:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Olá mundo!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shell scripts começam com um &lt;code&gt;shebang&lt;/code&gt;, ele informa que o script deve ser interpretado pelo Bash. Você pode usar outra interpretador shell como &lt;code&gt;#!/bin/sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;echo&lt;/code&gt; é um comando usado para exibir uma mensagem no terminal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dê permissão de execução ao script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x meu_script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Execute o script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./meu_script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Variáveis e Entrada do Usuário
&lt;/h2&gt;

&lt;p&gt;Podemos criar variáveis e interagir com o usuário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Alex"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Olá, &lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Qual é o seu nome?"&lt;/span&gt;
&lt;span class="nb"&gt;read &lt;/span&gt;usuario
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bem-vindo, &lt;/span&gt;&lt;span class="nv"&gt;$usuario&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variáveis são definidas com &lt;code&gt;=&lt;/code&gt; sem espaços ao redor do &lt;code&gt;=&lt;/code&gt;. Para usar uma variável colocamos &lt;code&gt;$&lt;/code&gt; antes de seu nome. Podemos fazer atribuições do tipo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;pais&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Brasil
&lt;span class="nv"&gt;novo_pais&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$pais&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando &lt;code&gt;read&lt;/code&gt; permite capturar uma entrada do usuário.&lt;/p&gt;

&lt;h2&gt;
  
  
  Condicionais
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Digite um número"&lt;/span&gt;
&lt;span class="nb"&gt;read &lt;/span&gt;numero

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$numero&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 10 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"O númeor é maior que 10."&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"O número é menor ou igual a 10."&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No shell script usamos &lt;code&gt;[]&lt;/code&gt; para testar condições. Operadores comuns são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-eq&lt;/code&gt; -&amp;gt; igual a (==)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-ne&lt;/code&gt; -&amp;gt; diferente de (!=)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-gt&lt;/code&gt; -&amp;gt; maior que (&amp;gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-lt&lt;/code&gt; -&amp;gt; menor que (&amp;lt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-ge&lt;/code&gt; -&amp;gt; maior ou igual (&amp;gt;=)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-le&lt;/code&gt; -&amp;gt; menor ou igual (&amp;lt;=)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; -&amp;gt; AND (operador lógico)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-o&lt;/code&gt; -&amp;gt; OR (operador lógico)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Laços de repetição
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For loop&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..5&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Número: &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;While loop&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;contador&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$contador&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; 5 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Contador: &lt;/span&gt;&lt;span class="nv"&gt;$contador&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="o"&gt;((&lt;/span&gt;contador++&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usamos &lt;code&gt;((expressão++))&lt;/code&gt; para incrementar valores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Funções
&lt;/h2&gt;

&lt;p&gt;Podemos criar funções:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
diz_ola&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Olá, &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

diz_ola &lt;span class="s2"&gt;"Alex"&lt;/span&gt;
diz_ola &lt;span class="s2"&gt;"Maria"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;$1&lt;/code&gt; é usado para indicar o primeiro argumento passado, e não está restrito ser usado em funções.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trabalhando com arquivos e diretórios
&lt;/h2&gt;

&lt;p&gt;Criar, ler e manipular arquivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Criando um arquivo..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Este é um arquivo de teste."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; teste.txt

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Conteúdo do arquivo:"&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;teste.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A expressão &lt;code&gt;echo "texto" &amp;gt; texto.txt&lt;/code&gt; escreve um text dentro de um arquivo.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cat&lt;/code&gt;é usado para exibir o conteúdo de um arquivo.&lt;/p&gt;

&lt;p&gt;Existem muitos outros comandos e coisas possiveís que se pode fazer com shell script mas esta é uma introdução básica.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>linux</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Estruturas de Dados: Heap</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Mon, 13 Jan 2025 11:00:00 +0000</pubDate>
      <link>https://forem.com/alexreis/estruturas-de-dados-heap-2k0h</link>
      <guid>https://forem.com/alexreis/estruturas-de-dados-heap-2k0h</guid>
      <description>&lt;p&gt;Heap é uma lista linear onde cada elemento armazena um dado e sua prioridade de modo que: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;H[i] &amp;gt; H[2i], (ou H[i] &amp;lt; H[i/2])&lt;/li&gt;
&lt;li&gt;H[i] &amp;gt; H[2i+1], Para 1 &amp;lt;= i &amp;lt;= n.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo: [33, 32, 38, 31, 29, 26, 25, 30, 27]&lt;/p&gt;

&lt;p&gt;Essa estrutra pode ser representada visualmente na forma de uma árvore binaria, onde cada nó possui prioridade maior que seus dois filhos, se existirem. Na memória a estrutra está disposta como uma lista linear sequencial.&lt;/p&gt;

&lt;p&gt;As condições anteriormente descritas implicam que o elemento de maior prioridade sempre é o primeiro, ou seja, a raiz da árvore.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;seleção: O(1)&lt;/li&gt;
&lt;li&gt;inserção: O(log n) &lt;/li&gt;
&lt;li&gt;remoção: O(log n)&lt;/li&gt;
&lt;li&gt;alteração: O(log n)&lt;/li&gt;
&lt;li&gt;construção: O(n)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Alteração de prioridade
&lt;/h2&gt;

&lt;p&gt;De modo geral, uma operação que se deseja realizar no heap está associada a "subir" ou "descer" num caminho da árvore. Associa-se então o aumento de prioridade à "subida" e a diminuição à "descida". OS algoritmos correspondentes a estas operações são:&lt;/p&gt;

&lt;p&gt;Algoritmo subir() recursivo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    subir(i)
        j := i/2
        se j &amp;gt;= 1 então
            se H[j].chave &amp;lt; H[i].chave então
                torcar (H[j], H[i])
                subir(j)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Algoritmo subir() iterativo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    subir(i)
        j := i/2
        enquanto j &amp;gt;= 1 e H[j].chave &amp;lt; H[i].chave
            torcar H[j] &amp;lt;=&amp;gt; H[i]
            i := j
            j := i/2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Algoritmo descer() recursivo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    descer(i,n)
        j := 2*i
        se j &amp;lt;= n então
            se j &amp;lt; n então
                se H[j].chave &amp;lt; H[j+1].chave então
                    j := j+1
            se H[i].chave &amp;lt; H[j].chave então
                trocar (H[i], H[j])
                descer(j,n)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Algoritmo descer() iterativo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    descer(i,n)
        j := 2*i
        enquanto j &amp;lt;= n faça
            se j &amp;lt; n então
                se H[j].chave &amp;lt; H[j+1].chave então
                    j := j+1
            se H[i].chave &amp;lt; H[j].chave então
                trocar (H[i], H[j])
                i := j
                j := 2*i
            senão
                j := n+1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As complexidades dos algoritmos subir() e descer() &lt;strong&gt;recursivos&lt;/strong&gt; são as mesmas de percorrer o caminho de uma árvore binária completa: O(log n)&lt;/p&gt;

&lt;h2&gt;
  
  
  Inserção de elemento
&lt;/h2&gt;

&lt;p&gt;Suponha a inserção de um novo elemento, a lista agora passará a ter n+1 elementos. Obviamente o lista não respeita mais a propriedade de heap. O procedimento a seguir corrige esse problema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    inserir(x)
        H[n+1] := x
        n := n+1
        subir(n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complexidade igual ao algoritmo subir(): O(log n)&lt;/p&gt;

&lt;h2&gt;
  
  
  Remoção de elemento
&lt;/h2&gt;

&lt;p&gt;A remoção é feita sempre com o de maior prioridade, logo a sua posição fica vazia e a lista passa a ter n-1 elementos, o último elemento então deve preenche-la mas como sua prioridade está deslocada a lista deve ser corrigida.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    remover()
        se n != 0 então
            H[1] := H[n]
            n := n-1
            descer(1, n)
        senão "lista vazia"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A complexidade desse algoritmo depende do algoritmo descer(): O(log n)&lt;/p&gt;

&lt;h2&gt;
  
  
  Construção de um heap
&lt;/h2&gt;

&lt;p&gt;Observando que toda lista ordenada corresponde a um heap, podemos construir um através da ordenação de uma lista.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    construirHeap()
        para i := 2 até n faça
            subir(i)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complexidade O(n log n)&lt;/p&gt;

&lt;p&gt;Uma solução alternativa é descrita observando que para um nó sem filhos satisfaz as propriedades de heap, isto é, todo nó alocado a partir da posição n/2 + 1. Por essa razão, na construção de um heap os únicos nós relevantes são os internos da árvore. Estes devem ter suas prioridades verificadas e acertadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    construirHeapOtimizado()
        para i := n/2 até 1 faça
            descer(i,n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complexidade linear: O(n)&lt;/p&gt;

&lt;h2&gt;
  
  
  Referência
&lt;/h2&gt;

&lt;p&gt;Livro: Estruturas de Dados e seus Algoritmos&lt;/p&gt;

</description>
      <category>programming</category>
      <category>dsa</category>
      <category>braziliandevs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Estruturas de Dados: Árvores</title>
      <dc:creator>Alex Reis</dc:creator>
      <pubDate>Mon, 06 Jan 2025 17:05:50 +0000</pubDate>
      <link>https://forem.com/alexreis/arvores-2e50</link>
      <guid>https://forem.com/alexreis/arvores-2e50</guid>
      <description>&lt;p&gt;Uma árvore &lt;em&gt;T&lt;/em&gt; é um conjunto finito de elementos denominados &lt;em&gt;nós&lt;/em&gt; tais que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;T = {0}, a árvore é dita &lt;em&gt;vazia&lt;/em&gt; ou&lt;/li&gt;
&lt;li&gt;existe um nó especial chamado &lt;em&gt;raiz&lt;/em&gt; de &lt;em&gt;T(r(T))&lt;/em&gt;; os nós restantes constituem um conjunto vazio ou são dividios em m &amp;gt;= 1 conjuntos disjuntos não vazios, as subárvores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um conjunto de árvores forma uma floresta. Se &lt;em&gt;v&lt;/em&gt; é um nó de &lt;em&gt;T&lt;/em&gt;, a notação &lt;em&gt;T(v)&lt;/em&gt; indica uma subárvore de &lt;em&gt;T&lt;/em&gt; com raiz &lt;em&gt;v&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Os nós raízes &lt;em&gt;w1, w2, ..., wj&lt;/em&gt; das subárvores de &lt;em&gt;T(v)&lt;/em&gt; são chamados filhos de &lt;em&gt;v&lt;/em&gt;. Se &lt;em&gt;z&lt;/em&gt; é filho de &lt;em&gt;w1&lt;/em&gt; então &lt;em&gt;w2&lt;/em&gt; é tio de &lt;em&gt;z&lt;/em&gt; e &lt;em&gt;v&lt;/em&gt; é avô de &lt;em&gt;z&lt;/em&gt;. O número de filhos de um nó é chamado de grau de saída desse nó. Se &lt;em&gt;x&lt;/em&gt; pertence à subárvore &lt;em&gt;T(v)&lt;/em&gt;, &lt;em&gt;x&lt;/em&gt; é descendente de &lt;em&gt;v&lt;/em&gt;, e &lt;em&gt;v&lt;/em&gt;, ancestral de &lt;em&gt;x&lt;/em&gt;. Um nó que não possuí descendentes próprios é chamado de folha. Toda árvore com n &amp;gt; 1 nós possuí no mínimo 1 e no máximo n - 1 folhas. Um nó não folha é dito interior.&lt;/p&gt;

&lt;p&gt;Uma sequência de nós distintos &lt;em&gt;v1, v2, ..., vk&lt;/em&gt;, tal que existe sempre entre nós consecutivos a relação "é filho de" ou "é pai de", é denominada &lt;em&gt;caminho&lt;/em&gt; da árvore. O &lt;em&gt;comprimento k do caminho&lt;/em&gt; é a quantidade de pares da relação ao longo do caminho. &lt;em&gt;Nível&lt;/em&gt; de um nó &lt;em&gt;v&lt;/em&gt; é o número de nós do caminho da raiz até o nó &lt;em&gt;v&lt;/em&gt;. O nível da raiz portanto é 1. A &lt;em&gt;altura&lt;/em&gt; de um nó &lt;em&gt;v&lt;/em&gt; é o número de nós do maior caminho &lt;em&gt;v&lt;/em&gt; até um dos seus descentes. A altura da árvore &lt;em&gt;T&lt;/em&gt; é igual ao nível máximo de seus nós. Representa-se a altura de &lt;em&gt;T&lt;/em&gt; por &lt;em&gt;T(h)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Uma árvore ordenada é aquela na qual os filhos de cada nó estão ordenados. Assume-se que tal ordenação se desenvolva da esquerda para a direita. &lt;/p&gt;

&lt;h2&gt;
  
  
  Árvores Binárias
&lt;/h2&gt;

&lt;p&gt;Dentre as ávores, as binárias, são as mais comuns.&lt;br&gt;
Uma &lt;em&gt;árvore binária&lt;/em&gt; &lt;em&gt;T&lt;/em&gt; é um conjunto finito de elementos denominados &lt;em&gt;nós&lt;/em&gt; tais que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;T = {0}, a árvore é dita &lt;em&gt;vazia&lt;/em&gt; ou&lt;/li&gt;
&lt;li&gt;existe um nó especial chamado &lt;em&gt;raiz&lt;/em&gt; de &lt;em&gt;T(r(T))&lt;/em&gt;; os nós restantes são dividios em dois subconjuntos disjuntos, &lt;em&gt;Te(r(T))&lt;/em&gt; e &lt;em&gt;Td(r(T))&lt;/em&gt; a &lt;em&gt;subárvore esquerda&lt;/em&gt; e a &lt;em&gt;direita&lt;/em&gt; da raiz, respectivamente, as quais também são binárias.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A raiz da subárvore esquerda (direita) de um nó v, se existir, é denominada filho esquerdo (direito) de v. Naturalmente, o esquerdo pode existir sem o direito e vice-versa.&lt;/p&gt;

&lt;p&gt;O número de subárvores esquerdas e direitas vazias em uma árvore binária com n &amp;gt; 0 nós é n + 1.&lt;/p&gt;

&lt;p&gt;Uma &lt;em&gt;árvore estritamente binária&lt;/em&gt; é uma árvore binária em que cada nó possui 0 ou 2 filhos. Uma &lt;em&gt;árvore binária completa&lt;/em&gt; é aquela que apresenta a seguinte propriedade: se &lt;em&gt;v&lt;/em&gt; é um nó tal que alguma subárvore de &lt;em&gt;v&lt;/em&gt; é vazia, então &lt;em&gt;v&lt;/em&gt; se localiza ou no último (maior) ou no penúltimo nível da árvore. Uma &lt;em&gt;árvore binária cheia&lt;/em&gt; é aquela em que, se &lt;em&gt;v&lt;/em&gt; é um nó com alguma de suas subárvores vazias, então &lt;em&gt;v&lt;/em&gt; se localiza no último nível.&lt;/p&gt;

&lt;p&gt;A árvore binária que possui altura máxima é aquela cujos nós interiores possuem exatamente uma subárvore vazia. Essas árvores são denominadas &lt;em&gt;zigue-zague&lt;/em&gt;. Naturalmente, a altura de uma árvore zigue-zague é igual a n. Por outro lado, uma árvore completa sempre apresenta altura mínima.&lt;/p&gt;

&lt;p&gt;Seja &lt;em&gt;T&lt;/em&gt; uma árvore binária completa com n &amp;gt; 0 nós. Então &lt;em&gt;T&lt;/em&gt; possui &lt;em&gt;altura h mínima&lt;/em&gt;. Além disso, h = 1 + log n.&lt;/p&gt;

&lt;p&gt;Uma &lt;em&gt;árvore m-ária&lt;/em&gt; T, m ≥ 2, é um conjunto finito de elementos, denominados nós ou vértices, tais que&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;T = Ø e a árvore é dita &lt;em&gt;vazia&lt;/em&gt;, ou&lt;/li&gt;
&lt;li&gt;contém um nó especial chamado &lt;em&gt;raiz&lt;/em&gt; de &lt;em&gt;T(r(T))&lt;/em&gt;, e os restantes podem ser sempre divididos em m subconjuntos disjuntos, as i-ésimas subárvores de r(T), 1 ≤ i ≤ m, as quais são também árvores m-árias.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A raiz da i-ésima subárvore de um nó &lt;em&gt;v&lt;/em&gt; de T, se existir, é denominada i-ésimo filho de &lt;em&gt;v&lt;/em&gt;. Naturalmente, a árvore m-ária é uma generalização da árvore binária em que cada nó possui &lt;em&gt;m&lt;/em&gt; subárvores. A árvore m-ária possui uma ordenação implícita nas subárvores de cada nó, mesmo que algumas ou todas essas subárvores sejam vazias.&lt;/p&gt;

&lt;p&gt;Analogamente ao caso binário, podem-se definir &lt;em&gt;árvore estritamente m-ária, árvore m-ária completa e cheia&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O armazenamento de árvores pode utilizar alocação sequencial ou encadeada. Sendo a árvore uma estrutura mais complexa do que listas lineares, as vantagens na utilização da alocação encadeada prevalecem.&lt;/p&gt;

&lt;p&gt;Em árvores binárias cada nó deve possuir dois campos de ponteiros, &lt;em&gt;esq&lt;/em&gt; e &lt;em&gt;dir&lt;/em&gt;, que apontam para as suas subárvores esquerda e direita respectivamente. O ponteiro &lt;em&gt;ptraiz&lt;/em&gt; indica a raiz da árvore. Necessita-se, então, de 2*n* + 1 (os dois campos mencionados e o campo com as informações do nó) unidades de memória para representar uma árvore binária com &lt;em&gt;n&lt;/em&gt; nós.&lt;/p&gt;
&lt;h3&gt;
  
  
  Percurso em Árvores Binárias
&lt;/h3&gt;

&lt;p&gt;Para percorrer uma árvore deve-se visitar cada um de seus nós. Visitar um nó significa operar de alguma forma, com a informação a ele relativa. &lt;/p&gt;

&lt;p&gt;O &lt;em&gt;percurso em pré-ordem&lt;/em&gt; segue recursivamente os seguintes passos, para cada subárvore da árvore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visitar a raiz&lt;/li&gt;
&lt;li&gt;percorrer sua subárvore esquerda, em pré ordem;&lt;/li&gt;
&lt;li&gt;percorrer sua subárvore direita, em pré ordem;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A variavel &lt;em&gt;pt&lt;/em&gt;, parametro do procedimento, é um ponteiro que indica a raiz da subárvore que está sendo considerada na chamada atual. Em cada chamada, somente esse nó é analisado. Após a visita, é verificada a existência de uma subárvore esquerda. Se verdadeiro, então a chamada recursiva percorrerá toda essa subárvore antes de ir para a subárvore direita.&lt;/p&gt;

&lt;p&gt;A versão não recursiva deve manter atualizados os caminhos percorridos a partir da raiz da árvore. Um forma de fazer isso é utilizando uma pilha. O nó é visitado ao ser colocado na pilha, enquanto que a retirada da pilha indica o final da visita cuja raiz é o nó considerado. Além disso, deve ser armazenada a direção do percurso, isto é, se o caminho tomado é é referente à subárvore esquerda ou direita. O nó só é retirado da pilha após ambos os caminhos percorridos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;procedimento&lt;/span&gt; &lt;span class="nf"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt;
        &lt;span class="nf"&gt;visita&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;procedimento&lt;/span&gt; &lt;span class="nf"&gt;preNaoRecursivo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raiz&lt;/span&gt;
    &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arvore vazia&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;Pilha&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nf"&gt;empilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;enquanto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;desempilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;visita&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt; &lt;span class="nf"&gt;empilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt; &lt;span class="nf"&gt;empilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;em&gt;percurso em ordem simetrica&lt;/em&gt; segues os passos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;percorrer sua subárvore esquerda, em ordem simétrica;&lt;/li&gt;
&lt;li&gt;visitar a raiz&lt;/li&gt;
&lt;li&gt;percorrer sua subárvore direita, em ordem simétrica;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;procedimento&lt;/span&gt; &lt;span class="nf"&gt;simet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt;
        &lt;span class="nf"&gt;simet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;visita&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;simet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;procedimento&lt;/span&gt; &lt;span class="nf"&gt;simetNaoRecursivo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;
    &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arvore vaiza&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;Pilha&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nf"&gt;empilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;enquanto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt; &lt;span class="nf"&gt;empilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt; &lt;span class="nf"&gt;empilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;enquanto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;desempilhar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;visitar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma terceira alternativa de percurso, o &lt;em&gt;percurso pós-ordem&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;percorrer a subárvore esquerda, em pós-ordem &lt;/li&gt;
&lt;li&gt;percorrer a subárvore direita, em pós-ordem&lt;/li&gt;
&lt;li&gt;visitar a raiz
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;procedimento&lt;/span&gt; &lt;span class="nf"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;se&lt;/span&gt; &lt;span class="n"&gt;pt&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="n"&gt;então&lt;/span&gt;
        &lt;span class="nf"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;visitar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Referência
&lt;/h2&gt;

&lt;p&gt;Livro: &lt;a href="https://www.amazon.com.br/Estruturas-Dados-Algoritmos-Jayme-Szwarcfiter/dp/852161750X" rel="noopener noreferrer"&gt;Estruturas de Dados e seus Algoritmos&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>dsa</category>
      <category>beginners</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
