<?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: Francisco Zanfranceschi</title>
    <description>The latest articles on DEV Community by Francisco Zanfranceschi (@zanfranceschi).</description>
    <link>https://dev.to/zanfranceschi</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%2F839958%2F86f93374-f880-4d01-a920-f5d0fbece718.jpeg</url>
      <title>DEV Community: Francisco Zanfranceschi</title>
      <link>https://dev.to/zanfranceschi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zanfranceschi"/>
    <language>en</language>
    <item>
      <title>Uma Introdução Simples ao RSA</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Mon, 26 May 2025 01:20:31 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/uma-introducao-simples-ao-rsa-gek</link>
      <guid>https://dev.to/zanfranceschi/uma-introducao-simples-ao-rsa-gek</guid>
      <description>&lt;p&gt;Você já deve ter ouvido falar de RSA – aquele negócio de criptografia, chaves assimétricas –, certo? Mas você sabe o que é, como funciona e de onde vem o nome? Nessa thread, vou dar uma visão geral bem simples pra você entender e arrasar no próximo date ou churrasco.&lt;/p&gt;




&lt;p&gt;Vamos direto ao ponto! RSA é um algoritmo de criptografia de chaves assimétricas (ou chaves públicas). E chaves assimétricas aqui significa que são valores diferentes, mas matematicamente relacionados pra que a criptografia e descriptografia funcionem certinho.&lt;/p&gt;




&lt;p&gt;O nome RSA vem dos sobrenomes dos seus 3 criadores: Ron Rivest, Adi Shamir e Leonard Adleman. RSA é provavelmente o sistema de criptografia mais conhecido atualmente e foi divulgado em 1977.   &lt;/p&gt;




&lt;p&gt;Voltando na questão das chaves assimétricas ou públicas. Essa parte é interessante porque pra que duas partes se comuniquem de forma segura, elas não precisam compartilhar uma senha – elas compartilham apenas uma informação pública e cada uma tem sua "senha" – chave privada.&lt;/p&gt;




&lt;p&gt;Vamos supor que A queira se comunicar com B de forma segura. No RSA, A tem uma chave pública e uma chave privada e B também tem uma chave pública e outra privada. A e B trocam livremente suas chaves públicas. Sem problemas se terceiros acessarem essas chaves públicas.&lt;/p&gt;




&lt;p&gt;Quando A precisa enviar uma mensagem pra B, A usa a chave pública de B para criptografar uma mensagem e então a envia para B. B então usa sua chave privada para descriptografar essa mensagem. E vice-versa para quando B quiser enviar mensagens para A.&lt;/p&gt;

&lt;p&gt;Tranquilo até aqui?&lt;/p&gt;




&lt;p&gt;O algoritmo pra criptografar e descriptografar é super simples. Imaginando que toda informação que trocamos entre computadores seja representada por números, vamos a um exemplo de que "oi" seja representado por 111 e 115.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cryptii.com/pipes/text-decimal" rel="noopener noreferrer"&gt;https://cryptii.com/pipes/text-decimal&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;As chaves públicas do RSA na verdade são pares de números. Vamos supor que a chave pública seja (143, 17) e a privada seja (143, 113). A fórmula pra criptografar é (para cada caractere):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;c ^ 17 mod 143&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;...onde c é 111 e depois 115&lt;/p&gt;




&lt;p&gt;Então "oi" que é 111 e 115, seria representado por 89 e 124. Se formos na tabela ASCII, o valor criptografado seria "Y|".&lt;/p&gt;

&lt;p&gt;Pra descriptografar, a fórmula usa valores da chave privada:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;d ^ 113 mod 143&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;...onde d é 89 e depois 124&lt;/p&gt;




&lt;p&gt;Vamos descriptografar 89 e 124 então:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;89 ^ 113 mod 143 = 111&lt;/code&gt;&lt;br&gt;
&lt;code&gt;124 ^ 113 mod 143 = 115&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tá-dá! Temos 111 e 115 de novo que representa "oi"!&lt;/p&gt;




&lt;p&gt;A parte que acho mais legal do RSA é a geração das chaves. Mas como já existem muitos materiais na internet sobre como fazer isso, fiz apenas uma representação visual porque não achei nada assim e talvez isso te ajude a entender.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cryptool.org/en/cto/rsa-step-by-step/" rel="noopener noreferrer"&gt;https://www.cryptool.org/en/cto/rsa-step-by-step/&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1tw1a8jl69dqnkpdw4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1tw1a8jl69dqnkpdw4f.png" alt="Geração de Chaves RSA com Exemplos" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Bom, isso aqui foi o básico do básico sobre RSA de uma forma extremamente simplificada.&lt;/p&gt;

&lt;p&gt;O RSA tem umas coisas bem interessantes que valem ser mencionadas. Continua aqui pra você ser a pessoa mais legal no jantar do natal desse ano e soltar essas pros seus primos.&lt;/p&gt;




&lt;p&gt;A fortaleza do RSA é ser baseado em números primos e seu produto. Isso porque fatorar dois números primos gigantes (n) é extremamente custoso. Um computador normal levaria muuuuito tempo pra fazer isso. Com computadores quânticos o negócio já muda de figura.&lt;/p&gt;




&lt;p&gt;Se alguém descobrir um algoritmo pra quebrar o número n em q e p, basicamente a segurança da maioria da internet estaria seriamente comprometida. Ou você acha mesmo que não têm governos que interceptam mensagens criptografadas e guardam tudo pra tentar descriptografar? Humpf...&lt;/p&gt;




