<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fernanda Kipper</title>
    <description>The latest articles on DEV Community by Fernanda Kipper (@fernandakipper).</description>
    <link>https://dev.to/fernandakipper</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%2F699968%2F1572adab-7d1a-4fdc-9d53-ee33339fad0b.png</url>
      <title>DEV Community: Fernanda Kipper</title>
      <link>https://dev.to/fernandakipper</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fernandakipper"/>
    <language>en</language>
    <item>
      <title>Funções Serverless na AWS: Simplificando o nosso Processo de Desenvolvimento</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Thu, 18 Jan 2024 12:09:10 +0000</pubDate>
      <link>https://dev.to/nodebr/funcoes-serverless-na-aws-simplificando-o-nosso-processo-de-desenvolvimento-3l5i</link>
      <guid>https://dev.to/nodebr/funcoes-serverless-na-aws-simplificando-o-nosso-processo-de-desenvolvimento-3l5i</guid>
      <description>&lt;p&gt;Neste post nós vamos explorar como as funções serverless da AWS, as Lambda Functions, podem simplificar, e muito, o nosso processo de desenvolvimento. Ao longo do post nós vamos conseguir entender como elas permitem que a gente se concentre no desenvolvimento da regra de negócio da nossa aplicação, sem se preocupar com a infraestrutura, servidor, memória ram...&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução à Arquitetura Serverless
&lt;/h2&gt;

&lt;p&gt;Antes de tudo, quebrando a primeira ideia que você possa ter: não, arquitetura serverless não é uma arquitetura sem servidor. Diferente do que o nome nos faz imaginar, a arquitetura serverless tem sim um servidor. O que acontece é que ele não fica 100% do tempo pronto esperando uma requisição, na verdade, o servidor vai ao ar apenas quando essa requisição chega! E melhor, depois de executado o que for necessário, o servidor ja é desligado novamente automaticamente. Esse tempo de provisionar e começar a executar a maquina é chamado de &lt;em&gt;Cold Start&lt;/em&gt; e pode ser um problema dependendo da nossa aplicação. Mas como veremos até o final desse post, existem maneiras de diminuir ele e manter bem alta a performance da nossa função. Além disso que eu comentei, como não precisamos hospedar um servidor, também não precisamos nos preocupar a infraestrutura dele. Quanto de RAM meu servidor precisa? Qual CPU devo utilizar? Um SSD de 1 TB basta? Essas são perguntas que não fazemos, pois quem cuida disso é a provedora desse serviço, no nosso caso, a AWS (Amazon Web Services). Essa arquitetura permite que a gente se concentre &lt;strong&gt;exclusivamente&lt;/strong&gt; na regra de negócio da nossa aplicação, sem precisar gerenciar toda uma infraestrutura e sem se preocupar com código boilerplate para iniciar um servidor web (usando express.js por exemplo). &lt;/p&gt;

&lt;p&gt;Claro, esse conceito se aplica não apenas às funções Lambda da AWS, mas também aos serviços serverless oferecidos por outras provedoras, como Google e Azure (da Microsoft). Sendo assim, as funções serverless acabam sendo ideais para tarefas esporádicas ou infrequentes, ou tarefas independentes que não precisam existir dentro de um servidor nosso, pois acabam ajudando a economizar custos e fazer a gente focar no valor que queremos entregar ao usuário, ao invés de gastar nosso tempo gerenciando servidores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nossa função serverless na AWS
&lt;/h2&gt;

