<?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: Uriel dos Santos Souza</title>
    <description>The latest articles on DEV Community by Uriel dos Santos Souza (@urielsouza29).</description>
    <link>https://dev.to/urielsouza29</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%2F555747%2F7232e03c-096f-4dea-8972-c6dbf11dc45e.jpg</url>
      <title>DEV Community: Uriel dos Santos Souza</title>
      <link>https://dev.to/urielsouza29</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/urielsouza29"/>
    <language>en</language>
    <item>
      <title>Reactor e Proactor - Segredos do Event Loop do NodeJS</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Thu, 11 Dec 2025 19:28:16 +0000</pubDate>
      <link>https://dev.to/urielsouza29/reactor-e-proactor-pattern-no-nodejs-segredo-do-event-loop-114b</link>
      <guid>https://dev.to/urielsouza29/reactor-e-proactor-pattern-no-nodejs-segredo-do-event-loop-114b</guid>
      <description>&lt;h3&gt;
  
  
  Introdução
&lt;/h3&gt;

&lt;p&gt;Esta é uma pequena introdução &lt;strong&gt;às&lt;/strong&gt; soluções utilizadas no Node.js e nos navegadores para lidar com concorrência e operações de Entrada/Saída (E/S).&lt;/p&gt;

&lt;h4&gt;
  
  
  A História Rápida do Node.js
&lt;/h4&gt;

&lt;p&gt;Quando o Node.js foi criado, ele utilizou o conceito do &lt;strong&gt;Event Loop&lt;/strong&gt; em conjunto com E/S Não Bloqueante para evitar que as operações de entrada e saída travassem o sistema.&lt;/p&gt;

&lt;p&gt;Em praticamente todos os aplicativos web modernos, temos muita E/S:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interação com o banco de dados (solicitar, inserir ou atualizar registros).&lt;/li&gt;
&lt;li&gt;Acesso a arquivos no disco rígido.&lt;/li&gt;
&lt;li&gt;Comunicação em rede.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No modelo de programação síncrona, essas operações de E/S causam &lt;em&gt;bloqueio&lt;/em&gt;, fazendo com que o programa espere (e fique inativo) até que a operação seja concluída. A solução para contornar isso é a adoção de um modelo assíncrono, implementado pelo &lt;strong&gt;Event Loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Event Loop&lt;/strong&gt; não foi inventado pelo pessoal do Node.js. O conceito por trás dele já existia em padrões arquiteturais como &lt;strong&gt;Reactor&lt;/strong&gt; e &lt;strong&gt;Proactor&lt;/strong&gt;. O Event Loop do Node.js atua como o componente central que &lt;strong&gt;implementa&lt;/strong&gt; a lógica do padrão &lt;strong&gt;Reactor&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Entendendo o Padrão Reactor
&lt;/h3&gt;

&lt;p&gt;O Padrão Reactor é um padrão de projeto de &lt;em&gt;software&lt;/em&gt; fundamental usado em programação concorrente para lidar com eficiência com &lt;strong&gt;solicitações de serviço assíncronas&lt;/strong&gt; que chegam de múltiplos clientes, utilizando um número limitado (muitas vezes, um único) de &lt;em&gt;threads&lt;/em&gt; para a lógica principal de despacho.&lt;/p&gt;

&lt;p&gt;O seu objetivo principal é permitir que um sistema (como um servidor de rede) gerencie múltiplas operações de E/S sem precisar de uma &lt;em&gt;thread&lt;/em&gt; dedicada para cada conexão, melhorando a escalabilidade e o desempenho.&lt;/p&gt;

&lt;p&gt;O padrão Reactor desacopla a &lt;strong&gt;detecção&lt;/strong&gt; de que um evento está pronto (função do Desmultiplexador) do &lt;strong&gt;processamento&lt;/strong&gt; real do evento (função do Manipulador).&lt;/p&gt;

&lt;p&gt;Os principais componentes do Reactor são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identificadores (&lt;em&gt;Handles&lt;/em&gt;):&lt;/strong&gt; Recursos de E/S que são monitorados (como um &lt;em&gt;socket&lt;/em&gt; de rede).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desmultiplexador de Eventos Síncrono:&lt;/strong&gt; O mecanismo de nível de OS (&lt;code&gt;select()&lt;/code&gt;, &lt;code&gt;epoll()&lt;/code&gt;, etc.) que bloqueia até que um ou mais identificadores estejam prontos para uma operação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reactor (Event Loop/Despachante):&lt;/strong&gt; O componente principal que despacha o evento detectado para o Manipulador apropriado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manipulador de Eventos (&lt;em&gt;Handler&lt;/em&gt;):&lt;/strong&gt; O código da aplicação que processa o evento de forma não bloqueante.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Node.js: Arquitetura de Thread Única e Múltiplas Threads
&lt;/h3&gt;

&lt;p&gt;Para lidar com solicitações da &lt;em&gt;Web&lt;/em&gt;, existem duas arquiteturas concorrentes principais: &lt;strong&gt;baseadas em *threads&lt;/strong&gt;* (uma &lt;em&gt;thread&lt;/em&gt; por requisição) e &lt;strong&gt;orientadas a eventos&lt;/strong&gt; (como o Reactor).&lt;/p&gt;

&lt;p&gt;No Node.js, o código &lt;strong&gt;JavaScript do usuário roda sempre em uma única *thread&lt;/strong&gt;&lt;em&gt;. Esta é a **Thread Principal&lt;/em&gt;* (ou &lt;em&gt;Main Thread&lt;/em&gt; V8). É por isso que o Node.js é frequentemente descrito como "de &lt;em&gt;thread&lt;/em&gt; única".&lt;/p&gt;

&lt;p&gt;No entanto, para lidar com E/S de forma assíncrona, o Node.js conta com a biblioteca &lt;strong&gt;libuv&lt;/strong&gt;, que é quem implementa o Event Loop.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;libuv&lt;/code&gt; é responsável por:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;I/O Não Bloqueante (via OS):&lt;/strong&gt; Para a maioria das operações de rede, a &lt;code&gt;libuv&lt;/code&gt; usa mecanismos assíncronos nativos do sistema operacional (como &lt;code&gt;epoll&lt;/code&gt; no Linux). Isso não envolve o &lt;em&gt;Thread Pool&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;I/O Bloqueante (via &lt;em&gt;Thread Pool&lt;/em&gt;):&lt;/strong&gt; Para operações que são inerentemente bloqueantes (como a maioria das operações de sistema de arquivos - &lt;code&gt;fs&lt;/code&gt;), a &lt;code&gt;libuv&lt;/code&gt; as envia para um &lt;strong&gt;Pool de *Threads&lt;/strong&gt;* (4 &lt;em&gt;threads&lt;/em&gt; por padrão) para execução. Isso é totalmente transparente para o desenvolvedor JavaScript.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A Clarificação:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O Node.js &lt;strong&gt;é&lt;/strong&gt; de &lt;em&gt;thread&lt;/em&gt; única no que diz respeito à &lt;strong&gt;execução do código JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O Node.js &lt;strong&gt;é&lt;/strong&gt; multi-&lt;em&gt;thread&lt;/em&gt; no que diz respeito à &lt;strong&gt;execução das tarefas de E/S pesadas&lt;/strong&gt;, que são delegadas para o &lt;em&gt;Thread Pool&lt;/em&gt; da &lt;code&gt;libuv&lt;/code&gt; para não bloquear o Event Loop principal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O &lt;strong&gt;Event Loop&lt;/strong&gt; é o coração: A única &lt;em&gt;thread&lt;/em&gt; de JS executa o &lt;em&gt;loop&lt;/em&gt; de eventos. Quando uma operação de E/S (seja nativa ou do &lt;em&gt;Thread Pool&lt;/em&gt;) termina, o &lt;em&gt;callback&lt;/em&gt; é enfileirado e executado.&lt;/p&gt;




&lt;h3&gt;
  
  
  Reactor vs. Proactor: A Diferença Crucial
&lt;/h3&gt;