&lt;p&gt;Outra coisa interessante sobre RSA é que as chaves são comutativas no sentido que a chave pública pode ser usada também pra descriptografar algo que foi criptografado com a chave privada. E isso é usado para assinaturas.&lt;/p&gt;




&lt;p&gt;Ou seja, de forma simplificada, eu criptografo algo com minha chave privada e qualquer um poderia descriptografar com minha chave pública para comprovar minha autenticidade. Por exemplo, isso é usado em emails. &lt;/p&gt;




&lt;p&gt;RSA ainda é muito usado. Por exemplo, no TLS 1.2, o RSA pode ser usado pra troca de chaves.&lt;/p&gt;




&lt;p&gt;Se achou esse conteúdo legal, posso te sugerir algumas coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Procure por detalhes relacionados a RSA em certificados de sites – p.ex. a chave pública (geralmente em formato hexadecimal).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Escreva o algoritmo para gerar chaves e (des)criptografar na sua linguagem favorita.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Muito obrigado se leu até aqui!&lt;/p&gt;




&lt;p&gt;Acesse &lt;a href="https://gist.github.com/zanfranceschi/aae284f2446adf00c0bc240d2d43cf33" rel="noopener noreferrer"&gt;https://gist.github.com/zanfranceschi/aae284f2446adf00c0bc240d2d43cf33&lt;/a&gt; para um exemplo prático em Python.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Conceito] - Índice de Instabilidade de Software</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Sat, 10 Aug 2024 22:30:21 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/conceito-indice-de-instabilidade-de-software-20aj</link>
      <guid>https://dev.to/zanfranceschi/conceito-indice-de-instabilidade-de-software-20aj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1822399151998636165" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1822399151998636165&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Estou elaborando um material que menciono o Índice de Instabilidade de software que é:&lt;/p&gt;

&lt;p&gt;Ce / (Ce + Ca)&lt;/p&gt;

&lt;p&gt;Onde:&lt;br&gt;
Ce = Acoplamento Eferente&lt;br&gt;
Ca = Acoplamento Aferente&lt;/p&gt;

&lt;p&gt;O resultado vai de 0 a 1 e quanto mais próximo de 0, mais estável e vice-versa. Mas você entende o por quê disso?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quote de &lt;a href="https://twitter.com/zanfranceschi/status/1543662061095227392" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1543662061095227392&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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




&lt;p&gt;A gente nota que com essa fórmula, quanto maior o número de dependências (acoplamentos) eferentes em relação às eferentes, mais instável o resultado é (próximo de 1). E o inverso também é verdadeiro.&lt;/p&gt;




&lt;p&gt;Isso acontece por dois motivos:&lt;/p&gt;

&lt;p&gt;- Quanto maior o número de dependências que nosso componente tem de outros (eferentes), mais suscetível à falhas; e&lt;/p&gt;

&lt;p&gt;- Quanto maior o número de outros componentes que dependem da gente (aferentes) mais estável a gente precisa ser.&lt;/p&gt;




&lt;p&gt;Pelo que sei, esse índice foi criado pelo Robert C. Martin (?). Mas o conheci por um texto do &lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/elemarjr"&gt;@elemarjr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Esse índice pode ser aplicado a muitas coisas (de classes a serviços e além), tem algumas limitações e acho válido falarmos sobre elas também.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arquiteturadesoftware.online/volume-1/nunca-ignore-o-acoplamento-capitulo-4-v1-03/" rel="noopener noreferrer"&gt;https://arquiteturadesoftware.online/volume-1/nunca-ignore-o-acoplamento-capitulo-4-v1-03/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Por exemplo, um componente com 0 dependências aferentes, e 1 ou 1000 eferentes vai ter o mesmo índice máximo de instabilidade, mas na prática um componente com 1000 dependências é muito mais frágil do que um com 1.&lt;/p&gt;

&lt;p&gt;Então se decidir aplicá-lo, tenha isso em mente!&lt;/p&gt;

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

</description>
    </item>
    <item>
      <title>[Desafio] - "Low Level" toInt Function</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Fri, 02 Aug 2024 16:43:55 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/desafio-low-level-toint-function-19hk</link>
      <guid>https://dev.to/zanfranceschi/desafio-low-level-toint-function-19hk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://x.com/zanfranceschi/status/1819413388360810601" rel="noopener noreferrer"&gt;https://x.com/zanfranceschi/status/1819413388360810601&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Um desafio "low level" pra você.&lt;/p&gt;

&lt;p&gt;Crie uma função &lt;code&gt;toInt&lt;/code&gt; que transforma strings numéricas (ex. "42") em números inteiros SEM usar funções embutidas/nativas da sua lang como int, intval, parseInt, etc.&lt;/p&gt;

&lt;p&gt;Dica: talvez você precise se apoiar numa tabela de caracteres.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Conceito] - Meus 3 Tipos Preferidos de Diagramas</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Sat, 06 Jul 2024 17:58:20 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/conceito-meus-3-tipos-preferidos-de-diagramas-20me</link>
      <guid>https://dev.to/zanfranceschi/conceito-meus-3-tipos-preferidos-de-diagramas-20me</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://x.com/zanfranceschi/status/1809646770361614528" rel="noopener noreferrer"&gt;https://x.com/zanfranceschi/status/1809646770361614528&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Vou compartilhar com você os tipos de diagramas que mais gosto e uso para desenhar soluções novas ou mapear soluções existentes.&lt;/p&gt;

&lt;p&gt;Segue o fio. 🧵&lt;/p&gt;

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