&lt;p&gt;No tutorial de hoje nós vamos criar uma função serverless na AWS (Lambda Function) que ficará disponível via uma URL para toda a internet. Para isso, precisaremos criar uma conta na AWS (&lt;a href="https://aws.amazon.com/resources/create-account/" rel="noopener noreferrer"&gt;https://aws.amazon.com/resources/create-account/&lt;/a&gt;) e depois logar no nosso Console (&lt;a href="https://console.aws.amazon.com/" rel="noopener noreferrer"&gt;https://console.aws.amazon.com/&lt;/a&gt;). Então, na barra de pesquisa iremos buscar por “Lambda” e clicar na primeira opção, como na imagem:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7l2b0eq87e9nw83sue3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7l2b0eq87e9nw83sue3.png" alt="dashboard da AWS mostrando o serviço Lambda" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando a nossa função
&lt;/h2&gt;

&lt;p&gt;Agora, na aba “Functions”, vamos clicar no botão “Create Function” para… criar a nossa função.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fveywijn09k31b8h776y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fveywijn09k31b8h776y2.png" alt="Página do serviço Lambda na AWS" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso nos levará a uma outra pagina onde vamos definir algumas informações importantes. &lt;/p&gt;

&lt;p&gt;A primeira é o nome da nossa função. Vou colocar &lt;strong&gt;KipperNodeFunction&lt;/strong&gt; mas você pode colocar o que achar melhor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escolha da Linguagem e Ambiente de Execução
&lt;/h2&gt;

&lt;p&gt;Na segunda opção definimos o ambiente de execução em que a nossa função será executada. A seleção do ambiente já determina qual a linguagem que usaremos (claro, até porque não tem como rodar JS em um ambiente .NET, por exemplo). Essa é uma das propriedade que a AWS usa para saber o que ela deve provisionar quando a nossa função for executada e nosso servidor precisar ser criado. Para o Node.js, o ambiente de execução que utilizaremos, a AWS oferece as versões 20, 18, 16 e 14. Mas também podemos utilizar um contêiner personalizado, se quisermos. A escolha do ambiente de execução correto é crucial para a execução eficiente da nossa função.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6mqbt7sa3xn6bpc161e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6mqbt7sa3xn6bpc161e.png" alt="Modal mostrando as linguagens de programação disponíveis para uso nas Lambda Functions" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ponto de Entrada
&lt;/h2&gt;

&lt;p&gt;Para que a nossa função seja acessível pela internet, habilitar a URL é essencial. Isso nós podemos encontrar na seção de configurações avançadas. Ao habilitarmos essa opção, a nossa função será acionada quando a rota que nos será fornecida for acessada, servindo como o ponto inicial de execução. Quando uma função é acionada, ela recebe um objeto de evento e um objeto de contexto, fornecendo informações sobre o evento que chamou a função e todo o contexto envolvido. Eles acabam sendo dois parâmetros que são passados para a nossa função.&lt;/p&gt;

&lt;p&gt;Aqui vai uma dica: é MUITO importante evitar código recursivo na nossa função, pois ele pode levar a chamadas infinitas e tempos de execução altíssimos, o que pode levar a contas extratosféricas. Além disso, o código recursivo acumula recursos de memória a cada chamada recursiva, aumentando ainda mais o uso de recursos e os nossos custos.&lt;/p&gt;

&lt;p&gt;Na mesma seção também devemos habilitar o CORS para permitir que a nossa função seja executada a partir de qualquer origem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7rfsmu8ecenuhxtx4mo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7rfsmu8ecenuhxtx4mo.png" alt="Parte da página da AWS Lambda mostrando as configurações avançadas" width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com a função criada, caímos no dashboard da nossa função e já temos um URL disponível para acessar, mas que por enquanto não faz nada…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctxyhr1qprh4j1qbx3kj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctxyhr1qprh4j1qbx3kj.png" alt="Página da uma Lambda Function específica" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuração de Gatilhos e Ações
&lt;/h2&gt;

&lt;p&gt;O AWS Lambda pode ser configurado para acionar outros serviços da AWS ou serviços de terceiros. Além disso, também podemos fazer o inverso. Fazer com que outros serviços da AWS acionem a nossa função. Um uso interessante é na limpeza de Cache de CDN’s. Podemos configurar para que um outro serviço da AWS, chamado EventBridge Scheduler, execute a nossa Lambda uma vez ao dia e essa nossa Lambda estar configurada para invalidar o cache da nossa CDN. Assim, podemos ter uma limpeza de cache automatizada e sem provisionar um servidor pra isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nosso código
&lt;/h2&gt;

&lt;p&gt;Jogando a página um pouco mais para baixo, nós chegamos em uma seção onde conseguimos programar! É aqui que a mágica acontece, é essa função que é executada quando alguma requisição bate na URL que nós recebemos.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Criar um agente HTTP&lt;/p&gt;

&lt;p&gt;Por padrão, a cada requisição o Node.js cria uma nova conexão TCP. Para evitarmos que isso aconteça sempre, podemos criar um agente HTTP customizado e definir o parâmetro &lt;code&gt;keepAlive&lt;/code&gt; como true. (Para saber mais, clique &lt;a href="https://docs.aws.amazon.com//sdk-for-javascript/v2/developer-guide/node-reusing-connections.html" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frm3ilnpzpueg62blzf3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frm3ilnpzpueg62blzf3o.png" alt="Boa prática para escrever um código de uma Lambda function" width="800" height="844"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Separar a lógica da função do handler principal&lt;/p&gt;

&lt;p&gt;Outra dica muito importante é a separação da lógica da função e do handler da nossa função. Como podemos ver na imagem abaixo, ao separar as duas funções (poderíamos até separar em arquivos diferentes), temos o nosso código com uma uma função que pode ser testada de maneira unitária (testes unitários), o que faz aumentar a sua confiabilidade e nos garante o Separation of Concerns, um design pattern que diz que devemos separar a responsabilidade de cada função. Quase como o “S” de “SOLID” (link para algum outro post do NodeBR?).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyv5x92d6wo2wiqpzdv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyv5x92d6wo2wiqpzdv2.png" alt="Código de uma Lambda Function" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;NÃO USAR código recursivo!!!&lt;/p&gt;

&lt;p&gt;Vou ressaltar a importância disso porque basta um simples bug que a nossa conta vais às alturas! Então, tomem MUITO cuidado com isso!&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Vamos testar?
&lt;/h2&gt;

&lt;p&gt;Abrindo o Postman, uma aplicação que basicamente executa requisições, podemos fazer uma chamada GET para o URL que nos foi fornecido e veremos que ele está retornando o resultado como esperado!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbfmibo45axc5d497uoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbfmibo45axc5d497uoc.png" alt="Página do Postman mostrando o resultado de uma Lambda Function" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Permissões e Considerações de Segurança
&lt;/h2&gt;

&lt;p&gt;Por fim, vale ressaltar que, ao configurar funções serverless na AWS, é crucial garantir que elas tenham apenas as permissões necessárias e restrições de acesso. Tipicamente, as funções serverless têm permissões limitadas e não têm acesso a outros serviços da AWS, como por exemplo nossas instâncias do EC2 ou arquivos no S3, a menos que sejam explicitamente concedidas. &lt;/p&gt;

&lt;p&gt;Também é importante observar que a URL da função é pública e pode ser acessada sem autenticação nesse nosso caso, mas que também podemos configurá-la para que fique mais segura. Para isso, devemos habilitar a autenticação da nossa função, e dessa forma a AWS passará a controlar quem faz as chamadas da função, validando o token de autenticação enviado no header.&lt;/p&gt;

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

&lt;p&gt;Neste artigo, destacamos como a integração das Lambda Functions da AWS com Node.js transforma o desenvolvimento de software. Esta combinação nos permite focar na lógica de negócios, eliminando a complexidade do gerenciamento de infraestrutura. Com Node.js, aproveitamos sua eficiência e flexibilidade, enquanto a AWS oferece uma infraestrutura gerenciada e escalável. Isso resulta em um processo de desenvolvimento mais ágil, eficiente e menos oneroso.&lt;/p&gt;

&lt;p&gt;A sinergia entre Node.js e as funcionalidades serverless da AWS representa uma estratégia moderna de desenvolvimento. Essa abordagem não só agiliza a criação de software robusto e seguro, mas também atende às exigências de um mercado que demanda inovação rápida e soluções eficazes. Assim, desenvolvedores podem se dedicar inteiramente à entrega de valor, impulsionando o avanço tecnológico e a satisfação do usuário.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ONvfQElw1bo" rel="noopener noreferrer"&gt;Assista à live completa no YouTube!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linktr.ee/nodebr" rel="noopener noreferrer"&gt;Acompanhe a comunidade NodeBR&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.fernandakipper.com/links" rel="noopener noreferrer"&gt;Me acompanhe em todas redes!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>nodebr</category>
      <category>node</category>
      <category>aws</category>
    </item>
    <item>
      <title>Introdução ao SSH</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Tue, 24 Oct 2023 03:42:55 +0000</pubDate>
      <link>https://dev.to/fernandakipper/introducao-ao-ssh-12j5</link>
      <guid>https://dev.to/fernandakipper/introducao-ao-ssh-12j5</guid>
      <description>&lt;p&gt;O SSH desempenha um papel fundamental na segurança e na administração de sistemas e serviços online e por isso se tornou uma tecnologia necessária para os desenvolvedores.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos entender os conceitos básicos que envolvem o protoloco SSH, entendendo os principais comandos e sair daqui sabendo utilizá-lo no nosso dia-a-dia!&lt;/p&gt;

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

&lt;p&gt;SSH, ou Secure Shell, é um &lt;strong&gt;&lt;em&gt;protocolo de comunicação que permite a conexão segura entre dois computadores&lt;/em&gt;&lt;/strong&gt;, possibilitando a transferência de dados e a execução de comandos à distância. Em muitos aspectos, o SSH é semelhante ao HTTP, um protocolo amplamente utilizado na web. No entanto, &lt;strong&gt;a principal diferença que distingue o SSH é a segurança que oferece&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comunicação segura
&lt;/h2&gt;

&lt;p&gt;O grande diferencial do SSH é a encriptação dos dados transmitidos entre os dois computadores. Isso significa que qualquer informação enviada ou recebida através de uma conexão SSH é codificada, tornando-a praticamente impenetrável para interceptações não autorizadas.&lt;/p&gt;

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

&lt;p&gt;O SSH utiliza um mecanismo de &lt;strong&gt;chaves pública e privada&lt;/strong&gt; para autenticar e proteger as conexões. &lt;br&gt;
Esse método de autenticação garante que apenas as partes autorizadas tenham acesso aos sistemas envolvidos. &lt;/p&gt;

&lt;p&gt;As chaves pública e privada agem como um sistema de bloqueio e chave, onde a chave privada é mantida em segredo pelo dono e a chave pública é compartilhada com o servidor SSH.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhbv7pgtk6n98yh9bfm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhbv7pgtk6n98yh9bfm0.png" alt="Image description" width="613" height="193"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Usos Comuns do Protocolo SSH
&lt;/h2&gt;

&lt;p&gt;Uma das aplicações mais comuns do SSH é permitir o &lt;strong&gt;acesso remoto a servidores e computadores&lt;/strong&gt;. Isso é especialmente útil em ambientes de servidores e nuvem, como por exemplo instâncias EC2 da AWS, onde nós podemos nos conectar a instâncias remotas para gerenciá-las.&lt;/p&gt;

&lt;p&gt;Outros usos incluem: Transferência de Arquivos Segura, Túneis Seguros....&lt;/p&gt;
&lt;h3&gt;
  
  
  Começando com SSH
&lt;/h3&gt;
&lt;h2&gt;
  
  
  Listando suas chaves SSH
&lt;/h2&gt;

&lt;p&gt;Quando você gera chaves SSH, elas são armazenadas por padrão na pasta &lt;code&gt;.ssh&lt;/code&gt; no diretório do seu usuário. Para listar todas as chaves SSH disponíveis, você pode usar o seguinte comando no seu terminal:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LINUX e MacOS&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="nb"&gt;ls&lt;/span&gt; ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows&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="nb"&gt;dir&lt;/span&gt; ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando listará os arquivos na pasta .ssh, que geralmente podem ser os seguintes tipos de arquivos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;id_rsa: Sua chave privada RSA.&lt;/li&gt;
&lt;li&gt;id_rsa.pub: Sua chave pública RSA correspondente.&lt;/li&gt;
&lt;li&gt;id_dsa: Sua chave privada DSA (se você a gerou).&lt;/li&gt;
&lt;li&gt;id_dsa.pub: Sua chave pública DSA correspondente.&lt;/li&gt;
&lt;li&gt;Outros arquivos, dependendo de como você configurou suas chaves SSH.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gerando uma Chave SSH
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Instalando o Cliente SSH
&lt;/h4&gt;

&lt;p&gt;O primeiro passo é garantir que você tenha um cliente SSH instalado em seu computador. Os clientes SSH estão disponíveis para Mac, Windows e Linux. Você pode encontrar links para download nos seguintes sites:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenSSH para Windows:&lt;/strong&gt; &lt;a href="https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install" rel="noopener noreferrer"&gt;Instale aqui&lt;/a&gt; se você for usuário do Windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenSSH para Linux:&lt;/strong&gt; A maioria das distribuições Linux já inclui o OpenSSH, portanto, você não precisa instalá-lo separadamente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenSSH para Mac:&lt;/strong&gt; O macOS também inclui o OpenSSH. Portanto, você pode prosseguir para o próximo passo.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Gerando o Par de Chaves SSH
&lt;/h4&gt;

&lt;p&gt;Com o cliente SSH instalado, abra o seu terminal e execute o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando você executar este comando, o utilitário ssh-keygen iniciará o processo de geração de chaves. Ele solicitará que você indique onde deseja armazenar as chaves. Por padrão, as chaves são armazenadas na pasta &lt;code&gt;.ssh&lt;/code&gt; em seu diretório de usuário.&lt;/p&gt;

&lt;p&gt;O utilitário ssh-keygen também solicitará que você defina uma senha para proteger sua chave privada. Embora seja opcional, é altamente recomendável definir uma senha para aumentar a segurança.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;IMPORTANTE&lt;/em&gt;&lt;/strong&gt;: &lt;em&gt;O uso de uma senha para proteger sua chave privada é altamente recomendado, pois adiciona uma camada adicional de segurança. Mesmo com acesso ao seu computador, sem a senha não é possível utilizá-la.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Recuperando sua chave pública
&lt;/h2&gt;

&lt;p&gt;Após gerar o par de chaves, você pode recuperar a chave pública, que é a parte que você compartilhará com servidores e serviços que deseja acessar com SSH como AWS e GitHub. &lt;/p&gt;

&lt;p&gt;Para copiar a chave pública para sua área de transferência, execute o seguinte comando:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No macOS e Windows:&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;pbcopy &amp;lt; ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No Linux:&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="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A chave privada (id_rsa) permanecerá armazenada em seu computador e nunca deve ser compartilhada com ninguém.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's all, folks!
&lt;/h2&gt;

&lt;p&gt;Obrigada por ter lido até aqui e espero que o post tenha te ajudado a entender mais sobre o protocolo 💜&lt;/p&gt;

</description>
      <category>security</category>
      <category>protocol</category>
      <category>ssh</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Beginner's Guide to JavaScript's Single Thread and Event Loop</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Mon, 10 Apr 2023 01:06:01 +0000</pubDate>
      <link>https://dev.to/fernandakipper/a-beginners-guide-to-javascripts-single-thread-and-event-loop-1a9h</link>
      <guid>https://dev.to/fernandakipper/a-beginners-guide-to-javascripts-single-thread-and-event-loop-1a9h</guid>
      <description>&lt;p&gt;As a Single Thread non-blocking language, JavaScript can be a bit tricky to understand at first. &lt;br&gt;
When I first began exploring the language, I found myself overwhelmed with questions about how it worked. In this article, I'll try to answer some of the most common questions I had when I first started learning about the JavaScript event loop. By the end of this article, you'll have a better grasp of how JavaScript manages to remain non-blocking despite being single-threaded, and you'll be better equipped to build efficient and responsive applications using this powerful language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Thread
&lt;/h2&gt;

&lt;p&gt;JavaScript is a single-threaded language, which means that it has only one thread of execution. This means that all operations are executed sequentially, one after the other, in a single call stack. &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;call stack is a data structure used by JavaScript to manage function invocations&lt;/strong&gt;. &lt;strong&gt;It keeps track of the current position in the execution context&lt;/strong&gt; (the point where the code is currently being executed) and all pending function calls that have been made but not yet completed. &lt;/p&gt;

&lt;p&gt;Whenever a function is called, a new frame is added to the top of the call stack, representing the execution context of that function. When a function completes, its frame is removed from the top of the call stack and control is returned to the previous function in the stack. &lt;strong&gt;This allows JavaScript to maintain the order of function calls and ensure that each function completes before the next one is executed&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Look at the following example of how the Call Stack works&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7dn4kxmzen3xp05wyz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7dn4kxmzen3xp05wyz1.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fckehz9g36invasqzhixx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fckehz9g36invasqzhixx.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Non-blocking
&lt;/h2&gt;

&lt;p&gt;Non-blocking code is code that allows other code to execute while it is running. Specifically, asynchronous code, that should not block the execution of synchronous code that does not depend on it.&lt;/p&gt;

&lt;p&gt;Asynchronous code should execute in the background, without interrupting the flow of the main program. Instead of waiting for an operation to complete before moving on to the next line of code, asynchronous code should allow the program to continue executing while the operation runs in the background. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now, you should be thinking, how does JavaScript manages to be non-blocking since executes only in one thread?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Event loop
&lt;/h2&gt;

&lt;p&gt;Event Loop is the mechanism used to JavaScript to handle asyncronous code. &lt;br&gt;
When an asynchronous operation is started, it is added to the callback queue and removed from from call stack. The event loop constantly checks this queue for pending tasks waiting to be executed. If there are any pending tasks, the event loop will retrieve the next task and add it to the call stack for execution. Once the task is complete, its callback function is added to the callback queue. The event loop will continue to check the callback queue for pending tasks and add them to the call stack as necessary. This process allows JavaScript to execute asynchronous code in a non-blocking way, ensuring that the main program can continue to run while waiting for long-running tasks to complete.&lt;/p&gt;

&lt;p&gt;Consider the following code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff20ugbb9vxklx8yc72i5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff20ugbb9vxklx8yc72i5.png" alt="Image description" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What would happen in the Call Stack and Callback Queue would be:&lt;/p&gt;

&lt;p&gt;1 - First the &lt;code&gt;fetchData()&lt;/code&gt; function would be added to the Call Stack&lt;br&gt;
2 - &lt;code&gt;fetch()&lt;/code&gt; is added to the Call Stack and initiates a network request. The Promise created by &lt;code&gt;fetch()&lt;/code&gt;is added to the queue.&lt;br&gt;
3- &lt;code&gt;console.log("hello")&lt;/code&gt; is added to the Call Stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c57kthoquod7yajj0iq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c57kthoquod7yajj0iq.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 - After that,  &lt;code&gt;console.log("hello")&lt;/code&gt; would be executed and removed of the Call Stack&lt;br&gt;
5 - &lt;code&gt;fetchData()&lt;/code&gt; is finished executing and is removed from the Call Stack&lt;br&gt;
6 - The Promise created by &lt;code&gt;fetch()&lt;/code&gt; is resolved with the response data and the &lt;code&gt;then()&lt;/code&gt; method attached to the Promise is added to the queue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxxp3ccrc9yug6lnmgpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxxp3ccrc9yug6lnmgpe.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisrz7863f6wglhm1w211.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisrz7863f6wglhm1w211.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7 - Event Loop would takes &lt;code&gt;console.log(data)&lt;/code&gt; and adds to Call Stack&lt;br&gt;
8- &lt;code&gt;console.log(data)&lt;/code&gt; would be executed&lt;br&gt;
9 -  There are no more tasks to execute, and the program terminates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldujo2h1xtlzs3mlbrb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldujo2h1xtlzs3mlbrb0.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ok, that makes sense, but now you probably asking yourself, how does the fetch gets executeded?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Browser APIs
&lt;/h2&gt;

&lt;p&gt;Browser APIs (Application Programming Interfaces) are interfaces provided by the browser or the host environment that allow us to perform various operations, such as making network requests, setting timeouts, and manipulating the DOM. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These APIs are used to handle asynchronous operations in JavaScript by offloading them to the browser or the host environment, which can perform the operation in the background without blocking the main program.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, when a fetch request is made using the &lt;code&gt;fetch()&lt;/code&gt; method , the browser's web API (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" rel="noopener noreferrer"&gt;Fetch API&lt;/a&gt;) handles the request, sending it to the server and waiting for a response. During this time, the JavaScript program can continue to execute, thanks to the event loop, which checks the callback queue for any pending tasks. Once the server responds with the requested data, the web API adds the response to the callback queue, triggering the callback function associated with the original &lt;code&gt;fetch()&lt;/code&gt; request.&lt;/p&gt;

&lt;p&gt;Interesting, isn't it?&lt;/p&gt;




&lt;p&gt;Overall, understanding the principles behind the event loop, non-blocking code, and web APIs has been essential in my growth as a JavaScript developer, and I hope this article have helped you to get a better understing of these concepts. &lt;/p&gt;

&lt;p&gt;This kind of knowledge can be a key piece for you to take your programming skills to another level.&lt;/p&gt;

&lt;p&gt;Thats all :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Beginner's Guide to Github Actions</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Sun, 12 Feb 2023 13:48:01 +0000</pubDate>
      <link>https://dev.to/fernandakipper/github-actions-for-begginers-2m3</link>
      <guid>https://dev.to/fernandakipper/github-actions-for-begginers-2m3</guid>
      <description>&lt;p&gt;In this article, we will be diving into the world of GitHub Actions, exploring the basics of this powerful automation tool. Whether you are a beginner or an experienced developer, you will find that GitHub Actions is a valuable tool to have in your arsenal.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is a feature provided by GitHub that allows users to &lt;strong&gt;automate their software development workflows&lt;/strong&gt;, including building, testing, and deploying code. With GitHub Actions, you can create custom automated processes that run whenever specific events occur in a GitHub repository. For example, you can configure a workflow that automatically builds and deploys your code whenever you push changes to a specific branch.&lt;/p&gt;

&lt;p&gt;So, after this brief explanation, let's jump to the GitHub Actions features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow Files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A workflow file specifies the steps that should be taken to automate any task&lt;/strong&gt;, like building, testing, and deploying your code or even sending an sms when someone opens a pull request.&lt;/p&gt;

&lt;p&gt;The workflow files are composed of Events, Jobs, Runners, Steps and Actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Events
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Events are the triggers for the workflow&lt;/strong&gt;, they are what needs to happen for this workflow to fire and run the automated work.&lt;br&gt;
Events are defined in the &lt;code&gt;yaml&lt;/code&gt; workflow file by passing the &lt;code&gt;on&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Examples of events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PR Created&lt;/li&gt;
&lt;li&gt;Push&lt;/li&gt;
&lt;li&gt;Issue Created&lt;/li&gt;
&lt;li&gt;Collaborator Join&lt;/li&gt;
&lt;li&gt;PR Merged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;And you can specify branches, statuses, tags and paths to specifically limit the trigger to the desired event.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I recommend &lt;a href="https://docs.github.com/en/actions/using-workflows/triggering-a-workflow" rel="noopener noreferrer"&gt;reading the documentation&lt;/a&gt; to know all existing events.&lt;/p&gt;
&lt;h3&gt;
  
  
  Jobs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Jobs group a set of steps that will be executed&lt;/strong&gt;. After the Worflow is triggered, it will run all the jobs presented on it.&lt;br&gt;
Inside the job we need to specified the &lt;code&gt;runs-on&lt;/code&gt; property, that correspond to the enviroment this job will run, most commom is &lt;code&gt;ubuntu-latest&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Each step in a job represents a single task that should be performed&lt;/strong&gt;. The steps can be defined using either an action or a command-line command. &lt;/p&gt;

&lt;p&gt;An action is called using the &lt;code&gt;uses&lt;/code&gt; property, and its parameters are passed to the action through the &lt;code&gt;with&lt;/code&gt; property. Alternatively, a command-line command can be executed using the &lt;code&gt;run&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Heres an example of an &lt;code&gt;workflow.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Test Workflow&lt;/span&gt; 

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# Push event&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# On branches &lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;releases/**'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;master'&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hello_world&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# Define the job&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt; &lt;span class="c1"&gt;# Specify the runner to run the job on&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint code&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Linter&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/super-linter@v3&lt;/span&gt; &lt;span class="c1"&gt;# Use Github Super Linter repository&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# Input fot the action&lt;/span&gt;
          &lt;span class="na"&gt;some_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.api_key }}&lt;/span&gt; &lt;span class="c1"&gt;# Get the API key from repository secrets&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Print IPv4&lt;/span&gt; &lt;span class="c1"&gt;# Some random command&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ifconfig -a&lt;/span&gt; &lt;span class="c1"&gt;# Run ifconfig command&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;⚠️ &lt;em&gt;In order for your Workflow file to work correctly, it needs to be placed inside the &lt;code&gt;/.github/workflows&lt;/code&gt; path within your repository.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-root
  -.github
    -workflows
     your_worflow_file.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've set up a workflow file within your repository, there's nothing left to do but code!&lt;/p&gt;