&lt;p&gt;Ambos os padrões são modelos arquiteturais que lidam com concorrência de E/S, mas se diferenciam no momento em que o código da aplicação é invocado:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Característica&lt;/th&gt;
&lt;th&gt;Padrão Reactor&lt;/th&gt;
&lt;th&gt;Padrão Proactor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Invocação (O quê)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Prontidão&lt;/strong&gt; para E/S (&lt;em&gt;Readiness&lt;/em&gt;).&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Conclusão&lt;/strong&gt; da E/S (&lt;em&gt;Completion&lt;/em&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Onde a E/S ocorre&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;O sistema notifica que os dados estão &lt;strong&gt;prontos&lt;/strong&gt;. A &lt;strong&gt;aplicação&lt;/strong&gt; deve ler/escrever os dados no &lt;em&gt;handle&lt;/em&gt;.&lt;/td&gt;
&lt;td&gt;O sistema operacional executa a operação de E/S (leitura/escrita) em segundo plano e notifica a &lt;strong&gt;aplicação&lt;/strong&gt; com o &lt;strong&gt;resultado&lt;/strong&gt; pronto.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modelo de I/O&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Síncrono (demultiplexação) + Assíncrono (despacho)&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Totalmente Assíncrono&lt;/strong&gt; (baseado em chamadas de conclusão).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exemplo (&lt;em&gt;Web&lt;/em&gt; Servers)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Node.js (majoritariamente)&lt;/strong&gt;, Nginx.&lt;/td&gt;
&lt;td&gt;Windows &lt;strong&gt;IOCP&lt;/strong&gt; (nativamente), alguns &lt;em&gt;frameworks&lt;/em&gt; de servidor de alta performance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  O Caso do Node.js (libuv)
&lt;/h4&gt;

&lt;p&gt;A &lt;code&gt;libuv&lt;/code&gt; adota uma abordagem híbrida com base no sistema operacional:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js no Linux/macOS:&lt;/strong&gt; É predominantemente &lt;strong&gt;Reactor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js no Windows:&lt;/strong&gt; Utiliza o mecanismo nativo &lt;strong&gt;IOCP&lt;/strong&gt; (&lt;em&gt;I/O Completion Ports&lt;/em&gt;), que é a base para o Proactor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É por isso que o Node.js é frequentemente chamado de modelo &lt;strong&gt;Reactor + "pseudo-Proactor" via *Thread Pool&lt;/strong&gt;*.&lt;/p&gt;




&lt;p&gt;Analogia do Restaurante:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Padrão Reactor (O Event Loop do Node.js)&lt;/strong&gt; O garçom recebe o pedido (tarefa de E/S). Ele é notificado de que o bife está pronto para ser cortado/finalizado. A Thread Principal (ou uma thread do Thread Pool) executa os passos finais (corta o bife/processa a E/S) e o entrega.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PROACTOR&lt;/strong&gt;: O garçom (Thread Principal/Event Loop) recebe o pedido e o delega. Ele é notificado de que o bife está completamente pronto e já na bandeja. A Thread Principal simplesmente entrega o resultado (o sistema operacional fez todo o trabalho de E/S)&lt;/p&gt;

&lt;p&gt;Fila de Atendimento Telefônico (Call Center):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Padrão Reactor (O Event Loop do Node.js)&lt;/strong&gt;&lt;br&gt;
O Atendente (Reactor/Event Loop): É a única thread de execução. Ele tem fones de ouvido que monitoram 100 linhas (sockets) de uma vez.&lt;/p&gt;

&lt;p&gt;O Trabalho do OS/Desmultiplexador: Quando a Linha 5 e a Linha 12 ficam prontas (alguém começou a falar/dados prontos), o sistema notifica o atendente.&lt;/p&gt;

&lt;p&gt;Ação da Aplicação: O atendente para de monitorar momentaneamente e ouve a Linha 5 (lê os dados), processa o pedido rapidamente e desliga (executa o callback). O atendente não fica esperando na linha 5; ele só reage quando a linha está pronta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Padrão Proactor&lt;/strong&gt;&lt;br&gt;
O Cliente (Aplicação): O cliente diz ao sistema telefônico: "Quando esta pessoa terminar de me dar todas as 5 informações que preciso, ligue-me de volta."&lt;/p&gt;

&lt;p&gt;O Trabalho do OS/Sistema: O sistema (em segundo plano, com suas próprias threads) completa toda a interação (pega as 5 informações) e só então notifica a aplicação principal.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Ação da Aplicação: A aplicação principal recebe uma notificação de conclusão que já contém todas as 5 informações.
&lt;/h2&gt;

&lt;p&gt;REACTOR: "Avise-me quando puder fazer o trabalho." (Ênfase na prontidão.)&lt;/p&gt;

&lt;p&gt;PROACTOR: "Avise-me quando o trabalho estiver concluído." (Ênfase na conclusão.)&lt;/p&gt;

&lt;h3&gt;
  
  
  As Fases do Event Loop do Node.js
&lt;/h3&gt;

&lt;p&gt;O Event Loop divide seu ciclo de execução em fases, girando sobre o modelo Reactor para distribuir eventos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Timers:&lt;/strong&gt; Execução de &lt;em&gt;callbacks&lt;/em&gt; de &lt;code&gt;setTimeout&lt;/code&gt; e &lt;code&gt;setInterval&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Pending Callbacks:&lt;/strong&gt; Execução de &lt;em&gt;callbacks&lt;/em&gt; de operações internas pós-E/S.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Idle, Prepare:&lt;/strong&gt; Uso interno da &lt;code&gt;libuv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Poll (Sonda):&lt;/strong&gt; &lt;strong&gt;Esta é a fase onde o Reactor realmente acontece.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;libuv&lt;/code&gt; chama o Desmultiplexador de Eventos (ex: &lt;code&gt;epoll_wait()&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Ele espera que &lt;em&gt;sockets&lt;/em&gt; fiquem prontos (&lt;code&gt;read-ready&lt;/code&gt; / &lt;code&gt;write-ready&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Ao ser notificado, ele acorda e despacha os eventos para os &lt;em&gt;handlers&lt;/em&gt; registrados.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Check:&lt;/strong&gt; Execução de &lt;em&gt;callbacks&lt;/em&gt; de &lt;code&gt;setImmediate&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Close Callbacks:&lt;/strong&gt; Execução de &lt;em&gt;callbacks&lt;/em&gt; de fechamento (ex: &lt;code&gt;socket.on('close')&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusão:&lt;/strong&gt; O ciclo inteiro é o &lt;strong&gt;Reactor&lt;/strong&gt; (o despachante) rodando e distribuindo eventos. Mas a fase &lt;strong&gt;Poll&lt;/strong&gt; é a parte que implementa o &lt;strong&gt;Desmultiplexador de Eventos Síncrono&lt;/strong&gt; (a espera pela prontidão da E/S) do Padrão Reactor.&lt;/p&gt;

&lt;p&gt;Em resumo, o sucesso do Node.js reside na adoção do padrão &lt;strong&gt;Reactor&lt;/strong&gt; (e uma implementação híbrida com o &lt;strong&gt;Proactor&lt;/strong&gt; em certas plataformas), garantindo que a &lt;em&gt;Thread&lt;/em&gt; Principal do JavaScript nunca bloqueie, permitindo uma escalabilidade enorme com baixo consumo de memória.&lt;/p&gt;




&lt;p&gt;Fontes para aprofundamento do conteúdo!&lt;br&gt;
&lt;a href="https://betterprogramming.pub/scalable-concurrency-meet-non-blocking-i-o-edb6b39c59d7" rel="noopener noreferrer"&gt;https://betterprogramming.pub/scalable-concurrency-meet-non-blocking-i-o-edb6b39c59d7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://subscription.packtpub.com/book/web-development/9781783287314/1/ch01lvl1sec09/the-reactor-pattern" rel="noopener noreferrer"&gt;https://subscription.packtpub.com/book/web-development/9781783287314/1/ch01lvl1sec09/the-reactor-pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://didawiki.cli.di.unipi.it/lib/exe/fetch.php/magistraleinformatica/tdp/tpd_reactor_proactor.pdf" rel="noopener noreferrer"&gt;http://didawiki.cli.di.unipi.it/lib/exe/fetch.php/magistraleinformatica/tdp/tpd_reactor_proactor.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://indico.cern.ch/event/282910/contributions/645355/attachments/521441/719267/efficient_parallel_IO_on_multicore_arch2.pdf" rel="noopener noreferrer"&gt;https://indico.cern.ch/event/282910/contributions/645355/attachments/521441/719267/efficient_parallel_IO_on_multicore_arch2.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/56739934/is-nodejs-representing-reactor-or-proactor-design-pattern" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/56739934/is-nodejs-representing-reactor-or-proactor-design-pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/9138294/what-is-the-difference-between-event-driven-model-and-reactor-pattern" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/9138294/what-is-the-difference-between-event-driven-model-and-reactor-pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/61163161/how-does-the-libuv-implementation-of-non-blockingness-work-exactly" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/61163161/how-does-the-libuv-implementation-of-non-blockingness-work-exactly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Reactor_pattern" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Reactor_pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Proactor_pattern" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Proactor_pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tusharf5.com/posts/node-design-patterns-reactor-pattern/" rel="noopener noreferrer"&gt;https://tusharf5.com/posts/node-design-patterns-reactor-pattern/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://progressivecoder.com/nodejs-reactor-pattern-event-loop/" rel="noopener noreferrer"&gt;https://progressivecoder.com/nodejs-reactor-pattern-event-loop/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@mohamed-khattab/demystifying-the-reactor-design-pattern-in-node-js-a8aabd73a315" rel="noopener noreferrer"&gt;https://medium.com/@mohamed-khattab/demystifying-the-reactor-design-pattern-in-node-js-a8aabd73a315&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Vm5l8zH4hOE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Vm5l8zH4hOE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.artima.com/articles/comparing-two-high-performance-io-design-patterns" rel="noopener noreferrer"&gt;https://www.artima.com/articles/comparing-two-high-performance-io-design-patterns&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>node</category>
      <category>javascript</category>
      <category>patterns</category>
    </item>
    <item>
      <title>Peculiaridades do JS. Que não são erros! Nem esquisitice! - conversão implícita de tipos</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Wed, 11 Oct 2023 16:14:21 +0000</pubDate>
      <link>https://dev.to/urielsouza29/peculiaridades-do-js-que-nao-sao-erros-nem-esquisitice-conversao-implicita-de-tipos-4n7c</link>
      <guid>https://dev.to/urielsouza29/peculiaridades-do-js-que-nao-sao-erros-nem-esquisitice-conversao-implicita-de-tipos-4n7c</guid>
      <description>&lt;p&gt;Todos nós javascripteiros sabemos que nossa linguagem &lt;br&gt;
tem conversão implícita de tipos. &lt;/p&gt;

&lt;p&gt;O que não sabemos, ou pelo menos eu não sabia é que &lt;br&gt;
antes da sua versão final ela não tinha. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mocha(JS) originalmente não tinha conversão implícita de tipo, mas os usuários solicitaram que Eich adicionasse isso a 1.0. Ele lamenta profundamente isso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;fonte do que estou dizendo &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?time_continue=2503&amp;amp;v=krB0enBeSiE&amp;amp;embeds_referring_euri=https%3A%2F%2Ftwitter.com%2F&amp;amp;source_ve_path=MjM4NTE&amp;amp;feature=emb_title"&gt;https://www.youtube.com/watch?time_continue=2503&amp;amp;v=krB0enBeSiE&amp;amp;embeds_referring_euri=https%3A%2F%2Ftwitter.com%2F&amp;amp;source_ve_path=MjM4NTE&amp;amp;feature=emb_title&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thenewstack.io/brendan-eich-on-creating-javascript-in-10-days-and-what-hed-do-differently-today/#:%7E:text=notorious"&gt;https://thenewstack.io/brendan-eich-on-creating-javascript-in-10-days-and-what-hed-do-differently-today/#:~:text=notorious&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se a conversão de tipo é uma coisa que você odeia! &lt;br&gt;
Saiba que foi um pedido da comunidade de usuários da época. &lt;/p&gt;

&lt;p&gt;Podemos aprender que o que os usuários/comunidade querem ou acham bom pode mudar com o tempo. &lt;/p&gt;

&lt;p&gt;Hoje ferramentas fazem sucesso, linguagens incorporam funcionalidades. Em alguns anos isso pode ser odiado.  &lt;/p&gt;

&lt;p&gt;O que é bom hoje pra uma linguagem ter pode não ser bom em 30 anos! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Egoless Crafting(criação sem ego) para software: os princípios</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Sat, 23 Sep 2023 14:05:13 +0000</pubDate>
      <link>https://dev.to/urielsouza29/egoless-craftingcriacao-sem-ego-para-sofwtare-os-principios-119j</link>
      <guid>https://dev.to/urielsouza29/egoless-craftingcriacao-sem-ego-para-sofwtare-os-principios-119j</guid>
      <description>&lt;p&gt;A catarse intelectual e afetiva consiste em livrar-se dos preconceitos e opiniões. &lt;/p&gt;

&lt;p&gt;Em 2009, o Software Craftsmanship Manifesto foi publicado como uma extensão do Manifesto Ágil , para corrigir o desvio de parte do movimento Ágil em reconhecer a importância da excelência técnica.&lt;/p&gt;

&lt;p&gt;Conheça seus príncipios!&lt;/p&gt;

&lt;h3&gt;
  
  
  1- Você não é suas práticas
&lt;/h3&gt;

&lt;p&gt;Nenhuma prática é perfeita e você tem que aceitar que alguém possa criticar as práticas que você usa. A crítica à sua prática não é uma crítica a si mesmo. Tenha em mente que as práticas evoluem, adaptam-se e eventualmente tornam-se obsoletas quando as suas limitações impedem a resposta aos desafios tecnológicos em constante mudança.&lt;/p&gt;

&lt;h3&gt;
  
  
  2 - Não seja um sobrevivente
&lt;/h3&gt;

&lt;p&gt;Só porque você aplicou com sucesso uma prática em uma experiência anterior, não significa que ela funcionará em todos os casos: o contexto é importante. Cada contexto é diferente, os parâmetros que garantiram este sucesso anterior podem não existir em todas as situações.&lt;/p&gt;

&lt;p&gt;Na maioria das vezes, esquecemos que as Pessoas são importantes no contexto e essa é a variável mais importante que você precisa considerar. Você deve identificar as dores contra as quais as pessoas estão lutando. Só então você poderá sugerir uma prática de acordo com seus benefícios em relação a essas dores. Você deve aceitar e reconhecer que cada equipe evolui em seu próprio ritmo, equilibrando obstáculos operacionais e curvas de aprendizado.&lt;/p&gt;

&lt;p&gt;O que salvou você pode não funcionar para os outros, então não force. Considere o fato de que você pode estar fazendo isso apenas para se convencer de que fez a escolha certa naquele momento.&lt;/p&gt;

&lt;h3&gt;
  
  
  3 - Desafie os resultados, não force a sua opinião
&lt;/h3&gt;

&lt;p&gt;Quando você é solicitado a revisar uma solução,** é tentador tentar moldá-la de acordo com sua preferência.** Sempre existem várias soluções para o mesmo problema. Não deixe que suas preferências pessoais tragam entropia improdutiva às discussões.&lt;/p&gt;

&lt;p&gt;Durante uma revisão, sempre que outra implementação vier à mente, tente se perguntar se ambas as soluções apresentam os mesmos benefícios. Caso contrário, comece por melhorar a primeira solução na sua lógica antes de propor uma implementação alternativa, sem esquecer de considerar as possíveis desvantagens.&lt;/p&gt;

&lt;p&gt;Repita o procedimento acima, substituindo “implementação” por “decisão” e “prática”.&lt;/p&gt;

&lt;h3&gt;
  
  
  4 - Software não se trata apenas de código
&lt;/h3&gt;

&lt;p&gt;Software bem elaborado é um valor apresentado no &lt;a href="http://www.yanaga.com.br/2011/12/manifesto-pelo-artesanato-de-software.html"&gt;Manifesto de Artesanato de Software&lt;/a&gt;. Infelizmente, alguns aspirantes a artesãos de software &lt;strong&gt;parecem se importar apenas com o código&lt;/strong&gt;. Isto se deve em parte ao fato de que as práticas mais populares na caixa de ferramentas de elaboração são centradas no código – por exemplo, Código Limpo, Desenvolvimento Orientado a Testes ou Katas.&lt;/p&gt;

&lt;p&gt;No entanto, código não é software. Ao escrever código, você apenas faz suposições sobre o que os usuários realmente precisam. Essas hipóteses são validadas (ou não) quando os usuários interagem com seu ambiente de produção: então a produção importa. A entrega frequente à produção é a única maneira de agregar valor de forma constante. Adotar uma prática como o &lt;strong&gt;Desenvolvimento Orientado a Testes terá um impacto muito limitado na qualidade do seu produto&lt;/strong&gt;, se você receber feedback sobre o que está construindo apenas uma ou duas vezes por ano.&lt;br&gt;
**&lt;br&gt;
Não somos pagos para criar software apenas por diversão. Nosso know-how técnico deve servir o negócio.** Portanto, construir parcerias produtivas com nossos especialistas em domínio é necessário para melhor atender às necessidades de nossos usuários: O Domínio Empresarial é importante .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Não é o conhecimento das partes interessadas, mas a ignorância dos desenvolvedores que é implantada na produção”. Alberto Brandolini&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5 - O software é produzido por uma organização, não por indivíduos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Existe uma falsa crença comum que afirma que os desenvolvedores produzem software, o que leva a uma espécie de Síndrome do Herói.&lt;/strong&gt; Conforme afirmado acima, as habilidades de desenvolvimento não são suficientes para construir software. É a sua organização multidisciplinar que produz software.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.cs.umd.edu/~basili/publications/proceedings/P125.pdf"&gt;A influência da estrutura organizacional na qualidade do software: um estudo de caso empírico&lt;/a&gt; (Nagappan, Murphy, Basili - 2008) demonstrou que a qualidade da estrutura organizacional era um melhor preditor de propensão a falhas do que as métricas tradicionais - como cobertura de código, complexidade de código ou Code Churn – no caso do Windows Vista.&lt;/p&gt;

&lt;p&gt;Não importa quão habilidoso você seja, a comunicação e a colaboração sempre terão um impacto maior no sistema projetado e você não pode projetar um sistema sozinho. Seja curioso e preste atenção e respeito aos demais atores envolvidos na construção do software: &lt;strong&gt;Design e Organização importam.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6 - Software Craftsmanship diz respeito a todos, não apenas aos artesãos
&lt;/h3&gt;

&lt;p&gt;Pode ser muito tentador ficar entre artesãos para evitar o trabalho de convencer. No entanto, esta filosofia gera uma auto-segregação e prende os artesãos numa bolha deletéria de meios que nunca são desafiados.&lt;/p&gt;

&lt;p&gt;A caixa de ferramentas de elaboração rapidamente se tornará obsoleta sem ser questionada por visões externas e sem se beneficiar da experiência complementar de toda a comunidade de profissionais de software. A sua capacidade de responder a novos desafios será bastante limitada.&lt;/p&gt;

&lt;p&gt;É também por isso que o manifesto tem como subtítulo a elevação da fasquia: o objetivo é ajudar toda a comunidade profissional. Ao ajudar, aprendemos e descobrimos contextos que fogem às nossas formas comuns e diferentes de pensar.&lt;/p&gt;

&lt;p&gt;Ao trabalhar com pessoas de fora do movimento, tenha em mente que nunca se deve vender uma prática como uma injunção de meios, mas sempre convencer pelos benefícios que esta prática traz. Em outras palavras, se você “vender” o Domain-Driven Design explicando que é o melhor método no mercado para modelar um domínio de negócios, então você o está “vendendo” mal.&lt;/p&gt;

&lt;p&gt;As pessoas tentam fazer o seu melhor em contextos onde são pressionadas a chegar a um acordo pelas autoridades locais. Portanto, não julgue as deficiências do que foi feito. Identifique as reais dores dessas pessoas e veja como você pode ajudá-las. No entanto, lembre-se de que você deve fornecer ajuda, nunca infligir ajuda .&lt;/p&gt;

&lt;h3&gt;
  
  
  7 - Não carregue a carga(alusão ao culto a carga)
&lt;/h3&gt;

&lt;p&gt;Só porque você reproduz as práticas, ferramentas e processos de outra pessoa não significa que alcançará o mesmo sucesso. Como mencionado acima, o contexto é importante. Essa pessoa “outra pessoa” pode ter meios, restrições ou facilitadores que você não tem.&lt;/p&gt;

&lt;p&gt;Cuidado, sua atividade não é igual à das grandes empresas de TI. S*&lt;em&gt;ó porque o Google usa o Kubernetes não significa que você precisa do Kubernetes&lt;/em&gt;* e que ele atenderá às suas necessidades.&lt;/p&gt;

&lt;p&gt;Sempre analise o espaço do problema e defina suas necessidades antes de pensar em uma solução. &lt;strong&gt;Não deixe que o hype e as figuras de autoridade lhe ditem o que fazer&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  8 -O treinador de Usain Bolt não corre mais rápido que Usain Bolt
&lt;/h3&gt;

&lt;p&gt;Ter mais experiência ou ser coach não faz de você um desenvolvedor melhor do que as pessoas que você ajuda. Você aprenderá coisas com seus pupilos, e eles podem até ser melhores do que você em alguns aspectos. E tudo bem: ninguém espera que você seja o melhor em tudo. Você deve permitir que os outros expressem seu potencial e ajudá-los a fazê-lo.&lt;/p&gt;

&lt;p&gt;Não use sua autoridade para impor sua opinião. Software Craftsmanship é uma comunidade de realizadores. Não construa para si uma torre de marfim da qual lançará seu conhecimento “acima do solo” em relação à realidade da área. Da mesma forma, tome cuidado com os pregadores em sua própria torre. Lidere pelo exemplo e pela ação, organize sessões de programação em pares ou mob com pessoas onde você interage durante a construção do software.&lt;/p&gt;

&lt;p&gt;Respeite e trate os outros como iguais seja qual for o seu nível para que a transmissão do conhecimento possa ser feita de acordo com uma abordagem horizontal, evite a abordagem vertical que tem a infeliz tendência de criar cultos. Ouvir e humildade são essenciais para construir uma parceria produtiva e de confiança. Desenvolvimento de software é trabalho em equipe.&lt;/p&gt;

&lt;h3&gt;
  
  
  9 - Ferramentas e práticas não são uma garantia
&lt;/h3&gt;

&lt;p&gt;Software Craftsmanship é escolher a melhor ferramenta para a situação certa. A desvantagem de ferramentas poderosas é que você acaba pensando que elas são suficientes para garantir o sucesso. Ferramentas e práticas recomendadas são modelos criados para melhor atender a um caso de uso específico. Às vezes, esses modelos podem ser aplicados com sucesso a novos casos de uso para os quais não foram originalmente pensados, com algumas adaptações.&lt;/p&gt;

&lt;p&gt;Mas todos os modelos têm os seus limites: nunca serão adequados para todas as situações existentes e nem sempre serão igualmente eficazes. Não existe Bala de Prata . Além disso, os limites e eficiências de cada uma das nossas ferramentas são apenas muito mal documentados cientificamente (através de estudos rigorosos).&lt;/p&gt;

&lt;p&gt;É por isso que é preciso saber deixar espaço para a experimentação de novas ferramentas, sejam elas “aprovadas pelo Craft” ou não. Mais uma vez, é mais importante concentrar-se nos resultados das práticas implementadas do que nos meios. Esta é a única maneira de inovar .&lt;/p&gt;

&lt;p&gt;Tenha em mente que não há menção a nenhuma ferramenta como Desenvolvimento Orientado a Testes ou Kata no Manifesto de Artesanato de Software. Usá-los não fará de você um artesão, assim como não usá-los não desqualifica alguém de ser um artesão.&lt;/p&gt;

&lt;h3&gt;
  
  
  10 - Não seja um crente, a dúvida impulsiona a melhoria
&lt;/h3&gt;

&lt;p&gt;Quando alguém é convencido pelos méritos de um movimento, facilmente se transforma em evangelista. Mas esta postura pode rapidamente tornar-se uma prisão de crença, mantendo a sua própria escalada de compromisso com o movimento ao embarcar toda uma estrutura rumo a um fracasso programado, ao mesmo tempo que cria exclusão à sua volta.&lt;/p&gt;

&lt;p&gt;No entanto, uma crença firme em algo é muitas vezes vista como um ponto forte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando alguém acredita firmemente que o artesanato envolve ferramentas, ele cria fantoches.&lt;/li&gt;
&lt;li&gt;Quando alguém acredita firmemente que o artesanato tem tudo a ver com meios, isso gera cultos à Carga.&lt;/li&gt;
&lt;li&gt;Quando alguém acredita firmemente que elaborar tem a ver com gols, cai na obsessão por marcar.&lt;/li&gt;
&lt;li&gt;E quando alguém acredita firmemente que o artesanato é uma paixão, torna-se um guardião.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O dogmatismo é um veneno que trata a dúvida como uma fraqueza. Mas a dúvida é na verdade um vetor de melhoria, através do questionamento. &lt;strong&gt;O questionamento sempre terá um resultado positivo:&lt;/strong&gt; seja destacando um ponto fraco de uma prática que poderia ser melhorado, seja melhorando a compreensão de quem expressa a dúvida. A dúvida é um pilar disruptivo fundamental do pensamento científico.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concluindo o artesanato sem ego
&lt;/h3&gt;

&lt;p&gt;Egoless Crafting tenta reorientar o Software Craftsmanship, não em práticas, ferramentas ou código, mas em comportamentos humanos. Devem refletir os valores do manifesto. Ou seja, a Cultura importa e é a única forma de corrigir os excessos que hoje podemos presenciar #egolesscrafting.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A cultura come a estratégia no café da manhã.” Peter Drucker&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Original &amp;gt; &lt;a href="https://egolesscrafting.org/"&gt;https://egolesscrafting.org/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>O objeto Atomics do JS uma introdução, multithreading e memória!</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Sat, 15 Jul 2023 14:35:43 +0000</pubDate>
      <link>https://dev.to/urielsouza29/o-objeto-atomics-do-js-uma-introducao-5d17</link>
      <guid>https://dev.to/urielsouza29/o-objeto-atomics-do-js-uma-introducao-5d17</guid>
      <description>&lt;p&gt;Nosso querido JavaScript é single threaded(como todos sempre pensamos, embora isso não esteja na especificação da linguagem JS). &lt;br&gt;
Java Script só pode executar uma coisa por ve sendo single threaded, guarde isso, isso é importante! &lt;/p&gt;

&lt;p&gt;Portanto, se uma tarefa de execução longa bloquear o encadeamento principal do navegador, o navegador terá dificuldade para renderizar.&lt;/p&gt;

&lt;p&gt;Por exemplo, se fôssemos percorrer e executar operações em uma grande estrutura de dados, &lt;br&gt;
ou criar um loop simples muito grande. &lt;br&gt;
Isso poderia fazer com que a renderização congelasse. Enquanto o loop não terminasse, ou enquanto o algoritmo estivesse percorrendo a grande estrutura de dados, não da pra fazer nada, apenas olhar e esperar. &lt;/p&gt;

&lt;p&gt;Esse é um problema de single threaded. &lt;br&gt;
Só da pra fazer uma coisa por vez e se ela toma muito tempo, não da pra fazer mais nada!&lt;/p&gt;

&lt;p&gt;Não iremos falar sobre callbacks e promises neste texto. &lt;/p&gt;

&lt;p&gt;Uma das soluções para esse problema é usar Web Workers. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Web Workers são mecanismos que permitem que uma operação de um dado script seja executado em uma thread diferente da thread principal da aplicação Web. Permitindo que cálculos laboriosos sejam processados sem que ocorra bloqueio da thread principal (geralmente associado à interface).&lt;br&gt;
Fonte &amp;gt; mdn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sabemos que js é single threaded. &lt;br&gt;
Com o tempo as aplicações no navegador estavam ficando cada vez mais exigentes. &lt;br&gt;
Então resolveram trazer os web Workers para nos ajudar! &lt;/p&gt;

&lt;p&gt;Agora aquele loop gigante pode ir pra outro thread e deixa nossa tela principal linda e leve sem ninguém atrapalhar! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Os Web Workers permitem a execução paralela no contexto do navegador.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No entanto como tudo em tecnologia, os Web Workers têm suas desvantagens; por exemplo, há um custo de transferência de dados de e para o thread Worker. Toda transferência é feita via postMessage. &lt;/p&gt;

&lt;p&gt;O que é postMessage: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" rel="noopener noreferrer" class="c-link"&gt;
          Window: postMessage() method - Web APIs | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The window.postMessage() method safely enables
  cross-origin communication between Window objects; e.g., between
  a page and a pop-up that it spawned, or between a page and an iframe embedded within it.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;O navegador usa o algoritmo structured clone&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm" rel="noopener noreferrer" class="c-link"&gt;
          The structured clone algorithm - Web APIs | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The structured clone algorithm copies complex JavaScript objects.
  It is used internally when invoking structuredClone(), to transfer data between Workers via postMessage(), storing objects with IndexedDB, or copying objects for other APIs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Para duplicar um objeto, ou seja duplicação dos mesmos dados na memoria. Esse custo, dependendo das circunstâncias, pode superar o benefício da transferência para o thread Worker. &lt;/p&gt;

&lt;p&gt;Você também pode transferir array Buffer! &lt;/p&gt;

&lt;p&gt;O que é array Buffer: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer" rel="noopener noreferrer" class="c-link"&gt;
          ArrayBuffer - JavaScript | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          O objeto ArrayBuffer é um tipo de dado usado para representar um genérico, buffer de dados binários de tamanho fixo. Você não pode manipular diretamente os conteúdos de um ArrayBuffer; em vez disso, você cria um objeto ArrayBufferView que representa o buffer em um formato específico, e usa para ler e escrever os conteúdos do buffer.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Mas temos o problema, assim que for transferido o main perde ele. &lt;br&gt;
É melhor que postMessage sim.&lt;/p&gt;

&lt;p&gt;Arraybuffer objeto transferivel: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects" rel="noopener noreferrer" class="c-link"&gt;
          Transferable objects - Web APIs | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Transferable objects are objects that own resources that can be transferred from one context to another, ensuring that the resources are only available in one context at a time.
  Following a transfer, the original object is no longer usable; it no longer points to the transferred resource, and any attempt to read or write the object will throw an exception.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Mas nosso foco não é array buffer também! &lt;/p&gt;

&lt;p&gt;Você tem uma outra opção que é a Broadcast Channel API&lt;/p&gt;

&lt;p&gt;O que é Broadcast Channel API: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API" rel="noopener noreferrer" class="c-link"&gt;
          Broadcast Channel API - Web APIs | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The Broadcast Channel API allows basic communication between browsing contexts (that is, windows, tabs, frames, or iframes) and workers on the same origin.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Mas ela tem o mesmo problema de mensagens! &lt;br&gt;
E usa o mesmo algoritmo de clone o structured clone e claro usa PostMessage! &lt;/p&gt;

&lt;p&gt;E se pudéssemos evitar a cópia ou transferência de dados?&lt;br&gt;
Uma maneira de contornar esses problemas é aproveitar &lt;strong&gt;SharedArrayBuffer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A partir daqui podemos afirmar que JavaScript não é mais single threaded por padrão! &lt;/p&gt;

&lt;p&gt;Web workers não fazem parte do javascript em si. Não estão na especificação da linguagem. &lt;br&gt;
Mas estão em outras especificações(que não vem ao caso agora)&lt;/p&gt;

&lt;p&gt;Para desenvolvedores de JavaScript, essa construção nos permite criar pedaços de memoria compartilhada. Em vez de copiar os dados do thread principal para o Worker e vice-versa, podemos atualizar a mesma memória compartilhada de ambos os lados.&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="c1"&gt;// &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="c1"&gt;// Criando o tamanho do nosso buffer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BYTES_PER_ELEMENT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="c1"&gt;// Criando o buffer com 10 inteiros &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sharedBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SharedArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&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;sharedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;O que é Int32Array: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array" rel="noopener noreferrer" class="c-link"&gt;
          Int32Array - JavaScript | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The Int32Array typed array represents an array of twos-complement 32-bit signed integers in the platform byte order. If control over byte order is needed, use DataView instead. The contents are initialized to 0. Once established, you can reference elements in the array using the object's methods, or using standard array index syntax (that is, using bracket notation).
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;O que é sharedarraybuffer: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developers.google.com/search/blog/2021/03/sharedarraybuffer-notes?hl=pt-br" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--pdz5zK_w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developers.google.com/static/search/blog/images/social-share-blog.png%3Fhl%3Dpt-br" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developers.google.com/search/blog/2021/03/sharedarraybuffer-notes?hl=pt-br" rel="noopener noreferrer" class="c-link"&gt;
          Esclarecimentos sobre a mensagem do objeto SharedArrayBuffer  |  Blog da Central da Pesquisa Google  |  Google for Developers
        &lt;/a&gt;
      &lt;/h2&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--7hcH5Fcg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.gstatic.com/devrel-devsite/prod/v47124a092dd56bf2680cfca4b2ab69e9e6a534f056a1a0dbc4abcaa7cdbba977/developers/images/favicon-new.png" width="24" height="24"&gt;
        developers.google.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Agora temos um pedaço de memória que pode ser compartilhado. Ou seja, o thread principal e os web workers podem acessar esse mesmo local juntos! &lt;/p&gt;

&lt;p&gt;Isso é muito bom, economiza memória! &lt;br&gt;
Mas como tudo em tecnologia, tem desvantagens!&lt;/p&gt;

&lt;p&gt;Imagina o seguinte: Temos 3 ou mais Web Workers além do thread principal acessando um mesmo local de memória. Isso vai dar errado. &lt;br&gt;
Muito errado. Podemos ter uma condição de corrida. Todos disputando o mesmo lugar ou termos um problema de atualizar 2 vezes o mesmo lugar com as mesmas informações. &lt;br&gt;
Ou seja 2 workers podem fazer o mesmo trabalho ao mesmo tempo e isso é desperdício. &lt;/p&gt;

&lt;p&gt;O que é condição de corrida: &lt;/p&gt;
&lt;div class="ltag__wikipedia--container"&gt;
  &lt;div class="ltag__wikipedia--header"&gt;
    &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Y-xY3vU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/wikipedia-logo-0a3e76624c7b1c3ccdeb9493ea4add6ef5bd82d7e88d102d5ddfd7c981efa2e7.svg" class="ltag__wikipedia--logo" alt="Wikipedia Logo" width="128" height="128"&gt;
    &lt;a href="https://en.wikipedia.org/wiki/Race_condition" rel="noopener noreferrer"&gt;Race condition&lt;/a&gt;
  &lt;/div&gt;
  &lt;div class="ltag__wikipedia--extract"&gt;&lt;p&gt;A &lt;b&gt;race condition&lt;/b&gt; or &lt;b&gt;race hazard&lt;/b&gt; is the condition of an electronics, software, or other system where the system's substantive behavior is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when one or more of the possible behaviors is undesirable.&lt;/p&gt;&lt;/div&gt;
  &lt;div class="ltag__wikipedia--btn--container"&gt;
    
      &lt;a href="https://en.wikipedia.org/wiki/Race_condition" rel="noopener noreferrer"&gt;View on Wikipedia&lt;/a&gt;
    
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Então criaram o objeto Atomics. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As operações atômicas garantem que tenhamos uma maneira padronizada de ler e gravar dados em uma ordem previsível&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Atomics gerencia o acesso de todo mundo ao pedaço de memória, assim impedindo condições de corrida, trabalhos desperdiçado, etc. &lt;/p&gt;

&lt;p&gt;O que é Atomics: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHjFdr30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/mdn-social-share.cd6c4a5a.png" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" rel="noopener noreferrer" class="c-link"&gt;
          Atomics - JavaScript | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The Atomics namespace object contains static methods for carrying out atomic operations. They are used with SharedArrayBuffer and ArrayBuffer objects.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_bI64N_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.mozilla.org/favicon-48x48.cbbd161b.png" width="48" height="48"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;worker.js&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;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&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;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BYTES_PER_ELEMENT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;length&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;sharedBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SharedArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&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;sharedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedBuffer&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Acessando o dados no worker&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="c1"&gt;// worker.js&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&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="nx"&gt;event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sharedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&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;arrayValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`The item at array index &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;arrayValue&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;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;


&lt;p&gt;E se quiséssemos atualizar a matriz do trabalhador? Temos duas opções para essas atualizações usando o Atomics. Podemos usar storeo que vimos antes, ou podemos usar exchange. A diferença aqui é que storeretorna o valor que é armazenado e exchangeretorna o valor que é substituído. Vamos ver como isso funciona na prática:&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="c1"&gt;// worker.js&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&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="nx"&gt;event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sharedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&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;storedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`The item at array index &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is now &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;storedValue&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="k"&gt;else&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;exchangedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exchange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`The item at array index &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; was &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;exchangedValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, now 2`&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Agora podemos ler e atualizar a matriz do thread principal e do thread de trabalho. Atomics tem alguns outros métodos que podemos usar a nosso favor para gerenciar nossos novos arrays compartilhados. Dois dos métodos mais úteis são waite wake. waitnos permite esperar uma mudança em um índice de array e então continuar com as operações. Na prática, isso pode parecer algo assim no lado do trabalhador:&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="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&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="nx"&gt;event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sharedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Int32Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayIndex&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedStoredValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// An optional 4th argument can be passed which is a timeout&lt;/span&gt;
    &lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arrayIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expectedStoredValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Log the new value&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arrayIndex&lt;/span&gt;&lt;span class="p"&gt;));&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Aqui estamos esperando uma alteração em arrayIndex0, onde o valor armazenado esperado é 50. Então, podemos dizer a ele para acordar do thread principal quando alterarmos o valor no índice:&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;newArrayValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newArrayValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// The index that is being waited on&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayIndex&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="c1"&gt;// The first agent waiting on the value&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queuePos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;Atomics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arrayIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queuePos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Outras funções são fornecidas por conveniência, como adde subque adicionam ou subtraem do índice da matriz, respectivamente. Se você estiver interessado em operações bit a bit , algumas delas são fornecidas, incluindo or, ande xor.&lt;/p&gt;

&lt;p&gt;Podemos ver que atomics podemos evitar condições de corrida e fazer atualizações previsíveis em um array usando os métodos de Atomics. &lt;/p&gt;

&lt;p&gt;Para usar strings, precisamos convertê-las em uma representação numérica, por exemplo, um padrão conhecido para codificação como UTF-16.&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;function&lt;/span&gt; &lt;span class="nx"&gt;sharedArrayBufferToUtf16String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&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;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Uint16Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromCharCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;utf16StringToSharedArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 2 bytes for each char&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&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;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SharedArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bytes&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;arrayBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Uint16Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;strLen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;strLen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="p"&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;exampleString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world, this is an example string!&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;sharedArrayBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;utf16StringToSharedArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exampleString&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;buffer&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;backToString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sharedArrayBufferToUtf16String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sharedArrayBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Todos os códigos são retirados deste texto: &lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--BOoiL_s1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://media.sitepen.com/blog-images/2018/09/SharedArrayBuffers.jpg" height="420" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics" rel="noopener noreferrer" class="c-link"&gt;
          The Return of SharedArrayBuffers and Atomics - SitePen
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          See how we leverage SharedArrayBuffers to share memory between various thread contexts while avoiding race conditions using the Atomics methods.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--oitXKejF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.sitepen.com/favicon.15vi9UaB.png" width="512" height="512"&gt;
        sitepen.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Fiz uma pequena introdução ao objeto Atomics&lt;br&gt;
lembrando que tudo isso *&lt;em&gt;funciona no Node também! *&lt;/em&gt;&lt;br&gt;
Se você quiser saber mais basta ler as fontes: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics"&gt;https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/feezyhendrix/worker-threads-in-node-js-2ikh"&gt;https://dev.to/feezyhendrix/worker-threads-in-node-js-2ikh&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://exploringjs.com/es2016-es2017/ch_shared-array-buffer.html"&gt;https://exploringjs.com/es2016-es2017/ch_shared-array-buffer.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogtitle.github.io/using-javascript-sharedarraybuffers-and-atomics/"&gt;https://blogtitle.github.io/using-javascript-sharedarraybuffers-and-atomics/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.logrocket.com/understanding-sharedarraybuffer-and-cross-origin-isolation/"&gt;https://blog.logrocket.com/understanding-sharedarraybuffer-and-cross-origin-isolation/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tutorialspoint.com/what-is-the-use-of-atomics-in-javascript"&gt;https://www.tutorialspoint.com/what-is-the-use-of-atomics-in-javascript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webreflection.medium.com/about-sharedarraybuffer-atomics-87f97ddfc098"&gt;https://webreflection.medium.com/about-sharedarraybuffer-atomics-87f97ddfc098&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/atomics-in-javascript/"&gt;https://www.geeksforgeeks.org/atomics-in-javascript/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=2w7Ewkpftd4"&gt;https://www.youtube.com/watch?v=2w7Ewkpftd4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Actor Model, modelo do ator em programação! Você conhece?</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Tue, 20 Jun 2023 16:18:57 +0000</pubDate>
      <link>https://dev.to/urielsouza29/o-modelo-do-ator-em-programacao-voce-conhece-34n9</link>
      <guid>https://dev.to/urielsouza29/o-modelo-do-ator-em-programacao-voce-conhece-34n9</guid>
      <description>&lt;p&gt;O Actor Model é um modelo matemático para sistemas concorrentes em ciência da computação. Ou em outras palavras: o modelo de ator fornece regras e primitivas para lidar com o &lt;strong&gt;paralelismo&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Actor Model é um modelo conceitual de computação concorrente, &lt;strong&gt;surgiu em 1973&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As regras, que normalmente são impostas pela linguagem ERLANG, são as seguintes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tudo (não primitivo) é um ator&lt;/li&gt;
&lt;li&gt;Um ator tem estado local (“variáveis”)&lt;/li&gt;
&lt;li&gt;Um ator é uma entidade computacional (“processo”) que executa sequencialmente (“single-threaded”)&lt;/li&gt;
&lt;li&gt;Um ator tem um endereço (no sentido de caixa de correio, não de memória)&lt;/li&gt;
&lt;li&gt;Um ator pode receber mensagens e reagir a elas por:

&lt;ul&gt;
&lt;li&gt;Mutando seu estado local&lt;/li&gt;
&lt;li&gt;Criando novos atores&lt;/li&gt;
&lt;li&gt;Envio de mensagens para outros atores de forma assíncrona usando seus endereços&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Embora cada ator seja executado sequencialmente, ou seja, apenas uma mensagem é processada por um ator por vez, dois atores podem muito bem ser executados em paralelo.&lt;/p&gt;

&lt;p&gt;As implementações mais famosas para o Actor Model são Akka &amp;amp; Erlang. Falaramos mais de Erlang. &lt;/p&gt;

&lt;p&gt;Os atores são leves e é muito fácil criar milhões deles, pois consomem menos recursos do que os Threads. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O estado privado do ator só pode ser alterado pelo processamento de uma mensagem, ele pode manipular apenas uma mensagem por vez e eles funcionam de forma assíncrona, isso significa que um ator nunca espera por uma resposta de outro ator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No cenário distribuído, é possível que os Atores estejam em máquinas diferentes, portanto, eles se comunicam com endereços com mensagens, um endereço pode ser um endereço local ou um endereço remoto.&lt;/p&gt;

&lt;p&gt;A linguagem Erlang, construída por Joe Armstrong na Ericson, ainda é usada hoje para sistemas extremamente escaláveis e tolerantes a falhas. &lt;/p&gt;

&lt;p&gt;Por exemplo, os backbones de sua conexão LTE são escritos em Erlang e também são usados para produtos como WhatsApp ou usados ​​por empresas como Facebook e Amazon.&lt;/p&gt;

&lt;p&gt;Actor Model não precisa de nenhuma primitiva de sincronização como mutexes ou semáforos. Nenhum ator pode modificar o estado local de outro ator e cada ator em si é *&lt;em&gt;single-threaded. *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Qualquer recurso exigido por vários atores deve ter seu próprio ator designado que gerencia o acesso a esse recurso. Todos os outros atores podem solicitar operações a serem executadas enviando uma mensagem ao ator gestor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Um ator é a unidade primitiva de computação. É aquilo que recebe uma mensagem e faz algum tipo de cálculo com base nela."&lt;br&gt;&lt;br&gt;
Basicamente como Alan Kays definia OOP. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A ideia é muito parecida com a que temos nas linguagens orientadas a objetos: um objeto recebe uma mensagem (uma chamada de método) e faz algo dependendo de qual mensagem ele recebe (qual método estamos chamando).&lt;/p&gt;

&lt;p&gt;A principal diferença é que os &lt;strong&gt;atores estão completamente isolados **uns dos outros e **nunca compartilharão a memória&lt;/strong&gt;. Também vale a pena notar que um ator pode manter um estado privado que nunca pode ser alterado diretamente por outro ator.&lt;/p&gt;

&lt;p&gt;Uma diferença importante entre passar mensagens e chamar métodos é que as mensagens não têm valor de retorno. Ao enviar uma mensagem, um ator delega trabalho a outro ator, se esperasse um valor de retorno, o ator remetente precisaria bloquear ou executar o trabalho do outro ator no mesmo thread. Em vez disso, o ator receptor entrega os resultados em uma mensagem de resposta.&lt;/p&gt;

&lt;p&gt;Os atores reagem às mensagens da mesma forma que os objetos “reagem” aos métodos invocados neles. A diferença é que, em vez de vários encadeamentos “projetando” em nosso ator e causando estragos no estado interno e invariantes, os atores executam independentemente dos remetentes de uma mensagem e reagem às mensagens recebidas sequencialmente, uma de cada vez. Enquanto cada ator processa as mensagens enviadas a ele sequencialmente, diferentes atores trabalham simultaneamente uns com os outros para que um sistema de ator possa processar tantas mensagens simultaneamente quantas o hardware suportar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No modelo de ator tudo é um ator e eles precisam ter endereços para que um ator possa enviar uma mensagem para outro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Atores têm &lt;strong&gt;caixas de correio&lt;/strong&gt;&lt;br&gt;
É importante entender que, embora vários atores possam ser executados ao mesmo tempo, um ator processará uma determinada mensagem sequencialmente. &lt;strong&gt;Isso significa que se você enviar 3 mensagens para o mesmo ator, ele executará apenas uma de cada vez&lt;/strong&gt;. Para que essas 3 mensagens sejam executadas simultaneamente, você precisa criar 3 atores e enviar uma mensagem para cada um.&lt;/p&gt;

&lt;p&gt;As mensagens são enviadas de forma assíncrona para um ator, que precisa armazená-las em algum lugar enquanto processa outra mensagem. &lt;strong&gt;A caixa de correio é o local onde essas mensagens são armazenadas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os atores se comunicam entre si enviando mensagens assíncronas. Essas mensagens são armazenadas nas caixas de correio de outros atores até serem processadas.&lt;/p&gt;

&lt;p&gt;O uso de passagem de mensagens evita travamentos e bloqueios.&lt;/p&gt;

&lt;p&gt;Em vez de chamar métodos(oop), os atores enviam mensagens uns aos outros. O envio de uma mensagem não transfere o thread de execução do remetente para o destino. Um ator pode enviar uma mensagem e continuar sem bloquear. Portanto, ele pode realizar mais na mesma quantidade de tempo.&lt;/p&gt;

&lt;p&gt;O que os atores fazem&lt;br&gt;
Quando um ator recebe uma mensagem, ele pode fazer uma destas 3 coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar mais atores&lt;/li&gt;
&lt;li&gt;Enviar mensagens para outros atores&lt;/li&gt;
&lt;li&gt;Designar o que fazer com a próxima mensagem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um ator pode manter um estado privado. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Designar o que fazer com a próxima mensagem” &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;significa basicamente definir como será esse estado para a próxima mensagem que receber. Ou, mais claramente, é como os atores mudam de estado.&lt;/p&gt;

&lt;p&gt;Vamos imaginar que temos um ator que se comporta como uma calculadora e que seu estado inicial é simplesmente o número 0. Quando este ator recebe a mensagem add(1), ao invés de mudar seu estado original, ele designa que para a próxima mensagem que receber, o estado será 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tolerância a erro
&lt;/h3&gt;

&lt;p&gt;Erlang introduziu a filosofia &lt;strong&gt;“deixe travar”. **A ideia é que você não precise programar defensivamente, tentando antecipar todos os possíveis problemas que podem acontecer e encontrar uma maneira de lidar com eles, **simplesmente porque não há como pensar em cada ponto de falha.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O que Erlang faz é simplesmente deixá-lo travar, mas fazer com que esse código crítico seja supervisionado por alguém cuja única responsabilidade seja saber o que fazer quando esse travamento acontecer(como redefinir essa unidade de código para um estado estável), e o que torna tudo isso possível é o modelo de ator.&lt;/p&gt;

&lt;p&gt;Todo código roda dentro de um process(é basicamente assim que Erlang chama seus atores). &lt;br&gt;
Isse process é completamente isolado, o que significa que seu estado não influenciará nenhum outro process. Temos um supervisor, que é basicamente outro process(tudo é ator, lembra?), que será avisado quando o supervisionado process travar e poderá fazer algo a respeito.&lt;/p&gt;

&lt;p&gt;Isso possibilita a criação de sistemas que se &lt;strong&gt;“autocuram”&lt;/strong&gt;, o que significa que se um ator chegar a um estado excepcional e travar, por qualquer motivo, um supervisor pode fazer algo a respeito para tentar colocá-lo em um estado consistente novamente (e há existem várias estratégias para fazer isso, sendo a mais comum apenas reiniciar o ator com seu estado inicial).&lt;/p&gt;

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

&lt;p&gt;Outro aspecto interessante do modelo de ator é que &lt;strong&gt;não importa se o ator para o qual estou enviando uma mensagem está sendo executado localmente ou em outro nó.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pense nisso, se um ator é apenas esta unidade de código com uma caixa de correio e um estado interno, e apenas responde a mensagens, quem se importa em qual máquina ele está realmente rodando? Contanto que possamos fazer a mensagem chegar lá, estamos bem.&lt;/p&gt;

&lt;p&gt;Isso nos permite criar sistemas que aproveitam vários computadores e nos ajudam a recuperar se um deles falhar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prós do modelo de ator
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fácil de escalar&lt;/li&gt;
&lt;li&gt;Tolerante a falhas&lt;/li&gt;
&lt;li&gt;Nenhum estado compartilhado&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Contras do modelo de ator
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A caixa de correio pode transbordar&lt;/li&gt;
&lt;li&gt;Suscetível a impasses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O Actor Model é bem conceituado e faz todo o sentido usar o Actor Model se alguém estiver projetando sistemas concorrentes. &lt;/p&gt;

&lt;p&gt;Fontes: &lt;br&gt;
&lt;a href="https://surma.dev/things/actormodel/"&gt;https://surma.dev/things/actormodel/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.brianstorti.com/the-actor-model/"&gt;https://www.brianstorti.com/the-actor-model/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Actor_model"&gt;https://en.wikipedia.org/wiki/Actor_model&lt;/a&gt;&lt;br&gt;
&lt;a href="https://eximia.co/reactive-messaging-patterns-with-the-actor-model/"&gt;https://eximia.co/reactive-messaging-patterns-with-the-actor-model/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@KtheAgent/actor-model-in-nutshell-d13c0f81c8c7"&gt;https://medium.com/@KtheAgent/actor-model-in-nutshell-d13c0f81c8c7&lt;/a&gt;&lt;br&gt;
&lt;a href="https://doc.akka.io/docs/akka/current/typed/guide/actors-intro.html"&gt;https://doc.akka.io/docs/akka/current/typed/guide/actors-intro.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://getakka.net/articles/intro/what-are-actors.html"&gt;https://getakka.net/articles/intro/what-are-actors.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://s3-sa-east-1.amazonaws.com/thedevconf/presentations/TDC2019SP/dotnet/UJJ-3987_2019-07-17T025204_Introdu%C3%A7%C3%A3o%20ao%20Actor%20Model%20com%20Microsoft%20Orleans.pdf"&gt;https://s3-sa-east-1.amazonaws.com/thedevconf/presentations/TDC2019SP/dotnet/UJJ-3987_2019-07-17T025204_Introdu%C3%A7%C3%A3o%20ao%20Actor%20Model%20com%20Microsoft%20Orleans.pdf&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>actor</category>
      <category>programming</category>
    </item>
    <item>
      <title>Escreva código que seja fácil de excluir e fácil de depurar também!</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Sun, 07 May 2023 12:53:31 +0000</pubDate>
      <link>https://dev.to/urielsouza29/escreva-codigo-que-seja-facil-de-excluir-e-facil-de-depurar-tambem-jpj</link>
      <guid>https://dev.to/urielsouza29/escreva-codigo-que-seja-facil-de-excluir-e-facil-de-depurar-tambem-jpj</guid>
      <description>&lt;p&gt;Código depuravel é um código que não é mais esperto que você. Alguns códigos são um pouco mais difíceis de depurar do que outros: código com comportamento oculto, tratamento de erros insatisfatório, ambiguidade, muito pouca ou muita estrutura ou código que está no meio de ser alterado. Em um projeto grande o suficiente, você eventualmente encontrará um código que não entende.&lt;/p&gt;

&lt;p&gt;Em um projeto antigo o suficiente, você descobrirá o código que esqueceu que escreveu - e se não fosse pelos logs de confirmação, você juraria que era outra pessoa. À medida que um projeto aumenta de tamanho, fica mais difícil lembrar o que cada parte do código faz, mais difícil ainda quando o código não faz o que deveria. Quando se trata de alterar o código que você não entende, você é forçado a aprender da maneira mais difícil: depuração.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escrever um código fácil de depurar começa com a percepção de que você não se lembrará de nada sobre o código posteriormente.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Regra 0&lt;/strong&gt;: Um bom código tem falhas óbvias.&lt;br&gt;
Muitos &lt;strong&gt;vendedores de metodologias&lt;/strong&gt; argumentaram que a maneira de escrever um código compreensível é escrever um código limpo. O problema é que “limpo” tem um &lt;strong&gt;significado altamente contextual&lt;/strong&gt;. O código limpo pode ser codificado em um sistema e, às vezes, um hack sujo pode ser escrito de uma maneira fácil de desativar. Às vezes, o código está limpo porque a sujeira foi enviada para outro lugar. &lt;strong&gt;Código bom não é necessariamente código limpo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O código estar &lt;strong&gt;limpo ou sujo tem mais a ver com quanto orgulho ou constrangimento o desenvolvedor sente no código&lt;/strong&gt;, &lt;em&gt;do que com a facilidade de mantê-lo ou alterá-lo&lt;/em&gt;. Em vez de limpo, &lt;strong&gt;queremos um código enfadonho&lt;/strong&gt; onde a mudança é óbvia — descobri que é mais fácil fazer com que as pessoas contribuam para uma base de código quando o fruto mais fácil foi deixado para outros coletarem. O melhor código pode ser qualquer coisa que você possa ver e aprender rapidamente.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Código que não tenta fazer um problema feio parecer bom, ou um problema chato parecer interessante.&lt;/li&gt;
&lt;li&gt;Código onde as falhas são óbvias e o comportamento é claro, em vez de código sem falhas óbvias e comportamentos sutis.&lt;/li&gt;
&lt;li&gt;Código que documenta onde fica aquém da perfeição, em vez de almejar ser perfeito.&lt;/li&gt;
&lt;li&gt;Código com comportamento &lt;strong&gt;tão óbvio&lt;/strong&gt; que qualquer desenvolvedor pode imaginar inúmeras maneiras diferentes de alterá-lo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Às vezes, o código é desagradável pra caralho, e qualquer tentativa de limpá-lo deixa você em um estado pior. Escrever um código limpo sem entender as consequências de suas ações também pode ser um ritual de convocação para um código sustentável.&lt;/p&gt;

&lt;p&gt;Isso não quer dizer que o código limpo seja ruim, mas às vezes a prática do código limpo é mais semelhante a varrer os problemas para debaixo do tapete. O** código depuravel não é necessariamente limpo**, e o código repleto de verificações ou tratamento de erros raramente torna a leitura agradável.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regra 1&lt;/strong&gt;: O computador está sempre pegando fogo.&lt;/p&gt;

&lt;p&gt;O computador está pegando fogo e o programa travou na última vez em que foi executado.&lt;/p&gt;

&lt;p&gt;A primeira coisa que um programa deve fazer é garantir que está começando de um estado conhecido, bom e seguro antes de tentar realizar qualquer trabalho. Às vezes, não há uma cópia limpa do estado porque o usuário a excluiu ou atualizou o computador. O programa travou na última vez que foi executado e, paradoxalmente, o programa também está sendo executado pela primeira vez.&lt;/p&gt;

&lt;p&gt;Por exemplo, ao ler e gravar o estado do programa em um arquivo, vários problemas podem ocorrer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O arquivo está faltando&lt;/li&gt;
&lt;li&gt;O arquivo está corrompido&lt;/li&gt;
&lt;li&gt;O arquivo é uma versão mais antiga ou mais recente&lt;/li&gt;
&lt;li&gt;A última alteração no arquivo está inacabada&lt;/li&gt;
&lt;li&gt;O sistema de arquivos estava mentindo para você&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estes não são problemas novos e os bancos de dados têm lidado com eles desde o início dos tempos (01/01/1970). Usar algo como o SQLite resolverá muitos desses problemas para você, mas se o programa travou na última vez em que foi executado, o código pode ser executado com os dados errados ou da maneira errada também.&lt;/p&gt;

&lt;p&gt;Com programas programados, por exemplo, você pode garantir que os seguintes acidentes ocorrerão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ele é executado duas vezes na mesma hora por causa do horário de verão.&lt;/li&gt;
&lt;li&gt;Ele é executado duas vezes porque um operador esqueceu que já havia sido executado.&lt;/li&gt;
&lt;li&gt;Ele perderá uma hora, devido à falta de disco na máquina ou a problemas misteriosos de rede na nuvem.&lt;/li&gt;
&lt;li&gt;Levará mais de uma hora para ser executado e pode atrasar chamadas subsequentes do programa.&lt;/li&gt;
&lt;li&gt;Será executado com a hora errada do dia&lt;/li&gt;
&lt;li&gt;Ele inevitavelmente será executado próximo a um limite, como meia-noite, final do mês, final do ano e falha devido a erro aritmético.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A criação de um software robusto começa com a criação de um software que assumiu que travou na última vez em que foi executado e trava sempre que não sabe a coisa certa a fazer. A melhor coisa sobre lançar uma exceção em vez de deixar um comentário como “Isso não deveria acontecer” é que, quando inevitavelmente acontecer, você terá uma vantagem inicial na depuração de seu código.&lt;/p&gt;

&lt;p&gt;Você também não precisa se recuperar desses problemas - basta deixar o programa desistir e não piorar as coisas. &lt;strong&gt;Pequenas verificações que geram uma exceção podem economizar semanas de rastreamento por meio de logs&lt;/strong&gt;, e um arquivo de bloqueio simples pode economizar horas de restauração do backup.&lt;/p&gt;

&lt;p&gt;O código fácil de depurar é o código que &lt;strong&gt;verifica se as coisas estão corretas antes de fazer o que foi solicitado&lt;/strong&gt;, o código que facilita voltar a um bom estado conhecido e tentar novamente e o código que possui camadas de defesa para forçar erros para emergir o mais cedo possível.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regra 2&lt;/strong&gt;: Seu programa está em guerra consigo mesmo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;_ Os maiores ataques DoS do Google vêm de nós mesmos - porque temos sistemas realmente grandes - embora de vez em quando alguém apareça e tente nos dar uma corrida pelo nosso dinheiro, mas na verdade somos mais capazes de nos martelar no chão do que qualquer um Mais é._&lt;br&gt;
&lt;em&gt;Isso vale para todos os sistemas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Astrid Atkinson, livro Engenharia para o Jogo Longo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O software sempre travou na última vez em que foi executado e agora está sempre sem CPU, sem memória e sem disco também. Todas as threads estão martelando uma fila vazia, todos estão tentando novamente uma solicitação com falha que expirou há muito tempo e todos os servidores pausaram para coleta de lixo ao mesmo tempo. Não apenas o sistema está quebrado, mas está constantemente tentando quebrar a si mesmo.&lt;/p&gt;

&lt;p&gt;Mesmo verificar se o sistema está realmente em execução pode ser bastante difícil.&lt;/p&gt;

&lt;p&gt;Pode ser muito fácil implementar algo que verifique se o servidor está em execução, mas não se está lidando com solicitações. A menos que você verifique o tempo de atividade, é possível que o programa falhe entre cada verificação. As verificações de integridade também podem desencadear bugs: c*&lt;em&gt;onsegui escrever verificações de integridade que travaram o sistema que deveria proteger. Em duas ocasiões distintas&lt;/em&gt;*, com três meses de diferença.&lt;/p&gt;

&lt;p&gt;Em software, escrever código para lidar com erros inevitavelmente levará à descoberta de mais erros para lidar, muitos deles causados ​​pelo próprio tratamento de erros. Da mesma forma, as otimizações de desempenho muitas vezes podem ser a causa de gargalos no sistema – criar um aplicativo agradável de usar em uma guia pode tornar um aplicativo difícil de usar quando você tem vinte cópias dele em execução.&lt;/p&gt;

&lt;p&gt;Outro exemplo é quando um trabalhador(thread) em um pipeline está executando muito rápido e esgotando a memória disponível antes que a próxima parte tenha a chance de alcançá-lo. Se preferir uma metáfora de carro: engarrafamentos. Acelerar é o que os cria e pode ser visto na maneira como o congestionamento se move para trás no trânsito. As otimizações podem criar sistemas que falham sob carga alta ou pesada, geralmente de maneiras misteriosas.&lt;/p&gt;

&lt;p&gt;Em outras palavras: quanto mais rápido você fizer isso, mais difícil será empurrado e, se você não permitir que seu sistema empurre para trás nem um pouco, não se surpreenda se ele quebrar.&lt;/p&gt;

&lt;p&gt;A contrapressão é uma forma de feedback dentro de um sistema, e um programa fácil de depurar é aquele em que o usuário está envolvido no loop de feedback, tendo uma visão de todos os comportamentos de um sistema, o acidental, o intencional, o desejado, e os indesejados também. O código depuravel é fácil de inspecionar, onde você pode observar e entender as mudanças que estão acontecendo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regra 3&lt;/strong&gt;: O que você não elimina a ambiguidade agora, você depura mais tarde.&lt;br&gt;
Em outras palavras: não deve ser difícil olhar para as variáveis ​​em seu programa e descobrir o que está acontecendo. Com ou sem algumas sub-rotinas de álgebra linear aterrorizantes, você deve se esforçar para representar o &lt;strong&gt;estado do seu programa da forma mais óbvia possível&lt;/strong&gt;. Isso significa coisas como não mudar de ideia sobre o que uma variável faz no meio de um programa, se houver &lt;strong&gt;um pecado capital óbvio, é usar uma única variável para dois propósitos diferentes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Também significa evitar cuidadosamente o problema do semipredicado, nunca usando um único valor ( count) para representar um par de valores ( boolean, count). Evitando coisas como retornar um número positivo para um resultado e retornar -1 quando nada corresponder. O motivo é que é fácil acabar na situação em que você deseja algo como "0, but true"(e notavelmente, o Perl 5 tem esse recurso exato) ou cria um código difícil de compor com outras partes do sistema ( -1 pode ser uma entrada válida para a próxima parte do programa, em vez de um erro).&lt;/p&gt;

&lt;p&gt;Juntamente com o** uso de uma única variável para dois propósitos, pode ser tão ruim quanto usar um par de variáveis ​​para um único propósito** — especialmente se forem booleanas. Não quero dizer que manter um par de números para armazenar um intervalo seja ruim, mas usar vários booleanos para indicar em que estado seu programa está geralmente é uma máquina de estado disfarçada.&lt;/p&gt;

&lt;p&gt;Quando o estado não flui de cima para baixo, dê ou tire o loop ocasional, é melhor dar ao estado uma variável própria e limpar a lógica. Se você tiver um conjunto de booleanos dentro de um objeto, substitua-o por uma variável chamada estado e use um enum (ou uma string se persistir em algum lugar). As instruções if acabam parecendo if state == name e param de parecer if bad_name &amp;amp;&amp;amp; !alternate_option.&lt;/p&gt;

&lt;p&gt;Mesmo quando você torna a máquina de estado explícita, ainda pode errar: às vezes o código tem duas máquinas de estado escondidas dentro. Tive grande dificuldade em escrever um proxy HTTP até tornar cada máquina de estado explícita, rastreando o estado da conexão e analisando o estado separadamente. Quando você mescla duas máquinas de estado em uma, pode ser difícil adicionar novos estados ou saber exatamente em que estado algo deve estar.&lt;/p&gt;

&lt;p&gt;Isso é muito mais sobre criar coisas que você não terá que depurar, do que tornar as coisas fáceis de depurar. Ao elaborar a lista de estados válidos, é muito mais fácil rejeitar os inválidos completamente, em vez de deixar acidentalmente um ou dois passarem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regra 4&lt;/strong&gt;: Comportamento acidental é um comportamento esperado.&lt;/p&gt;

&lt;p&gt;Quando você não tem certeza sobre o que uma estrutura de dados faz, os usuários preenchem as lacunas — qualquer comportamento do seu código, intencional ou acidental, acabará por ser considerado em outro lugar. Muitas linguagens de programação convencionais tinham tabelas de hash pelas quais você podia iterar, o que meio que preservava a ordem de inserção, na maioria das vezes.&lt;/p&gt;

&lt;p&gt;Algumas linguagens optaram por fazer a tabela hash se comportar como muitos usuários esperavam, iterando pelas chaves na ordem em que foram adicionadas, mas outras optaram por fazer a tabela hash retornar as chaves em uma ordem diferente, a cada iteração. No último caso, alguns usuários &lt;strong&gt;reclamaram que o comportamento não era aleatório o suficiente&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Tragicamente, qualquer fonte de aleatoriedade em seu programa será eventualmente usada para fins de simulação estatística, ou pior, criptografia, e qualquer fonte de ordenação será usada para classificação.&lt;/p&gt;

&lt;p&gt;Em um banco de dados, alguns identificadores carregam um pouco mais de informação do que outros. Ao criar uma tabela, um desenvolvedor pode escolher entre diferentes tipos de chave primária. A resposta correta é um UUID ou algo indistinguível de um UUID. O problema com as outras opções é que elas podem expor informações de pedido, bem como identidade, ou seja, não apenas se, a == b mas se a &amp;lt;= b, e outras opções significam chaves de incremento automático.&lt;/p&gt;

&lt;p&gt;Com uma chave de incremento automático, o banco de dados atribui um número a cada linha da tabela, adicionando 1 quando uma nova linha é inserida. Isso cria uma espécie de ambiguidade: as pessoas não sabem qual parte dos dados é canônica. Em outras palavras: você classifica por chave ou por carimbo de data/hora? Como nas tabelas de hash anteriores, as pessoas decidirão a resposta certa por si mesmas. O outro problema é que os usuários também podem adivinhar facilmente os outros registros de chaves próximos.&lt;/p&gt;

&lt;p&gt;Em última análise, qualquer tentativa de ser mais inteligente do que um UUID sairá pela culatra: já tentamos com códigos postais, números de telefone e endereços IP, e falhamos miseravelmente todas as vezes. Os UUIDs podem não tornar seu código mais depuravel, mas um comportamento menos acidental tende a significar menos acidentes.&lt;/p&gt;

&lt;p&gt;A ordem não é a única informação que as pessoas extrairão de uma chave: se você criar chaves de banco de dados construídas a partir de outros campos, as pessoas jogarão fora os dados e os reconstruirão a partir da chave. Agora você tem dois problemas: quando o estado de um programa é mantido em mais de um lugar, é muito fácil que as cópias comecem a discordar umas das outras. É ainda mais difícil mantê-los sincronizados se você não tiver certeza de qual deles precisa alterar ou qual deles você alterou.&lt;/p&gt;

&lt;p&gt;Tudo o que você permitir que seus usuários façam, eles implementarão. Escrever código depuravel é pensar antecipadamente sobre as maneiras pelas quais ele pode ser mal utilizado e como outras pessoas podem interagir com ele em geral.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regra 5&lt;/strong&gt;: A depuração é social, antes de ser técnica.&lt;/p&gt;

&lt;p&gt;Quando um projeto de software é dividido em vários componentes e sistemas, pode ser consideravelmente mais difícil encontrar bugs. Depois de entender como o problema ocorre, talvez seja necessário coordenar as alterações em várias partes para corrigir o comportamento. Corrigir bugs em um projeto maior é menos sobre encontrar os bugs e mais sobre convencer as outras pessoas de que eles são reais, ou mesmo que uma correção é possível.&lt;/p&gt;

&lt;p&gt;Os bugs persistem no software porque ninguém tem certeza absoluta de quem é o responsável pelas coisas. Em outras palavras, é mais difícil depurar o código quando nada está escrito, tudo deve ser perguntado no Slack e nada é respondido até que a única pessoa que sabe faça logon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Planejamento, ferramentas, processo e documentação são as maneiras pelas quais podemos corrigir isso&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O planejamento é como podemos remover o estresse de estar de plantão, com estruturas para gerenciar incidentes. Os planos são como mantemos os clientes informados, trocamos pessoas quando estão de plantão por muito tempo e como rastreamos os problemas e introduzimos mudanças para reduzir riscos futuros. As ferramentas são a maneira pela qual desqualificamos o trabalho e o tornamos acessível a outras pessoas. O processo é a maneira pela qual podemos remover o controle do indivíduo e entregá-lo à equipe.&lt;/p&gt;

&lt;p&gt;As pessoas vão mudar, as interações também, mas os processos e ferramentas serão mantidos à medida que a equipe mudar com o tempo. Não é tanto valorizar um mais do que o outro, mas construir um para apoiar mudanças no outro. O processo também pode ser usado para remover o controle da equipe, então nem sempre é bom ou ruim, mas sempre há algum processo de trabalho, mesmo quando não está escrito, e o ato de documentá-lo é o primeiro passo para permitir que outras pessoas o modifiquem.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;documentação significa mais do que arquivos de texto:&lt;/strong&gt; a documentação é como você transfere responsabilidades, como atualiza as novas pessoas e como comunica o que mudou para as pessoas afetadas por essas mudanças. &lt;strong&gt;Escrever documentação requer mais empatia do que escrever código&lt;/strong&gt;, e mais habilidade também: não há flags de compilador ou verificadores de tipo fáceis, e é fácil escrever muitas palavras sem documentar nada.&lt;/p&gt;

&lt;p&gt;Sem documentação, como você pode esperar que as pessoas tomem decisões informadas ou até mesmo concordem com as consequências do uso do software? Sem documentação, ferramentas ou processos, você não pode dividir o ônus da manutenção ou mesmo substituir as pessoas atualmente sobrecarregadas com a tarefa.&lt;/p&gt;

&lt;p&gt;Tornar as coisas fáceis de depurar se aplica tanto aos processos em torno do código quanto ao próprio código, deixando claro em quem você terá que se apoiar para consertar o código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código fácil de depurar é fácil de explicar&lt;/strong&gt;.&lt;br&gt;
Uma ocorrência comum durante a depuração é perceber o problema ao explicá-lo para outra pessoa. A outra pessoa nem precisa existir, mas você tem que se forçar a começar do zero, explicar a situação, o problema, os passos para reproduzi-lo, e muitas vezes esse enquadramento é suficiente para nos dar uma ideia da resposta.&lt;/p&gt;

&lt;p&gt;Se apenas. Às vezes, quando pedimos ajuda, não pedimos a ajuda certa, e sou tão culpado disso quanto qualquer um - é uma aflição tão comum que tem nome: “O problema XY”: como faço para obter o últimas três letras de um nome de arquivo? Oh? Não, eu quis dizer a extensão do arquivo.&lt;/p&gt;

&lt;p&gt;Falamos sobre problemas em termos das soluções que entendemos e falamos sobre as soluções em termos das consequências que conhecemos. Depurar é aprender da maneira mais difícil sobre consequências inesperadas e soluções alternativas, e envolve uma das coisas mais difíceis que um programador pode fazer: admitir que fez algo errado.&lt;/p&gt;

&lt;p&gt;Afinal, não era um bug do compilador.&lt;/p&gt;

&lt;p&gt;Fonte: programming is terrible lessons learned from a life wasted &lt;br&gt;
&lt;a href="https://programmingisterrible.com/post/173883533613/code-to-debug"&gt;https://programmingisterrible.com/post/173883533613/code-to-debug&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Beacon API! Use para telemetria de seus projetos web</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Wed, 03 May 2023 13:04:22 +0000</pubDate>
      <link>https://dev.to/urielsouza29/beacon-api-use-para-telemetria-de-seus-projetos-web-52kn</link>
      <guid>https://dev.to/urielsouza29/beacon-api-use-para-telemetria-de-seus-projetos-web-52kn</guid>
      <description>&lt;p&gt;Os aplicativos da Web geralmente precisam emitir solicitações que relatam eventos, atualizações de estado e análises para um ou mais servidores. Tais solicitações normalmente não requerem processamento de resposta no cliente (por exemplo, resultam em 204 ou 200 códigos de resposta HTTP com um corpo de resposta vazio) e não devem competir por rede e recursos de computação com outras operações de alta prioridade, como buscar recursos críticos, reagir para inserir, executar animações e assim por diante. No entanto, essas solicitações unidirecionais (beacons) também são responsáveis ​​por fornecer dados críticos de aplicativos e medições, forçando os desenvolvedores a usar métodos caros para garantir sua entrega:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Os desenvolvedores optam pela entrega imediata de cada beacon, em vez de combinar e adiar a entrega, pois isso proporciona melhores taxas de entrega. Adiar a entrega pode significar que a solicitação de beacon pode não ter tempo suficiente para ser concluída com sucesso, o que leva à perda de dados importantes do aplicativo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Os desenvolvedores optam por emitir solicitações de bloqueio por meio de XMLHttpRequest síncronos, inserindo loops ocupados no-op ou usando outras técnicas que impedem o agente do usuário de executar operações de tempo crítico (por exemplo, clicar, descarregar e outros manipuladores) e prejudicar a experiência do usuário. O comportamento de bloqueio é usado para fornecer uma taxa de entrega aprimorada, pois evita que o agente do usuário e o sistema operacional cancelem a solicitação se a página for descarregada, suspensa ou eliminada pelo sistema.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A incompatibilidade entre os requisitos de entrega e processamento acima deixa a maioria dos desenvolvedores com uma escolha difícil e adoção generalizada de técnicas de bloqueio que prejudicam a experiência do usuário. Esta especificação define uma interface que os desenvolvedores da Web podem usar para agendar a entrega assíncrona e sem bloqueio de dados que minimiza a contenção de recursos com outras operações de tempo crítico, garantindo que tais solicitações ainda sejam processadas e entregues ao destino:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As solicitações de beacon são priorizadas para evitar a competição com operações de tempo crítico e solicitações de rede de prioridade mais alta.&lt;/li&gt;
&lt;li&gt;As solicitações de beacon podem ser agrupadas de forma eficiente pelo agente do usuário para otimizar o uso de energia em dispositivos móveis.&lt;/li&gt;
&lt;li&gt;As solicitações de beacon são garantidas para serem iniciadas antes que a página seja descarregada e podem ser executadas até a conclusão sem exigir solicitações de bloqueio ou outras técnicas que bloqueiam o processamento de eventos interativos do usuário.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enviar um beacon é simples(já esta em todos os navegadores modernos!)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As solicitações de beacon não exigem uma resposta. Esta é uma grande diferença das solicitações regulares XHR ou fetch em que o cliente (navegador) espera uma resposta do servidor.&lt;/li&gt;
&lt;li&gt;As solicitações de beacon são iniciadas antes &lt;strong&gt;que uma página seja descarregada&lt;/strong&gt;, &lt;strong&gt;mesmo quando você fecha o navegador&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;As solicitações de beacon são concluídas sem exigir uma solicitação de bloqueio (XHR, por exemplo).&lt;/li&gt;
&lt;li&gt;As solicitações de beacon usam o método HTTP POST.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;navigator.sendBeacon('/url-que-vai-receber-o-dado', data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma implementação maior!&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="c1"&gt;//evento não bloqueante! Não bloqueia o loop de eventos do JS no cliente!&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reportEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendBeacon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/collector&lt;/span&gt;&lt;span class="dl"&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="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// emite beacon sem bloqueio com análise de sessão da página&lt;/span&gt;
   &lt;span class="c1"&gt;// transições para o estado de segundo plano (Page Visibility API)&lt;/span&gt;

  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visibilitychange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visibilityState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hidden&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sessionData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;buildSessionReport&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendBeacon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionData&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;As solicitações iniciadas por meio do sendBeacon()método não bloqueiam ou competem com o trabalho de tempo crítico, podem ser priorizadas pelo agente do usuário para melhorar a eficiência da rede e eliminar a necessidade de usar operações de bloqueio para garantir a entrega de dados beacon.&lt;/p&gt;

&lt;p&gt;OBS: &lt;br&gt;
O método sendBeacon() não fornece capacidade de personalizar o método de solicitação, fornecer cabeçalhos de solicitação personalizados ou alterar outras propriedades de processamento da solicitação e resposta. Os aplicativos que exigem configurações não padrão para tais solicitações devem usar a API [ FETCH ] com keepalive definido como true.&lt;/p&gt;

&lt;p&gt;Beacons são úteis para enviar dados ao servidor quando uma página é descarregada(load completo) (por exemplo, fechamento do navegador, navegações de página, etc.).&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendBeacon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// faça a magica acontecer &lt;/span&gt;
  &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendBeacon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/collector&lt;/span&gt;&lt;span class="dl"&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// esse navegador não tem beacon &lt;/span&gt;
  &lt;span class="c1"&gt;// use XHR ou fetch&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Formatos aceitos pelo beacon para envio&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ArrayBufferView &lt;/li&gt;
&lt;li&gt;Blob&lt;/li&gt;
&lt;li&gt;DOMStringou &lt;/li&gt;
&lt;li&gt;FormData
O data é opcional! &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Casos de uso &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saber quanto tempo um usuário ficou numa sessão!&lt;/li&gt;
&lt;li&gt;Quais são os controles de interface do usuário usados pelos usuários!&lt;/li&gt;
&lt;li&gt;Qualquer outro tipo de informação de telemetria a ser capturada!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Há um limite nos dados que podem ser enviados ao servidor usando a API Beacon. No entanto, esse limite não é uniforme em todos os navegadores e agentes de usuário.&lt;/p&gt;

&lt;p&gt;Você já usa a API? &lt;/p&gt;

&lt;p&gt;Fontes: &lt;br&gt;
&lt;a href="https://www.w3.org/TR/beacon/"&gt;https://www.w3.org/TR/beacon/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/save-your-analytics-data-with-the-beacon-and-pagevisibility-apis-f7d6a01087c4"&gt;https://javascript.plainenglish.io/save-your-analytics-data-with-the-beacon-and-pagevisibility-apis-f7d6a01087c4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>javascript</category>
      <category>api</category>
      <category>telemetria</category>
    </item>
    <item>
      <title>Uma forma de ensinar OOP para programadores procedurais na década de 80 com cartões!</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Mon, 10 Apr 2023 16:12:56 +0000</pubDate>
      <link>https://dev.to/urielsouza29/uma-forma-de-ensinar-oop-para-programadores-procedurais-na-decada-de-80-com-cartoes-5db7</link>
      <guid>https://dev.to/urielsouza29/uma-forma-de-ensinar-oop-para-programadores-procedurais-na-decada-de-80-com-cartoes-5db7</guid>
      <description>&lt;p&gt;Este e um texto traduzido livremente! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kent Beck&lt;/strong&gt;, Apple Computer, Inc.&lt;br&gt;
Ward Cunningham, Wyatt Software Services, Inc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dos Anais da Conferência OOPSLA'89,&lt;br&gt;
de 1 a 6 de outubro de 1989, Nova Orleans, Louisiana&lt;br&gt;
E da edição especial do SIGPLAN Notices&lt;br&gt;
Volume 24, Número 10, outubro de 1989&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;É difícil introduzir programadores procedimentais novatos e experientes à perspectiva antropomórfica necessária para o projeto orientado a objetos. Apresentamos os cartões CRC, que &lt;strong&gt;caracterizam os objetos pelo nome da classe&lt;/strong&gt;, responsabilidades e colaboradores, como forma de dar aos alunos uma experiência direta dos objetos. Descobrimos que essa abordagem é bem-sucedida ao ensinar aos programadores novatos os conceitos de objetos e ao apresentar aos programadores experientes projetos complicados existentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Problema
&lt;/h2&gt;

&lt;p&gt;O problema mais difícil no ensino de programação orientada a objetos é fazer com que o aluno desista do conhecimento global de controle que é possível com programas procedurais e confie no conhecimento local de objetos para realizar suas tarefas. Projetos novatos estão repletos de regressões ao pensamento global: variáveis globais gratuitas, ponteiros desnecessários e confiança inadequada na implementação de outros objetos.&lt;br&gt;
Como aprender sobre objetos requer uma mudança na abordagem geral, ensinar objetos reduz-se a ensinar o design de objetos. Nós nos concentramos em design, quer estejamos ensinando conceitos básicos para novatos ou as sutilezas de um design complicado para programadores de objetos experientes.&lt;/p&gt;

&lt;p&gt;Em vez de tentar tornar o design de objetos o mais parecido possível com o design processual, descobrimos que a maneira mais eficaz de ensinar a maneira idiomática de pensar com objetos é imergir o aluno na "objetividade" do material. Para fazer isso, devemos remover o máximo possível de material familiar, esperando que detalhes como sintaxe e operação do ambiente de programação sejam captados com rapidez suficiente, uma vez que os fundamentos tenham sido totalmente compreendidos.&lt;/p&gt;

&lt;p&gt;É nesse contexto que descreveremos nossa perspectiva sobre o design de objetos, sua manifestação concreta, os cartões CRC (para Classe, Responsabilidade e Colaboração) e nossa experiência no uso desses cartões para ensinar os fundamentos e as sutilezas do pensamento com objetos.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Perspectiva
&lt;/h2&gt;

&lt;p&gt;Projetos procedimentais podem ser caracterizados em um nível abstrato como tendo processos, fluxos de dados e armazenamentos de dados [1], independentemente da linguagem de implementação ou do ambiente operacional. Queríamos criar um conjunto semelhante de princípios fundamentais para projetos de objetos. Estabelecemos três dimensões que identificam o papel de um objeto em um design: nome da classe, responsabilidades e colaboradores.&lt;br&gt;
O nome de classe de um objeto cria um vocabulário para discutir um projeto. De fato, muitas pessoas observaram que o projeto de objeto tem mais em comum com o projeto de linguagem do &lt;strong&gt;que com o projeto de programa processual&lt;/strong&gt;. Incentivamos os alunos (e passamos um tempo considerável enquanto projetamos) a encontrar o conjunto certo de palavras para descrever nossos objetos, um conjunto que seja internamente consistente e evocativo no contexto do ambiente de design mais amplo.&lt;/p&gt;

&lt;p&gt;As responsabilidades identificam os problemas a serem resolvidos. As soluções existirão em muitas versões e refinamentos. Uma responsabilidade serve como um identificador para discutir possíveis soluções. As responsabilidades de um objeto são expressas por um punhado de frases verbais curtas, cada uma contendo um verbo ativo. Quanto mais puder ser expresso por essas frases, mais poderoso e conciso será o design. Mais uma vez, procurar as palavras certas é um uso valioso do tempo durante o design.&lt;/p&gt;

&lt;p&gt;Uma das características distintivas do design de objetos é que nenhum objeto é uma ilha. Todos os objetos estão em relação com outros, de quem dependem para serviços e controle. A última dimensão que usamos na caracterização de projetos de objetos são os colaboradores de um objeto. Nomeamos objetos colaboradores que enviarão ou receberão mensagens no decorrer do cumprimento de responsabilidades. A colaboração não é necessariamente uma relação simétrica. Por exemplo, em Smalltalk-80 [2] , View e Controller operam quase iguais (veja o exemplo abaixo), enquanto OrderedCollection oferece um serviço com pouca consideração ou mesmo consciência de seu cliente.&lt;/p&gt;

&lt;p&gt;Ao longo deste artigo, deliberadamente obscurecemos a distinção entre classes e instâncias. Essa informalidade não é tão confusa quanto pode parecer porque a concretude de nosso método substitui a nomeação de instâncias. Isso também torna nosso método de ensino independente de uma &lt;strong&gt;linguagem baseada em classe ou protótipo&lt;/strong&gt; ser usada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Cartões CRC&lt;/strong&gt;&lt;br&gt;
O segundo autor inventou os &lt;strong&gt;cartões CRC&lt;/strong&gt; em resposta à necessidade de documentar as decisões de design colaborativo. Os cartões começaram como uma pilha HyperCard [3] que fornecia indexação automática aos colaboradores, mas foram movidos para sua forma atual para resolver problemas de portabilidade e independência do sistema.&lt;br&gt;
Como nosso trabalho anterior na documentação da colaboração de objetos [4] , os cartões CRC representam explicitamente vários objetos simultaneamente. No entanto, em vez de simplesmente traçar os detalhes de uma colaboração na forma de envio de mensagens, os cartões CRC colocam o foco do designer na motivação para a colaboração, representando (potencialmente) muitas mensagens como uma frase de texto em inglês.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ylEB9q5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c2.com/doc/oopsla89/fig1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ylEB9q5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c2.com/doc/oopsla89/fig1.gif" alt="" width="221" height="127"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 1. Um cartão de índice de Colaborador de Responsabilidade de Classe (CRC)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Como os usamos atualmente, todas as informações de um objeto são escritas em um cartão de índice de 4" x 6". Estes têm as vantagens de serem baratos, portáteis, prontamente disponíveis e familiares. A Figura 1 mostra um cartão idealizado. O nome da classe aparece sublinhado no canto superior esquerdo, uma lista de responsabilidades aparece abaixo dela nos dois terços esquerdos do cartão e a lista de colaboradores aparece no terço direito.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kps55QMV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c2.com/doc/oopsla89/fig2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kps55QMV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c2.com/doc/oopsla89/fig2.gif" alt="" width="338" height="314"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 2. Cartões CRC descrevendo as responsabilidades e colaborações do Model, View e Controller de Smalltalk.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A Figura 2 mostra um exemplo obtido da imagem Smalltalk-80, a muito incompreendida estrutura de interface do usuário Model, View e Controller. Mostramos deliberadamente apenas uma parte das responsabilidades que cada um desses objetos assume para clareza de exposição. Observe que os cartões são colocados de modo que View e Controller se sobreponham (o que implica em estreita colaboração) e colocados acima do Model (o que implica supervisão). Descobrimos que esses e outros agrupamentos informais ajudam na compreensão de um projeto. As partes, por exemplo, muitas vezes são dispostas abaixo do todo. Da mesma forma, os refinamentos de uma abstração podem ser coletados e tratados como uma única pilha de cartas com a carta mais abstrata no topo, onde ela pode representar o resto.&lt;/p&gt;

&lt;p&gt;O design com os cartões tende a progredir de conhecidos para desconhecidos, em vez de de cima para baixo ou de baixo para cima. Observamos duas equipes chegando essencialmente ao mesmo projeto por meio de sequências quase opostas, uma começando com drivers de dispositivo e a outra com modelos de alto nível. O problema exigia um certo conjunto de capacidades que ambas as equipes descobriram ao cumprir os requisitos do projeto.&lt;/p&gt;

&lt;p&gt;Sugerimos direcionar um projeto para a conclusão com o auxílio de cenários de execução. Começamos com apenas uma ou duas cartas óbvias e começamos a jogar "e se". Se a situação exigir uma responsabilidade ainda não coberta por um dos objetos, adicionamos a responsabilidade a um dos objetos ou criamos um novo objeto para tratar dessa responsabilidade. Se um dos objetos ficar muito confuso durante esse processo, copiamos as informações de seu cartão para um novo cartão, buscando maneiras mais concisas e poderosas de dizer o que o objeto faz. Se não for possível reduzir ainda mais as informações, mas o objeto ainda for muito complexo, criamos um novo objeto para assumir algumas das responsabilidades.&lt;/p&gt;

&lt;p&gt;Encorajamos os alunos a pegar o cartão cujo papel estão assumindo enquanto "executam" um cenário. Não é incomum ver um designer com um cartão em cada mão, agitando-o, fazendo uma forte identificação com os objetos ao descrever sua colaboração.&lt;/p&gt;

&lt;p&gt;Ressaltamos a importância de criar objetos &lt;strong&gt;não para atender às míticas necessidades futuras, mas apenas sob as demandas do momento&lt;/strong&gt;. Isso garante que um projeto contenha apenas o máximo de informações que o designer experimentou diretamente e evita a complexidade prematura. Trabalhar em equipe ajuda aqui porque um designer preocupado pode influenciar os membros da equipe sugerindo cenários voltados especificamente para suspeitas de fraquezas ou omissões.&lt;/p&gt;

&lt;p&gt;A capacidade de organizar rapidamente e endereçar fichas espacialmente é mais valiosa quando um projeto está incompleto ou mal compreendido. Vimos designers referirem-se repetidamente a um cartão que pretendiam escrever, apontando para onde o colocariam quando concluído.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Experiência
&lt;/h2&gt;

&lt;p&gt;Um dos contextos em que utilizamos os cartões CRC é uma aula de três horas intitulada "Pensando com Objetos", destinada a profissionais de computação que já programaram, mas cujas funções não necessariamente envolvem programação diária. A aula prossegue apresentando um exemplo de fluxo de dados (uma escola, com processos de ensino e administração) que é então reformulado em termos de objetos com responsabilidades e colaboradores (como Professor, Zelador e Diretor). A turma então forma duplas e passa uma hora projetando os objetos em um caixa eletrônico, exercício escolhido pela familiaridade de todos com o aplicativo e sua pronta decomposição em objetos para controlar os aparelhos, comunicar-se com o banco de dados do banco central e controlar o usuário. interface. (Consulte o apêndice para obter uma solução de exemplo.&lt;br&gt;
Ao ensinar este curso a mais de uma centena de alunos, não encontramos ninguém que fosse incapaz de completar o exercício sem ajuda, embora um par em cada classe geralmente precise de algumas dicas para começar. Embora não tenhamos feito estudos de acompanhamento, a classe é considerada um recurso valioso na empresa e ainda é bem atendida com uma longa lista de espera quase um ano após seu início.&lt;/p&gt;

&lt;p&gt;Também pedimos aos programadores de objetos qualificados que tentassem usar cartões CRC. Nossa experiência pessoal sugere um papel para os cartões na engenharia de software, embora ainda não possamos reivindicar uma metodologia completa (outros [5][6] desenvolveram metodologias mais completas que podem tirar proveito dos métodos CRC). Sabemos de um caso em que os cartões acabados foram entregues a um cliente como documentação de design (parcial). Embora a equipe que produziu os cartões tenha ficado bastante satisfeita com o design, o destinatário não conseguiu entender os cartões fora do contexto.&lt;/p&gt;

&lt;p&gt;Outra experiência ilustra a importância do contexto estabelecido pelo manuseio e discussão das cartas. Tínhamos filmado designers experientes resolvendo um problema semelhante ao do caixa eletrônico. Nossa colocação de câmera tornou os cartões e as mãos dos designers visíveis, mas não a escrita nos cartões. Os espectadores da fita não tiveram problemas para acompanhar o desenvolvimento e muitas vezes pediram que a fita fosse interrompida para que pudessem expressar suas opiniões. Os momentos mais marcantes ocorreram quando a explicação do espectador exigia que ele apontasse para um cartão borrado na imagem congelada na tela.&lt;/p&gt;

&lt;p&gt;Finalmente, usamos cartões CRC para explicar projetos complexos. Alguns minutos de introdução são suficientes para preparar o público para uma apresentação baseada em cartão. Os cartões podem ser feitos com antecedência ou escritos na hora. Este último permite que a complexidade de um projeto seja revelada lentamente, um processo relacionado ao "gerenciamento de mentiras" de Dave Thomas. Os cartões estão sendo usados como acessórios para ajudar a contar uma história de computação. Os cartões permitem que seja contado sem recorrer à sintaxe ou idioma da linguagem de programação.&lt;/p&gt;

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

&lt;p&gt;Tomando nossa perspectiva como base, damos a novatos e programadores experientes uma experiência de aprendizado que lhes ensina algo valioso sobre objetos. Os cartões CRC dão ao aluno que nunca encontrou objetos uma compreensão física da objetividade e os prepara para entender o vocabulário e os detalhes de idiomas específicos. Os cartões CRC também fornecem uma experiência útil e convincente com objetos para aqueles que aprenderam os mecanismos dos objetos, mas ainda não perceberam seu valor.&lt;br&gt;
Ragu Raghavan [7] disse que na mudança para objetos os programadores fortes se tornam mais fortes, mas os programadores mais fracos são deixados para trás. Usando os cartões em configurações de grupo, descobrimos que mesmo os programadores mais fracos, sem uma compreensão profunda dos objetos, poderiam contribuir para projetos de objetos. Especulamos que, como os projetos são muito mais concretos e a relação lógica entre os objetos é mais fácil de entender, avaliar e modificar um projeto.&lt;/p&gt;

&lt;p&gt;Ficamos surpresos com o valor de mover fisicamente as cartas. Quando os alunos pegam um objeto, eles parecem se identificar mais prontamente com ele e estão preparados para lidar com o restante do design de sua perspectiva. É o valor dessa interação física que nos levou a resistir à informatização dos cartões.&lt;/p&gt;

&lt;p&gt;É exatamente esse problema – integrar os cartões com metodologias de design mais amplas e com ambientes de linguagem específicos – que acreditamos ser o mais promissor para o futuro. A necessidade de reter o valor da interação física aponta para a necessidade de um novo tipo de interface de usuário e ambiente de programação muito além do que temos hoje, pois nossos sistemas atuais estão além dos ambientes orientados a ferramentas do passado.&lt;/p&gt;

&lt;p&gt;Referências&lt;br&gt;
[1] DeMarco, T.: Análise Estruturada e Especificação de Sistema, Yourdon, 1978.&lt;br&gt;
[2] Imagem Smalltalk-80, Xerox Corp, 1983.&lt;/p&gt;

&lt;p&gt;[3] Manual do HyperCard, Apple Computer Inc.&lt;/p&gt;

&lt;p&gt;[4] Cunningham, W. e Beck, K.: "A Diagram for Object-Oriented Programs", em Proceedings of OOPSLA-86, outubro de 1986.&lt;/p&gt;

&lt;p&gt;[5] Wirfs-Brock, R. e Wilkerson, B. "Design orientado a objetos: uma abordagem voltada para a responsabilidade", submetido à OOPSLA '89.&lt;/p&gt;

&lt;p&gt;[6] Reenskaug, T.: "A Methodology for the Design and Description of Complex, Object-Oriented Systems", relatório técnico, Centro de Pesquisa Industrial, Oslo, Noruega, novembro de 1988.&lt;/p&gt;

&lt;p&gt;[7] Raghavan, R.: "Panel: Experiences with Reusability", in Proceedings of OOPSLA '88, outubro de 1988.&lt;/p&gt;

&lt;p&gt;Fonte: &lt;a href="https://c2.com/doc/oopsla89/paper.html"&gt;https://c2.com/doc/oopsla89/paper.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>O que faz de uma linguagem Orientada a Objetos? Por Peter Wegner</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Thu, 16 Mar 2023 00:27:24 +0000</pubDate>
      <link>https://dev.to/urielsouza29/o-que-faz-de-uma-linguagem-orientada-a-objetos-3hi1</link>
      <guid>https://dev.to/urielsouza29/o-que-faz-de-uma-linguagem-orientada-a-objetos-3hi1</guid>
      <description>&lt;p&gt;Isso era um assunto controverso nos anos 80.&lt;/p&gt;

&lt;p&gt;Em 87, Peter Wegner, publicou um artigo na OOPSLA que resolveu a questão (pelo menos entre aqueles que concordam com o Wegner) &lt;br&gt;
Para uma linguagem ser Orientada a Objetos ela precisa segundo Wegner &lt;/p&gt;

&lt;p&gt;ser baseada em objetos, ou seja, deve ser fácil programar objetos que encapsulam dados e operações;&lt;/p&gt;

&lt;p&gt;ser baseadas em classes, ou seja, cada objeto pertence a (ou é fabricado a partir de) uma classe; e +&lt;br&gt;
permitir herança, ou seja, deve ser fácil agrupar classes em hierarquias de subclasses e superclasses.&lt;/p&gt;

&lt;p&gt;Outros estudiosos (chatos?) acrescentam outros itens à lista: (eu não concordo - Wegner)&lt;br&gt;
enlace dinâmico, tardio (late binding)&lt;/p&gt;

&lt;p&gt;A linguagem Self é uma grande exceção entre as linguagens claramente orientada a objetos: ela não possui classes. &lt;/p&gt;

&lt;p&gt;JS e Lua tem coletores de lixo e não são baseadas em classes. &lt;/p&gt;

&lt;p&gt;Para Wegner essas não são linguagem OOP.&lt;/p&gt;

&lt;p&gt;Fontes: &lt;br&gt;
&lt;a href="https://dl.acm.org/doi/abs/10.1145/38765.38823"&gt;https://dl.acm.org/doi/abs/10.1145/38765.38823&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>oop</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>CDD - Cognitive Driven Development - Uma forma de programar criada por brasileiros!</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Mon, 13 Mar 2023 14:08:09 +0000</pubDate>
      <link>https://dev.to/urielsouza29/cdd-cognitive-driven-development-o-uma-forma-de-programar-criada-por-brasileiros-34ma</link>
      <guid>https://dev.to/urielsouza29/cdd-cognitive-driven-development-o-uma-forma-de-programar-criada-por-brasileiros-34ma</guid>
      <description>&lt;p&gt;A importância de desenvolver estratégias que reduzam o cognitive load dos nossos códigos para garantir seu entendimento por todos. Foi desse raciocínio que nasceu o conceito de Cognitive-Driven Development, ou design orientado ao entendimento. &lt;/p&gt;

&lt;h2&gt;
  
  
  CDD - Cognitive Driven Development
&lt;/h2&gt;

&lt;p&gt;Descobrir quais são as nossas limitações de entendimento e como a nossa mente atua nessa questão é tema de estudo de longa data. O artigo mais influente nessa área vem de 1956 e foi escrito pelo psicólogo George A. Miller, da universidade de Harvard. O título da famosa publicação é “The Magical Number Seven, Plus or Minus Two: Some Limits on our Capacity for Processing Information“. &lt;br&gt;
&lt;a href="http://psychclassics.yorku.ca/Miller/"&gt;http://psychclassics.yorku.ca/Miller/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Miller explica que provavelmente nós temos uma severa limitação na hora de processar informações. No resumo do resumo, é explicado que temos um &lt;strong&gt;limite de itens a serem entendidos em determinado momento que varia entre 5 e 9. Por isso o título +-7&lt;/strong&gt;. Essa ideia foi fortemente explorada e é bem aceito hoje em dia que realmente temos essa limitação. &lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Esforço cognitivo, ou carga cognitiva se refere ao nível de utilização de recursos psicológicos como memórias, atenção, percepção, representação de conhecimento, raciocínio e criatividade na resolução de problemas.&lt;/p&gt;

&lt;p&gt;A Teoria da Carga Cognitiva fundamenta-se na impossibilidade que o ser humano manifesta em processar muitas informações em simultâneo. O excesso de informação gera um esforço demasiado para todo o processo cognitivo o que origina uma sobrecarga cognitiva que dificulta a compreensão do conteúdo que se deseja apreendido.&lt;br&gt;
&lt;a href="https://sites.google.com/site/teoriadacargacognitiva/a-contribuicao-dos-principios-da-teoria-da-carga-cognitiva-na-aprendizagem-multimedia/resumo-1"&gt;https://sites.google.com/site/teoriadacargacognitiva/a-contribuicao-dos-principios-da-teoria-da-carga-cognitiva-na-aprendizagem-multimedia/resumo-1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;Para entender mais sobre a teoria da carga cognitiva &lt;br&gt;
&lt;a href="http://www.ucs.mun.ca/%7Ebmann/0_ARTICLES/CogLoad_Paas04.pdf"&gt;http://www.ucs.mun.ca/~bmann/0_ARTICLES/CogLoad_Paas04.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um trecho retirado do artigo referenciado diz o seguinte: “The load is called ‘intrinsic’ if it is imposed by the number of information elements and their interactivity.” &lt;/p&gt;

&lt;p&gt;Em tradução livre, temos: “A carga é chamada de ‘intrínseca’ se for imposta pelo número de elementos de informação e sua interativida”. &lt;/p&gt;

&lt;p&gt;E é da ideia de carga intrínseca que nasce a proposta de design de &lt;strong&gt;código orientado a entendimento&lt;/strong&gt;. Caso a gente considere que um pedaço de &lt;strong&gt;código é um material que precisa ser entendido&lt;/strong&gt;, como podemos diminuir de maneira eficaz a carga intrínseca dele? &lt;/p&gt;

&lt;h2&gt;
  
  
  Afinal, o que é Cognitive-Driven Development (CDD)?
&lt;/h2&gt;

&lt;p&gt;Cognitive-Driven Development (CDD), ou em português desenvolvimento orientado a cognição, é uma estratégia para reduzir a sobrecarga cognitiva durante o desenvolvimento ao melhorar o design do código.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ou seja, a ideia é manter os níveis de entendimento sobre um pedaço de código dentro &lt;br&gt;
do que o ser humano pode entender bem! Ou seja, dentro de +-7 items simultaneos. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Limitando a carga intrínseca do código ou Ponto de Complexidade Intrínseca (ICP)
&lt;/h2&gt;

&lt;p&gt;Uma das bases do Cognitive-Driven Development (CDD) é &lt;strong&gt;analisar e buscar limitar a complexidade de um código&lt;/strong&gt;, esta limitação pode ser arbritrária decidida no time. Para que a gente consiga, de fato, ter uma maneira interessante de limitar a carga intrínseca do código que escrevemos, precisamos seguir alguns passos. &lt;/p&gt;

&lt;p&gt;A primeira tarefa do time é decidir qual vai ser a unidade de código que será analisada. Por exemplo, se falarmos de uma linguagem orientada a objetos temos algumas possibilidades de definição de unidade de código, como, por:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;método dentro de uma classe;&lt;/li&gt;
&lt;li&gt;classe;&lt;/li&gt;
&lt;li&gt;arquivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A equipe pode definir um número de linhas maximo por classe dentro de um arquivo. &lt;br&gt;
100, ou seja o limite não pode passar de 100. Se passar outro arquivo deve ser criado. &lt;/p&gt;

&lt;p&gt;O que mais foi explorado até agora(dentro dos teste internos an ZUP) é usar o arquivo como uma unidade de código a ter sua carga intrínseca limitada. Isso implica que &lt;strong&gt;se tivermos duas classes dentro do mesmo arquivo&lt;/strong&gt;, vamos somar as cargas intrínsecas de cada uma e essa vai ser a carga total do arquivo. &lt;/p&gt;

&lt;p&gt;Uma vez que a unidade de código a ser analisada foi definida, é importante que a equipe do projeto entre em um acordo sobre o que vai influenciar na carga. É o que chamamos de &lt;strong&gt;Intrisc Complex Point (ou Ponto de Complexidade Intrínseca)&lt;/strong&gt; no Cognitive-Driven Development. Para facilitar, vamos referenciar estes pontos como ICP. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aqui não existe regra&lt;/strong&gt;, o objetivo do Cognitive-Driven Development (CDD) não é achar uma composição de Ponto de Complexidade Intrínseca (ICP) que forme uma métrica perfeita. A ideia é que a equipe, considerando suas características, encontre os ICP que façam sentido para aquele contexto. &lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Aquilo que a equipe achar naquele momento! E que pode mudar com o tempo! &lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;E qual o &lt;strong&gt;limite de ICP&lt;/strong&gt; que podemos ter então por unidade de código? Atualmente a nossa sugestão é que você tenha um número que seja o dobro ou maior ao número de ICP escolhidos. No exemplo citado temos cinco itens, então o limite por unidade de código seria dez ou mais. &lt;/p&gt;

&lt;h2&gt;
  
  
  Visão prática sobre o Ponto de Complexidade Intrínseca (ICP)
&lt;/h2&gt;

&lt;p&gt;Por exemplo, a equipe de engenharia da Zup Edu definiu que para os projetos em Java que escrevemos, vamos considerar os itens abaixo como ICP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;branches de código padrões (if, else, loops, when, case do when, try, catch);&lt;/li&gt;
&lt;li&gt;funções como argumento;&lt;/li&gt;
&lt;li&gt;condicionais;&lt;/li&gt;
&lt;li&gt;acoplamento com classes específicas do projeto;&lt;/li&gt;
&lt;li&gt;herança de classe abstrata ou concreta (extends).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada equipe pode definir seu conjunto de ICP e revisitá-lo com frequência. Até porque a combinação de níveis de habilidade da equipe pode influenciar no escopo do projeto e em vários outros fatores que afetam a qualidade e complexidade do código. Outro detalhe muito interessante é que o conjunto de itens influencia diretamente no estilo de código. &lt;/p&gt;

&lt;p&gt;Algumas dicas práticas para escolher e trabalhar melhor com ICPs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Herança foi escolhida como ICP? O recado é: Use com moderação. &lt;/li&gt;
&lt;li&gt;Condicional foi escolhida como ICP? O recado é: Não crie if com várias condicionais&lt;/li&gt;
&lt;li&gt;Função como argumento foi escolhida como ICP? O recado é: Não exagerar em transformação de coleção. &lt;/li&gt;
&lt;li&gt;Apenas acoplamento com classe específica foi escolhido como ICP? O recado é: Saiba das tecnologias que sustentam o projeto, vamos usar sem moderação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A definição do limite de ICP por unidade de código ainda precisa de muita exploração. O importante para o &lt;strong&gt;Cognitive-Driven Development (CDD) é que exista um conjunto de itens claros&lt;/strong&gt; que a equipe considere que dificulta o entendimento, assim como um limite estabelecido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefícios de criar um entendimento sobre complexidade
&lt;/h2&gt;

&lt;p&gt;Com um conjunto de ICP claro e um limite definido, muitas atividades e debates são facilitados no intervalo de tempo em que o combinado estiver valendo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Esse código está complexo? Se o número de ICP estiver abaixo ou igual ao limite, a resposta é não. &lt;/li&gt;
&lt;li&gt;Esse código vai passar no review? Se o número de ICP estiver abaixo ou igual ao limite, a resposta é sim. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Não importa se a pessoa é junior&lt;/strong&gt;, plena, sênior ou qualquer outro nível. Ninguém vai escrever um código que passa do limite de complexidade definido pela equipe!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um limite sempre arbitrário e simples para qualquer um entender!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quaisquer outras discussões sobre &lt;strong&gt;complexidade agora têm uma regra clara&lt;/strong&gt;. Entendemos que isso facilita bastante o dia a dia de comunicação dentro do projeto no que diz respeito à análise do código em si.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como o Cognitive-Driven Development se relaciona com o que você já utiliza hoje em dia?
&lt;/h2&gt;

&lt;p&gt;Importante notar que o Cognitive-Driven Development (CDD) não vem com a ideia de ser a principal referência dentro do design do seu código. Limitar a dificuldade de entendimento é algo que pode ser útil em qualquer ponto do projeto.&lt;/p&gt;

&lt;p&gt;Imagine que você está escrevendo um caso de uso inspirado na arquitetura proposta pelo &lt;strong&gt;Clean Architecture&lt;/strong&gt;. Se a equipe tiver definido os pontos de complexidade intrínseca (ICP) e o limite, você vai conseguir ter um caminho claro de como separar o código de modo a fazer o caso de uso e ainda manter o nível de carga cognitiva necessário para entendimento adequado com os padrões da equipe. &lt;/p&gt;

&lt;p&gt;Olhando ainda para as ideias de camadas propostas pela Clean Architecture, você pode encontrar situações semelhantes na camada de entidades. As classes que estão no núcleo da sua aplicação tendem a ser transversais ao sistema todo. Elas podem ganhar mais atributos, métodos etc. &lt;/p&gt;

&lt;p&gt;Então como fazer para saber o limite daquele código no que diz respeito a facilidade de entendimento? Mais uma vez a ideia do Cognitive-Driven Development (CDD) pode ser aplicada para facilitar. &lt;/p&gt;

&lt;p&gt;A mesma linha de raciocínio pode ser aplicada quando você está se inspirando no Domain Driven Design, pensando no princípio da responsabilidade única etc. &lt;/p&gt;

&lt;p&gt;Peguei este artigo da zup e fiz comentários que estão citados! &lt;br&gt;
&lt;a href="https://www.zup.com.br/blog/cognitive-driven-development-cdd"&gt;https://www.zup.com.br/blog/cognitive-driven-development-cdd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma definição em vídeo do autor Alberto Luiz Oliveira Tavares de Souza&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=rqw_Jnv6ZX4"&gt;https://www.youtube.com/watch?v=rqw_Jnv6ZX4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fontes: &lt;br&gt;
&lt;a href="https://www.zup.com.br/blog/cognitive-driven-development-cdd"&gt;https://www.zup.com.br/blog/cognitive-driven-development-cdd&lt;/a&gt; &lt;br&gt;
&lt;a href="https://ieeexplore.ieee.org/document/9240662"&gt;https://ieeexplore.ieee.org/document/9240662&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Autores: Alberto Luiz Oliveira Tavares de Souza&lt;br&gt;
Zup Innovation - Academy, São Paulo, SP, Brazil&lt;br&gt;
E &lt;br&gt;
Victor Hugo Santiago Costa Pinto&lt;br&gt;
Zup Innovation - Academy,São Paulo,SP,Brazil&lt;/p&gt;

&lt;p&gt;Entre em contato com um dos autores &lt;br&gt;
&lt;a href="https://twitter.com/alberto_souza"&gt;https://twitter.com/alberto_souza&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ele é muito simpatico e sempre que pode responde a todos!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Lista de servidores VPS baratos</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Thu, 02 Mar 2023 12:24:37 +0000</pubDate>
      <link>https://dev.to/urielsouza29/uma-lista-de-vps-baratos-51ne</link>
      <guid>https://dev.to/urielsouza29/uma-lista-de-vps-baratos-51ne</guid>
      <description>&lt;p&gt;Olá, quase todo mundo ama um cloud, uma AWS ou algo com netifly etc. &lt;br&gt;
Como eu não sou todo mundo, eu prefiro servidor VPS ou parecido! &lt;/p&gt;

&lt;p&gt;Alguns projetos pequenos cabem super bem neles! Um cloud ou algo com front separado é muito trabalho pra pouco retorno de projetos pessoais! Se for profissional é outro modo de pensar! &lt;br&gt;
Versões frees de alguns serviços como aws/gcp e outros é muita do de cabeça pra gente fazer pouco(minha opinião)&lt;/p&gt;

&lt;p&gt;Lista sem ordenamento!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.time4vps.com/" rel="noopener noreferrer"&gt;https://www.time4vps.com/&lt;/a&gt; - ele é barato e bem antigo. Quase não vejo reclamações! &lt;br&gt;
Mas os servidores ficam Lituania. Se PING for importante pra você pode não ser uma boa ideia! &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://contabo.com/" rel="noopener noreferrer"&gt;https://contabo.com/&lt;/a&gt; - relativamente barato. Uso ele tem uns 8 anos e nunca tive qualquer problema. Infelizmente eles aumentaram seus preços. Mas vale a pena. 
Você pode escolher entre EUA e Alemanha seu VPS. q
Quando eu entrei tinha apenas Alemanha! 
OBS: Eles tem um serviço igual ao S3 da AWS mas muito mais barato! &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://vpsdime.com/" rel="noopener noreferrer"&gt;https://vpsdime.com/&lt;/a&gt; - é um serviço que conheço pouco. Não sei muito dele. Mas seus VPS são bem baratos! &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;https://www.digitalocean.com/&lt;/a&gt; este nem precisa de palavras. Super conhecido! &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.server4you.de/" rel="noopener noreferrer"&gt;https://www.server4you.de/&lt;/a&gt; super barato. Mas pouco conhecido. Seus servidores ficam na Alemanha&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EDITADO - sugestões&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vultr.com/" rel="noopener noreferrer"&gt;https://www.vultr.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tinykvm.com/" rel="noopener noreferrer"&gt;https://tinykvm.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.buyvm.net/" rel="noopener noreferrer"&gt;https://www.buyvm.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linode.com/pt/" rel="noopener noreferrer"&gt;https://www.linode.com/pt/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloudcone.com/" rel="noopener noreferrer"&gt;https://cloudcone.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://servarica.com/" rel="noopener noreferrer"&gt;https://servarica.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://securedragon.net/" rel="noopener noreferrer"&gt;https://securedragon.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://upcloud.com/" rel="noopener noreferrer"&gt;https://upcloud.com/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hosthatch.com/" rel="noopener noreferrer"&gt;https://hosthatch.com/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hetzner.com/cloud" rel="noopener noreferrer"&gt;https://www.hetzner.com/cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://incognet.io/" rel="noopener noreferrer"&gt;https://incognet.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webdock.io/" rel="noopener noreferrer"&gt;https://webdock.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hostdzire.com/" rel="noopener noreferrer"&gt;https://hostdzire.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cloudatcost.com/" rel="noopener noreferrer"&gt;https://www.cloudatcost.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ssdnodes.com/" rel="noopener noreferrer"&gt;https://www.ssdnodes.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hostkey.com/vps/hourly/" rel="noopener noreferrer"&gt;https://hostkey.com/vps/hourly/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.scaleway.com/pricing/" rel="noopener noreferrer"&gt;https://www.scaleway.com/pricing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kamatera.com/" rel="noopener noreferrer"&gt;https://www.kamatera.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.lunanode.com/pricing" rel="noopener noreferrer"&gt;https://www.lunanode.com/pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hostwinds.com/vps/" rel="noopener noreferrer"&gt;https://www.hostwinds.com/vps/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://virpus.com/" rel="noopener noreferrer"&gt;http://virpus.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.budgetvm.com/" rel="noopener noreferrer"&gt;https://www.budgetvm.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://my.frantech.ca/cart.php" rel="noopener noreferrer"&gt;https://my.frantech.ca/cart.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.vpscheap.net" rel="noopener noreferrer"&gt;https://www.vpscheap.net&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hudsonvalleyhost.com" rel="noopener noreferrer"&gt;https://www.hudsonvalleyhost.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hostbrz.com/" rel="noopener noreferrer"&gt;https://www.hostbrz.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.supremevps.com" rel="noopener noreferrer"&gt;https://www.supremevps.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ramnode.com/vps.php" rel="noopener noreferrer"&gt;https://www.ramnode.com/vps.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.skysilk.com/" rel="noopener noreferrer"&gt;https://www.skysilk.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/pt/lightsail/pricing/" rel="noopener noreferrer"&gt;https://aws.amazon.com/pt/lightsail/pricing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://n6cloud.com/" rel="noopener noreferrer"&gt;https://n6cloud.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ultahost.com/" rel="noopener noreferrer"&gt;https://ultahost.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oneprovider.com/" rel="noopener noreferrer"&gt;https://oneprovider.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.interserver.net/vps/" rel="noopener noreferrer"&gt;https://www.interserver.net/vps/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fly.io/" rel="noopener noreferrer"&gt;https://fly.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netcup.eu/vserver/vps.php" rel="noopener noreferrer"&gt;https://www.netcup.eu/vserver/vps.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://alexhost.com/pt/" rel="noopener noreferrer"&gt;https://alexhost.com/pt/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oneprovider.com/" rel="noopener noreferrer"&gt;https://oneprovider.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ionos.com/servers/vps" rel="noopener noreferrer"&gt;https://www.ionos.com/servers/vps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com pagamento em real&lt;br&gt;
Já usei, não tive problemas&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://minivps.com.br/" rel="noopener noreferrer"&gt;https://minivps.com.br/&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não usei mas pretendo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.hostinger.com.br/servidor-vps" rel="noopener noreferrer"&gt;https://www.hostinger.com.br/servidor-vps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://king.host/servidor-vps" rel="noopener noreferrer"&gt;https://king.host/servidor-vps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://squarecloud.app" rel="noopener noreferrer"&gt;https://squarecloud.app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Você tem alguma indicação? &lt;br&gt;
Eu sei que existem outros. Mas só quis começar a lista. &lt;br&gt;
Eu mesmo gosto de ficar pesquisando por novidades! &lt;/p&gt;

&lt;p&gt;Por favor deixe sua lista nos comentários!&lt;/p&gt;

&lt;p&gt;Você quer alternativas a Heroku? &lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/urielsouza29" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F555747%2F7232e03c-096f-4dea-8972-c6dbf11dc45e.jpg" alt="urielsouza29"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/urielsouza29/-de-15-alternativas-ao-heroku-nem-todas-gratis-12a7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;+ de 15 alternativas ao Heroku - nem todas grátis!&lt;/h2&gt;
      &lt;h3&gt;Uriel dos Santos Souza ・ Sep 8 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#heroku&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#braziliandevs&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Fazendo um jabá! &lt;br&gt;
Caso você esteja procurando um serviço simples de upload e download de arquivos sem registros ou logins! &lt;br&gt;
Recomendo o &lt;a href="https://shareallfiles.net/" rel="noopener noreferrer"&gt;https://shareallfiles.net/&lt;/a&gt;&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://shareallfiles.net/" rel="noopener noreferrer"&gt;
      shareallfiles.net
    &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>server</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>O que é processo e um thread?</title>
      <dc:creator>Uriel dos Santos Souza</dc:creator>
      <pubDate>Tue, 17 Jan 2023 16:25:10 +0000</pubDate>
      <link>https://dev.to/urielsouza29/o-que-e-processo-e-um-thread-g65</link>
      <guid>https://dev.to/urielsouza29/o-que-e-processo-e-um-thread-g65</guid>
      <description>&lt;p&gt;Hoje vamos falar um pouco de CPU. &lt;br&gt;
Mais especificamente de processos e threads! &lt;br&gt;
Falaremos aqui de forma simples sem entrar em muitos detalhes, para um entedimento básico do assunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é um processo?
&lt;/h2&gt;

&lt;p&gt;Um processo em palavras simples é alguma coisa usar uma CPU(um processador). &lt;br&gt;
Ou seja de forma simplificada, se um computador tem um só núcleo, ele só pode executar 1 processo por vez! Um único programa apenas! Hoje todos os novos chips tem N núcleos. Ou seja qualquer novo computador ou celular tem muitos processadores. &lt;/p&gt;

&lt;p&gt;Quando você abre um programa, ele usa um processo. Ele ocupa totalmente esse CPU(no caso de um único núcleo)! &lt;br&gt;
Antigamente quando só existia um unico núcleo ele ficaria tomado 100% do tempo por um unico programa! &lt;/p&gt;

&lt;p&gt;Mas, resolveram isso de forma simples.&lt;br&gt;
o kernel, por meio de uma interrupção de timer ou outro mecanismo semelhante, suspende um, salvando seu estado de máquina e substituindo-o pelo estado salvo anteriormente de outro. &lt;/p&gt;

&lt;p&gt;O programa(processo) usa o núcleo por poucos milesimos, ai salva tudo na memoria. E outro processo passa a usar aquele núcleo por mais alguns milésimos tudo é salvo. Ai se pega o que foi salvo antes e processa por alguns milésimos, salva e assim por diante. É tão rapido que tudo parece paralelo. &lt;/p&gt;

&lt;p&gt;Isso tudo em termos simples! &lt;br&gt;
Hoje funciona de modo parecido!&lt;/p&gt;

&lt;p&gt;Seu computador e celular tem bem mais de um núcleo.&lt;/p&gt;

&lt;p&gt;Se você abrir poucos programas pode ser que nem se use todos os núcleos. Assim economizando energia eletrica. &lt;br&gt;
Não tem motivos para usar todos os processadores é mais barato usar poucos.&lt;br&gt;
Hoje um processo pode estar em mais de um núcleo ao mesmo tempo.&lt;br&gt;
O navegador Chrome por exemplo, usa multiplos processos! Cada aba que você abre é um novo processo sendo criado pelo Chrome!&lt;br&gt;&lt;br&gt;
Hoje mesmo com multinúcleos a maioria dos programas usa um só!&lt;/p&gt;

&lt;p&gt;Um processo pode criar outros processos, o qual chamamos de processos filhos! &lt;/p&gt;

&lt;p&gt;O processo pode ter os seguintes estados: novo, pronto, em execução, aguardando, encerrado, suspenso. &lt;/p&gt;

&lt;p&gt;As operações de processo podem ser facilmente controladas com a ajuda do PCB (bloco de controle de processo). Você pode considerá-lo como o cérebro do processo, que contém todas as informações cruciais relacionadas ao processamento, como id do processo, prioridade, estado e registro de conteúdo da CPU, etc.&lt;/p&gt;

&lt;p&gt;Um processo é único. Não conversa facilmente com outro. Não compartilham memoria. &lt;br&gt;
Para você conversar com outro processo precisa usar mensagens de IPC(Inter-Process Communication) &lt;br&gt;
Onde cada mensagem enviada é copiada para o outro processo. &lt;/p&gt;

&lt;p&gt;Processo 1 - "Oi processo 2"&lt;/p&gt;

&lt;p&gt;A mensagem "Oi processo 2" acaba de ser copiada&lt;/p&gt;

&lt;p&gt;Processo 2, recebe a mensagem &lt;br&gt;
Processo 2 - "Oi, recebi usa mensagem"&lt;/p&gt;

&lt;p&gt;A mensagem "Oi, recebi usa mensagem" acaba de ser copiada &lt;/p&gt;

&lt;p&gt;Processo 1, recebe a mensagem. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A criação de cada processo requer chamadas de sistema separadas para cada processo.&lt;/li&gt;
&lt;li&gt;É uma entidade de execução isolada e não compartilha dados e informações.&lt;/li&gt;
&lt;li&gt;Os processos usam o mecanismo IPC (Inter-Process Communication) para comunicação que aumenta significativamente o número de chamadas do sistema.&lt;/li&gt;
&lt;li&gt;O gerenciamento de processos leva mais chamadas de sistema.&lt;/li&gt;
&lt;li&gt;Um processo tem sua própria pilha, memória heap com memória e mapa de dados.&lt;/li&gt;
&lt;li&gt;Um processo demora para ser criado, demora mais pra terminar! &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora sabemos o que é um processo por cima, sem muitos detalhes e existe muito mais coisas, Tem muito mais material detalhado na web, com todos os conceitos bem explicados. Passo a passo deixarei fontes no fim do artigo!&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é thread?
&lt;/h2&gt;

&lt;p&gt;Vamos falar de forma alta. Sem detalhes! &lt;/p&gt;

&lt;p&gt;Sabemos o que é um processo. Mas dentro dele podem ter threads(um mini processo por núcleo). Um processo pode ter várias threads. Todos os threads de um processo compartilhamo mesmo espaço na memória e recursos do sistema.&lt;br&gt;
Se um thread abrir um arquivo, outro pode ler ou mexer nele! &lt;br&gt;
Isso não acontece entre processos! &lt;/p&gt;

&lt;p&gt;Vamos imaginar que dentro de um processo existem vários pequenos trabalhadores. &lt;br&gt;
Mais ou menos como uma fabrica. &lt;br&gt;
Um processo com muitos funcionarios. &lt;/p&gt;

&lt;p&gt;O bom de thread é que elas compartilham coisas! &lt;br&gt;
Como estão dentro de um mesmo processo, tudo que o processo tem acesso, thread também tem! &lt;br&gt;
Ou seja, threads podem conversar entre si e podem acessar os mesmos pontos da memória! &lt;br&gt;
Isso torna as coisas mais rápidas! &lt;br&gt;
Mas não mais simples de gerenciar! &lt;/p&gt;

&lt;p&gt;Threads podem ter 3 estados: em execução, pronto e bloqueado. &lt;/p&gt;

&lt;p&gt;Thread também é conhecido como processo leve. A ideia é alcançar o paralelismo dividindo um processo em vários threads. Por exemplo, em um navegador, várias guias podem ser threads diferentes. O MS Word usa vários threads: um thread para formatar o texto, outro thread para processar entradas. &lt;br&gt;
Programas que suportam multithreading podem ser complicados de gerenciar! &lt;/p&gt;

&lt;p&gt;Usando processos tudo fica separado!&lt;br&gt;
E quem gerencia seu funcionamento é o sistema operacional, multithreading quem deve gerenciar é o programador! &lt;/p&gt;

&lt;p&gt;Então entendemos que um processo pode ter muitos threads. &lt;br&gt;
Cada thread pode fazer uma coisa. &lt;br&gt;
Se bem gerenciado pode se usar muitos thread e executar coisas em paralelo(literalmente). &lt;br&gt;
Antes cada processo rodada na sua vez. &lt;br&gt;
Agora cada thread pode rodar ao mesmo tempo! &lt;/p&gt;

&lt;p&gt;Multithreading em sistemas com multiprocessadores é realmente muito mais difícil, já que você tem problemas de acesso simultâneo à memória de várias CPUs/núcleos e todos os problemas desagradáveis ​​de sincronização de memória que surgem disso.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma única chamada de sistema pode criar mais de um thread&lt;/li&gt;
&lt;li&gt;Threads compartilham dados e informações.&lt;/li&gt;
&lt;li&gt;Threads compartilha regiões de instruções, globais e de heap. No entanto, ele tem seu registrador e pilha.&lt;/li&gt;
&lt;li&gt;O gerenciamento de threads consome muito poucas ou nenhuma chamada de sistema devido à comunicação entre threads que pode ser obtida usando memória compartilhada.&lt;/li&gt;
&lt;li&gt;É criado rapidamente, e termina mais rápido! Tornando barato sua criação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sabemos o que são threads, sabemos o que são processos. Entendemos que um processo pode ocupar vários núcleos permitindo &lt;br&gt;
Multithreading, E cada processo tem sua vez de rodar. &lt;/p&gt;

&lt;p&gt;Um thread é barato para criar e termina mais rápidamente que um processo! &lt;/p&gt;

&lt;p&gt;Tenho que lembrar que isso é uma pincelada sobre o assunto. Existe muito mais coisas envolvidas das quais não coloquei aqui! &lt;/p&gt;

&lt;p&gt;Fontes: &lt;br&gt;
&lt;a href="https://www.programacaoprogressiva.net/2014/09/Como-os-Processos-Sao-Executados-em-um-Computador.html"&gt;https://www.programacaoprogressiva.net/2014/09/Como-os-Processos-Sao-Executados-em-um-Computador.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/nfo94/o-que-e-um-processo-em-um-sistema-operacional-2769"&gt;https://dev.to/nfo94/o-que-e-um-processo-em-um-sistema-operacional-2769&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.inf.ufpr.br/wagner/so/processos+threads.2pp.pdf"&gt;https://www.inf.ufpr.br/wagner/so/processos+threads.2pp.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sites.google.com/site/proffernandosiqueiraso/aulas/5-processo"&gt;https://sites.google.com/site/proffernandosiqueiraso/aulas/5-processo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.guru99.com/difference-between-multiprocessing-and-multithreading.html"&gt;https://www.guru99.com/difference-between-multiprocessing-and-multithreading.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://acervolima.com/diferenca-entre-processo-e-thread/"&gt;https://acervolima.com/diferenca-entre-processo-e-thread/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://acervolima.com/diferenca-entre-processo-processo-pai-e-processo-filho/"&gt;https://acervolima.com/diferenca-entre-processo-processo-pai-e-processo-filho/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/16116952/can-multithreading-be-implemented-on-a-single-processor-system"&gt;https://stackoverflow.com/questions/16116952/can-multithreading-be-implemented-on-a-single-processor-system&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://acervolima.com/diferenca-entre-processo-processo-pai-e-processo-filho/"&gt;https://acervolima.com/diferenca-entre-processo-processo-pai-e-processo-filho/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.inf.ufpr.br/wagner/so/processos+threads.4pp.pdf"&gt;https://www.inf.ufpr.br/wagner/so/processos+threads.4pp.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Dhf-DYO1K78"&gt;https://www.youtube.com/watch?v=Dhf-DYO1K78&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://alldifferences.net/difference-between-process-and-thread/"&gt;https://alldifferences.net/difference-between-process-and-thread/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>process</category>
      <category>thread</category>
      <category>beginners</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