&lt;p&gt;Antes de mais nada, acho importante saber diferenciar desenhos ESTRUTURAIS e COMPORTAMENTAIS. Então se você não sabe, vale a pena dar uma lida sobre isso antes de prosseguir – já escrevi sobre isso nessa thread. 👇&lt;/p&gt;

&lt;p&gt;Depois volta aqui.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/zanfranceschi/status/1515015604977401857" rel="noopener noreferrer"&gt;https://x.com/zanfranceschi/status/1515015604977401857&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;DIAGRAMAS DE SEQUÊNCIA&lt;/p&gt;

&lt;p&gt;De longe, esse é o diagrama que mais uso. Pra mim, ele é muito útil pra desenhar integrações entre serviços/aplicações.&lt;/p&gt;

&lt;p&gt;Também é possível desenhar interações entre componentes dentro da mesma aplicação (no mesmo processo), mas raramente faço isso.&lt;/p&gt;

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




&lt;p&gt;DIAGRAMAS DE COMPONENTES&lt;/p&gt;

&lt;p&gt;Acho um bom diagrama pra mostrar dependências entre serviços. É uma visão estática que oferece um bom contexto duma solução. Diria que é uma alternativa mais técnica e menos descritiva aos primeiros níveis do modelo C4 do &lt;a class="mentioned-user" href="https://dev.to/simonbrown"&gt;@simonbrown&lt;/a&gt;.&lt;/p&gt;

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




&lt;p&gt;DIAGRAMA DE MÁQUINA DE ESTADOS&lt;/p&gt;

&lt;p&gt;Uso com menos frequência, mas acho ele muito útil pra quando preciso modela ou entender os possíveis estados de algo mais complexo. Desenhá-los me ajuda a fixar e/ou fomentar o entendimento dessas coisas mais complexas.&lt;/p&gt;

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




&lt;p&gt;Pra mim, essa é a frequência de uso dos diagramas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SEQUÊNCIA: muito frequente&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;COMPONENTES: frequente (geralmente após desenhar diagramas de sequência)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ESTADOS: pouco frequente (apenas quando preciso desenhar algo complexo o suficiente pra ser difícil de lembrar/decorar)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Eu praticamente só uso o drawio justamente por ter um bom suporte aos diagramas de sequência.&lt;/p&gt;

&lt;p&gt;Dá pra fazer bons diagramas com mermaid ou plantuml – eles são bons porque você não perde tempo com alinhamentos. Mas são menos flexíveis e ficam ruins com modelos grandes.&lt;/p&gt;




&lt;p&gt;Muita gente usa excalidraw, miro, etc. Mas por causa da falta de suporte ou suporte ruim aos diagramas de sequência, raramente uso essas ferramentas.&lt;/p&gt;

&lt;p&gt;Cada pessoa se dá melhor com diferentes diagramas e o essencial no final é sempre se comunicar bem ­– com qualquer notação!&lt;/p&gt;

&lt;p&gt;Fim.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Conceito] - Não Use HTTP 404 ou 204 para Buscas Sem Resultados</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Tue, 04 Jun 2024 03:45:15 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/conceito-nao-use-http-404-ou-204-para-buscas-sem-resultados-6ki</link>
      <guid>https://dev.to/zanfranceschi/conceito-nao-use-http-404-ou-204-para-buscas-sem-resultados-6ki</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://x.com/zanfranceschi/status/1797835707962245352" rel="noopener noreferrer"&gt;https://x.com/zanfranceschi/status/1797835707962245352&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Bora falar um pouco de semântica HTTP e porque acho FEIO retornar um 404 numa busca sem resultados?&lt;/p&gt;

&lt;p&gt;No HTTP, uma imagem, uma folha de estilos, um arquivo javascript e detalhes de um usuário em formato JSON são todos igualmente considerados RECURSOS. TUDO É RECURSO!&lt;/p&gt;

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

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




&lt;p&gt;E como TUDO É UM RECURSO, um endpoint de busca também é um recurso por si só!&lt;/p&gt;

&lt;p&gt;Vamos supor os seguintes endpoints:&lt;/p&gt;

&lt;p&gt;GET /users/:id - retorna detalhes de um usuário.&lt;br&gt;
GET /users?q=:termo - retorna o resultado duma busca.&lt;/p&gt;




&lt;p&gt;Dado que todos nós concordamos que GET /users é um recurso (certo?), o CONTEÚDO desse recurso, que é o resultado duma busca, por exemplo, pode ou não conter informações em formato de lista sobre usuários com atributos que se assemelham ao termo usado na query string 'q'.&lt;/p&gt;




&lt;p&gt;O retorno de GET /users?=berto poderia ser algo como:&lt;/p&gt;

&lt;p&gt;[{"nome": "Roberto"}, {"nome": "Adalberto"}]&lt;/p&gt;

&lt;p&gt;E uma chamada para o mesmo recurso de busca com parâmetros diferentes – GET /users?=jubis – poderia retornar algo como:&lt;/p&gt;

&lt;p&gt;[]&lt;/p&gt;

&lt;p&gt;...uma lista vazia.&lt;/p&gt;

&lt;p&gt;GET /users é um recurso – sempre!&lt;/p&gt;




&lt;p&gt;404 é considerado um erro de quem chama seu servidor informando um recurso inexistente! O recurso de busca tá lá, o que não tá é o usuário com o nome Jubiscleiton que você colocou no parâmetro de busca. Faz sentido?&lt;/p&gt;




&lt;p&gt;Se você é (era?) do time 404, espero ter te convencido de que uma busca é um recurso por si só.&lt;/p&gt;

&lt;p&gt;Agora vou falar com você que é do time 204. Fica junto, cola na grade.&lt;/p&gt;