&lt;h2&gt;
  
  
  Actions Files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The actions are a pre-packaged set of instructions that perform a specific task&lt;/strong&gt;. Whether you create your own custom actions or use actions from the GitHub Actions Marketplace, you can easily integrate them into your workflows using YAML files. &lt;/p&gt;

&lt;p&gt;Actions are defined in a &lt;code&gt;action.yaml&lt;/code&gt; file and must be stored in the root directory of your repository. It is recommended to store actions that will be used by third-parties or across multiple projects in a separate, dedicated repository that is publicly accessible. This ensures that the action is easily accessible and reusable by others.&lt;/p&gt;

&lt;p&gt;Actions files are formed by name, description, inputs and runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inputs
&lt;/h3&gt;

&lt;p&gt;The inputs section defines the data needed to perform this action, which must be provided in the workflow that invokes them as mentioned earlier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runs
&lt;/h3&gt;

&lt;p&gt;The runs section specifies the runtime environment for the action (example: Node.js version 12), and the main entry point for the action (example: dist/index.js). &lt;/p&gt;

&lt;p&gt;Here´s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Custom&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Action"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;custom&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;doing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;something&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cool."&lt;/span&gt;
&lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;input1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;first&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;action."&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;input2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;second&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;action."&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;input3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;third&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;action."&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;using&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node12"&lt;/span&gt;
  &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dist/index.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Main file