&lt;p&gt;"Ain, mas não tem resultado, então não tem conteúdo, então é 204" ouço você resmungar. Rola pra baixo. ↓&lt;/p&gt;




&lt;p&gt;SEMANTICAMENTE, a gente usa 204 pra quando estamos cagando para o (não) conteúdo.&lt;/p&gt;

&lt;p&gt;Por exemplo, quando você manda um PUT /users/1, foda-se o corpo porque você sabe o novo estado do recurso. Tudo que importa é um retorno HTTP com status 204 dizendo que sua requisição deu certo. 👍&lt;/p&gt;




&lt;p&gt;E num recurso que retorna, p.ex., uma lista (vazia ou não), você se importa com o corpo. É muito mais uniforme verificar o tamanho da lista do resultado da busca, por exemplo. Do contrário, você teria que verificar o status code pra ver se tem itens na lista. ↓&lt;/p&gt;




&lt;p&gt;if vote 200t&lt;br&gt;
 then prinltn(data)&lt;br&gt;
else if vote 204t&lt;br&gt;
 then "sem resultados"&lt;/p&gt;

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




&lt;p&gt;Pra finalizar, uma singela homenagem ao &lt;a class="mentioned-user" href="https://dev.to/leandronsp"&gt;@leandronsp&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Poesia "Pelo Reconhecimento da Busca Como um Recurso" by Zan:&lt;/p&gt;

&lt;p&gt;GET /users/:id é a comida&lt;br&gt;
GET /users?q=:termo é o pote&lt;br&gt;
E o pote vazio&lt;br&gt;
Não deixa de ser um pote&lt;/p&gt;




&lt;p&gt;Mais uma coisa: se você tá mexendo num legado que retorna 404 ou 204 pra uma busca vazia e simplesmente não existe benefício em mudar isso, não sofra. O que importa em primeiro lugar é funcionar – seja com 404 ou 204, sinceramente.&lt;/p&gt;




&lt;p&gt;Muito obrigado se chegou até aqui.&lt;/p&gt;

&lt;p&gt;E não esqueça de deixar seu like, se inscrever no canal, e ativar o sininho pra você não vídeo novo do canal.&lt;/p&gt;

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

</description>
    </item>
    <item>
      <title>[Desafio] - Race Condition em Sistemas Distribuídos</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Thu, 04 Jan 2024 22:42:19 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/desafio-race-condition-em-sistemas-distribuidos-5hb3</link>
      <guid>https://dev.to/zanfranceschi/desafio-race-condition-em-sistemas-distribuidos-5hb3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1743040590751977636" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1743040590751977636&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Eu tenho a solução para sua falta de novos problemas! Yey 🥹&lt;/p&gt;

&lt;p&gt;Cola aqui pra resolver esse desafio de RACE CONDITION em um SISTEMA DISTRIBUÍDO de compras.&lt;/p&gt;

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

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




&lt;p&gt;DISCLAIMER: É um cenário simplificado e hipotético. (O diagrama tá em inglês porque vocês são tudo metido a besta, mas saibam que prefiro em pt_BR 💅).&lt;/p&gt;

&lt;p&gt;Acredito que esse desafio seja adequado pra quem já é pleno – talvez os sandy e júnior sofram um pouco pra resolvê-lo.&lt;/p&gt;




&lt;p&gt;CENÁRIO: Um conjunto de aplicações com serviços assíncronos de cadastro de cliente e processamento de pagamentos de compras.&lt;/p&gt;

&lt;p&gt;However, existe a premissa de que um cliente já esteja persistido no banco do serviço de pagamentos para que os pagamentos sejam processados.&lt;/p&gt;

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




&lt;p&gt;E para que essa premissa seja satisfeita, o serviço de cadastro emite um evento sempre que um cliente for cadastrado. A imagem mostra esse fluxo.&lt;/p&gt;

&lt;p&gt;(Obs.: Esse padrão em que serviço de pgto guarda uma referência do cliente se chama "Event-Carried State Transfer" – já falei sobre.)&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://twitter.com/zanfranceschi/status/1511294401603006465" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1511294401603006465&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;O PROBLEMA:&lt;/p&gt;

&lt;p&gt;Só que para novos clientes, às vezes acontece do comando para processar o pagamento ser consumido antes do consumo do evento de cadastro do cliente. Temos aí um cenário de RACE CONDITION! Ebaaa! 🥲&lt;/p&gt;

&lt;p&gt;E aí, o pessoal te incumbiu de resolver esse problema.&lt;/p&gt;

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




&lt;p&gt;E pro problema ficar ainda mais problemático (afinal queremos problemas aqui, não é mesmo?), te pediram pra evitar o uso de banco de dados para essa resolução – lhe pediram para que use outras filas (??).&lt;/p&gt;

&lt;p&gt;E aí, dev com tempo livre em busca de problemas, como resolve isso?!&lt;/p&gt;




&lt;p&gt;Muito obrigado a você que chegou até aqui!!! ♥️&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Conceito] - Lock Pessimista x Otimista: Desenvolvendo Senso Analítico</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Wed, 03 Jan 2024 04:51:43 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/conceito-lock-pessimista-x-otimista-desenvolvendo-senso-analitico-2k</link>
      <guid>https://dev.to/zanfranceschi/conceito-lock-pessimista-x-otimista-desenvolvendo-senso-analitico-2k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1742406772139430162" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1742406772139430162&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Esses dias postei provocações sobre lock otimista x pessimista. Alguns disseram que até certo nível de concorrência/conflito uma opção vale mais a pena que outra.&lt;/p&gt;