&lt;/h3&gt;

&lt;p&gt;The main file used in an action is typically a &lt;strong&gt;script file that is executed when the action is triggered in a workflow&lt;/strong&gt;. The script file can be written in a &lt;strong&gt;variety of programming languages, such as JavaScript, Python, or Ruby.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of a JavaScript script that could be used as the main file in an action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;core&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@actions/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@actions/exec&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;command&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Running command: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFailed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Note that i used the &lt;code&gt;@actions/core&lt;/code&gt; and &lt;code&gt;@actions/exec&lt;/code&gt;, &lt;strong&gt;these libraries are part of the GitHub Actions Toolkit&lt;/strong&gt;, a collection of libraries and tools provided by GitHub to simplify the development of custom actions for GitHub Actions.&lt;/p&gt;

&lt;p&gt;The actual implementation of your main file will depend on the requirements of your action and the tools and services that you are integrating with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Illustration
&lt;/h2&gt;

&lt;p&gt;To summarize, I found this image on the internet that excellently illustrates the hierarchy within GitHub Actions, showing all the components discussed and their interrelationships. It serves as a visual representation of the concepts covered in this article and I believe it can help to better visualize how it works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43y0ykto45wks2ueqgzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43y0ykto45wks2ueqgzg.png" alt="Image description" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading this far and I hope it helped you understand a little more about this incredible feature on GitHub! 😊&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>opensource</category>
      <category>siliconvalley</category>
    </item>
    <item>
      <title>Iniciando estudos de RxJs em Angular</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Thu, 20 Oct 2022 17:33:03 +0000</pubDate>
      <link>https://dev.to/fernandakipper/iniciando-estudos-de-rxjs-em-angular-17mm</link>
      <guid>https://dev.to/fernandakipper/iniciando-estudos-de-rxjs-em-angular-17mm</guid>
      <description>&lt;h2&gt;
  
  
  O que é RxJs?