&lt;p&gt;Vamos pensar nisso juntos? Não vou dar uma resposta – quero apenas aprofundar nosso senso analítico.&lt;/p&gt;

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

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

&lt;p&gt;&lt;a href="https://twitter.com/zanfranceschi/status/1738927304372371552" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1738927304372371552&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;DISCLAIMER: Essa thread vale mais a pena se você souber pelo menos por cima o que é um lock otimista e um lock pessimista de banco de dados. Se não souber e mesmo assim quiser continuar lendo, tem todo meu apoio. rsrs&lt;/p&gt;

&lt;p&gt;Mas sério, dá uma pesquisada – não são conceitos difíceis.&lt;/p&gt;




&lt;p&gt;→ O primeiro passo é termos números concretos. Bora pensar um pouco sobre a probabilidade de conflitos. Pra isso, vamos imaginar o seguinte cenário: requisições simultâneas para comprar algum produto – para simplicidade, vamos imaginar que todos os produtos vendem a mesma coisa.&lt;/p&gt;




&lt;p&gt;Vamos então supor que temos 10 requisições simultâneas para 8 produtos diferentes. Queremos calcular a probabilidade de p.ex. 2 dessas requisições concorrerem para afetar o estoque do mesmo produto. Lembre-se, é um cenário síncrono e simplista!&lt;/p&gt;

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




&lt;p&gt;Para chegar nisso, precisamos achar o número de combinações de conflitos (R ÷ C × P × P ^ (R - C)) e dividí-lo pelo número total de combinações (P ^ R), onde R = número de requisições simultâneas, P = produtos disponíveis, C = número de conflitos.&lt;/p&gt;

&lt;p&gt;R ÷ C × P × P ^ (R - C) / P ^ R&lt;/p&gt;




&lt;p&gt;Meio mala essa fórmula, eu sei. O resultado dela é 0,625 – ou seja, ~62% de chance de conflito/concorrência com os parâmetros mencionados. Se quiséssemos a probabilidade com, p.ex., 3 conflitos, essa porcentagem cairia para ~5%; com 4, iria para ~0,4%. Com 5, 4,8828125E-4. 🥲&lt;/p&gt;




&lt;p&gt;Agora a gente precisa entender quanto tempo &amp;gt;MAIS OU MENOS&amp;lt; cada abordagem – pessimista e otimista – leva pra processar cada requisição.&lt;/p&gt;




&lt;p&gt;Vamos começar pela abordagem pessimista chutando um valor para o processamento da requisição: ~10ms. Como existe a concorrência de 2 requisições, a gente teria por cima um tempo de processamento de ~20ms para as 10 requisições simultâneas.&lt;/p&gt;




&lt;p&gt;Se fossem 3 conflitos, ~30ms; 4, ~40ms para 10 requisições; e assim por diante. Por favor, note que essa é uma estimativa simplificada.&lt;/p&gt;




&lt;p&gt;Nesse cenário pessimista, a gente geralmente precisa de menos mecanismos para tratar problemas de inconsistência nos dados.&lt;/p&gt;

&lt;p&gt;Lembre-se, estamos fazendo mais locks para termos mais consistência de dados ao preço de uma possível maior contenção – menos paralelismo.&lt;/p&gt;




&lt;p&gt;Bora pro otimismo – aqui a porca torce o rabo. No cenário Poliana, a gente geralmente introduz mais mecanismos para compensar os conflitos/não possibilidade de realização dos comandos no banco. Isso pode se traduzir em retentativas, rollbacks, mensagens de erro, etc, e etc.&lt;/p&gt;




&lt;p&gt;Pra nossa comparação fazer sentido, deveríamos incluir o tempo de processamento desses possíveis mecanismos de compensação. Por exemplo, 1 retentativa automática pode levar o dobro do tempo; 2 retentativas o triplo; devolver uma mensagem de erro pode ser muito rápido, etc.&lt;/p&gt;




&lt;p&gt;Se devolver uma mensagem de erro, talvez não haja acréscimo de tempo como há para uma compensação automática, mas talvez o usuário final o irá fazer manualmente gerando mais requisições subsequentes. Isso tudo precisa ser considerado. 🤔&lt;/p&gt;




&lt;p&gt;A maior diferença entre os dois cenários é que o pessimista é (mais ou menos) mais serial durante os conflitos (porque há o lock de mais registros) e o cenário pessimista é menos serial porque um processo interfere menos em outros (não há lock por toda a transação).&lt;/p&gt;




&lt;p&gt;Uma estimativa super simplificada do cenário otimista, onde apenas uma mensagem de erro é devolvida, se tivéssemos 2, 3 ou N conflitos simultâneos e cada processamento levasse ~10ms, nós ainda teríamos os mesmos ~10ms para as 10 requisições simultâneas – com ou sem conflitos.&lt;/p&gt;




&lt;p&gt;Vou deixar pra você fazer um exercício sobre como calcular o cenário otimista duma maneira melhor, pois estou com 2% de life estatística. 🙂&lt;/p&gt;

&lt;p&gt;Espero que agora você tenha pelo menos uma intuição sobre alguns cálculos para obter números relevantes.&lt;/p&gt;




&lt;p&gt;Obviamente, num cenário real muitas outras dimensões seriam consideradas. P.ex.: produtos que vendem mais (ponderação), picos de acesso, promoções, publicidade, etc. Em outros domínios, outras dimensões devem ser consideradas.&lt;/p&gt;




&lt;p&gt;O resumo é o seguinte:&lt;/p&gt;