&lt;/h2&gt;

&lt;p&gt;RxJs é uma biblioteca que fornece formas de trabalhar com programação assíncrona e baseada em eventos - reativa - usando observables. A biblioteca provém um tipo principal o &lt;code&gt;Observable&lt;/code&gt;, tipos satélites como &lt;code&gt;Subjects&lt;/code&gt;, &lt;code&gt;Observers&lt;/code&gt; e &lt;code&gt;Schedulers&lt;/code&gt;  e também operadores para lidar a coleção de eventos assíncronos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recapitulando: o que são Observables?
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;Observable&lt;/code&gt; é a peça chave do &lt;strong&gt;Design Pattern Observer&lt;/strong&gt;,  baseado em eventos o padrão define Observable como o objeto de interesse e que pode ser observado, o mesmo guarda uma lista de interessados em suas mudanças - Observers ou Subscribers - e emite um evento avisando aos interessados todas as vezes que ocorrer uma mudança em seus itens. &lt;br&gt;
Se ainda não ficou claro, recomendo a leitura do &lt;a href="https://www.instagram.com/p/Ci8th7ROUcP/" rel="noopener noreferrer"&gt;meu post sobre o Padrão Observer&lt;/a&gt; antes de continuar.&lt;/p&gt;
&lt;h2&gt;
  
  
  RxJs + Angular
&lt;/h2&gt;

&lt;p&gt;O novo Angular foi construído em cima da programação reativa, o uso de Promises foi abandonado e fora adotado o uso de Observables, e ai que entra o RxJs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Requisições HTTP
&lt;/h3&gt;

&lt;p&gt;Vamos começar com o básico, lidando com respostas de requisições HTTP. Normalmente, fariamos usando Promises como acontece em React JS, porém em Angular vamos usar Observables do RxJS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criando nosso service&lt;/strong&gt;&lt;br&gt;
Ele que realiza a requisição e retorna um Observable do tipo &lt;code&gt;HttpResponse&amp;lt;User&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HttpResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IUser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;imgUrl&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HttpResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IUser&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HttpResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IUser&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consumindo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nosso componente irá chamar o &lt;code&gt;UserService&lt;/code&gt;, e para receber a resposta da requisição precisamos realizar o &lt;code&gt;subscribe&lt;/code&gt; no &lt;code&gt;Observable&lt;/code&gt; retornado pelo método &lt;code&gt;getUser()&lt;/code&gt;, passando como parâmetro para o método &lt;code&gt;subscribe&lt;/code&gt; um objeto do tipo &lt;code&gt;observer&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.component.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserComponent&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUserData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getUserData&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1234&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observer&lt;/strong&gt;&lt;br&gt;
O Observer é o consumidor dos valores emitidos pelo o Observable, ele nada mais é que um objeto que possui callbacks para cada evento do emissor. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Observer recebeu o prox valor: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Observer recebeu um erro: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Observer completou o recibimento&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro de cada um desses callbacks podemos realizar o necessário com o dado emitido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Eventos Pai -&amp;gt; Filho
&lt;/h3&gt;

&lt;p&gt;O segundo caso que irei demostrar é quando precisamos que um componente filho reaja a um evento do seu pai.&lt;/p&gt;

&lt;p&gt;Exemplo: enquanto a requisição para buscar o usuário não finaliza, quero que um componente filho mostre a mensagem "carregando" e quando finalizar ele mostra os dados normalmente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entendo o conceito de Subject&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enquanto Observables são unicast, ou seja, cada subscriber possui uma execução única e indepente (seu próprio "canal") do Observable pois cada &lt;code&gt;subscribe()&lt;/code&gt; invoca uma nova execução. Os &lt;strong&gt;Subjects&lt;/strong&gt; são multicast, eles &lt;strong&gt;não invocam uma nova execução&lt;/strong&gt; para cada &lt;code&gt;subscribe()&lt;/code&gt;, eles simplemente adicionam na lista de Observers e avisa a todos pelo mesmo "canal" quando houver uma mudança.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criando um Behavior Subject&lt;/strong&gt;&lt;br&gt;
Para emitir eventos do pai para o filho, vamos utilizar &lt;code&gt;Behavior Subject&lt;/code&gt;, que consiste em um Subject que &lt;strong&gt;possui valor inicial e emite seu valor atual&lt;/strong&gt; para cada Observer inscrito.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criamos um atributo &lt;code&gt;isLoading$&lt;/code&gt; no componente pai
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;isLoading$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;BehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Ao completar a requisição, atualizamos o valor para false
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;getUserData&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1234&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoading$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Passando para o filho&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;child-component&lt;/span&gt;
  &lt;span class="na"&gt;[name]=&lt;/span&gt;&lt;span class="s"&gt;"user.name"&lt;/span&gt;
  &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="na"&gt;]=&lt;/span&gt;&lt;span class="s"&gt;"isLoading$"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/child-component&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Recebendo no filho&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/app/shared/services/user.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./child.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./child.component.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChildComponent&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;isLoading$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Utilizando o Behavior Subject&lt;/strong&gt;&lt;br&gt;