&lt;p&gt;- Tente se basear em números;&lt;br&gt;
- Entenda as dimensões específicas do seu problema/domínio;&lt;br&gt;
- Faça experimentos! A prática muitas vezes nos dá insights muito mais tangíveis do que algumas teorias, ainda mais quando não temos experiência.&lt;/p&gt;




&lt;p&gt;Talvez eu tenha sido filosófico/genérico demais nessa thread porque na verdade muita coisa nela serve pra outras coisas não relacionadas a simplesmente escolher entre usar uma abordagem de lock pessimista x otimista de banco de dados (inclusive, existem abordagens híbridas!).&lt;/p&gt;




&lt;p&gt;Mas olha só: muito obrigado se você chegou até aqui – mesmo!&lt;/p&gt;

&lt;p&gt;Um abraço pra quem é de abraço e um beijo pra quem é de beijo. ♥️&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Desafio] - Engenharia Reversa De Algoritmo</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Mon, 20 Nov 2023 14:49:23 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/desafio-engenharia-reversa-de-algoritmo-bpn</link>
      <guid>https://dev.to/zanfranceschi/desafio-engenharia-reversa-de-algoritmo-bpn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1726613006921150913" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1726613006921150913&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Pega esse desafio de engenharia reversa.&lt;/p&gt;

&lt;p&gt;1. Explique o que a função "f(units input) → output" está fazendo apenas olhando os exemplos das imagens.&lt;/p&gt;

&lt;p&gt;2. Se achou fácil, implemente a função – experimente com e sem recursão. E não esqueça de postar pra gente ver!&lt;/p&gt;

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

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

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

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

</description>
    </item>
    <item>
      <title>[Conceito] - Como Atuar com Arquitetura</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Tue, 18 Jul 2023 01:27:30 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/conceito-como-atuar-com-arquitetura-1a1j</link>
      <guid>https://dev.to/zanfranceschi/conceito-como-atuar-com-arquitetura-1a1j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1681112067934396416" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1681112067934396416&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Algumas pessoas me perguntam sobre arquitetura – pedem algum direcionamento, livros, cursos, etc.&lt;/p&gt;

&lt;p&gt;Tenho cerca de 10 anos de experiência atuando exclusivamente com arquitetura e o começo foi difícil porque é uma disciplina sem muito material explicitamente dedicado.&lt;/p&gt;

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

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




&lt;p&gt;DISCLAIMER 1: O assunto aqui é arquitetura de sistemas, integrações, solução. Não é sobre a organização de código – arquitetura de aplicação, software.&lt;/p&gt;

&lt;p&gt;DISCLAIMER 2: É o meu ponto de vista, a minha experiência individual.&lt;/p&gt;




&lt;p&gt;Vou começar pela conclusão: é uma disciplina/área que dificilmente no início você vai se sentir preparada/o.&lt;/p&gt;

&lt;p&gt;Se já estiver dando seus primeiros passos nessa direção e tiver aquela sensação de estar perdida/o, saiba que isso é mais normal do que imagina.&lt;/p&gt;




&lt;p&gt;EXPERIÊNCIA PRÁTICA&lt;/p&gt;

&lt;p&gt;Arquitetura (ou "System Design" que está mais na moda) é difícil praticar porque os desafios estão justamente na escala, no longo tempo de execução dos sistemas, na operação, etc. Coisas que um localhost ou apenas uma conta na AWS não vão te oferecer.&lt;/p&gt;




&lt;p&gt;ABRANGÊNCIA DE CONHECIMENTO&lt;/p&gt;

&lt;p&gt;Cada empresa pode – e geralmente vai – exigir diferentes níveis de conhecimento em diferentes subáreas para quem exerce a disciplina de arquitetura. Existem empresas com times dedicados à rede, então p.ex. uma arquiteta talvez não precise conhecer [+]&lt;/p&gt;




&lt;p&gt;muita coisa ou até mesmo não tenha autonomia para decisões nessa subárea. O mesmo pode acontecer com bancos de dados, armazenamento, identificação/autenticação/autorização, etc.&lt;/p&gt;




&lt;p&gt;Na minha experiência, geralmente quanto maior a empresa, mais as coisas já estão resolvidas por times dedicados.&lt;/p&gt;

&lt;p&gt;Em empresas menores, geralmente você terá uma atuação mais abrangente e aprofundada – você precisará conhecer mais sobre mais coisas.&lt;/p&gt;




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

&lt;p&gt;Um desenho pode funcionar muito bem em uma empresa, mas não em outra. O código de uma API tem mais chances de funcionar bem em mais lugares. Arquitetura é sobre contexto: vendors, suporte, operação, orçamento, infra, etc. Já um código é algo mais especializado/focado.&lt;/p&gt;




&lt;p&gt;Você precisa desenhar a solução de acordo com as ferramentas, suporte, conhecimento das pessoas, e qualquer outro tipo de recurso disponível para aquele contexto. Não adianta colocar Kubernetes que funciona super bem para uma empresa numa empresa que não tem a capacidade e/ou [+]&lt;/p&gt;




&lt;p&gt;intenção de manter uma tecnologia dessas. gRPC pode ter sido uma escolha muito boa na sua empresa anterior, mas na atual pode simplesmente não fazer sentido. E assim por diante.&lt;/p&gt;

&lt;p&gt;Ou seja, contexto e restrições – que podem ser a mesma coisa no final do dia.&lt;/p&gt;




&lt;p&gt;HÁ ESPERANÇA&lt;/p&gt;

&lt;p&gt;Mas nem tudo é uma mudança drástica ou uma experiência completamente diferente de empresa para empresa. Com o passar do tempo e acúmulo de experiência, você nota que muitas coisas mais fundamentais são iguais nos desenhos de solução de diversas empresas.&lt;/p&gt;