Agora no template do componente filho vamos usar um condicional para saber quando mostrar "carregando".&lt;/p&gt;

&lt;p&gt;Quando o valor atual for &lt;code&gt;true&lt;/code&gt; =&amp;gt; ele deve mostrar&lt;br&gt;
Quando o valor atual for &lt;code&gt;false&lt;/code&gt; =&amp;gt; ele deve esconder a div&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"isLoading$ | async"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;carregando&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note que utilizei o pipe async, um recurso fornecido pelo Angular, que automaticamente realiza o subscribe no Observable - nesse caso é nosso Behavior Subject &lt;code&gt;isLoading$&lt;/code&gt; - e retorna sempre o último valor emitido. Se quiser saber mais sobre esse operador, recomendo a leitura da &lt;a href="https://angular.io/api/common/AsyncPipe" rel="noopener noreferrer"&gt;documentação do Angular&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Para usar o pipe async não esqueca de importar o CommonModule no módulo do seu componente.&lt;/em&gt; &lt;/p&gt;




&lt;p&gt;Quando iniciei meus estudos em Angular, dois anos atrás, RxJs era um assunto bem conturbado para mim e existiam poucos conteúdos em português, mesmo ele sendo uma peça fundamental para construirmos aplicações mais robustas com Angular. &lt;br&gt;
Então, resolvi compartilhar um pouco do que aprendi nesses anos para ajudar quem esteja começando agora, espero que você tenha gostado do artigo 😊&lt;/p&gt;

&lt;p&gt;Seu feedback é bem vindo! &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Programação Orientada Objetos e Programação Procedural - entendendo a diferença</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Sun, 30 Jan 2022 15:58:04 +0000</pubDate>
      <link>https://dev.to/fernandakipper/programacao-orientada-objetos-e-programacao-procedural-qual-a-diferenca-22lj</link>
      <guid>https://dev.to/fernandakipper/programacao-orientada-objetos-e-programacao-procedural-qual-a-diferenca-22lj</guid>
      <description>&lt;p&gt;Em algum momento na nossa carreira de desenvolvedores topamos com uma discussão sobre paradigmas de linguagens de programação. E como é importante entendermos mais sobre as vantagens que uma linguagem pode nos trazer para fazermos a escolha mais vantajosa para nosso projeto, entender a diferença e as vantagens dos paradigmas de programação vai nos ajudar. Então, foi pensando nisso que resolvi escrever esse post explicando a diferença e trazendo alguns exemplos práticos de dois paradigmas de programação, o procedural e o orientado a objetos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Programação orientada a objetos
&lt;/h1&gt;

&lt;p&gt;A Programação orientada objetos (POO) se baseia na ideia de que tudo são classes e objetos, as classes são como agrupadores e objetos são os participantes desses grupos. Cada classe define atributos e métodos que são comuns a todos pertencentes a essa classe, nesse caso a cada objeto que seja uma instância da classe. Os objetos podem possuir um atributo que seja  _IGUAL _  a todos pertencentes á classe, que são chamados de atributos da classe, ou atributos que apesar de definirem a mesma coisa não possuem o mesmo valor, chamados de atributos do objeto (como por exemplo o nome, toda pessoa possui um nome, mas não obrigatoriamente toda pessoa possui o mesmo nome). Os métodos são abstrações para esconder os detalhes dos objetos, expondo apenas as funções que operam seus dados.&lt;br&gt;
Outro conceito muito importante no mundo de POO, é o de &lt;strong&gt;polimorfismo&lt;/strong&gt;, que simplificando é o princípio de que classes derivadas de uma mesma superclasse (classe mãe) expõem métodos que possuiem a  &lt;strong&gt;mesma identificação porém com implementações diferentes&lt;/strong&gt;, pois cada classe possui sua singularidade e por isso comportamentos distintos para realizar a mesma ação. Exemplificando: imaginamos a superclasse &lt;code&gt;VeiculoDeLomocoção&lt;/code&gt;, ela define que todas suas derividas devem possuir o método &lt;code&gt;limpar&lt;/code&gt;, a classe derivada &lt;code&gt;Carro&lt;/code&gt; implementa o método &lt;code&gt;limpar&lt;/code&gt; que seria passar lava-jato e cera em todo carro, já a classe &lt;code&gt;Bicicleta&lt;/code&gt; implementa limpar como apenas passar uma mangueira no veículo. Entrentanto, esse comportamento interno não importa pra quem vê a classe de fora. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fhqdeai8hzf0ftyghfk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fhqdeai8hzf0ftyghfk.png" alt="Image description" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Programação Procedural
&lt;/h1&gt;

&lt;p&gt;Por outro lado, a Programação Procedural (PC) ou também chamada como &lt;strong&gt;Programação Estruturada&lt;/strong&gt; se resume a modularizar instruções da execucação do programa em &lt;strong&gt;procedimentos&lt;/strong&gt;. Os procedimentos contêm um conjunto de passos computacionais a serem executados. Um dado procedimento pode ser chamado a qualquer hora durante a execução de um programa, inclusive por outros procedimentos ou por si mesmo.  Os procedimentos podem receber parâmetros para realizar manipulações e podem ou não retornar valores, e diferente do conceito da programação funcional, procedimentos também podem causar efeitos colaterais como os métodos de objetos.&lt;br&gt;
Então simplificando a diferença de conceitos entre uma função e um procedimento é de que uma função sempre retornaria algum valor e não modificaria nenhum parâmetro fora de seu escopo, já os procedimentos podem modificar algo fora de seu escopo e não necessariamente retornam algum valor. &lt;strong&gt;Essa alteração de dados de fora de seu escopo que são os chamados de efeitos colaterais.&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Na prática 💪
&lt;/h1&gt;

&lt;p&gt;No livro &lt;a href="https://g.co/kgs/QzZy9o" rel="noopener noreferrer"&gt;Clean Code do Uncle Bob&lt;/a&gt;, no capítulo acerca de Estrutura de Dados e Objetos ele menciona um exemplo muito claro sobre a diferença desses dois paradigmas, então resolvi trazer o mesmo exemplo nesse post para analisarmos a implementação do mesmo programa nos dois paradigmas e compararmos suas diferenças.&lt;/p&gt;

&lt;p&gt;Imagine o seguinte cenário, precisamos calcular a área de algumas formas geométricas, cada uma possui uma fórmula diferente para o cálculo de sua área.&lt;/p&gt;

&lt;p&gt;Em POO a implementação aconteceria mais ou menos da seguinte forma&lt;/p&gt;

&lt;p&gt;💡 Consideramos &lt;code&gt;Shape&lt;/code&gt; como sendo uma interface que define o contrato para que uma forma seja uma forma geométrica&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Square implements Shape {
    private double sideValue;

    //construtor

    public double area() {
        return sideValue*sideValue;
    }
}

public class Rectangle implements Shape {
    private double heigth;
    private double width;

    //construtor