&lt;p&gt;Vê-se que para um tipo de cenário, p.ex. o processamento assíncrono é mais adequado, e usar Kafka, RabbitMQ, uma fila em banco de dados é mais um detalhe de implementação. E assim o é com muitas outras coisas – segurança, processamento em lote, redes pública vs privada, etc.&lt;/p&gt;




&lt;p&gt;Ou seja, a cada novo desenho, novo projeto, você pode aprender mais um pouquinho e usar um pouco do que já aprendeu. É um ciclo que vai – mais ou menos rapidamente dependendo da sua exposição à coisas novas – preenchendo alguns buracos de conhecimento dessa estrada.&lt;/p&gt;




&lt;p&gt;CARGO/DISCIPLINA&lt;/p&gt;

&lt;p&gt;Algumas empresas possuem o cargo para arquitetura, outras empresas incorporam a arquitetura como uma disciplina aplicada pela engenharia. No começo, não se preocupe muito com títulos, se preocupe com o aprendizado.&lt;/p&gt;




&lt;p&gt;E COMO APRENDER?&lt;/p&gt;

&lt;p&gt;A pergunta de milhões! Não existe uma resposta, mas uma forma de aprender é manter a curiosidade, buscar entender como as coisas funcionam. Se você é dev, procure entender onde e como as aplicações que desenvolve funcionam. Se envolva com times e pessoas com [+]&lt;/p&gt;




&lt;p&gt;conhecimentos diferentes dos seus. Fale com DBAs, pessoal de segurança, de foundation, etc. Se junte com pessoas que exercem a disciplina de arquitetura. Tente fazer um desenho de algo que já sabe como poderia funcionar – talvez algo mais simples no início.&lt;/p&gt;




&lt;p&gt;Arquitetura/System Design é uma jornada gradual e às vezes mais ambígua do que programação justamente pela quantidade das dimensões/interpretações que podem ser menos objetivas para um desenho (pessoas, contratos, restrições, suporte, etc.).&lt;/p&gt;




&lt;p&gt;Tenha paciência! Eu nunca vi uma arquiteta ou arquiteto júnior, mas todo mundo envelhece e fica mais experiente. 🙃&lt;/p&gt;

&lt;p&gt;E muito obrigado por ter lido até aqui! ♥️&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Desafio] - Agregação de Registros</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Fri, 14 Jul 2023 14:04:26 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/desafio-agregacao-de-registros-4299</link>
      <guid>https://dev.to/zanfranceschi/desafio-agregacao-de-registros-4299</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1679497149732585472" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1679497149732585472&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Pega esse desafio de agregação de registros!&lt;/p&gt;

&lt;p&gt;Dado registros granulares que contêm data e quantidade, crie uma função que os agregue por data em um dicionário e some os atributos "qtd". O código a seguir explica melhor o desafio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# dado os seguintes registros
&lt;/span&gt;&lt;span class="n"&gt;registros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-13&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-14&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-13&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-14&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-15&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-13&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&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="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-17&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-16&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qtd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="c1"&gt;# desenvolva uma função de agrupamento
&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;agrupar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registros&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# que retorne o seguinte resultado
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-13&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-14&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-15&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-17&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-07-16&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Se alguém tiver curiosidade sobre como isso poderia ser feito em Clojure, aí está.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;agrupar&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;registros&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                  &lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;second&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reduce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="p"&gt;))])&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;group-by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;registros&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;agrupar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-13"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-14"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-13"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-14"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-12"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-12"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-12"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-15"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-13"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-12"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-17"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2023-07-16"&lt;/span&gt;&lt;span class="n"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:qtd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;}])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>[Desafio] - Algoritmo Round-Robin Pica-Pau</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Sat, 08 Jul 2023 16:50:07 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/desafio-algoritmo-round-robin-pica-pau-4ifn</link>
      <guid>https://dev.to/zanfranceschi/desafio-algoritmo-round-robin-pica-pau-4ifn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Conteúdo original em &lt;a href="https://twitter.com/zanfranceschi/status/1677719152545636352" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1677719152545636352&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ei dev,&lt;/p&gt;

&lt;p&gt;Pega esse desafio do algoritmo Round Robin do Pica-Pau!&lt;/p&gt;

&lt;p&gt;Faça um algoritmo de distribuição/ciclo da mesma forma que o Pica-Pau fez com o lobo do episódio: "1 pra mim, 1 pra você; 2 pra mim (pegando 2 itens), 2 pra você (dando apenas 1 item)".&lt;/p&gt;

&lt;p&gt;cc @sseraphini&lt;/p&gt;

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

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




&lt;p&gt;O resultado precisa ser algo como na imagem aqui.&lt;/p&gt;

&lt;p&gt;Escolhi Python pro exemplo/guia porque é uma lang fácil de ler, mas obviamente faça com sua lang preferida.&lt;/p&gt;

&lt;p&gt;Posta aí depois a presepada que você fez!&lt;/p&gt;

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

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




&lt;p&gt;Ah, me esqueci. Se quiser saber o que é um algoritmo round-robin que não seja zoeira, olha essa thread aqui.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/zanfranceschi/status/1525916697332371457" rel="noopener noreferrer"&gt;https://twitter.com/zanfranceschi/status/1525916697332371457&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Desafio] - 10 Desafios Simples de System Design: Resolução 5/9 (Integração com Eventos via Webhook)</title>
      <dc:creator>Francisco Zanfranceschi</dc:creator>
      <pubDate>Fri, 07 Apr 2023 17:51:50 +0000</pubDate>
      <link>https://dev.to/zanfranceschi/desafio-10-desafios-simples-de-system-design-resolucao-59-integracao-com-eventos-via-webhook-656</link>
      <guid>https://dev.to/zanfranceschi/desafio-10-desafios-simples-de-system-design-resolucao-59-integracao-com-eventos-via-webhook-656</guid>
      <description>&lt;p&gt;Dando continuidade às discussões sobre os 10 Desafios Simples de System Design, esse post é sobre Integração com Eventos via Webhook (parte 5/9).&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/zanfranceschi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F839958%2F86f93374-f880-4d01-a920-f5d0fbece718.jpeg" alt="zanfranceschi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/zanfranceschi/desafio-10-desafios-simples-de-system-design-c3h" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;[Desafio] - 10 Desafios Simples de System Design&lt;/h2&gt;
      &lt;h3&gt;Francisco Zanfranceschi ・ Mar 21 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;





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

&lt;p&gt;Para ser capaz de resolver esse desafio, é importante primeiramente entender o que é uma Arquitetura Orientada a Eventos. Não é o objetivo desse material se aprofundar nesse assunto, mas – superficialmente falando – eventos são como notificações de coisas que ocorreram (um usuário cadastrado, um pagamento realizado, etc.). Um sistema/arquitetura sem eventos, geralmente é um sistema baseado apenas em comandos (cadastre um usuário, faça o pagamento, etc.). Comandos existem mesmo numa arquitetura orientada a eventos e são geralmente as fontes geradoras de eventos.&lt;/p&gt;




&lt;p&gt;No mundo corporativo, geralmente webhooks são usados para integração/notificação de eventos entre sistemas de empresas diferentes localizados em redes diferentes. Isso ocorre porque webhooks nada mais são do que chamadas HTTP e HTTP é possivelmente o protocolo mais usado, conhecido, e interoperável que existe.&lt;/p&gt;

&lt;p&gt;Sistemas corporativos que residem na mesma rede/da mesma empresa frequentemente usam middlewares específicos de mensageria como o Kafka, RabbitMQ, IBM MQ, etc. Dessa forma, outro ponto importante nesse desafio é entender que provavelmente haverá integração entre sistemas que residem em redes diferentes quando se usa webhooks.&lt;/p&gt;




&lt;p&gt;A integração via eventos através de middlewares específicos de mensageria nos oferece muitas vantagens – mecanismos de tratamento de erros, retentativas, garantias de entrega, etc, são algumas delas. O material seguinte fala um pouco sobre isso.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/zanfranceschi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F839958%2F86f93374-f880-4d01-a920-f5d0fbece718.jpeg" alt="zanfranceschi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/zanfranceschi/conceito-filas-de-retry-e-dead-letter-4n45" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;[Conceito] - Filas de Retry e Dead-Letter&lt;/h2&gt;
      &lt;h3&gt;Francisco Zanfranceschi ・ May 6 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Sendo assim, um dos principais desafios em uma integração via webhooks é o tratamento de erros. O que ocorre se o endpoint de callback estiver indisponível? Algumas integrações mais robustas com webhooks oferecem retentativas. Ou seja, se o endpoint não responder à requisição com um status code HTTP na faixa 200 haverá requisições posteriores. É de suma importância considerar esse aspecto de tratamento de indisponibilidade e erros.&lt;/p&gt;




&lt;p&gt;Outro ponto importante é o tempo de resposta desejado para o endpoint do webhook. Talvez o endpoint de callback precise responder em um tempo máximo estipulado, caso contrário poderá ocorrer timeout da parte de quem fez a requisição (client timeout).&lt;/p&gt;

&lt;p&gt;Bom, considerando a questão de tratamento de erros e tempos de resposta, uma abordagem comum para endpoints de callbacks é não realizar o processamento de forma síncrona durante o ciclo de vida da requisição, mas enviar os eventos recebidos para um processamento assíncrono, inclusive se apoiando em middlewares de mensageria já citados aqui. Dessa forma, a única operação de I/O durante o ciclo de vida da requisição seria enviar o evento para outro componente para processamento posterior (banco de dados, fila, etc.).&lt;/p&gt;




&lt;p&gt;A segurança é um aspecto fundamental para esse problema. Considere sobre o endpoint de callback estar em uma rede pública ou conexão privada entre redes diferentes, tokens de acesso, revogação de tokens, VPNs, mTLS, regras de firewall com ranges de IPs de empresas, etc.&lt;/p&gt;




&lt;p&gt;O desafio proposto direciona para a elaboração do endpoint que receberá os eventos, mas elaborar uma solução do ponto de vista de quem notifica os eventos (realiza os callbacks) pode ser bem interessante também. Por exemplo, como será feita a retentativa, qual intervalo entre elas, etc.&lt;/p&gt;

&lt;p&gt;O material seguinte aborda sobre questões de retentativas.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/zanfranceschi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F839958%2F86f93374-f880-4d01-a920-f5d0fbece718.jpeg" alt="zanfranceschi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/zanfranceschi/conceito-backoff-e-jitter-3a30" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;[Conceito] - Backoff e Jitter&lt;/h2&gt;
      &lt;h3&gt;Francisco Zanfranceschi ・ Jun 6 '22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;





&lt;p&gt;Bom, é isso o que tinha para falar sobre integração via webhooks. Com certeza há muito mais aspectos do que os abordados aqui, mas espero que esse conteúdo tenha lhe dado uma boa intuição sobre os desafios da integração via webhooks.&lt;/p&gt;

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