    public double area() {
        return width* heigth;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quissemos calcular a área de qualquer uma dessas formas, bastaria:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public double squareAreaValue = new Square(4);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Já em PC a implementação seria diferente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Square {
    public double sideValue;
}

public class Rectangle {
    public double heigth;
    public double width;
}

public class Geometry{
    public double area(Object shape) throws NoSuchShapeException{
        if (shape instanceof Square) {
            Square s = (Square)shape;
            return s.sideValue* s.sideValue;
        }
        else if (shape instanceof Rectangle ) {
            Rectangle r = (Rectangle )shape;
            return r.width* r.heigth;
        }
        else
            throw new NoSuchShapeException();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quissemos calcular a área de uma dessas formas no último exemplo fariamos o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Square square = new Square();
square.sideValue = 4;
public Geometry geometryCalc = new Geometry();
public double squareAreaValue = geometryCalc.area(square);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comparando:
&lt;/h2&gt;

&lt;p&gt;Uma das maiores diferenças na minha opnião é a forma em que os dados são tratados, note que no exemplo de POO nós manipulamos os &lt;strong&gt;objetos&lt;/strong&gt; mas não temos acesso direto aos valores e nem mesmo sabemos como os valores são utilizados para o cálculo da área, pois os objetos expõem apenas o método necessário para obter a área da forma geométrica e abstraem seu funcionamento interno. &lt;br&gt;
Já no exemplo de PC percebemos os valores como uma &lt;strong&gt;estrutura de dados&lt;/strong&gt;, e segundo Uncle Bob&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As estruturas de dados expõem seus dados e não possuem funções significativas para a sua manipulação. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mas diferente do primeiro exemplo nós conseguimos manipular diretamente esses valores e realizar implementação que desejamos com eles.&lt;/p&gt;

&lt;p&gt;Outra diferença, também citada em Clean Code é que a facilidade e a dificuldade de implementação são invertidas em cada um dos paradigmas. Como assim? Note que ao usar as estruturas de dados em PC, podemos adicionar novos procedimentos facilmente, por que precisamos alterar apenas um local, porém para adicionar uma nova estrutura de dados teriamos que alterar todos os procedimentos que as utilizam - imagine se tivessemos um procedimento para calculo da área, outro para perimetro, outro para mediatrix, todos teriam que ser alterados para prever essa nova forma geométrica.&lt;br&gt;
Mas em POO temos o contrário, para adicionar um novo método seria mais trabalhoso por que teriamos que alterar todas as classes de formas geométrica para implementar esse novo método, já para adicionar uma nova classe (uma nova forma geométrica) precisariamos alterar apenas um local, que seria criando a nova classe seguindo a interface &lt;code&gt;Shape&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Além disso, mesmo com os exemplos estando na mesma linguagem, notamos que cada um faz o uso dos recursos da linguagem de maneira diferente, mostrando que uma linguagem não é obrigatoriamente presa a um paradigma.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Testes unitários Frontend - Como Mockar Módulos e React Hooks usando apenas o Jest</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Thu, 30 Dec 2021 16:25:17 +0000</pubDate>
      <link>https://dev.to/fernandakipper/testes-unitarios-front-end-como-mockar-modulos-e-react-hooks-usando-apenas-o-jest-28ba</link>
      <guid>https://dev.to/fernandakipper/testes-unitarios-front-end-como-mockar-modulos-e-react-hooks-usando-apenas-o-jest-28ba</guid>
      <description>&lt;p&gt;Olá Pessoal! Nesse post eu vou explicar algumas maneiras que você pode adotar para realizar os mocks dos seus testes unitários.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mockando imports de módulos
&lt;/h2&gt;

&lt;p&gt;Caso as funções ou componentes que você deseja mockar nos seus testes venham de um módulo externo, existe uma maneira de utilizar apenas o objeto Jest para realizar o mock. &lt;br&gt;
Exemplo, digamos que queremos testar se nosso componente está chamando corretamente a função &lt;code&gt;push&lt;/code&gt; retornada pelo hook &lt;code&gt;useHistory&lt;/code&gt;do módulo &lt;code&gt;react-router&lt;/code&gt;. Nós podemos mockar a função &lt;code&gt;push&lt;/code&gt;e usá-la no &lt;code&gt;expect&lt;/code&gt; do nosso teste para ter certeza que ela foi chamada, para fazer isso nos devemos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar uma função de mock usando o método do Jest &lt;code&gt;jest.fn()&lt;/code&gt; que retorna uma função de simulação OU criar nossa própria implementação
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   // OPÇÃO 1
   const mockPush = jest.fn()
  // OPÇÃO 2
  const mockPush = () =&amp;gt; {
    // alguma funcionalidade...
    // return algo
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Mockar o import do módulo &lt;code&gt;react-router&lt;/code&gt; no ínicio do arquivo antes de iniciar os testes, dessa forma toda vez que um componente renderizado pelo Jest durante o teste tentar importar esse módulo, o Jest substituirá o real conteúdo por aquele que nos mockamos
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  jest.mock('react-router', () =&amp;gt; ({
  ...jest.requireActual('react-router'),
  useHistory: () =&amp;gt; ({
    push: mockPush
  })
}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;🎯 Note que usamos o método &lt;code&gt;requireActual&lt;/code&gt; do objeto Jest que retorna o módulo real e com o spread operator copiamos tudo do módulo verdadeiro e apenas subsstituimos o que precisávamos testar, nesse caso o hook &lt;code&gt;useHistory&lt;/code&gt; e seu retorno.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/pt-BR/docs/jest-object" rel="noopener noreferrer"&gt;Caso queira saber mais sobre o objeto Jest e seus métodos, recomendo muito que você leia a documentação do Jest&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agora, ao escrever seu teste unitário você deve utilizar a função mockada &lt;code&gt;mockPush&lt;/code&gt; para conferir o resultado com o expect, e pronto!
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await waitFor(() =&amp;gt; expect(mockPush).toHaveBeenCalledWith('sua-rota'))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Mockando React Hooks
&lt;/h2&gt;

&lt;p&gt;Em testes unitários de componentes React, é muito comum precisarmos mockar Hooks para realizar verificações de comportamento em nossos componentes. Caso você deseja mockar apenas a implementação de um hook, também é possível utilizar apenas o objeto Jest para realizar nosso teste.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primeiro você deve importar todo o arquivo que contém seu hook, o que retornará um objeto que contém todos os retornos desse arquivo
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as MeuHook from 'path-para-seu-hook'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;No ínicio do arquivo antes de iniciar os testes mockaremos UM dos retornos desse arquivo, nesse caso o hook, usando o método do Jest &lt;code&gt;jest.spyOn&lt;/code&gt; que cria uma função de mock similar ao &lt;code&gt;jest.fn&lt;/code&gt; mas também observa todas as chamadas pelo objectDoArquivo[nomeDoMétodo]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; O primeiro parâmetro que passamos ao jest.spyOn é justamente o  objeto contendo todos os retornos do nosso arquivo &lt;/li&gt;
&lt;li&gt; E o segundo parâmetro é o nome do método (o nome do hook ou função) que é exportado desse arquivo e  queremos observar (note, caso seu hook seja exportado através de um &lt;code&gt;export default&lt;/code&gt; em vez de fornecermos o seu nome, passaremos 'default' como parâmetro)
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  jest.spyOn(MeuHook, 'useNomeDoMeuHook')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Agora temos duas opções, podemos mockar a implementação do hook para todo o nosso arquivo de teste, ou seja, para cada test case ele retornará o mesmo valor, OU, podemos realizar uma implementação diferente para cada test case&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
  2.1 Caso queiramos a mesma implementação para todo o arquivo, podemos realizar a declaração junto com método &lt;code&gt;spyOn&lt;/code&gt; e todos os nossos tests cases terão acesso ao mesmo mock&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  jest.spyOn(MeuHook, 'useNomeDoMeuHook').mockImplementation(() =&amp;gt; 
  {
    //  implemente aqui
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.2 Caso contrário, guardaremos o retorno do spyOn em uma constante&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const useNomeDoMeuHookMock = jest.spyOn(MeuHook, 'useNomeDoMeuHook')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E dentro de cada test case realizaremos a diferente implementação&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test('It should ....', async () =&amp;gt; {
  useNomeDoMeuHookMock.mockReturnValue(// valor retornado pelo hook)
})

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

&lt;/div&gt;



&lt;p&gt;E por fim, não podemos nos esquecer de depois de cada teste limpar o mock para não sujar as implementações dos próximos testes, por isso colocaremos no inicio do nosso suite de testes a função &lt;code&gt;afterEach&lt;/code&gt; para resetar nosso mock&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe('...', () =&amp;gt; {
  afterEach(() =&amp;gt; {
      useNomeDoMeuHookMock.mockClear()
})

  test()....
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Obrigada por ter lido até aqui e espero que eu tenha te ajudado! Qualquer dúvida ou sugestão fique a vontade para entrar em contato comigo 😀&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Algorithm Time Complexity Simplified</title>
      <dc:creator>Fernanda Kipper</dc:creator>
      <pubDate>Fri, 10 Sep 2021 01:22:12 +0000</pubDate>
      <link>https://dev.to/fernandakipper/algorithm-time-complexity-simplified-4fe</link>
      <guid>https://dev.to/fernandakipper/algorithm-time-complexity-simplified-4fe</guid>
      <description>&lt;p&gt;Recently, I have been studying about algorithm complexity, and as I like to share and write about things that I am learning, I have decided to talk about this subject to help others by sharing what I learned so far. &lt;/p&gt;

&lt;h1&gt;
  
  
  How to measure Algorithm Complexity
&lt;/h1&gt;

&lt;p&gt;First of all, lets talk about what counts when we are performing the time complexity measurement of an algorithm. And to do that, we need to understand what &lt;em&gt;Asymptotic complexity&lt;/em&gt; stands for. &lt;br&gt;
&lt;strong&gt;But remember, we can't measure the time complexity of a program, just an algorithm, and algorithms always end at some point.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Asymptotic complexity
&lt;/h2&gt;

&lt;p&gt;If we compare the absolute time of executation of two algorithms, we would be comparing subjective values, since they are specific to particular hardware and context. For example, even if we run both algorithms on the same computer each program would have to run without sharing CPU with other programs or operating system service and even the order in which we run the programs can affect the result, due to the thermal characteristics of the CPU or the mere oscillation of the ambient temperature.&lt;br&gt;
So, we need to compare their running time mathematically, here where the term Asymptotic complexity comes in, &lt;strong&gt;considering that the time complexity of an algorithm summarizes how the execution time of algorithm grows with the input size&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This growth is calculate based on how many steps (for example, how many times it enters in a for loop) an algorithm need to do ir order the solve a problem given an n number of elements to be counted.&lt;/p&gt;

&lt;p&gt;But we cannot considerer just one value of n to measure a complexity of an algorithnm, because as we know, a program can be very efficient for big values but not the best choice for small values and the other way around. &lt;/p&gt;
&lt;h2&gt;
  
  
  Worst and Best Case
&lt;/h2&gt;

&lt;p&gt;Since its almost impossible to consider all cases, we choose the worst and best scenario of an input to calculate the complexity of certain algorithm.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Worst case runtime means that you are feeding the worst possible input (of that size) into your algorithm. Best case runtime means that you are feeding the best possible input into your algorithm, which is the fastest scenario&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Big O Notation
&lt;/h1&gt;

&lt;p&gt;In short way, the big O notation is way to classify how scalable our algorithm is. This helps us determine how our algorithm will behave in the &lt;strong&gt;WORST&lt;/strong&gt; case or how long it will take to complete based on its input values.&lt;/p&gt;

&lt;p&gt;To get the final equation, there are some rules we need to follow, first is to drop constant values (such as variable declaration and other expressions that just happen once while your algorithm is running regardless of input size) and non-dominate terms (i will explain in the next section) since this one has minimal effect on the growth curve of time complexity when the input size are very large. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb4g637pkef2kzctjdis.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb4g637pkef2kzctjdis.png" alt="Complexity Curve" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Being the horizontal line the growth of time complexity and the vertical line the input size, note that the equations that have exponential degree are the worst ones, because as the number of input size grow, the time complexity is more then duplicated and constants would have almost no effect on the growth of this curve.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pratice
&lt;/h2&gt;

&lt;p&gt;After all the theoretical explanation, let's dive into it and get our hands dirty.&lt;br&gt;
Let's considerer the following algorithm, which print all possible pairs given a certain array, the order matters and a element cannot be a pair with it self.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printPossiblePairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cont2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d - %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This algorithm´s &lt;strong&gt;worst&lt;/strong&gt; and &lt;strong&gt;best&lt;/strong&gt; scenario are equal.&lt;/p&gt;

&lt;p&gt;Checking step by step, we need to conclude how many times each step would repeat based on input size that we will call &lt;code&gt;N&lt;/code&gt; - in this case the input size consists on the array length. So let's analyze the algorithm shown earlier:&lt;/p&gt;

&lt;p&gt;First line, will execute &lt;strong&gt;only once&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printPossiblePairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// (1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line will execute &lt;strong&gt;(n + 1) times&lt;/strong&gt;, in other words, will execute one time for every element on the array + one (when it checks that the loop is end)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="c1"&gt;// N + 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line will execute &lt;strong&gt;(n + 1)(n + 1) times&lt;/strong&gt;&lt;br&gt;
Because it will run N + 1 times every time the outermost "for" executes (that is N + 1 as well)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cont2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="c1"&gt;// (N + 1)(N + 1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will run &lt;strong&gt;just one time&lt;/strong&gt; on all the times the above for loop runs&lt;br&gt;
&lt;em&gt;Note that if statement has almost no effect in time complexity&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;     &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cont&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="c1"&gt;// (N + 1)(N + 1)(1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To finish, this line will run only when the indexes cont are different, meaning all the times the for loop runs minus one, cause they will be igual just once&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;     &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d - %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cont&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cont2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;//// (N + 1)(N + 1)(1) - 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, your final equation is &lt;strong&gt;(N + 1)(N + 1)(1) - 1&lt;/strong&gt;&lt;br&gt;
Notice that we reduce&lt;br&gt;
Based on the rules we talked about before, we drop constant values such as &lt;strong&gt;(1)&lt;/strong&gt; and &lt;strong&gt;- 1&lt;/strong&gt;, cause this terms have no effect when we are dealing with big input numbers, so we leave only dominate terms&lt;br&gt;
&lt;strong&gt;(N+1)(N+1)&lt;/strong&gt;&lt;br&gt;
Dropping costants&lt;br&gt;
&lt;strong&gt;(N)(N)&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;(N²)&lt;/strong&gt;&lt;br&gt;
Our Big O is: &lt;strong&gt;O(N²)&lt;/strong&gt;&lt;br&gt;
When N increases, the running time increases by &lt;strong&gt;N * N&lt;/strong&gt;.&lt;/p&gt;

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