<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Giálisson Rocha - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Giálisson Rocha - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 07 Jun 2026 14:16:06 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/gsor/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Os melhores podcasts de tecnologia para desenvolvedores de software ]]>
                </title>
                <description>
                    <![CDATA[ > Nota da tradução: o artigo abaixo foi escrito por Quincy Larson em inglês e fala a respeito de podcasts em inglês. Há, certamente, diversas alternativas em português, como o próprio podcast do freeCodeCamp [/portuguese/news/freecodecamp-podcast-em-portugues/] no idioma. No artigo, trataremos apenas de podcasts em inglês para aqueles que desejam praticar ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/os-melhores-podcasts-de-tecnologia-para-desenvolvedores-de-software/</link>
                <guid isPermaLink="false">6521fda4bb3de103e1f888cb</guid>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Wed, 10 Apr 2024 00:59:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/601054f50a2838549dcb807e.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/best-tech-podcasts-for-software-developers/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Best Tech Podcasts for Software Developers in 2021</a>
      </p><blockquote>Nota da tradução: o artigo abaixo foi escrito por Quincy Larson em inglês e fala a respeito de podcasts em inglês. Há, certamente, diversas alternativas em português, como o próprio <a href="https://www.freecodecamp.org/portuguese/news/freecodecamp-podcast-em-portugues/">podcast do freeCodeCamp</a> no idioma. No artigo, trataremos apenas de podcasts em inglês para aqueles que desejam praticar o idioma e se interar das novidades do mundo da tecnologia diretamente em inglês. </blockquote><p>Os podcasts são uma ótima maneira de se aprender sobre tecnologia em qualquer lugar. Eles podem expor você a uma ampla variedade de ferramentas e conceitos.</p><p>Desde que comecei a aprender a programar em 2012, ouvi milhares de horas de podcasts sobre tecnologia, geralmente enquanto me exercitava ou ia para o trabalho. Muitos desses podcasts ainda estão em alta. Este artigo se concentrará nesses recursos de aprendizado comprovados pelo tempo.</p><p>Uma observação antes de começarmos: antes que você comece a me enviar tweets sobre como deixei de fora seu podcast favorito, observe que excluí intencionalmente a maioria dos podcasts voltados para negócios e notícias. Em vez disso, concentrei-me em podcasts dirigidos por desenvolvedores e que têm os desenvolvedores em mente como público principal.</p><p>Posso dizer com segurança que todos esses podcasts são sólidos. Se você é um desenvolvedor ou está interessado em se tornar um desenvolvedor, esses podcasts o divertirão e iluminarão seus caminhos. Aproveite.</p><h2 id="o-melhor-podcast-de-desenvolvimento-para-a-web-syntaxfm">O melhor podcast de desenvolvimento para a web:<strong><strong> SyntaxFM</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/syntax-tasty-web-development-treats-wes-bos-HBLGrV82oAs.1400x1400.jpg" class="kg-image" alt="syntax-tasty-web-development-treats-wes-bos-HBLGrV82oAs.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/syntax-tasty-web-development-treats-wes-bos-HBLGrV82oAs.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/syntax-tasty-web-development-treats-wes-bos-HBLGrV82oAs.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/syntax-tasty-web-development-treats-wes-bos-HBLGrV82oAs.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do SyntaxFM</figcaption></figure><p>Sou fã de longa data de <a href="https://twitter.com/stolinski">Scott Tolinski</a> (um dançarino de break que se tornou desenvolvedor e dirige o canal LevelUpTuts no YouTube) e do icônico desenvolvedor canadense <a href="https://twitter.com/wesbos">Wes Bos</a>. Esses dois formam uma dupla carismática. Juntos, eles já apresentaram mais de 320 episódios de seu podcast SyntaxFM.</p><p>A cada episódio, Scott e Wes compartilham ferramentas e técnicas de desenvolvimento para a Web e frequentemente entrevistam alguns dos principais desenvolvedores da área.</p><p>Fique atento às suas dicas "saborosas" de CSS e JavaScript e ao seu senso de humor saudável.</p><p><a href="https://syntax.fm/">Navegue pelos episódios da SyntaxFM aqui</a>.</p><h2 id="o-melhor-podcast-para-c-digo-aberto-the-changelog">O melhor podcast para código aberto: <strong><strong>The Changelog</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/the-changelog-changelog-media-7o41SvyO8z_.1400x1400.jpg" class="kg-image" alt="the-changelog-changelog-media-7o41SvyO8z_.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/the-changelog-changelog-media-7o41SvyO8z_.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/the-changelog-changelog-media-7o41SvyO8z_.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/the-changelog-changelog-media-7o41SvyO8z_.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do The Changelog</figcaption></figure><p>O <em>The Changelog</em> é, a esta altura, uma instituição. Nos últimos anos, eles entrevistaram os criadores de uma grande variedade de projetos de código aberto.</p><p>Os principais anfitriões, <a href="https://twitter.com/adamstac">Adam Stacoviak</a> e <a href="https://twitter.com/jerodsanto">Jerod Santo</a>, são, eles mesmos, desenvolvedores. Eles mantêm uma comunidade on-line de última geração e incorporam toneladas de ferramentas de código aberto em sua própria plataforma.</p><p>Tive a honra de passar um tempo com eles na casa de Adam, em Houston, e <a href="https://changelog.com/ten">entrevistá-los para o 10º aniversário do podcast</a>. </p><p>Recomendo que você se inscreva e também navegue pelos mais de 400 episódios em seus arquivos (muitos deles têm até transcrições).</p><p><a href="https://changelog.com/podcast">Navegue pelos episódios do The Changelog aqui</a>.</p><h2 id="o-melhor-podcast-para-aprender-a-programar-learn-to-code-with-me">O melhor podcast para aprender a programar:<strong><strong> Learn to Code With Me</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/learn-to-code-with-me-laurence-bradford-nLOTazR6ph5-nVxCdhSp1Wf.1400x1400.jpg" class="kg-image" alt="learn-to-code-with-me-laurence-bradford-nLOTazR6ph5-nVxCdhSp1Wf.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/learn-to-code-with-me-laurence-bradford-nLOTazR6ph5-nVxCdhSp1Wf.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/learn-to-code-with-me-laurence-bradford-nLOTazR6ph5-nVxCdhSp1Wf.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/learn-to-code-with-me-laurence-bradford-nLOTazR6ph5-nVxCdhSp1Wf.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Learn to Code With Me</figcaption></figure><p>Em mais de 100 episódios, <a href="https://twitter.com/lebdev">Laurence Bradford</a> entrevistou uma grande variedade de desenvolvedores autodidatas. Aqui estão algumas das carreiras de pessoas que ela entrevistou antes de se tornarem desenvolvedores:</p><ul><li>seguranças de aeroporto</li><li>pais que ficam em casa</li><li>pastores</li><li>professores</li><li>e muito mais</li></ul><p>Ela também tem episódios que servem como guias para encontrar clientes <em>freelance</em>, escolher o laptop certo e aprender a programar enquanto cria os filhos. Recomendamos fortemente.</p><p><a href="https://learntocodewith.me/podcast/">Navegue pelos episódios do Podcast Learn to Code With Me Podcast aqui</a>.</p><h2 id="o-melhor-podcast-focado-em-desenvolvedores-empreendedores-o-podcast-indie-hackers">O melhor podcast focado em desenvolvedores-empreendedores<strong><strong>: </strong>o podcast<strong> Indie Hackers</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/the-indie-hackers-podcast-courtland-allen-e4XrQ1CkfMt-fATGd7LizVm.1400x1400.jpg" class="kg-image" alt="the-indie-hackers-podcast-courtland-allen-e4XrQ1CkfMt-fATGd7LizVm.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/the-indie-hackers-podcast-courtland-allen-e4XrQ1CkfMt-fATGd7LizVm.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/the-indie-hackers-podcast-courtland-allen-e4XrQ1CkfMt-fATGd7LizVm.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/the-indie-hackers-podcast-courtland-allen-e4XrQ1CkfMt-fATGd7LizVm.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Indie Hackers</figcaption></figure><p>Grande parte do mundo da tecnologia pensa nos negócios como uma série de rodadas de financiamento de capital de risco que levam a uma eventual "saída". Há, no entanto, milhares de empresas bem-sucedidas administradas pelos próprios desenvolvedores, muitas vezes sem nenhum financiamento externo.</p><p>Essas são as empresas "bootstrapped" nas quais <a href="https://twitter.com/csallen">Courtland Allen</a>, engenheiro treinado no MIT e que se tornou fundador, se dedica em seu podcast Indie Hackers.</p><p>Ao longo dos anos, Courtland entrevistou quase 200 fundadores – a maioria dos quais começou como desenvolvedores em tempo integral em outras empresas que iniciaram um projeto paralelo. Muitos desses projetos paralelos se transformaram em negócios lucrativos.</p><p>Em cada uma de suas entrevistas, Courtland faz com que esses desenvolvedores compartilhem seus números de receita com os ouvintes e tenta descobrir como eles foram tão bem-sucedidos. Ao longo do caminho, ele geralmente descobre insights que outros desenvolvedores podem usar para iniciar seus próprios negócios.</p><p><a href="https://www.indiehackers.com/podcasts?utm_campaign=Listen%20Notes&amp;utm_medium=website&amp;utm_source=listennotes.com">Navegue pelos episódios do podcast Indie Hackers aqui</a>.</p><h2 id="o-melhor-podcast-sobre-javascript-js-party">O melhor podcast sobre JavaScript<strong><strong>: JS Party</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/js-party-changelog-media-Id6Df4Nhi05.1400x1400.jpg" class="kg-image" alt="js-party-changelog-media-Id6Df4Nhi05.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/js-party-changelog-media-Id6Df4Nhi05.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/js-party-changelog-media-Id6Df4Nhi05.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/js-party-changelog-media-Id6Df4Nhi05.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do JS Party</figcaption></figure><p>O ecossistema JavaScript é enorme e diversificado, assim como esta lista de podcasts.</p><p>Toda semana, um painel rotativo de veteranos em JavaScript fala sobre novas bibliotecas, práticas recomendadas emergentes e outras mudanças que afetam os desenvolvedores.</p><p>Alguns dos muitos participantes frequentes do painel incluem:</p><ul><li>Desenvolvedora JS e professora <a href="https://twitter.com/shortdiv">Divya Sasidharan</a></li><li>Palestrante de Stanford e pioneiro do código aberto <a href="https://twitter.com/feross">Feross Aboukhadijeh</a></li><li>Entusiasta do TypeScript <a href="https://twitter.com/nicknisi">Nick Nisi</a></li><li>Defensor da descentralização <a href="https://twitter.com/mikeal">Mikeal Rogers</a></li><li>E engenheiro de software <a href="https://twitter.com/nomadtechie">Amal Hussein</a></li></ul><p>É um grupo divertido de pessoas que não apenas são apaixonadas por JavaScript, mas também fizeram contribuições significativas para a linguagem ao longo dos anos.</p><p><a href="https://changelog.com/jsparty">Veja os episódios do JS Party aqui</a>.</p><h2 id="o-melhor-podcast-sobre-python-talk-python-to-me">O melhor podcast sobre Python<strong><strong>: Talk Python to Me</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/talk-python-to-me-python-conversations-for-e85UJ2PBSAi.1400x1400.jpg" class="kg-image" alt="talk-python-to-me-python-conversations-for-e85UJ2PBSAi.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/talk-python-to-me-python-conversations-for-e85UJ2PBSAi.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/talk-python-to-me-python-conversations-for-e85UJ2PBSAi.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/talk-python-to-me-python-conversations-for-e85UJ2PBSAi.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Talk Python To Me</figcaption></figure><p>Toda semana, o desenvolvedor <a href="https://twitter.com/mkennedy">Michael Kennedy</a> explora o ecossistema Python e seus muitos aplicativos. Ao longo do caminho, ele entrevista entusiastas do Python de uma variedade de campos, incluindo:</p><ul><li>Desenvolvimento para a web</li><li>Ciência de dados</li><li>Aprendizado de máquina</li><li>E o meio acadêmico</li></ul><p>Com mais de 300 episódios para ouvir, o Talk Python To Me é uma ótima maneira de se expor a alguns dos pacotes mais poderosos do Python.</p><p><a href="https://talkpython.fm/episodes/all">Navegue pelos episódios do podcast Talk Python To Me aqui</a>.</p><h2 id="o-melhor-podcast-para-desenvolvedores-iniciantes-na-rea-o-podcast-code-newbie">O melhor podcast para desenvolvedores iniciantes na área<strong><strong>: </strong>o podcast<strong> Code Newbie</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/codenewbie-codenewbie-gOEruJxNc6_.1400x1399.jpg" class="kg-image" alt="codenewbie-codenewbie-gOEruJxNc6_.1400x1399" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/codenewbie-codenewbie-gOEruJxNc6_.1400x1399.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/codenewbie-codenewbie-gOEruJxNc6_.1400x1399.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/codenewbie-codenewbie-gOEruJxNc6_.1400x1399.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1399" loading="lazy"><figcaption>Logotipo do Code Newbie</figcaption></figure><p>Em setembro de 2014 – apenas um mês antes do lançamento do freeCodeCamp – <a href="https://twitter.com/saronyitbarek">Saron Yitbarek</a> lançou o podcast Code Newbie. Lembro-me com carinho de ter ouvido os primeiros episódios enquanto fazia corridas noturnas por São Francisco após sessões de programação que duravam o dia inteiro. Havia uma eletricidade no ar enquanto eu a ouvia entrevistar desenvolvedores de software autodidatas, alguns dos quais eram ainda mais novos na área do que eu.</p><p>Saron, é claro, tornou-se basicamente o rosto do movimento aprender a programar. Ela criou <a href="https://www.freecodecamp.org/news/inside-codeland-the-most-inclusive-supportive-developer-conference-yet-5f01cadf0a42/">a Codeland Developer Conference</a>, o excelente podcast <a href="https://www.redhat.com/en/command-line-heroes">Command Line Heroes podcast</a>. Porém, ela ainda grava novos episódios do Code Newbie, e eles são tão empolgantes quanto eram em 2014.</p><p>Ela já tem 261 episódios e não mostra sinais de estar diminuindo o ritmo. Se você se encontra no "deserto do desespero" ao aprender a programar e precisa de uma injeção de energia positiva, este é o podcast para você.</p><p><a href="https://www.codenewbie.org/podcast">Navegue pelos episódios do Code Newbie Podcast aqui</a>.</p><h2 id="o-melhor-podcast-sobre-aprendizado-de-m-quina-practical-ai">O melhor podcast sobre aprendizado de máquina<strong><strong>: Practical AI</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/practical-ai-changelog-media-2y6htZ4MdvW-VfEMrme9A4k.1400x1400.jpg" class="kg-image" alt="practical-ai-changelog-media-2y6htZ4MdvW-VfEMrme9A4k.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/practical-ai-changelog-media-2y6htZ4MdvW-VfEMrme9A4k.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/practical-ai-changelog-media-2y6htZ4MdvW-VfEMrme9A4k.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/practical-ai-changelog-media-2y6htZ4MdvW-VfEMrme9A4k.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Practical AI</figcaption></figure><p>O aprendizado de máquina tem inúmeras aplicações promissoras em tudo, desde carros autônomos até diagnósticos médicos. Quanto disso, no entanto, é exagero e quanto disso vai realmente acontecer nas próximas décadas?</p><p>O podcast Practical AI se concentra em implementações reais de ferramentas de aprendizado de máquina. Ele é apresentado por profissionais experientes que sabem do que estão falando: o cientista de dados <a href="https://twitter.com/dwhitena">Daniel Whitenack</a> e o engenheiro de software <a href="https://twitter.com/chrisbenson">Chris Benson</a>.</p><p>Em 120 episódios, Daniel e Chris entrevistam engenheiros que estão trabalhando com grandes conjuntos de dados – empresas de cartão de crédito, redes sociais e até mesmo governos. Eles o ajudam a analisar os mais recentes desenvolvimentos de aprendizado de máquina por meio de uma perspectiva mais prática.</p><p><a href="https://changelog.com/practicalai">Navegue pelos episódios de Practical AI aqui</a>.</p><h2 id="o-podcast-mais-atencioso-de-desenvolvedores-developer-tea">O podcast mais atencioso de desenvolvedores<strong><strong>: Developer Tea</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/developer-tea-spec-jonathan-cutrell-ohcZTfQrWeL-Yh5ar9JNDvE.1400x1400.jpg" class="kg-image" alt="developer-tea-spec-jonathan-cutrell-ohcZTfQrWeL-Yh5ar9JNDvE.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/developer-tea-spec-jonathan-cutrell-ohcZTfQrWeL-Yh5ar9JNDvE.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/developer-tea-spec-jonathan-cutrell-ohcZTfQrWeL-Yh5ar9JNDvE.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/developer-tea-spec-jonathan-cutrell-ohcZTfQrWeL-Yh5ar9JNDvE.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Developer Tea</figcaption></figure><p>Nos últimos 5 anos, o diretor de engenharia da PBS (e piloto de avião treinado) <a href="https://twitter.com/jcutrell">Jonathan Cutrell</a> compartilhou inúmeras dicas para desenvolvedores.</p><p>Muitos de seus 650 episódios são monólogos em que ele medita sobre um aspecto específico da experiência do desenvolvedor. Outros episódios são entrevistas íntimas com desenvolvedores que exploram temas de propósito e habilidade.</p><p>Este é um ótimo podcast para sessões de audição mais curtas, já que a maioria dos episódios tem apenas 15 ou 20 minutos de duração. Esses episódios o deixarão energizado e pronto para trabalhar com programação.</p><p><a href="https://spec.fm/podcasts/developer-tea">Navegue pelos episódios do Podcast Developer Tea aqui</a>.</p><h2 id="o-melhor-podcast-para-desenvolvedores-de-n-vel-m-dio-o-ladybug-podcast">O melhor podcast para desenvolvedores de nível médio<strong><strong>: </strong>o<strong> Ladybug Podcast</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/ladybug-podcast-YLstFJVCkvm-swCn6DupJQe.1400x1400.jpg" class="kg-image" alt="ladybug-podcast-YLstFJVCkvm-swCn6DupJQe.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/ladybug-podcast-YLstFJVCkvm-swCn6DupJQe.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/ladybug-podcast-YLstFJVCkvm-swCn6DupJQe.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/ladybug-podcast-YLstFJVCkvm-swCn6DupJQe.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Ladybug Podcast</figcaption></figure><p>O Ladybug Podcast é apresentado por quatro desenvolvedoras proeminentes de diversas origens – algumas autodidatas e outras com diplomas em Ciências da Computação – trabalhando com uma variedade de conjuntos de tecnologia: <a href="https://twitter.com/EmmaBostian">Emma Bostian</a>, <a href="https://twitter.com/shidonichan">Sidney Buckner</a>, <a href="https://twitter.com/ASpittel">Ali Spittel</a> e <a href="https://twitter.com/kvlly">Kelly Vaughn</a>.</p><p>Além de tópicos técnicos complexos, elas se concentram no crescimento da carreira, no desenvolvimento pessoal e até têm uma espécie de clube do livro, no qual todas leem o mesmo livro e o discutem.</p><p>Elas começaram o podcast em junho de 2019 e já publicaram mais de 65 episódios que você pode ouvir.</p><p><a href="https://www.ladybug.dev/episodes">Navegue pelos episódios do Ladybug Podcast aqui</a>.</p><h2 id="o-melhor-podcast-para-ui-ux-design-o-shoptalk-podcast">O melhor podcast para UI/UX Design<strong><strong>: </strong>O<strong> ShopTalk Podcast</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/shoptalk-podcast-feed-chris-coyier-and-dave-RD62zfpnKrv.1400x1400.jpg" class="kg-image" alt="shoptalk-podcast-feed-chris-coyier-and-dave-RD62zfpnKrv.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/shoptalk-podcast-feed-chris-coyier-and-dave-RD62zfpnKrv.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/shoptalk-podcast-feed-chris-coyier-and-dave-RD62zfpnKrv.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/shoptalk-podcast-feed-chris-coyier-and-dave-RD62zfpnKrv.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Shop Talk Show</figcaption></figure><p>Este é outro podcast de longa duração realizado por desenvolvedores famosos. <a href="https://twitter.com/chriscoyier">Chris Coyier</a>, criador do CSS Tricks e do CodePen, se junta ao desenvolvedor e prolífico podcaster <a href="https://twitter.com/davatron5000">Dave Rupert</a>. Juntos, eles falam sobre design para a web:</p><ul><li>Acessibilidade</li><li>Estéticas</li><li>Desempenho</li><li>Interação Humano-Computador</li><li>E mergulhe nos mínimos detalhes</li></ul><p>Em mais de 400 episódios, Chris e Dave exploram uma variedade de ferramentas antigas e novas. Tudo, desde o WordPress até o JAMstack.</p><p>Se você é um desenvolvedor que está começando a trabalhar com design – ou um designer que está começando a trabalhar com desenvolvimento – este é o podcast para você.</p><p><a href="https://shoptalkshow.com/">Navegue pelos episódios do ShopTalk Show aqui</a>.</p><h2 id="o-melhor-podcast-voltado-para-a-educa-o-de-desenvolvedores-the-hanselminutes-podcast">O melhor podcast voltado para a educação de desenvolvedores<strong><strong>: The Hanselminutes Podcast</strong></strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/CmsdbjuE.jpg" class="kg-image" alt="CmsdbjuE" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/CmsdbjuE.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/CmsdbjuE.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/CmsdbjuE.jpg 1518w" sizes="(min-width: 720px) 720px" width="1518" height="1263" loading="lazy"><figcaption>Alguns convidados recentes do Hanselminutes Podcast</figcaption></figure><p>Este é, de longe, o podcast mais antigo desta lista. Sua origem remonta a 2006, antes mesmo de a maioria das pessoas ter ouvido o termo "podcast".</p><p><a href="https://twitter.com/shanselman">Scott Hanselman</a> é um desenvolvedor e educador prolífico – principalmente em sua função de evangelista de desenvolvedores da Microsoft.</p><p>Em quase 800 episódios, Scott conversa com desenvolvedores de software de todas as áreas e de todos os cantos do mundo. Ele até incluiu transcrições completas de todos os seus episódios, para torná-los mais acessíveis a falantes não nativos do inglês.</p><p><a href="https://www.freecodecamp.org/news/best-tech-podcasts-for-software-developers/hanselminutes.com/episodes">Navegue pelos episódios do Podcast Hanselminutes aqui</a>.</p><h2 id="os-3-melhores-podcasts-para-seguran-a-cibern-tica-porque-todos-os-tr-s-valem-ouro-">Os 3 Melhores podcasts para segurança cibernética (porque todos os três valem ouro)</h2><p>Isso nos leva àquela que é, na minha humilde opinião, a área mais empolgante do podcasting de tecnologia: segurança da informação. O reino dos chapéus pretos, chapéus brancos e atores em nível estadual – todos competindo para ver quem pode hackear quem e quem pode defender melhor seus sistemas.</p><h3 id="melhor-podcast-de-seguran-a-cibern-tica-n-1-cyberwire-daily">Melhor podcast de segurança cibernética nº 1<strong><strong>: Cyberwire Daily</strong></strong></h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/the-cyberwire-daily-cyberwire-inc-dNPs3L8af7h-vKkUu8BsSbh.1400x1400.jpg" class="kg-image" alt="the-cyberwire-daily-cyberwire-inc-dNPs3L8af7h-vKkUu8BsSbh.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/the-cyberwire-daily-cyberwire-inc-dNPs3L8af7h-vKkUu8BsSbh.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/the-cyberwire-daily-cyberwire-inc-dNPs3L8af7h-vKkUu8BsSbh.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/the-cyberwire-daily-cyberwire-inc-dNPs3L8af7h-vKkUu8BsSbh.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Cyberwire Daily</figcaption></figure><p>Ouvir o Cyberwire Daily é uma boa maneira de ficar por dentro dos tópicos emergentes e, ao mesmo tempo, aumentar seu conhecimento prévio sobre segurança.</p><p>Não sou especialista em segurança, mas a segurança é uma parte importante de minhas discussões diárias. Ela permeia quase todas as decisões que nossa organização sem fins lucrativos toma como equipe. Portanto, considero este podcast uma parte vital de minha educação continuada.</p><p>Há mais de 1.500 episódios anteriores do Cyberwire Daily para navegar. É um registro vivo de notícias sobre segurança cibernética que remonta a 2015.</p><p><a href="https://thecyberwire.com/podcasts/daily-podcast">Navegue pelos episódios do CyberWire Daily Podcast aqui</a>.</p><h3 id="melhor-podcast-de-seguran-a-cibern-tica-n-2-malicious-life">Melhor podcast de segurança cibernética nº 2<strong><strong>: Malicious Life</strong></strong></h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/malicious-life-malicious-life-378EnTo0qI_-iEIF-ZyBgRQ.1400x1400.jpg" class="kg-image" alt="malicious-life-malicious-life-378EnTo0qI_-iEIF-ZyBgRQ.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/malicious-life-malicious-life-378EnTo0qI_-iEIF-ZyBgRQ.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/malicious-life-malicious-life-378EnTo0qI_-iEIF-ZyBgRQ.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/malicious-life-malicious-life-378EnTo0qI_-iEIF-ZyBgRQ.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo do Malicious Life</figcaption></figure><p>O Malicious Life é um podcast baseado em uma narrativa de um desenvolvedor misterioso com um sotaque legal que parece trabalhar para uma consultoria de segurança chamada Cybereason.</p><p>A cada episódio, o podcast conta uma história pouco conhecida por trás de <em>hacks </em>interessantes de toda a história da segurança cibernética. Até o momento, há mais de 110 episódios, o que é um catálogo bastante antigo para você absorver.</p><p><a href="https://malicious.life/">Navegue pelos episódios de Malicious Life aqui</a>.</p><h3 id="melhor-podcast-de-seguran-a-cibern-tica-n-3-darknet-diaries">Melhor podcast de segurança cibernética nº 3<strong><strong>: Darknet Diaries</strong></strong></h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/darknet-diaries-jack-rhysider-pTSkh95vCf2-ztuNyvC2F_O.1400x1400.jpg" class="kg-image" alt="darknet-diaries-jack-rhysider-pTSkh95vCf2-ztuNyvC2F_O.1400x1400" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/darknet-diaries-jack-rhysider-pTSkh95vCf2-ztuNyvC2F_O.1400x1400.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/darknet-diaries-jack-rhysider-pTSkh95vCf2-ztuNyvC2F_O.1400x1400.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/darknet-diaries-jack-rhysider-pTSkh95vCf2-ztuNyvC2F_O.1400x1400.jpg 1400w" sizes="(min-width: 720px) 720px" width="1400" height="1400" loading="lazy"><figcaption>Logotipo fo Darknet Diaries</figcaption></figure><p>Isso nos leva ao último podcast desta lista. Este talvez seja o podcast de tecnologia não noticioso mais popular do momento: Darknet Diaries.</p><p>Neste podcast, o anfitrião <a href="https://twitter.com/JackRhysider">Jack Rhysider</a> se concentra principalmente em criminosos capacitados pela tecnologia. Ele realmente atrai você com sua habilidade de contar histórias e produção de primeira linha.</p><p>Também digno de nota: Jack é bastante acessível em relação às métricas de seu podcast. Se estiver pensando em iniciar seu próprio podcast de tecnologia, <a href="https://darknetdiaries.com/stats/">não deixe de ler o relatório de avaliação de 2020 dele</a>.</p><p>Quando descobri Darknet Diaries em 2017, imediatamente voltei e ouvi o catálogo inteiro durante uma viagem de carro. Se você acabar fazendo o mesmo, não deixe de <a href="https://twitter.com/ossia">me marcar no Twitter</a> e me dizer qual é o seu episódio favorito.</p><p><a href="https://darknetdiaries.com/">Navegue pelos episódios de Darknet Diaries aqui</a>.</p><h2 id="como-eu-ou-o-podcasts">Como eu ouço podcasts</h2><p>Muitas pessoas me perguntam como eu ouço podcasts. Bem, chame-me de antiquado, mas eu uso apenas a aplicação de podcast padrão do meu iPhone. É gratuita, não há anúncios e não estou compartilhando meus dados com terceiros.</p><p>Ouço tudo em velocidade 2. Faço uso intenso do botão "pular 15 segundos para frente".</p><p>Uma área em que a aplicação de podcast da Apple deixa a desejar é seu mecanismo de busca. Portanto, para fazer a busca, uso uma ferramenta incrível de mecanismo de busca de podcast criada pelo colaborador do freeCodeCamp, Wenbin Fang, chamada <a href="https://www.listennotes.com/">ListenNotes.com</a>. Ele é extremamente rápido e tem muitos recursos úteis, inclusive um conveniente player de podcast baseado em HTML5.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/The_freeCodeCamp_Podcast_-_freeCodeCamp___Listen_Notes.png" class="kg-image" alt="The_freeCodeCamp_Podcast_-_freeCodeCamp___Listen_Notes" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/The_freeCodeCamp_Podcast_-_freeCodeCamp___Listen_Notes.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/The_freeCodeCamp_Podcast_-_freeCodeCamp___Listen_Notes.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/03/The_freeCodeCamp_Podcast_-_freeCodeCamp___Listen_Notes.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/The_freeCodeCamp_Podcast_-_freeCodeCamp___Listen_Notes.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1123" loading="lazy"></figure><p>Gosto tanto do ListenNotes que, para este artigo, eu teria feito um link apenas para o ListenNotes. Essa é a qualidade da experiência do usuário.</p><p>Porém, eu não queria privar esses incríveis criadores de podcasts dos visitantes e dos backlinks <code>rel="doFollow"</code>. Esses criadores de podcasts merecem toda a atenção que seus sites podem receber.</p><p>Outro fato interessante: Wenbin é um fanático por podcasts e criou algumas maneiras inovadoras de enfileirar podcasts e de ouvi-los em qualquer lugar. Se quiser se tornar um superusuário de podcasts como ele, experimente <a href="https://www.freecodecamp.org/news/podcasts-are-my-new-wikipedia-the-perfect-informal-learning-resource/#how-exactly-do-i-listen-to-podcasts-and-use-them-as-my-new-wikipedia">o método dele também</a> (texto em inglês).</p><p>De minha parte, isso é tudo. Espero que você aprenda muito com esses podcasts e aproveite esses recursos de aprendizagem gratuitos para se tornar um desenvolvedor melhor. Boa programação.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar uma aplicação em tempo real usando Socket.io, React, Node e MongoDB ]]>
                </title>
                <description>
                    <![CDATA[ > Nota da tradução: o artigo a seguir foi escrito quando o React estava em sua versão 16.7.0. No momento da tradução, ele se encontra em sua versão 18.2.0 e houve muitas mudanças no comportamento dos componentes – em especial, com a questão de roteamento. Caso deseje realizar o processo ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-uma-aplicacao-em-tempo-real-usando-socket-io-react-node-e-mongodb/</link>
                <guid isPermaLink="false">651893a9f57fe803e4aa2db2</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Tue, 09 Apr 2024 12:18:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/1_j_kShofJmfZ_-bEpt1IS8Q.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-create-a-realtime-app-using-socket-io-react-node-mongodb-a10c4a1ab676/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to create a realtime app using Socket.io, React, Node &amp; MongoDB</a>
      </p><blockquote>Nota da tradução: o artigo a seguir foi escrito quando o React estava em sua versão 16.7.0. No momento da tradução, ele se encontra em sua versão 18.2.0 e houve muitas mudanças no comportamento dos componentes – em especial, com a questão de roteamento. Caso deseje realizar o processo tal e qual ele está neste artigo, sugerimos a instalação da versão 16.7.0 do React para seguir o passo a passo. Para isso, use o comando <code>npm install react@16.7.0</code>.</blockquote><p>Você já se perguntou como as aplicações em tempo real são criadas? Já percebeu a importância e os casos de uso de aplicações em tempo real?</p><p>Se você está curioso sobre as perguntas acima e precisa de respostas, então este artigo é para você.</p><p>Primeiro, vamos identificar alguns casos de uso que precisam de aplicações em tempo real:</p><ol><li>Obter atualizações de localização do seu táxi em um mapa de uma aplicação de reserva de táxi.</li><li>Receba novas mensagens instantaneamente em sua aplicação de bate-papo favorito.</li><li>Atualização de informações sobre pedidos de comida para a cozinha de seu restaurante favorito.</li></ol><p>Todos esses são cenários comuns do nosso dia a dia, em que não podemos tolerar um atraso na atualização das informações e, portanto, precisamos de comunicação em tempo real.</p><p><strong>Tecnologias</strong> que podem ser usadas para <strong>comunicação em tempo real</strong> são:</p><ol><li><strong>Short Polling</strong>: AJAX, cria tráfego intenso.</li><li><strong>Long Polling</strong>: Igual ao AJAX, mas o servidor retém a resposta até que tenha uma atualização. Depois de recebê-la, o <em>client</em> envia outra solicitação e precisa que o cabeçalho adicional seja percorrido para frente e para trás, causando sobrecarga adicional.</li><li><strong>Web Sockets</strong>: possibilitam a abertura de comunicação interativa entre o <em>client</em> e o servidor. É possível enviar uma solicitação para o servidor e receber respostas orientadas por eventos sem consultar o servidor para obter uma resposta, o que torna os <em>Web Sockets</em> a <strong>melhor opção</strong> para o nosso caso de uso.</li></ol><p>Informações mais detalhadas sobre as três tecnologias acima podem ser lidas <a href="https://stackoverflow.com/questions/12555043/my-understanding-of-http-polling-long-polling-http-streaming-and-websockets" rel="noopener">aqui</a> (texto em inglês).</p><p>Vamos aprender a criar uma aplicação em tempo real, abordando o seguinte cenário: imagine que você está sentado em seu restaurante favorito e tem um menu digital. Você faz o pedido e a cozinha é atualizada sobre ele em tempo real. Quando a cozinha termina de fazer o pedido, ela também o atualiza em tempo real.</p><p>Características detalhadas:</p><ol><li><strong>Realizar o pedido</strong>: interface para selecionar a quantidade e fazer o pedido de um item alimentar selecionado para a cozinha.</li><li><strong>Cozinha</strong>: interface que pode ser aberta em várias cozinhas e atualiza em tempo real os chefs e cozinheiros com relação ao total de pedidos criados e à quantidade prevista de itens alimentícios, dando a eles a flexibilidade de atualizá-los. Também possui uma funcionalidade para baixar o relatório na forma de uma planilha do Excel.</li><li><strong>Mudança prevista</strong>: interface para atualizar a quantidade prevista de itens alimentares.</li></ol><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/6EyW3Wo0cKhjTFMskVgaWeTAaVS-3m26bhzL.gif" class="kg-image" alt="6EyW3Wo0cKhjTFMskVgaWeTAaVS-3m26bhzL" width="800" height="360" loading="lazy"></figure><p>Para uma melhor compreensão, abra-o em diferentes abas/dispositivos ao mesmo tempo para ver a alteração dos dados em tempo real.</p><p><strong>O código-fonte</strong> está <a href="https://github.com/honey93/OrderKitchen" rel="noopener">aqui</a>. Sinta-se à vontade para criar algo inovador/útil com base nele.</p><p>Então, vamos começar.</p><h3 id="stack-de-tecnologias-">Stack de tecnologias:</h3><p><strong>Front-end</strong>: React.js, Reactstrap, Socket.io</p><p><strong>Back-end</strong>: Node.js (Express), MongoDB, Socket.io</p><h3 id="estrutura-de-pastas-">Estrutura de pastas:</h3><pre><code>/*
Vá para o diretório raiz no código-fonte e encontre os arquivos mencionados abaixo. Essa arquitetura ajuda a criar uma grande aplicação modular.
*/
backend-my-app/ /* Código do back-end da aplicação */
 server.js       /* O código do soquete e do back-end fica aqui*/
 build/      /* Opcional para a implementação da build do front-end */ 
 package.json /* Dependências do back-end */
 ...
public/
src/  /*      Código-fonte do front-end      */
 global/      /*   Componentes usados em todos os lugares   */
  header.css
  header.js     
 main/           
  Kitchen.js
  PlaceOrder.js
  UpdatePredicted.js
 App.js   /* Lógica de roteamento e parte de montagem dos componentes */
package.json /* Dependências do front-end */ 
 ............</code></pre><h3 id="explica-o-do-c-digo-fonte-">Explicação do código-fonte:</h3><h4 id="front-end-">Front-end:</h4><pre><code>git clone https://github.com/honey93/OrderKitchen.git
cd OrderKitchen
npm install
npm start</code></pre><p>Pacotes utilizados:</p><ol><li><a href="https://reactstrap.github.io/" rel="noopener"><strong>Reactstrap</strong></a>: componentes do bootstrap 4 fáceis de usar.</li><li><a href="https://socket.io/docs/" rel="noopener"><strong>Socket.io</strong></a>: o Socket.io é uma biblioteca que permite a comunicação em tempo real, bidirecional e baseada em eventos entre o navegador e o servidor.</li><li><a href="https://www.npmjs.com/package/react-html-table-to-excel" rel="noopener"><strong>react-html-table-to-excel</strong></a>: fornece uma geração de arquivos Excel (.xls) no lado do <em>client</em> a partir de um elemento de tabela HTML.</li><li><a href="https://www.npmjs.com/package/react-router-dom" rel="noopener"><strong>react-router-dom</strong></a>: vinculações do DOM para o React Router. Ele consiste em vários componentes importantes, como BrowserRouter, usado quando há um servidor para lidar com solicitações dinâmicas, Switch, Route etc.</li></ol><h4 id="componente-app">Componente App</h4><p><strong>Caminho</strong>: <code>src/App.js</code></p><p>Este componente contém a lógica de roteamento principal do front-end. Esse arquivo é usado em src/index.js dentro do módulo Browser Router. O código abaixo demonstra uma das abordagens para manter sua aplicação modular.</p><pre><code class="language-javascript">import React, { Component } from "react";
import "./App.css";
import { Header } from "./global/header";
import { Switch, Route } from "react-router-dom";
import PlaceOrder from "./main/PlaceOrder";
import UpdatePredicted from "./main/UpdatePredicted";
import Kitchen from "./main/Kitchen";
/*O componente &lt;Route&gt; é a parte principal do React Router. Em qualquer lugar em que você queira renderizar apenas o conteúdo com base no nome do caminho do local, você deve usar um elemento &lt;Route&gt;. */
/* O componente Route espera uma propriedade de caminho, que é uma cadeia de caracteres que descreve o nome do caminho ao qual a rota corresponde */
/* O &lt;Switch&gt; iterará as rotas e renderizará apenas a primeira que corresponder ao nome do caminho atual */
class App extends Component {
  render() {
    return (
      &lt;div className="App"&gt;
        &lt;Header /&gt;
        &lt;Switch&gt;
          &lt;Route exact path="/" component={PlaceOrder} /&gt;
          &lt;Route path="/updatepredicted" component={UpdatePredicted} /&gt;
          &lt;Route path="/kitchen" component={Kitchen} /&gt;
        &lt;/Switch&gt;
      &lt;/div&gt;
    );
  }
}
export default App;</code></pre><h4 id="componente-do-cabe-alho">Componente do cabeçalho</h4><p><strong>Caminho</strong>: <code>src/global/header.js</code></p><p>Este componente será comum e usado em todas as seções, como Realizar Pedido (em inglês, <em>Place Order</em>), Mudança Prevista (em inglês, <em>Change Predicted</em>), Cozinha (em inglês, <em>Kitchen</em>). Essa abordagem ajuda a evitar a duplicação de código e mantém a aplicação modular.</p><pre><code class="language-js">import React, { Component } from "react";
import { NavLink } from "react-router-dom";
import socketIOClient from "socket.io-client";
import "./header.css";
// O cabeçalho cria links que podem ser usados para navegar
// entre as rotas.
var socket;
class Header extends Component {
/* Cria um client do Socket e o exporta no final para ser usado nos componentes Place Order, Kitchen etc. */
  constructor() {
    super();
    this.state = {
      endpoint: 'http://localhost:3001/'
    };
socket = socketIOClient(this.state.endpoint);
  }
render() {
    return (
      &lt;header&gt;
        &lt;nav&gt;
          &lt;ul className="NavClass"&gt;
            &lt;li&gt;
              &lt;NavLink exact to="/"&gt;
                Place Order
              &lt;/NavLink&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;NavLink to="/updatepredicted"&gt;Change Predicted &lt;/NavLink&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;NavLink to="/kitchen"&gt; Kitchen &lt;/NavLink&gt;
            &lt;/li  &gt;
          &lt;/ul&gt;
        &lt;/nav&gt;
      &lt;/header&gt;
    );
  }
}
export { Header, socket };</code></pre><h4 id="componente-da-cozinha">Componente da cozinha</h4><p><strong>Caminho</strong>: <code>src/main/Kitchen.js</code></p><p>A lógica da UI da tela da Cozinha e o código html residem neste componente:</p><pre><code class="language-js">import React, { Component } from "react";
import { Button, Table, Container } from "reactstrap";
import { socket } from "../global/header";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
class Kitchen extends Component {
  constructor() {
    super();
    this.state = {
      food_data: []
      // é onde estamos nos conectando com os soquetes,
    };
  }
getData = foodItems =&gt; {
    console.log(foodItems);
    this.setState({ food_data: foodItems });
  };
changeData = () =&gt; socket.emit("initial_data");
/* Assim que o componente for montado, ou seja, no método componentDidMount, dispara o evento initial_data para obter os dados para inicializar o Kitchen Dashboard */
/* Adiciona o ouvinte change_data para ouvir todas as alterações feitas pelos componentes Fazer pedido e Pedido previsto */ 
componentDidMount() {
    var state_current = this;
    socket.emit("initial_data");
    socket.on("get_data", this.getData);
    socket.on("change_data", this.changeData);
  }

/* Remove o ouvinte antes de desmontar o componente para evitar a adição de vários ouvintes no momento da revisão */
componentWillUnmount() {
    socket.off("get_data");
    socket.off("change_data");
  }
/* Quando Done (Pronto) é clicado, essa função é chamada e o evento mark_done é emitido, o qual é ouvido no back-end, explicado mais adiante*/
markDone = id =&gt; {
    // console.log(predicted_details);
    socket.emit("mark_done", id);
  };
getFoodData() {
    return this.state.food_data.map(food =&gt; {
      return (
        &lt;tr key={food._id}&gt;
          &lt;td&gt; {food.name} &lt;/td&gt;
          &lt;td&gt; {food.ordQty} &lt;/td&gt;
          &lt;td&gt; {food.prodQty} &lt;/td&gt;
          &lt;td&gt; {food.predQty} &lt;/td&gt;
          &lt;td&gt;
            &lt;button onClick={() =&gt; this.markDone(food._id)}&gt;Done&lt;/button&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
      );
    });
  }
render() {
    return (
      &lt;Container&gt;
        &lt;h2 className="h2Class"&gt;Kitchen Area&lt;/h2&gt;
        &lt;ReactHTMLTableToExcel
          id="test-table-xls-button"
          className="download-table-xls-button"
          table="table-to-xls"
          filename="tablexls"
          sheet="tablexls"
          buttonText="Download as XLS"
        /&gt;
&lt;Table striped id="table-to-xls"&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th&gt;Name&lt;/th&gt;
              &lt;th&gt;Quantity&lt;/th&gt;
              &lt;th&gt;Created Till Now&lt;/th&gt;
              &lt;th&gt;Predicted&lt;/th&gt;
              &lt;th&gt;Status&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;{this.getFoodData()}&lt;/tbody&gt;
        &lt;/Table&gt;
      &lt;/Container&gt;
    );
  }
}
export default Kitchen;</code></pre><h4 id="componente-fazer-pedido">Componente Fazer Pedido</h4><p><strong>Caminho</strong>: <code>src/main/PlaceOrder.js</code></p><pre><code class="language-js">import React, { Component } from "react";
import { Button, Table, Container } from "reactstrap";
import { socket } from "../global/header";
class PlaceOrder extends Component {
  constructor() {
    super();
    this.state = {
      food_data: []
      // é onde estamos nos conectando com os soquetes,
    };
  }
getData = foodItems =&gt; {
    console.log(foodItems);
    foodItems = foodItems.map(food =&gt; {
      food.order = 0;
return food;
    });
    this.setState({ food_data: foodItems });
  };
componentDidMount() {
    socket.emit("initial_data");
    var state_current = this;
    socket.on("get_data", state_current.getData);
  }
componentWillUnmount() {
    socket.off("get_data", this.getData);
  }
// Função para fazer o pedido.
sendOrder = id =&gt; {
    var order_details;
    this.state.food_data.map(food =&gt; {
      if (food._id == id) {
        order_details = food;
      }
      return food;
    });
    console.log(order_details);
    socket.emit("putOrder", order_details);
    var new_array = this.state.food_data.map(food =&gt; {
      food.order = 0;
      return food;
    });
    this.setState({ food_data: new_array });
  };
// Altera a quantidade no estado que é emitido para o back-end no momento da realização do pedido.
changeQuantity = (event, foodid) =&gt; {
    if (parseInt(event.target.value) &lt; 0) {
      event.target.value = 0;
    }
    var new_array = this.state.food_data.map(food =&gt; {
      if (food._id == foodid) {
        food.order = parseInt(event.target.value);
      }
      return food;
    });
    this.setState({ food_data: new_array });
  };
// Obtém os dados iniciais
getFoodData() {
    return this.state.food_data.map(food =&gt; {
      return (
        &lt;tr key={food._id}&gt;
          &lt;td&gt; {food.name} &lt;/td&gt;
          &lt;td&gt;
            &lt;input
              onChange={e =&gt; this.changeQuantity(e, food._id)}
              value={food.order}
              type="number"
              placeholder="Quantity"
            /&gt;
          &lt;/td&gt;
          &lt;td&gt;
            &lt;button onClick={() =&gt; this.sendOrder(food._id)}&gt;Order&lt;/button&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
      );
    });
  }
render() {
    return (
      &lt;Container&gt;
        &lt;h2 className="h2Class"&gt;Order Menu&lt;/h2&gt;
        &lt;Table striped&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th&gt;Product&lt;/th&gt;
              &lt;th&gt;Quantity&lt;/th&gt;
              &lt;th&gt;Order&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;{this.getFoodData()}&lt;/tbody&gt;
        &lt;/Table&gt;
      &lt;/Container&gt;
    );
  }
}
export default PlaceOrder;</code></pre><p>Mais uma seção chamada Atualizar caminho previsto (em inglês, <em>Update Predicted Path</em>): <code>src/main/UpdatePredicted.js</code>, semelhante à seção acima, está no repositório de código.</p><h3 id="back-end">Back-end</h3><p>Iniciando o back-end:</p><pre><code>cd backend-my-app
npm install
node server.js</code></pre><p>Pacotes utilizados:</p><ol><li><a href="https://www.npmjs.com/package/monk" rel="noopener"><strong>Monk</strong></a>: uma pequena camada que oferece melhorias simples, mas substanciais, na usabilidade do uso do MongoDB no Node.JS.</li><li><a href="https://socket.io/docs/" rel="noopener"><strong>Socket.io</strong></a>: o Socket.io é uma biblioteca que permite a comunicação em tempo real, bidirecional e baseada em eventos entre o navegador e o servidor.</li></ol><p>3. <a href="https://www.npmjs.com/package/express" rel="noopener"><strong>Express</strong></a>: estrutura da Web rápida e minimalista para o <a href="http://nodejs.org/" rel="noopener">node</a>.</p><h4 id="c-digo-principal">Código principal</h4><p><strong>Caminho</strong>: <code>backend-my-app/server.js</code></p><pre><code class="language-js">const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
// Cadeia de conexão do banco de dados MongoDb hospedado no Mlab ou localmente
var connection_string = "**********";
// O nome da coleção deve ser "FoodItems", pois há apenas uma coleção no momento.
// O formato do documento deve ser o mencionado abaixo, pelo menos um desses documentos:
// {
//     "_id": {
//         "$oid": "5c0a1bdfe7179a6ca0844567"
//     },
//     "name": "Veg Roll",
//     "predQty": 100,
//     "prodQty": 295,
//     "ordQty": 1
// }
const db = require("monk")(connection_string);
const collection_foodItems = db.get("FoodItems");
// nossa porta do localhost
const port = process.env.PORT || 3000;
const app = express();
// nossa instância de servidor
const server = http.createServer(app);
// Isso cria nosso soquete usando a instância do servidor
const io = socketIO(server);
io.on("connection", socket =&gt; {
// console.log("New client connected" + socket.id);
// console.log(socket);
// Retornando os dados iniciais do menu de comida da coleção FoodItems
  socket.on("initial_data", () =&gt; {
    collection_foodItems.find({}).then(docs =&gt; {
      io.sockets.emit("get_data", docs);
    });
  });
// A realização do pedido é chamada em /src/main/PlaceOrder.js do Frontend
  socket.on("putOrder", order =&gt; {
    collection_foodItems
      .update({ _id: order._id }, { $inc: { ordQty: order.order } })
      .then(updatedDoc =&gt; {
        // Emissão de evento para atualizar a Cozinha aberta nos dispositivos com os valores do pedido em tempo real
        io.sockets.emit("change_data");
      });
  });
// Conclusão do pedido, chamada a partir de /src/main/Kitchen.js
  socket.on("mark_done", id =&gt; {
    collection_foodItems
      .update({ _id: id }, { $inc: { ordQty: -1, prodQty: 1 } })
      .then(updatedDoc =&gt; {
        // Atualizar as diferentes áreas da cozinha com o status atual.
        io.sockets.emit("change_data");
      });
  });

// Funcionalidade para alterar o valor da quantidade prevista, chamada de /src/main/UpdatePredicted.js
  socket.on("ChangePred", predicted_data =&gt; {
    collection_foodItems
      .update(
        { _id: predicted_data._id },
        { $set: { predQty: predicted_data.predQty } }
      )
      .then(updatedDoc =&gt; {
        // Evento de soquete para atualizar a quantidade prevista na cozinha
        io.sockets.emit("change_data");
      });
  });

// A desconexão é acionada quando um cliente deixa o servidor
  socket.on("disconnect", () =&gt; {
    console.log("user disconnected");
  });
});
/* As etapas mencionadas abaixo são executadas para retornar a compilação do Front-end do create-react-app da pasta de compilação do Back-end.*/
app.use(express.static("build"));
app.use("/kitchen", express.static("build"));
app.use("/updatepredicted", express.static("build"));
server.listen(port, () =&gt; console.log(`Listening on port ${port}`));</code></pre><p><strong>Banco de dados</strong>: MongoDB</p><p><a href="https://mlab.com/" rel="noopener"><strong>Mlab</strong></a>: banco de dados como um serviço para o MongoDB</p><p><strong>Nome da coleção</strong>: FoodItems</p><p><strong>Formato do documento</strong>: é necessário pelo menos um documento na coleção FoodItems com o formato mencionado abaixo.</p><pre><code class="language-js">{
"name": "Veg Roll",  // Nome do alimento
"predQty": 100,  // Quantidade prevista
"prodQty": 295,  // Quantidade produzida
"ordQty": 1   // Quantidade total do pedido
}</code></pre><p>Espero que você tenha entendido como criar uma aplicação modular em tempo real usando a pilha MERN. Se você achou útil, deixe uma <strong>estrela</strong> no <a href="https://github.com/honey93/OrderKitchen" rel="noopener">repositório do GitHub</a> do projeto e compartilhe com seus amigos também.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como instalar o Node em um MacOS, Linux ou Windows usando o NVM ]]>
                </title>
                <description>
                    <![CDATA[ > Nota da tradução: no momento desta tradução, a versão mais recente do Node é a versão 18.17.1. Se você quiser utilizar a versão mais recente do Node, substitua "12.18.1" sempre que aparecer em alguma instrução do texto por "18.17.1". > A versão mais recente do script "nvm-sh" é a ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-instalar-o-node-em-um-macos-linux-ou-windows-usando-o-nvm/</link>
                <guid isPermaLink="false">64e4228f78917103e8a161ab</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Tue, 22 Aug 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/08/5f9c9a1a740569d1a4ca238a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-install-node-in-your-machines-macos-linux-windows/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Install Node on a MacOS, Linux, or Windows Machine Using NVM</a>
      </p><blockquote><strong>Nota da tradução:</strong> no momento desta tradução, a versão mais recente do Node é a versão 18.17.1. Se você quiser utilizar a versão mais recente do Node, substitua "12.18.1" sempre que aparecer em alguma instrução do texto por "18.17.1".</blockquote><blockquote>A versão mais recente do script "nvm-sh" é a 'v0.39.5'. Caso queira utilizar essa versão, substitua 'v0.35.3' pelo 'v0.39.5' no comando utilizado durante a instalação no Mac OS e Linux.</blockquote><p>Antes de começar a criar aplicações incríveis com o NodeJS, você precisa instalá-lo. Felizmente, a instalação do NodeJS é muito simples.</p><p>Neste tutorial, abordaremos como instalar o NodeJS/NPM no</p><ul><li>macOS/Linux</li><li>Windows</li></ul><p>Depois de instalar o NodeJS/NPM, você pode facilmente fazer o <em>upgrade</em>/<em>downgrade </em>para qualquer versão do Node com um comando. O tutorial em vídeo a seguir mostra como fazer o download do NodeJS em sua máquina.</p><h2 id="guia-de-instala-o-para-mac-os-e-linux">Guia de instalação para Mac OS e Linux</h2><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 75%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="150" src="https://www.youtube.com/embed/TmT_CGFnUuM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Install NodeJS/NPM on your macOS/Linux machines with NVM (node version manager)" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>Abra um novo terminal. Digite o seguinte e pressione Enter:</p><pre><code>curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
</code></pre><p>Feche seu terminal, abra um novo e digite o seguinte:</p><pre><code>nvm ls
</code></pre><p>Você verá algo parecido com isto:</p><pre><code>system
iojs -&gt; N/A (default)
node -&gt; stable (-&gt; N/A) (default)
unstable -&gt; N/A (default)
nvm_list_aliases:36: no matches found: /Users/adeelimran/.nvm/alias/lts/*
</code></pre><p>Em seguida, em seu terminal, digite:</p><pre><code>nvm install 12.18.1
</code></pre><p>Depois de instalado, ele estará pronta para ser usado. Para usar essa versão, basta digitar isto em seu terminal:</p><pre><code>nvm use 12.18.1
</code></pre><p>Agora que ele está instalado, vamos verificá-lo fazendo o seguinte:</p><figure class="kg-card kg-code-card"><pre><code>node --v</code></pre><figcaption>O resultado será "v12.18.1" (que é a versão do NodeJS que você acabou de instalar)</figcaption></figure><p>É isso! Você terminou. Divirta-se.</p><p>Agora, se no futuro, por algum motivo, você quiser desinstalar o NVM (do inglês, <em>Node Version Manager</em>), basta abrir o terminal e digitar o seguinte:</p><pre><code>rm -rf $NVM_DIR ~/.npm ~/.bower
</code></pre><h2 id="guia-de-instala-o-para-windows">Guia de instalação para Windows</h2><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/QWdSDo9V1Ho?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Install NodeJS/NPM on your Windows machines with NVM (node version manager)" name="fitvid1"></iframe>
          </div>
        </div>
      </figure><p>Primeiro, acesse a área de versões no repositório do <code>nvm-windows</code> <a href="https://github.com/coreybutler/nvm-windows/releases">https://github.com/coreybutler/nvm-windows/releases</a>.</p><p>Em seguida, escolha o arquivo <code>nvm-setup.zip</code> e faça o download.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/06/tempsnip.png" class="kg-image" alt="tempsnip" width="600" height="400" loading="lazy"></figure><p>Depois que o arquivo for baixado, descompacte-o, clique no instalador e siga as etapas (estou usando o <a href="https://www.7-zip.org/">7zip</a> para extração de arquivos .zip, porque ele é GRATUITO).</p><p>Em seguida, para verificar se o <code>nvm</code> está instalado corretamente, abra um novo terminal de prompt de comando e digite <code>nvm</code>. Quando for verificado que ele está instalado, você poderá passar para a próxima etapa.</p><p>Instale o NodeJS usando o <code>nvm</code> desta maneira:</p><pre><code>nvm install &lt;numero_da_versao&gt; // Vamos supor que seja a versão 12.18.1</code></pre><p>A versão pode ser uma versão do NodeJS ou "latest" (para a versão mais recente e estável).</p><p>Para usar a versão específica do node que você acabou de instalar, basta digitar o seguinte no terminal:</p><pre><code>nvm use 12.18.1;</code></pre><p>Verifique a versão do node com node -v. Isso deve mostrar a versão 12.18.1 em seu terminal.</p><p>Se você quiser instalar outra versão do Node, repita as etapas com uma versão diferente.</p><p>Agora, você deve ter uma versão funcional do NodeJS em execução em sua máquina. Boa programação, pessoal. 🙂</p><p>Se você achou este guia útil, envie uma mensagem para o autor no <a href="https://twitter.com/adeelibr">Twitter</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Siga estas etapas para resolver qualquer problema em entrevistas sobre Programação Dinâmica ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Nikola Otasevic Apesar de terem uma experiência significativa na criação de produtos de software, muitos engenheiros ficam nervosos com a ideia de passar por uma entrevista sobre programação com foco em algoritmos. Entrevistei centenas de engenheiros na Refdash [https://refdash.com/?utm_source=dp_blog_f], no Google e em startups das quais fiz parte. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/siga-estas-etapas-para-resolver-qualquer-problema-em-entrevistas-sobre-programacao-dinamica/</link>
                <guid isPermaLink="false">648399283aab28058e3816fe</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jul 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/0_DpsbrfUM89M_LHKY.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/follow-these-steps-to-solve-any-dynamic-programming-interview-problem-cc98e508cd0e/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Follow these steps to solve any Dynamic Programming interview problem</a>
      </p><p>Escrito por: Nikola Otasevic</p><p>Apesar de terem uma experiência significativa na criação de produtos de software, muitos engenheiros ficam nervosos com a ideia de passar por uma entrevista sobre programação com foco em algoritmos. Entrevistei centenas de engenheiros na <a href="https://refdash.com/?utm_source=dp_blog_f" rel="noopener">Refdash</a>, no Google e em startups das quais fiz parte. Algumas das perguntas mais comuns que deixam os engenheiros desconfortáveis são as que envolvem Programação Dinâmica (PD).</p><p>Muitas empresas de tecnologia gostam de fazer perguntas sobre PD em suas entrevistas. Embora possamos discutir se elas são eficazes para avaliar a capacidade de alguém para desempenhar uma função de engenheiro, a PD continua a ser uma área que atrapalha os engenheiros no caminho para encontrar um emprego que eles amam.</p><h3 id="programa-o-din-mica-previs-vel-e-prepar-vel">Programação Dinâmica – previsível e preparável</h3><p>Um dos motivos pelos quais acredito que as perguntas sobre PD podem não ser a melhor maneira de se testar a capacidade de engenharia é o fato de serem previsíveis e fáceis de combinar com padrões. Elas nos permitem filtrar muito mais a preparação do que a capacidade de engenharia.</p><p>Essas perguntas normalmente parecem bastante complexas por fora e podem dar a impressão de que a pessoa que as resolve é muito boa em algoritmos. Da mesma forma, as pessoas que talvez não consigam superar alguns conceitos de PD que confundem a mente podem parecer muito fracas em seu conhecimento de algoritmos.</p><p>A realidade, porém, é diferente. O maior fator em seu desempenho é a preparação. Portanto, vamos nos certificar de que todos estejam preparados para elas de uma vez por todas.</p><h3 id="7-etapas-para-resolver-um-problema-de-programa-o-din-mica">7 etapas para resolver um problema de Programação Dinâmica</h3><p>No restante deste artigo, examinarei uma receita que você pode seguir para descobrir se um problema é um "problema de PD", bem como para encontrar uma solução para esse problema. Especificamente, vou seguir as seguintes etapas:</p><ol><li>Reconhecer um problema de PD</li><li>Identificar as variáveis do problema</li><li>Expressar claramente a relação de recorrência</li><li>Identificar os casos básicos</li><li>Decidir se você deseja implementá-lo de maneira iterativa ou recursiva</li><li>Adicionar <em>memoização</em></li><li>Determinar a complexidade de tempo</li></ol><h3 id="exemplo-de-problema-de-pd">Exemplo de problema de PD</h3><p>Com o objetivo de ter um exemplo das abstrações que farei, vou apresentar um exemplo de problema. Em cada uma das seções, farei referência ao problema, mas você também pode ler as seções independentemente do problema.</p><h4 id="declara-o-do-problema-">Declaração do problema:</h4><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/YIelQx3b0OSZIaNWVkJEmirqOZRZWXm2fbBk.gif" class="kg-image" alt="YIelQx3b0OSZIaNWVkJEmirqOZRZWXm2fbBk" width="480" height="360" loading="lazy"></figure><p><em>Neste problema, estamos em uma bola que salta loucamente e tentamos parar, evitando "estacas" que ficam no caminho.</em></p><h4 id="as-regras-s-o-"><strong>As regras são:</strong></h4><p>1) Você recebe um caminho plana com várias estacas. O caminho é representado por um array de booleanos que indica se um determinado ponto (discreto) tem ou não tem uma estaca. O booleano diz True se não houver uma estaca e False se houver.</p><p>Exemplo de representação do array:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/c5h0NAmIsaNYEjJfcIZa3uPCiTxO28ew9gPV.jpeg" class="kg-image" alt="c5h0NAmIsaNYEjJfcIZa3uPCiTxO28ew9gPV" srcset="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/c5h0NAmIsaNYEjJfcIZa3uPCiTxO28ew9gPV.jpeg 600w" width="600" height="140" loading="lazy"></figure><p>2) Você tem uma velocidade inicial S. S é um número inteiro não negativo em um determinado ponto e indica o quanto você avançará no próximo salto.</p><p>3) Sempre que aterrissar em um ponto, você poderá ajustar sua velocidade em até mais ou menos 1 unidade antes do próximo salto.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/bCnFU8w6zxjnUpypi0ArUOyON6L20E0EPl0p.jpeg" class="kg-image" alt="bCnFU8w6zxjnUpypi0ArUOyON6L20E0EPl0p" srcset="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/bCnFU8w6zxjnUpypi0ArUOyON6L20E0EPl0p.jpeg 600w" width="600" height="220" loading="lazy"></figure><p>4) Você deseja parar com segurança em qualquer lugar do caminho (não precisa ser no final do array). Você para quando sua velocidade se torna 0. No entanto, se você parar em um estaca em qualquer ponto, sua bola saltitante maluca explode e o jogo acaba.</p><p><strong>O resultado da função deve ser um booleano indicando se podemos parar com segurança em qualquer lugar do caminho.</strong></p><h4 id="etapa-1-reconhecer-um-problema-de-programa-o-din-mica">Etapa 1: reconhecer um problema de Programação Dinâmica</h4><p>Primeiro, vamos deixar claro que a PD é, essencialmente, apenas uma técnica de otimização. A PD é um método para resolver problemas, dividindo-os em um conjunto de subproblemas mais simples, resolvendo cada um desses subproblemas apenas uma vez e armazenando suas soluções. Na próxima vez em que o mesmo subproblema ocorrer, em vez de recalcular sua solução, basta consultar a solução calculada anteriormente. Isso economiza tempo de computação às custas de um gasto modesto (espera-se) em espaço de armazenamento.</p><p>Reconhecer que um problema pode ser resolvido com o uso da PD é a primeira etapa e, muitas vezes, a mais difícil para resolvê-lo. O que você deve perguntar a si mesmo é se a solução do seu problema pode ser expressa como uma função de soluções de pequenos problemas semelhantes.</p><p>No caso do nosso problema de exemplo, dado um ponto no caminho, uma velocidade e o caminho à frente, poderíamos determinar os pontos onde poderíamos saltar em seguida. Além disso, parece que o fato de podermos parar no ponto atual com a velocidade atual depende apenas do fato de podermos parar no ponto para o qual escolhemos ir em seguida.</p><p>Isso é ótimo porque, ao avançarmos, encurtamos o caminho e tornamos nosso problema menor. Devemos ser capazes de repetir esse processo até chegarmos a um ponto em que seja óbvio que podemos parar.</p><blockquote>Reconhecer um problema de Programação Dinâmica geralmente é a etapa mais difícil para resolvê-lo. A solução do problema pode ser expressa como uma função de soluções de pequenos problemas semelhantes?</blockquote><h4 id="etapa-2-identificar-as-vari-veis-do-problema">Etapa 2: identificar as variáveis do problema</h4><p>Agora, estabelecemos que há alguma estrutura recursiva em nossos subproblemas. Em seguida, precisamos expressar o problema em termos dos parâmetros da função e ver quais desses parâmetros estão mudando.</p><p>Normalmente, nas entrevistas, você terá um ou dois parâmetros variáveis, mas, tecnicamente, pode ser qualquer número. Um exemplo clássico de um problema com um parâmetro variável é "determinar o n-ésimo número de Fibonacci". Um exemplo de problema de dois parâmetros variáveis é "Calcular a <em><a href="https://pt.wikipedia.org/wiki/Dist%C3%A2ncia_Levenshtein">distância de edição</a></em> entre strings". Se você não estiver familiarizado com esses problemas, não se preocupe.</p><p>Uma maneira de determinar o número de parâmetros variáveis é listar exemplos de vários subproblemas e comparar os parâmetros. A contagem do número de parâmetros variáveis é importante para determinar o número de subproblemas que temos de resolver. Ela também é importante por si só, pois nos ajuda a fortalecer a compreensão da relação de recorrência da etapa 1.</p><p>Em nosso exemplo, os dois parâmetros que podem mudar em cada subproblema são:</p><ol><li><strong>Posição no array <strong>(P)</strong></strong></li><li><strong>Velocidade<strong> (S)</strong></strong></li></ol><p>É possível dizer que o caminho à frente também está mudando, mas isso seria redundante, considerando que o caminho imutável inteiro e que a posição (P) já contêm essas informações.</p><p>Agora, com esses dois parâmetros variáveis e outros parâmetros estáticos, temos a descrição completa dos nossos subproblemas.</p><blockquote>Identifique os parâmetros variáveis e determine o número de subproblemas.</blockquote><h4 id="etapa-3-expressar-claramente-a-rela-o-de-recorr-ncia">Etapa 3: expressar claramente a relação de recorrência</h4><p>Essa é uma etapa importante que muitos atravessam rapidamente para poderem começar a programar. Expressar a relação de recorrência do modo mais clara possível fortalecerá sua compreensão do problema e facilitará significativamente todo o resto.</p><p>Depois de descobrir que a relação de recorrência existe e especificar os problemas em termos de parâmetros, essa deve ser uma etapa natural. Como os problemas se relacionam entre si? Em outras palavras, vamos supor que você tenha calculado os subproblemas. Como você calcularia o problema principal?</p><p>Veja como pensamos sobre isso em nosso problema de exemplo:</p><p>Como você pode ajustar sua velocidade em até 1 antes de pular para a próxima posição, há apenas 3 velocidades possíveis e, portanto, 3 pontos que poderiam ser o próximo.</p><p>Em termos mais formais, se nossa velocidade for S, posição P, poderíamos ir de (S, P) para:</p><ol><li><strong><strong>(S, P + S)</strong></strong>; # se não alterarmos a velocidade</li><li><strong><strong>(S — 1, P + S — 1)</strong></strong>; # se alterarmos a velocidade em -1</li><li><strong><strong>(S + 1, P + S + 1)</strong></strong>; # se alterarmos a velocidade em +1</li></ol><p>Se conseguirmos encontrar uma maneira de parar em qualquer um dos subproblemas acima, também poderemos parar em (S, P). Isso ocorre porque podemos fazer a transição de (S, P) para qualquer uma das três opções acima.</p><p>Normalmente, esse é um bom nível de compreensão do problema (explicação em inglês simples), mas, às vezes, você também pode querer expressar a relação matematicamente. Vamos chamar uma função que estamos tentando calcular de <em><strong>canStop</strong></em> (possível de parar). Então:</p><p><strong><strong>canStop(S, P) = canStop(S, P + S) || canStop(S — 1, P + S — 1) || canStop(S + 1, P + S + 1)</strong></strong></p><p>Certo! Parece que temos nossa relação de recorrência!</p><blockquote>Relação de recorrência: supondo que você tenha calculado os subproblemas, como você calcularia o problema principal?</blockquote><h4 id="etapa-4-identificar-os-casos-b-sicos">Etapa 4: identificar os casos básicos</h4><p>Um caso básico, ou de base, é um subproblema que não depende de nenhum outro subproblema. Para encontrar esses subproblemas, você normalmente quer experimentar alguns exemplos, ver como o problema se simplifica em subproblemas menores e identificar em que ponto ele não pode ser mais simplificado.</p><p>O motivo pelo qual um problema não pode ser simplificado ainda mais é que um dos parâmetros se tornaria um valor que não é possível, dadas as <strong>restrições</strong> do problema.</p><p>Em nosso problema de exemplo, temos dois parâmetros variáveis, S e P. Vamos pensar sobre quais valores possíveis de S e P podem não ser legais:</p><ol><li><strong><strong>P </strong>deve estar dentro dos limites do caminho determinada</strong></li><li><strong>Não é possível que runway[P] (o ponto P no array runway) seja <em>false</em>, pois isso significaria que cairemos sobre uma estaca</strong></li><li><strong>S não pode ser negativo, e um S==0 indica que paramos</strong></li></ol><p>Às vezes, pode ser um pouco desafiador converter as afirmações que fazemos sobre os parâmetros em casos básicos de programação. Isso ocorre porque, além de listar as afirmações para que o código pareça conciso e não verifique condições desnecessárias, você também precisa pensar em quais dessas condições são possíveis.</p><p>No nosso exemplo:</p><ol><li><strong>P &lt; 0 || P &gt;= comprimento</strong> do caminho parece fazer sentido. Uma alternativa poderia ser considerar fazer de <strong>P == </strong>fim do caminho um caso básico. No entanto, é possível que um problema se divida em um subproblema que vá além do final do caminho. Portanto, precisamos realmente verificar a desigualdade.</li><li>Isso parece bastante óbvio. Podemos simplesmente verificar se<strong> runway[P] é <em>false</em>.</strong></li><li>Semelhante ao caso número 1, poderíamos simplesmente verificar se S &lt; 0 e S == 0. No entanto, aqui podemos raciocinar que é impossível que S seja &lt; 0 porque S diminui em no máximo 1. Assim, teria que passar pelo caso S == 0 antes. Portanto, S == 0 é um caso base suficiente para o parâmetro S.</li></ol><h4 id="etapa-5-decidir-se-voc-deseja-implement-lo-de-maneira-iterativa-ou-recursiva">Etapa 5: decidir se você deseja implementá-lo de maneira iterativa ou recursiva</h4><p>A maneira como falamos sobre as etapas até agora pode levá-lo a pensar que devemos implementar o problema de modo recursivo. No entanto, tudo o que falamos até agora é completamente indiferente ao fato de você decidir implementar o problema recursiva ou iterativamente. Em ambas as abordagens, você teria que determinar a relação de recorrência e os casos de base.</p><p><strong>Para decidir se a opção é iterativa ou recursiva, você deve pensar cuidadosamente sobre as vantagens e desvantagens.</strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/image-5.png" class="kg-image" alt="image-5" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/image-5.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/image-5.png 705w" width="705" height="319" loading="lazy"></figure><p><strong>Os problemas de estouro de pilha (do inglês, <em>stack overflow</em>) costumam ser um obstáculo</strong> e um motivo pelo qual você não gostaria de ter recursão em um sistema de produção (<em>back-end</em>). No entanto, para fins de entrevista, contanto que você mencione as vantagens e desvantagens, normalmente não terá problemas com nenhuma das implementações. Você deve se sentir à vontade para implementar ambas.</p><p><strong>Em nosso problema específico, implementei as duas versões. Aqui está o código em Python para isso:</strong><br>Uma solução recursiva (os trechos de código originais podem ser encontrados <a href="http://blog.refdash.com/dynamic-programming-tutorial-example/" rel="noopener">aqui</a>):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/MmSzAzTeUbtfjiYFSjilQlCBaXRAsOOIesKL.png" class="kg-image" alt="MmSzAzTeUbtfjiYFSjilQlCBaXRAsOOIesKL" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/MmSzAzTeUbtfjiYFSjilQlCBaXRAsOOIesKL.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/MmSzAzTeUbtfjiYFSjilQlCBaXRAsOOIesKL.png 800w" sizes="(min-width: 720px) 720px" width="800" height="381" loading="lazy"></figure><p>Uma solução iterativa: (os trechos de código originais podem ser encontrados <a href="http://blog.refdash.com/dynamic-programming-tutorial-example/" rel="noopener">aqui</a>)</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/aZgiyRIJ3SAD0Mx6lywCaohZt1BUJ0ZW-1Hm.png" class="kg-image" alt="aZgiyRIJ3SAD0Mx6lywCaohZt1BUJ0ZW-1Hm" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/aZgiyRIJ3SAD0Mx6lywCaohZt1BUJ0ZW-1Hm.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/aZgiyRIJ3SAD0Mx6lywCaohZt1BUJ0ZW-1Hm.png 800w" sizes="(min-width: 720px) 720px" width="800" height="670" loading="lazy"></figure><h4 id="etapa-6-adicionar-memoiza-o">Etapa 6: adicionar memoização</h4><p><strong>Memoização</strong> é uma técnica que está intimamente associada à PD. Ela é usada para armazenar os resultados de chamadas de funções dispendiosas, retornando o resultado em cache quando as mesmas entradas ocorrerem novamente.</p><p>Por que estamos adicionando memoização à nossa recursão? Encontramos os mesmos subproblemas que, sem a memoização, são computados repetidamente. Essas repetições muitas vezes levam a complexidades de tempo exponenciais.</p><p>Em soluções recursivas, adicionar memoização deve ser simples. Vejamos por quê. Lembre-se de que a memoização é apenas um cache dos resultados da função. Há ocasiões em que você deseja se desviar dessa definição para conseguir algumas otimizações menores, mas tratar a memoização como um cache de resultados de funções é a maneira mais intuitiva de implementá-la.</p><p>Isso significa que você deve:</p><ol><li>Armazenar o resultado da função na memória antes de cada <em>declaração de retorno</em></li><li>Procurar na memória o resultado da função antes de começar a fazer qualquer outro cálculo</li></ol><p>Abaixo vemos o código acima com a memoização adicionada. As linhas adicionadas estão destacadas (os trechos de código originais podem ser encontrados <a href="http://blog.refdash.com/dynamic-programming-tutorial-example/" rel="noopener">aqui</a>):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/aAgK5alenVTE0zyCTsknv32r-RTjiFOJmMu6.png" class="kg-image" alt="aAgK5alenVTE0zyCTsknv32r-RTjiFOJmMu6" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/aAgK5alenVTE0zyCTsknv32r-RTjiFOJmMu6.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/aAgK5alenVTE0zyCTsknv32r-RTjiFOJmMu6.png 800w" sizes="(min-width: 720px) 720px" width="800" height="629" loading="lazy"></figure><p>Para ilustrar a eficácia da memoização e das diferentes abordagens, vamos fazer alguns testes rápidos. Farei um teste de estresse com os três métodos que vimos até agora. Aqui está a configuração:</p><ol><li>Criei um caminho com 1000 metros de comprimento e estacas em locais aleatórios (optei por uma probabilidade de 20% de uma estaca estar em um determinado local)</li><li>initSpeed (velocidade inicial) = 30</li><li>Executei todas as funções 10 vezes e medi o tempo médio de execução</li></ol><p>Aqui estão os resultados (em segundos):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/bOxJ2uGkAzVHEakgeFnPJMMe44oFIhLAqGh5.png" class="kg-image" alt="bOxJ2uGkAzVHEakgeFnPJMMe44oFIhLAqGh5" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/bOxJ2uGkAzVHEakgeFnPJMMe44oFIhLAqGh5.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/bOxJ2uGkAzVHEakgeFnPJMMe44oFIhLAqGh5.png 800w" sizes="(min-width: 720px) 720px" width="800" height="204" loading="lazy"></figure><p>Você pode ver que a abordagem recursiva pura leva cerca de 500 vezes mais tempo do que a abordagem iterativa e cerca de 1300 vezes mais tempo do que a abordagem recursiva com memoização. Observe que essa discrepância cresceria rapidamente com o comprimento do caminho. Eu o encorajo a tentar executar esse teste por conta própria.</p><h4 id="etapa-7-determinar-a-complexidade-do-tempo">Etapa 7: determinar a complexidade do tempo</h4><p>Existem algumas regras simples que podem facilitar muito o cálculo da complexidade do tempo de um problema de programação dinâmica. Aqui estão duas etapas que você precisa seguir:</p><ol><li>Contar o número de estados — isso dependerá do número de parâmetros variáveis em seu problema</li><li>Pense no trabalho realizado por cada estado. Em outras palavras, se tudo o mais, exceto um estado, tiver sido computado, quanto trabalho terá de ser feito para computar esse último estado?</li></ol><p>Em nosso problema de exemplo, o número de estados é <strong><strong>|P| * |S|,</strong></strong> onde</p><ul><li>P é o conjunto de todas as posições (|P| indica o número de elementos em P)</li><li>S é o conjunto de todas as velocidades</li></ul><p>O trabalho realizado por cada estado é O(1) nesse problema porque, considerando todos os outros estados, basta examinar 3 subproblemas para determinar o estado resultante.</p><p>Como observamos no código anterior, |S| é limitado pelo comprimento do caminho. Portanto, poderíamos dizer que o número de estados é |P|² e, como o trabalho realizado por cada estado é O(1), a complexidade de tempo total é O(|P|²).</p><p>No entanto, parece que |S| pode ser ainda mais limitado, porque se fosse realmente |P|, é muito claro que não seria possível parar, porque você teria que saltar o comprimento de todo o caminho no primeiro movimento.</p><p>Então, vamos ver como podemos colocar um limite mais estreito em |S|. Vamos chamar a velocidade máxima de S. Suponha que estejamos partindo da posição 0. Com que rapidez poderíamos parar se estivéssemos tentando parar o mais rápido possível e se ignorássemos as estacas possíveis?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/tnzdVcGH4Npix6BcaJu1vGVlOkcvJo89NYgv.jpeg" class="kg-image" alt="tnzdVcGH4Npix6BcaJu1vGVlOkcvJo89NYgv" srcset="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/tnzdVcGH4Npix6BcaJu1vGVlOkcvJo89NYgv.jpeg 600w" width="600" height="140" loading="lazy"></figure><p>Na primeira iteração, teríamos de chegar pelo menos ao ponto (S-1), ajustando nossa velocidade em zero para -1. A partir daí, avançaríamos pelo menos (S-2) passos e assim por diante.</p><p>Para um caminho de <strong>comprimento L</strong>, o seguinte deve ser válido:</p><p><strong><strong>=&gt; (S-1) + (S-2) + (S-3) + ….+ 1 </strong></strong>&lt; L</p><p><strong><strong>=&gt; S*(S-1) / 2 </strong></strong>&lt; L</p><p><strong><strong>=&gt; S² — S — 2L </strong></strong>&lt; 0</p><p>Se você encontrar as raízes da função acima, elas serão:</p><p><strong><strong>r1 = 1/2 + sqrt(1/4 + 2L) </strong>e <strong>r2 = 1/2 — sqrt(1/4 + 2L)</strong></strong></p><p>Podemos escrever nossa inequação como:</p><p><strong><strong>(S — r1) * (S — r2) &lt;</strong></strong>; 0</p><p>Considerando que S — r2 &gt; 0 para qualquer S &gt; 0 e L &gt; 0, precisamos do seguinte:</p><p><strong><strong>S — 1/2 — sqrt(1/4 + 2L) &lt;</strong></strong>; 0</p><p><strong><strong>=&gt; S &lt; 1/2 + sqrt(1/4</strong></strong> + 2L)</p><p>Essa é a velocidade máxima que poderíamos ter em um caminho de comprimento L. Se tivéssemos uma velocidade maior do que essa, teoricamente, não poderíamos parar, independentemente da posição das estacas.</p><p>Isso significa que a complexidade total do tempo depende apenas do comprimento do caminho L, assim:</p><p>O(L * sqrt(L)) que é melhor do que O(L²)</p><blockquote><em><em>O(L * sqrt(L)) </em></em>é o limite superior da complexidade de tempo</blockquote><p>Parabéns! Você conseguiu! :)</p><p>As 7 etapas que seguimos devem dar a você uma estrutura para resolver sistematicamente qualquer problema de programação dinâmica. Recomendo fortemente que você pratique essa metodologia em mais alguns problemas para aperfeiçoar sua técnica.</p><h3 id="aqui-est-o-algumas-das-pr-ximas-etapas-que-voc-pode-seguir">Aqui estão algumas das próximas etapas que você pode seguir</h3><ol><li>Amplie o problema de exemplo tentando encontrar um caminho para um ponto de parada. Resolvemos um problema que informa se você pode parar, mas e se você também quisesse saber as etapas a serem seguidas para parar eventualmente ao longo do caminho? Como você modificaria a implementação existente para fazer isso?</li><li>Se quiser solidificar sua compreensão da memoização e entender que ela é apenas um cache de resultados de uma função, leia sobre <em>decorators</em> em Python ou conceitos semelhantes em outras linguagens. Pense em como eles permitiriam que você implementasse a memoização em geral para qualquer função que queira memoizar.</li><li>Trabalhe em mais problemas de PD seguindo as etapas que fizemos. Você sempre pode encontrar vários deles <em>on-line</em> (por exemplo, no <a href="https://leetcode.com/tag/dynamic-programming/" rel="noopener">LeetCode</a> ou no <a href="http://www.geeksforgeeks.org/dynamic-programming/" rel="noopener">GeeksForGeeks</a>). Ao praticar, lembre-se de uma coisa: aprenda ideias, não aprenda problemas. O número de ideias é significativamente menor e é um espaço mais fácil de conquistar, o que também será muito mais útil para você.</li></ol><p>Quando achar que já superou essas ideias, confira o <a href="https://refdash.com/?utm_source=dp_blog" rel="noopener"><strong><strong>Refdash</strong></strong></a>, onde você é entrevistado por um engenheiro sênior e recebe um feedback detalhado sobre sua programação, algoritmos e projeto de sistema.</p><p><em>Publicado originalmente no <a href="http://blog.refdash.com/dynamic-programming-tutorial-example/" rel="noopener">blog do Refdash</a>. O Refdash é uma plataforma de entrevistas que ajuda os engenheiros a entrevistar anonimamente engenheiros experientes das principais empresas, como Google, Facebook ou Palantir, e obter um feedback detalhado. O <a href="https://refdash.com/" rel="noopener">Refdash</a> também ajuda os engenheiros a descobrir oportunidades de trabalho incríveis com base em suas habilidades e interesses.</em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como solucionar problemas de programação com um método simples em quatro etapas ]]>
                </title>
                <description>
                    <![CDATA[ Restavam quinze minutos. Eu sabia que não conseguiria. Passei dois meses estudando para minha primeira entrevista técnica. Achei que estava preparada, mas, quando a entrevista estava chegando ao fim, percebi: eu não tinha a menor ideia de como resolver os problemas de programação. Entre todos os tutoriais que vi quando ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-solucionar-problemas-de-programacao-com-um-metodo-simples-em-quatro-etapas/</link>
                <guid isPermaLink="false">6467c5abae2709063d5da45d</guid>
                
                    <category>
                        <![CDATA[ Resolução de problemas ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Thu, 15 Jun 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/iStock-527234840.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-solve-coding-problems/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Solve Coding Problems with a Simple Four Step Method</a>
      </p><p>Restavam quinze minutos. Eu sabia que não conseguiria.</p><p>Passei dois meses estudando para minha primeira entrevista técnica.</p><p>Achei que estava preparada, mas, quando a entrevista estava chegando ao fim, percebi: eu não tinha a menor ideia de como resolver os problemas de programação.</p><p>Entre todos os tutoriais que vi quando estava aprendendo a programar, nenhum deles incluía uma abordagem para resolver problemas de programação.</p><p>Eu tinha que encontrar um método para resolver problemas – minha carreira como desenvolvedora dependia disso.</p><p>Imediatamente, comecei a pesquisar métodos. Encontrei um. De fato, o que descobri foi uma estratégia inestimável. Era um método em quatro etapas testado pelo tempo que, de algum modo, estava fora do radar no ecossistema de desenvolvedores.</p><p>Neste artigo, abordarei esse método de solução de problemas em quatro etapas que você pode usar para começar a resolver problemas de programação com confiança.</p><p>A solução de problemas de programação não é apenas parte do processo de entrevista de emprego para desenvolvedores – é o que um desenvolvedor faz o dia todo. Afinal de contas, <em>escrever código é resolver problemas.</em></p><h2 id="um-m-todo-para-solucionar-problemas">Um método para solucionar problemas</h2><p>Esse método foi extraído do livro <em><em>How to Solve It</em></em>, de George Pólya. Ele foi lançado originalmente em 1945 e já vendeu mais de um milhão de cópias.</p><p>Seu método de solução de problemas tem sido usado e ensinado por muitos programadores, desde professores de ciência da computação (veja o curso <em>Intro to CS</em>, da Udacity, ministrado pelo professor David Evans) até professores modernos de desenvolvimento da Web, como Colt Steele.</p><p>Vamos solucionar um problema simples de programação usando o método de solução de problemas em quatro etapas. Isso nos permite ver o método em ação à medida que aprendemos. Usaremos JavaScript como nossa linguagem de escolha. O problema é o seguinte:</p><p>Crie uma função que some dois números e retorne esse valor.<br><br>Há quatro etapas no método de solução de problemas:</p><ol><li>Compreender o problema.</li><li>Elaborar um plano.</li><li>Executar o plano.</li><li>Olhar para trás.</li></ol><p>Vamos começar com a primeira etapa.</p><h2 id="etapa-1-entender-o-problema">Etapa 1: entender o problema</h2><p>Ao receber um problema de codificação em uma entrevista, é tentador se apressar em programar. Isso é difícil de evitar, especialmente se você tiver um limite de tempo.</p><p>Entretanto, tente resistir a esse impulso. Certifique-se de que você realmente entendeu o problema antes de começar a resolvê-lo.</p><p>Leia o problema. Se estiver em uma entrevista, você pode ler o problema em voz alta, se isso o ajudar a se acalmar.</p><p>Ao ler o problema, esclareça qualquer parte dele que você não tenha entendido. Se estiver em uma entrevista, você pode fazer isso perguntando ao entrevistador sobre a descrição do problema. Se estiver sozinho, pense e/ou pesquise no Google partes da pergunta que talvez não tenha compreendido.</p><p><strong>Essa primeira etapa é fundamental, pois, muitas vezes, não dedicamos tempo para entender completamente o problema. Se você não entender completamente o problema, será muito mais difícil resolvê-lo.</strong></p><p>Para ajudá-lo a entender melhor o problema, pergunte a si mesmo:</p><h3 id="quais-s-o-as-entradas">Quais são as entradas?</h3><p>Que tipos de entradas serão usadas nesse problema? Neste exemplo, as entradas são os argumentos que nossa função receberá.</p><p>Só de ler a descrição do problema até agora, sabemos que as entradas serão números. Porém, para sermos mais específicos sobre quais serão as entradas, podemos perguntar:</p><p>"As entradas serão sempre apenas dois números? O que deve acontecer se nossa função receber como entrada <em>três</em> números?"</p><p>Aqui, poderíamos pedir esclarecimentos ao entrevistador ou analisar melhor a descrição do problema.</p><p>O problema de progamação pode ter uma nota dizendo: "Você só deve esperar duas entradas para a função". Se for esse o caso, você sabe como proceder. Você pode ser mais específico, pois, provavelmente, perceberá que precisa fazer mais perguntas sobre os tipos de entradas que pode estar recebendo.</p><p>As entradas serão sempre números? O que a nossa função deve fazer se recebermos as entradas "a" e "b"? Esclareça se nossa função sempre receberá números ou não.</p><p>Opcionalmente, você pode anotar as possíveis entradas em um comentário de código para ter uma ideia de como elas serão:</p><p><code>//entradas: 2, 4</code></p><p>Depois, pergunte:</p><h3 id="quais-s-o-as-sa-das">Quais são as saídas?</h3><p>O que essa função retornará? Nesse caso, a saída será um número que é o resultado das duas entradas de números. Certifique-se de entender quais serão seus resultados.</p><h3 id="crie-exemplos-"><strong><strong>Cr</strong>ie exemplos<strong>.</strong></strong></h3><p>Depois de entender o problema e conhecer as possíveis entradas e saídas, você pode começar a trabalhar em alguns exemplos concretos.</p><p>Os exemplos também podem ser usados como verificações de integridade para testar seu eventual problema. A maioria dos editores de desafios de código em que você trabalhará (seja em uma entrevista ou apenas usando um site como o Codewars ou o HackerRank) tem exemplos ou casos de teste já escritos para você. Mesmo assim, escrever seus próprios exemplos pode ajudá-lo a consolidar sua compreensão do problema.</p><p>Comece com um ou dois exemplos simples de possíveis entradas e saídas. Vamos voltar à nossa função de adição.</p><p>Vamos chamar nossa função de "add" (em português, adicionar ou somar).</p><p>O que é um exemplo de entrada? Um exemplo de entrada pode ser:</p><p><code>// add(2, 3)</code></p><p>Qual é a saída para isso? Para escrever o exemplo de saída, podemos escrever:</p><p><code>// add(2, 3) ---&gt; 5</code></p><p>Isso indica que nossa função receberá uma entrada de 2 e 3 e retornará 5 como saída.</p><h3 id="crie-exemplos-complexos-">Crie exemplos complexos<strong><strong>.</strong></strong></h3><p>Ao analisar exemplos mais complexos, você pode reservar um tempo para procurar casos extremos que talvez precisem ser considerados.</p><p>Por exemplo, o que devemos fazer se nossas entradas forem <em>strings</em> em vez de números? Se tivermos como entrada duas <em>strings</em>, por exemplo, add('a', 'b'), como proceder?</p><p>Seu entrevistador talvez diga para retornar uma mensagem de erro se houver entradas que não sejam números. Nesse caso, você pode adicionar um comentário de código para lidar com a questão, se ajudar a lembrar que isso é algo necessário.</p><pre><code class="language-javascript">// retornar erro se as entradas não forem números.</code></pre><p>Seu entrevistador também pode dizer a você para presumir que suas entradas serão sempre números e, nesse caso, você não precisará escrever nenhum código adicional para lidar com esse caso extremo de entrada específico.</p><p>Se você não tem um entrevistador e está apenas resolvendo esse problema, o problema pode dizer o que acontece quando você insere dados inválidos.</p><p>Por exemplo, alguns problemas dirão: "Se houver zero entradas, retorne indefinido". Para casos como esse, você pode, opcionalmente, escrever um comentário.</p><p><code>// Verifique se não há entradas.</code></p><p><code>// Se não houver entradas, retorne indefinido.</code></p><p>Para nossos propósitos, assumiremos que nossas entradas serão sempre números. Porém, em geral, é bom pensar em casos extremos.</p><p>O professor de ciência da computação David Evans recomenda escrever o que os desenvolvedores chamam de código <em>defensivo</em>. Pense no que poderia dar errado e em como seu código poderia se defender contra possíveis erros.</p><p>Antes de passarmos para a etapa 2, vamos resumir a etapa 1: entender o problema:</p><p><code>- Leia o problema.</code></p><p><code>- Quais são as entradas?</code></p><p><code>- Quais são as saídas?</code></p><p><code>- Crie exemplos simples. Em seguida, crie exemplos mais complexos.</code></p><h2 id="etapa-2-elaborar-um-plano-para-solucionar-o-problema">Etapa 2:<strong><strong> </strong></strong>elaborar um plano para solucionar o problema</h2><p>Em seguida, elabore um plano de como resolverá o problema. Ao elaborar um plano, escreva-o em pseudocódigo.</p><p>Pseudocódigo é uma descrição em linguagem simples das etapas de um algoritmo. Em outras palavras, o pseudocódigo é o plano passo a passo de como resolver o problema.</p><p>Escreva as etapas que você precisa seguir para resolver o problema. Para um problema mais complicado, você teria mais etapas. Para esse problema, você poderia escrever:</p><p><code>// Crie uma variável de soma.</code></p><p><code>// Adicione a primeira entrada à segunda entrada usando o operador de adição.</code></p><p><code>// Armazene o valor de ambas as entradas na variável de soma.</code></p><p><code>// Retorne como saída a variável de soma.</code><br><br>Agora, você tem seu plano passo a passo para resolver o problema.<br><br>Para problemas mais complexos, o professor Evans observa: "Considere sistematicamente como um ser humano resolve o problema". Ou seja, esqueça por um momento como seu código pode resolver o problema e pense em como você o resolveria como um ser humano. Isso pode ajudá-lo a ver as etapas com mais clareza.</p><h2 id="etapa-3-executar-o-plano-resolver-o-problema-">Etapa 3:<strong><strong> </strong></strong>executar o plano (resolver o problema)</h2><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/hand-2208491_960_720.jpg" class="kg-image" alt="hand-2208491_960_720" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/hand-2208491_960_720.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/hand-2208491_960_720.jpg 960w" sizes="(min-width: 720px) 720px" width="960" height="540" loading="lazy"></figure><p>A próxima etapa da estratégia de solução de problemas é resolver o problema. Usando seu pseudocódigo como guia, escreva seu código real.</p><p>O professor Evans sugere que você se concentre em uma solução simples e mecânica. Quanto mais fácil e simples for a solução, maior a probabilidade de você programá-la corretamente.</p><p>Usando nosso pseudocódigo, poderíamos escrever o seguinte:</p><pre><code class="language-javascript">function add(a, b) {
 const sum = a + b;
 return sum;
}</code></pre><p>O professor Evans acrescenta: lembre-se de não <em>otimizar prematuramente</em>. Ou seja, você pode ficar tentado a começar a dizer: "Espere, estou fazendo isso e o código será ineficiente!"</p><p>Primeiro, pegue sua solução simples e mecânica.</p><p>Se você não conseguir resolver todo o problema, o que fazer? Caso haja uma parte dele que você ainda não sabe como resolver, como proceder?</p><p>Colt Steele dá um ótimo conselho aqui: se você não conseguir resolver parte do problema, ignore a parte difícil que está atrapalhando. Em vez disso, concentre-se em tudo o mais que você pode começar a escrever.</p><p>Ignore temporariamente a parte difícil do problema que você não está entendendo bem e escreva as outras partes. Depois de fazer isso, volte à parte mais difícil.</p><p>Isso permite que você termine pelo menos uma <em>parte</em> do problema. Muitas vezes, você perceberá como lidar com a parte mais difícil do problema quando voltar a ela.</p><h2 id="etapa-4-analisar-o-que-voc-fez">Etapa 4: analisar o que você fez</h2><p>Quando sua solução estiver funcionando, reserve um tempo para refletir sobre ela e descobrir como fazer melhorias. Esse pode ser o momento de refatorar sua solução para torná-la mais eficiente.</p><p>Ao analisar seu trabalho, aqui estão algumas perguntas que Colt Steele sugere que você faça a si mesmo para descobrir como pode melhorar sua solução:</p><ul><li>Você pode obter o resultado de modo diferente? Que outras abordagens são viáveis?</li><li>Você consegue entendê-lo em uma olhada rápida? Faz sentido?</li><li>Você pode usar o resultado ou o método em outro problema?</li><li>Você pode melhorar o desempenho de sua solução?</li><li>Você consegue pensar em outras maneiras de refatorar?</li><li>Como outras pessoas resolveram esse problema?</li></ul><p>Uma maneira de refatorar nosso problema para tornar nosso código mais conciso é remover nossa variável e usar um retorno implícito:</p><pre><code class="language-javascript">function add(a, b) {
 return a + b;
}</code></pre><p>Com a etapa 4, seu problema pode nunca parecer concluído. Até mesmo os grandes desenvolvedores ainda escrevem códigos que, mais tarde, olham e querem mudar. Essas são perguntas de orientação que podem ajudá-lo.</p><p>Se ainda tiver tempo em uma entrevista, você pode passar por essa etapa e melhorar sua solução. Se estiver programando por conta própria, reserve um tempo para revisar essas etapas.</p><p>Quando estou praticando programar por minha conta, quase sempre observo as soluções existentes que são mais elegantes ou eficazes do que as que eu criei.</p><h2 id="conclus-o">Conclusão</h2><p>Neste artigo, examinamos a estratégia de solução de problemas em quatro etapas para resolver problemas de programação.</p><p>Vamos analisá-las aqui:</p><ul><li>Etapa 1: <strong>entender o problema</strong></li><li>Etapa 2: <strong>criar um plano passo a passo de como você resolverá o problema</strong></li><li>Etapa 3: <strong>executar o plano</strong> e escrever o código real</li><li>Etapa 4: <strong>analisar o que foi feito</strong> e, possivelmente, refatorar sua solução se ela puder ser melhor.</li></ul><p>Praticar esse método de resolução de problemas me ajudou imensamente em minhas entrevistas técnicas e em meu trabalho como desenvolvedora.<br><br>Se você não se sentir confiante quando se trata de resolver problemas de programação, lembre-se de que a solução de problemas é uma habilidade que qualquer pessoa pode aprimorar com o tempo e a prática.</p><p>Boa sorte!</p><h3 id="se-voc-gostou-deste-artigo-participe-do-clube-de-programa-o-da-autora-onde-os-participantes-enfrentam-desafios-de-programa-o-juntos-todos-os-domingos-e-apoiam-uns-aos-outros-medida-que-aprendem-novas-tecnologias-">Se você gostou deste artigo, participe do <a href="https://madisonkanna.us14.list-manage.com/subscribe/post?u=323fd92759e9e0b8d4083d008&amp;id=033dfeb98f"><strong><strong>c</strong>lube de<strong> </strong></strong>programação</a> da autora, onde os participantes enfrentam desafios de programação juntos todos os domingos e apoiam uns aos outros à medida que aprendem novas tecnologias.<br></h3><h3 id="se-voc-tiver-coment-rios-ou-perguntas-sobre-esta-publica-o-sinta-se-vontade-para-enviar-um-tweet-para-a-autora-">Se você tiver comentários ou perguntas sobre esta publicação, sinta-se à vontade para enviar um tweet para a <a href="https://twitter.com/Madisonkanna">autora</a><strong><strong>.</strong></strong></h3> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como fazer com que o create-react-app funcione com uma API de back-end do Node ]]>
                </title>
                <description>
                    <![CDATA[ Esta é uma pergunta muito comum entre os novos desenvolvedores do React. É uma pergunta que eu tinha quando estava começando com o React e o Node.js. Neste breve exemplo, mostrarei como fazer com que o create-react-app funcione com o back-end com o Node.js e o Express. create-react-app Crie um ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-fazer-com-que-o-create-react-app-funcione-com-a-api-de-back-end-do-node/</link>
                <guid isPermaLink="false">64506d2ae704550645dfe9f8</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Sun, 28 May 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/1_eo3-wlU7ny1XYqPk4i2Blw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-make-create-react-app-work-with-a-node-backend-api-7c5c48acb1b0/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How To Make create-react-app work with a Node Back-end API</a>
      </p><p>Esta é uma pergunta muito comum entre os novos desenvolvedores do React. É uma pergunta que eu tinha quando estava começando com o React e o Node.js. Neste breve exemplo, mostrarei como fazer com que o <code>create-react-app</code> funcione com o back-end com o Node.js e o Express.</p><h4 id="create-react-app"><strong><strong>create-react-app</strong></strong></h4><p>Crie um projeto usando <code>create-react-app</code>.</p><pre><code class="language-bash">npx create-react-app example-create-react-app-express</code></pre><p>Crie um diretório <code>/client</code> no diretório <code>example-create-react-app-express</code> e mova todo o código <em>boilerplate </em>do React criado pelo <code>create-react-app</code> para esse novo diretório <code>client</code>.</p><pre><code class="language-bash">cd example-create-react-app-express
mkdir client</code></pre><h4 id="o-servidor-com-node-e-express">O servidor com Node e Express</h4><p>Crie um arquivo <code>package.json</code> dentro do diretório raiz (<code>example-create-react-app-express</code>) e copie o seguinte conteúdo:</p><pre><code class="language-json">{
  "name": "example-create-react-app-express",
  "version": "1.0.0",
  "scripts": {
    "client": "cd client &amp;&amp; yarn start",
    "server": "nodemon server.js",
    "dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
  },
  "dependencies": {
    "body-parser": "^1.18.3",
    "express": "^4.16.4"
  },
  "devDependencies": {
    "concurrently": "^4.0.1"
  }
}</code></pre><p>Observe que estou usando <code>concurrently</code> para executar a aplicação do React e o servidor ao mesmo tempo. O marcador <code>–kill-others-on-fail</code> eliminará outros processos se um deles for encerrado com um código de status diferente de zero.</p><p>Instale o <code>nodemon</code> globalmente e as dependências do servidor:</p><pre><code class="language-bash">npm i nodemon -g
yarn</code></pre><p>Crie um arquivo <code>server.js</code> e copie o seguinte conteúdo:</p><pre><code class="language-js">const express = require('express');
const bodyParser = require('body-parser');

const app = express();
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get('/api/hello', (req, res) =&gt; {
  res.send({ express: 'Hello From Express' });
});

app.post('/api/world', (req, res) =&gt; {
  console.log(req.body);
  res.send(
    `I received your POST request. This is what you sent me: ${req.body.post}`,
  );
});

app.listen(port, () =&gt; console.log(`Listening on port ${port}`));</code></pre><p>Este é um servidor Express simples que será executado na porta 5000 e terá duas rotas de API: <code>GET</code> - <code>/api/hello</code> e <code>POST</code> -<code>/api/world</code>.</p><p>Nesse ponto, você pode executar o servidor Express com o seguinte comando (ainda dentro do diretório raiz):</p><pre><code class="language-bash">node server.js</code></pre><p>Agora, navegue até <code>http://localhost:5000/api/hello</code> e você verá o seguinte:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/TPcEMDY475EhrLyGruM9uWQvM33ZKlDAl-cb.jpg" class="kg-image" alt="TPcEMDY475EhrLyGruM9uWQvM33ZKlDAl-cb" width="379" height="181" loading="lazy"></figure><p>Vamos testar a rota <code>POST</code> quando criarmos a aplicação em React.</p><h4 id="a-aplica-o-em-react">A aplicação em React</h4><p>Agora, vá para o diretório do <code>client</code> onde está a nossa aplicação em React.</p><p>Adicione a seguinte linha ao arquivo <code>package.json</code> criado pelo <code>create-react-app</code>.</p><pre><code class="language-json">"proxy": "http://localhost:5000/"</code></pre><p>A chave para usar um servidor de <em>back-end</em> do Express com um projeto criado com <code>create-react-app</code> é usar um proxy. Isso informa ao servidor de desenvolvimento do webpack para fazer proxy das nossas solicitações de API para o nosso servidor de API, já que o nosso servidor do Express está sendo executado em <code>localhost:5000</code>.</p><p>Agora, modifique o <code>./client/src/App.js</code> para chamar o <em>back-end</em> da API Express. As alterações estão em negrito.</p><pre><code class="language-js">import React, { Component } from 'react';

import logo from './logo.svg';

import './App.css';

class App extends Component {
  state = {
    response: '',
    post: '',
    responseToPost: '',
  };
  
  componentDidMount() {
    this.callApi()
      .then(res =&gt; this.setState({ response: res.express }))
      .catch(err =&gt; console.log(err));
  }
  
  callApi = async () =&gt; {
    const response = await fetch('/api/hello');
    const body = await response.json();
    if (response.status !== 200) throw Error(body.message);
    
    return body;
  };
  
  handleSubmit = async e =&gt; {
    e.preventDefault();
    const response = await fetch('/api/world', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ post: this.state.post }),
    });
    const body = await response.text();
    
    this.setState({ responseToPost: body });
  };
  
render() {
    return (
      &lt;div className="App"&gt;
        &lt;header className="App-header"&gt;
          &lt;img src={logo} className="App-logo" alt="logo" /&gt;
          &lt;p&gt;
            Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
          &lt;/p&gt;
          &lt;a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          &gt;
            Learn React
          &lt;/a&gt;
        &lt;/header&gt;
        &lt;p&gt;{this.state.response}&lt;/p&gt;
        &lt;form onSubmit={this.handleSubmit}&gt;
          &lt;p&gt;
            &lt;strong&gt;Post to Server:&lt;/strong&gt;
          &lt;/p&gt;
          &lt;input
            type="text"
            value={this.state.post}
            onChange={e =&gt; this.setState({ post: e.target.value })}
          /&gt;
          &lt;button type="submit"&gt;Submit&lt;/button&gt;
        &lt;/form&gt;
        &lt;p&gt;{this.state.responseToPost}&lt;/p&gt;
      &lt;/div&gt;
    );
  }
}

export default App;</code></pre><p>Criamos o método <code>callApi</code> para interagir com o caminho do <code>GET</code> da API do Express. Depois, chamamos esse método em <code>componentDidMount</code> e, por fim, definimos o estado para a resposta da API, que será "<em><em>Hello From Express</em>"</em>.</p><p>Observe que não usamos um URL totalmente qualificado <code>http://localhost:5000/api/hello</code> para chamar nossa API, mesmo que nossa aplicação do React seja executada em uma porta diferente (3000). Isso se deve à linha do <code><strong><strong>proxy</strong></strong></code><strong><strong> </strong></strong>que adicionamos ao arquivo <code>package.json</code> anteriormente.</p><p>Temos um formulário com uma única entrada. Quando enviado, chama <code>handleSubmit</code>, que, por sua vez, chama o caminho <code>POST</code> do Express API, salva a resposta no estado e exibe uma mensagem para o usuário: <em><em>I received your POST request. This is what you sent me: [message from input]</em></em>.</p><p>Agora, abra o arquivo <code>./client/src/App.css</code> e modifique a classe <code>.App-header</code> da seguinte forma (alterações em negrito)</p><pre><code class="language-js">.App-header {
...
  min-height: 50%;
...
  padding-bottom: 10px;
}</code></pre><h3 id="executando-a-aplica-o">Executando a aplicação</h3><p><em>Se o servidor ainda estiver em execução, interrompa-o pressionando Ctrl+C no terminal.</em></p><p>No diretório raiz do projeto, execute o seguinte:</p><pre><code class="language-bash">yarn dev</code></pre><p>Isso iniciará a aplicação do React e executará o servidor ao mesmo tempo.</p><p>Agora, navegue até <code>http://localhost:3000</code> e você verá a aplicação do React exibindo a mensagem proveniente do nosso caminho <code>GET</code> do Express. Legal!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/v3LAoDh50Yq4c60yOY69WpRwnZL2fRCIXfTs.jpg" class="kg-image" alt="v3LAoDh50Yq4c60yOY69WpRwnZL2fRCIXfTs" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/v3LAoDh50Yq4c60yOY69WpRwnZL2fRCIXfTs.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/v3LAoDh50Yq4c60yOY69WpRwnZL2fRCIXfTs.jpg 648w" width="648" height="581" loading="lazy"><figcaption>Exibição do caminho GET</figcaption></figure><p>Agora, digite algo no campo de entrada e envie o formulário. Você verá a resposta do caminho <code>POST</code> do Express exibida logo abaixo do campo de entrada.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/NcLZDJaVE0g833Xrn8jM2G8e5f4LVVygt10O.gif" class="kg-image" alt="NcLZDJaVE0g833Xrn8jM2G8e5f4LVVygt10O" width="633" height="544" loading="lazy"><figcaption>Chamada do caminho POST</figcaption></figure><p>Por fim, dê uma olhada no seu terminal e verá a mensagem que enviamos do <em>client</em>, porque chamamos <code>console.log</code> no corpo da solicitação no caminho <code>POST</code> Express.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/r43BMtm-aiA84Nxrin1eTHXi4YnnEX3SYzMM.jpg" class="kg-image" alt="r43BMtm-aiA84Nxrin1eTHXi4YnnEX3SYzMM" width="371" height="83" loading="lazy"><figcaption>Node</figcaption></figure><h3 id="implementa-o-de-produ-o-no-heroku">Implementação de produção no Heroku</h3><p>Abra o <code>server.js</code> e substitua pelo conteúdo a seguir:</p><pre><code class="language-js">const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');

const app = express();
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// API calls
app.get('/api/hello', (req, res) =&gt; {
  res.send({ express: 'Hello From Express' });
});

app.post('/api/world', (req, res) =&gt; {
  console.log(req.body);
  res.send(
    `I received your POST request. This is what you sent me: ${req.body.post}`,
  );
});

if (process.env.NODE_ENV === 'production') {
  // Serve any static files
  app.use(express.static(path.join(__dirname, 'client/build')));
    
  // Handle React routing, return all requests to React app
  app.get('*', function(req, res) {
    res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
  });
}

app.listen(port, () =&gt; console.log(`Listening on port ${port}`));</code></pre><p>Abra o arquivo <code>./package.json</code> e adicione o seguinte à entrada de <code>scripts</code></p><pre><code class="language-json">"start": "node server.js",
"heroku-postbuild": "cd client &amp;&amp; npm install &amp;&amp; npm install --only=dev --no-shrinkwrap &amp;&amp; npm run build"</code></pre><p>O Heroku executará o script <code>start</code> por padrão e isso servirá à nossa aplicação. Em seguida, queremos instruir o Heroku a criar nossa aplicação do <em>client</em>. Fazemos isso com o script <code>heroku-postbuild</code>.</p><p>Agora, vá até o <a href="https://www.heroku.com/" rel="noopener">Heroku</a> (em inglês) e faça login (ou abra uma conta, se ainda não tiver uma).</p><p>Crie uma aplicação e dê um nome a ela.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/YSsjVCvWV0-uieTxyQG1TDLrDT4ZxjOTb4pP.png" class="kg-image" alt="YSsjVCvWV0-uieTxyQG1TDLrDT4ZxjOTb4pP" width="230" height="131" loading="lazy"><figcaption>"Create new app" no Heroku</figcaption></figure><p>Clique na aba <strong><strong><em><em>Deploy</em></em></strong></strong> e siga as instruções de implantação (que eu acho que são bastante autoexplicativas, não há motivo para repeti-las aqui).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/vFyFAdbumn-k-39zK9DFZLJ6oWS9vfflmH1N.png" class="kg-image" alt="vFyFAdbumn-k-39zK9DFZLJ6oWS9vfflmH1N" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/vFyFAdbumn-k-39zK9DFZLJ6oWS9vfflmH1N.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/vFyFAdbumn-k-39zK9DFZLJ6oWS9vfflmH1N.png 800w" sizes="(min-width: 720px) 720px" width="800" height="505" loading="lazy"><figcaption>Deploy de uma aplicação no Heroku</figcaption></figure><p>É isso! Você pode abrir sua aplicação clicando no botão <strong><strong><em><em>Open app</em></em></strong></strong>, no canto superior direito do painel do Heroku da sua aplicação.</p><h4 id="outras-op-es-de-implementa-o">Outras opções de implementação</h4><p>Escrevo sobre outras opções de implementação aqui:</p><ul><li><a href="https://blog.bitsrc.io/react-production-deployment-part-1-netlify-703686631dd1" rel="noopener">Netlify</a> (em inglês)</li><li><a href="https://blog.bitsrc.io/react-production-deployment-part-2-now-c81657c700b7" rel="noopener">Now</a> (em inglês)</li><li><a href="https://blog.bitsrc.io/react-production-deployment-part-3-heroku-316319744885" rel="noopener">Heroku</a> (explicação mais detalhada - em inglês)</li></ul><h3 id="estrutura-do-projeto">Estrutura do projeto</h3><p>Esta será a estrutura final do projeto:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/YSFfgasf0j6pDjUX5TgcGCW6b8m74M6DTnY9.jpg" class="kg-image" alt="YSFfgasf0j6pDjUX5TgcGCW6b8m74M6DTnY9" width="195" height="315" loading="lazy"></figure><p>Acesse o código completo no <a href="https://github.com/esausilva/example-create-react-app-express" rel="noopener">repositório do GitHub</a>.</p><p>Obrigado pela leitura! Espero que você tenha gostado.</p><p>Você pode seguir o autor no <a href="https://twitter.com/_esausilva" rel="noopener">Twitter</a>, <a href="https://github.com/esausilva" rel="noopener">GitHub</a>, <a href="https://medium.com/@_esausilva/latest" rel="noopener">Medium</a>, <a href="https://www.linkedin.com/in/esausilva/" rel="noopener">LinkedIn</a> ou em todos eles.</p><p>Esta postagem foi publicada originalmente no <a href="https://esausilva.com/2017/11/14/how-to-use-create-react-app-with-a-node-express-backend-api/" rel="noopener">blog</a> pessoal do autor.</p><hr><p><strong><u>Atualização em</u><strong><u> </u></strong><u>25/0</u><strong><u>8</u></strong><u>/</u><strong><u>19:</u></strong></strong> o autor estava em processo de desenvolver uma aplicação para web de orações, chamada "<strong><strong>My Quiet Time - A Prayer Journal</strong></strong>". Para ver algumas capturas de tela de modelos, acesse o link a seguir: <a href="http://pc.cd/Lpy7">http://pc.cd/Lpy7</a>. Se quiser saber mais sobre a aplicação, o autor deixou disponível o endereço no <a href="https://twitter.com/_esausilva" rel="noopener">Twitter</a> para dúvidas sobre a aplicação.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como craquear senhas ]]>
                </title>
                <description>
                    <![CDATA[ Uma observação breve – este artigo é sobre a teoria de como quebrar senhas. Entender como os criminosos cibernéticos executam ataques é extremamente importante para entender como proteger sistemas contra esses tipos de ataques. A tentativa de invadir um sistema que você não possui é provavelmente ilegal em sua jurisdição ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-craquear-senhas/</link>
                <guid isPermaLink="false">643c8cb684d2fb0595fd67a4</guid>
                
                    <category>
                        <![CDATA[ Segurança da informação ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Thu, 18 May 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/5f9c9c61740569d1a4ca31d0.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/an-intro-to-password-cracking/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Crack Passwords</a>
      </p><p>Uma observação breve – este artigo é sobre a teoria de como quebrar senhas. Entender como os criminosos cibernéticos executam ataques é extremamente importante para entender como proteger sistemas contra esses tipos de ataques.</p><p>A tentativa de invadir um sistema que você não possui é provavelmente ilegal em sua jurisdição (além disso, invadir seus próprios sistemas pode violar – e, muitas vezes, viola – qualquer garantia para aquele produto).</p><h2 id="vamos-come-ar-com-o-b-sico-o-que-um-ataque-de-for-a-bruta">Vamos começar com o básico. O que é um ataque de força bruta?</h2><p>Este tipo de ataque envolve tentativas repetidas de entrar como usuário, tentando cada combinação possível de letras, números e caracteres (usando ferramentas automatizadas).</p><p>Isto pode ser feito tanto on-line (assim, em tempo real, tentando continuamente diferentes combinações de nome de usuário/senha em contas como redes sociais ou sites bancários) ou off-line (por exemplo, se você obteve um conjunto de senhas <em>hashed </em>e está tentando decifrá-las off-line).</p><p>A abordagem off-line nem sempre é possível (pode ser difícil obter um conjunto de senhas <em>hashed</em>), mas é muito menos barulhento. Isto porque uma equipe de segurança provavelmente notará o excesso de tentativas de acesso fracassadas na mesma conta, mas, se você conseguir quebrar a senha off-line, não terá um registro de tentativas de acesso fracassadas.</p><p>Isto é relativamente fácil com uma senha curta. Torna-se exponencialmente mais difícil com uma senha mais longa, devido ao grande número de possibilidades.</p><p>Por exemplo, se você souber que alguém está usando uma senha de 5 caracteres, composta apenas de letras minúsculas, o número total de senhas possíveis é 26^5 (26 possíveis escolhas para a primeira letra, 26 possíveis escolhas para a segunda letra etc.) ou 11.881.376 combinações possíveis.</p><p>Porém, se alguém estiver usando uma senha de 11 caracteres, apenas de letras minúsculas, o número total de senhas possíveis é 26 ^11, ou 3.670.344.486.987.776 de possíveis senhas.</p><p>Quando você adiciona letras maiúsculas, caracteres especiais e números, isto se torna ainda mais difícil e consome muito mais tempo para descobrir. Quanto mais senhas possíveis houver, mais difícil é para alguém conseguir entrar com sucesso com um ataque de força bruta.</p><h3 id="como-se-proteger">Como se proteger</h3><p>Este tipo de ataque pode ser evitado de duas maneiras diferentes. Primeiro, você pode usar senhas suficientemente longas e complexas (pelo menos 15 caracteres). Você também pode usar senhas únicas para cada conta (use um gerenciador de senhas!) para reduzir o perigo de violação de dados.</p><p>Uma equipe de segurança pode bloquear uma conta após um certo número de tentativas de acesso fracassadas. Eles também podem forçar um método secundário de verificação, como o Captcha, ou usar autenticação em 2 fatores (2FA), que requer um segundo código (por SMS ou e-mail, com base em aplicativos ou chaves de hardware).</p><p><a href="https://null-byte.wonderhowto.com/how-to/gain-ssh-access-servers-by-brute-forcing-credentials-0194263/">Aqui</a> está um artigo (em inglês) sobre como executar um ataque com força bruta.</p><h2 id="como-voc-pode-decifrar-senhas-mais-rapidamente">Como você pode decifrar senhas mais rapidamente?</h2><p>Um ataque de dicionário envolve a tentativa de entrar repetidamente, tentando várias combinações incluídas em um "dicionário" predefinido, ou lista de combinações.</p><p>Isto geralmente é mais rápido que um ataque de força bruta porque as combinações de letras e números já foram computadorizadas, economizando tempo e poder de processamento.</p><p>Porém, se a senha for suficientemente complexa (por exemplo, 1098324ukjbfnsdfsnej) e não aparecer no "dicionário" (a lista predefinida de combinações com as quais você está trabalhando), o ataque não vai funcionar.</p><p>É frequentemente bem-sucedido porque, muitas vezes, quando as pessoas escolhem senhas, elas escolhem palavras comuns ou variações dessas palavras (por exemplo, "password" ou "p@SSword").</p><p>Um hacker também pode usar este tipo de ataque quando sabe ou adivinha uma parte da senha (por exemplo, o nome de um cão, os aniversários de crianças, ou um aniversário - informações que um hacker pode encontrar em páginas de redes sociais ou outros recursos de código aberto).</p><p>Medidas de proteção similares às descritas acima contra ataques por força bruta podem impedir que estes tipos de ataques sejam bem sucedidos.</p><h2 id="o-que-voc-pode-fazer-se-j-tiver-uma-lista-de-senhas-hashed">O que você pode fazer se já tiver uma lista de senhas hashed?</h2><p>As senhas são armazenadas no arquivo <code>/etc/shadow</code> para Linux e <code>C:\Windows\System32\config</code> para Windows (que não estão disponíveis enquanto o sistema operacional é inicializado).</p><p>Se você conseguiu obter este arquivo, ou se obteve um hash de senha de uma maneira diferente, com <em>sniffing </em>do tráfego da rede, pode tentar quebrar a senha "off-line".</p><p>Enquanto os ataques acima requerem tentativas repetidas de acesso, se você tiver uma lista de senhas <em>hashed</em>, pode tentar quebrá-las em sua máquina, sem desencadear alertas gerados por repetidas tentativas de acesso fracassadas. Então, você só tentará fazer o acesso uma vez, depois de ter quebrado a senha com sucesso (e, portanto, não haverá nenhuma tentativa de acesso fracassada).</p><p>Você pode usar ataques de força bruta ou ataques de dicionário contra os arquivos de hash, podendo ter sucesso dependendo da força do hash.</p><h3 id="espere-a-o-que-hashing">Espere aí – o que é<strong><strong> <em>hashing</em>?</strong></strong></h3><p>35D4FFEF6EF231D998C6046764BB935D</p><p>Reconhece essa mensagem? Ela diz: "Hi my name is megan"</p><p>7DBDA24A2D10DAF98F23B95CFAF1D3AB</p><p>Este é o primeiro parágrafo deste artigo. Sim, parece um absurdo, mas na verdade é um <em>hash</em>.</p><p>Uma função hash permite que um computador insira uma string (alguma combinação de letras, números e símbolos), pegue essa string, misture-a e produza uma string de comprimento fixo. É por isso que ambas as strings acima são do mesmo tamanho, mesmo que as entradas das strings fossem de tamanhos muito diferentes.</p><p>Os <em>hashes </em>podem ser criados a partir de praticamente qualquer conteúdo digital. Basicamente, todo o conteúdo digital pode ser reduzido a binário, ou a uma série de 0s e 1s. Portanto, todo o conteúdo digital (imagens, documentos etc.) pode ser transformado em <em>hashes</em>.</p><p>Há muitas funções de <em>hashing </em>diferentes, algumas mais seguras do que outras. Os <em>hashes </em>acima foram gerados em MD5 (MD significa "Message Digest"). Diferentes funções também diferem no tamanho do <em>hash </em>que produzem.</p><p>O mesmo conteúdo na mesma função de <em>hash </em>produzirá sempre o mesmo <em>hash</em>. Entretanto, mesmo uma pequena mudança alterará completamente o <em>hash</em>. Por exemplo, o <em>hash</em>:</p><p>2FF5E24F6735B7564CAE7020B41C80F1</p><p>É o <em>hash </em>para "Hi my name is Megan". Colocar o M em Megan em letra maiúscula mudou completamente o <em>hash </em>acima.</p><p>Os <em>hashes </em>também são funções unidirecionais (o que significa que não podem ser revertidos). Isto significa que os <em>hashes </em>(únicos e unidirecionais) podem ser usados como um tipo de impressão digital para o conteúdo.</p><h3 id="qual-o-exemplo-de-como-os-hashes-s-o-usados">Qual o exemplo de como os <em>hashes </em>são usados?</h3><p><em>Hashes </em>podem ser usados como verificação de que uma mensagem que não tenha sido alterada.</p><p>Quando você envia um e-mail, por exemplo, você poderá fazer um <em>hash </em>de todo o e-mail e enviá-lo. Então, o destinatário pode executar a mensagem recebida através da mesma função de <em>hash </em>para verificar se a mensagem foi alterada durante o envio. Se os dois <em>hashes </em>corresponderem, a mensagem não foi alterada. Se não corresponderem, a mensagem foi alterada.</p><p>Além disso, as senhas geralmente são utilizadas em <em>hash </em>quando são armazenadas. Quando um usuário digita sua senha, o computador calcula o valor do <em>hash </em>e o compara com o valor do <em>hash </em>armazenado. Desse modo, o computador não armazena as senhas em texto claro (assim, alguns hackers bisbilhoteiros não podem roubá-las).</p><p>Se alguém é capaz de roubar o arquivo de senha, os dados são inúteis porque a função não pode ser revertida (embora existam maneiras, como tabelas arco-íris, de descobrir que o texto simples cria um <em>hash </em>conhecido).</p><h3 id="qual-o-problema-dos-hashes">Qual é o problema dos <em>hashes</em>?</h3><p>Se um <em>hash </em>pode obter dados de qualquer comprimento ou conteúdo, há possibilidades ilimitadas de dados que podem ser tratados com <em>hash</em>.</p><p>Como um <em>hash </em>converte o texto em um conteúdo de comprimento fixo (por exemplo, 32 caracteres), há um número finito de combinações de um <em>hash</em>. Trata-se de um número muito grande de possibilidades, mas não infinito.</p><p>Eventualmente, dois conjuntos diferentes de dados produzirão o mesmo valor de <em>hash</em>. Isto é chamado de colisão.</p><p>Se você tiver um <em>hash </em>e estiver tentando passar por cada um dos valores possíveis de texto sem formatação para encontrar o texto sem formatação que corresponda ao seu <em>hash</em>, será um processo muito longo, muito difícil.</p><h3 id="-poss-vel-que-voc-n-o-se-importe-que-dois-hashes-colidam">É possível que você não se importe que dois hashes colidam</h3><p>Isto é chamado de "<a href="https://pt.wikipedia.org/wiki/Paradoxo_do_anivers%C3%A1rio">paradoxo do aniversário</a>" em matemática. Em uma turma de 23 alunos, a probabilidade de alguém ter um aniversário em um dia específico é de cerca de 7%, mas a probabilidade de duas pessoas compartilharem o mesmo aniversário é de cerca de 50%.</p><p>O mesmo tipo de análise pode ser aplicado às funções de <em>hash </em>para encontrar quaisquer dois <em>hashes </em>que combinem (ao invés de um <em>hash </em>específico que combine com o outro).</p><p>Para evitar isto, você pode usar funções de <em>hash </em>mais longas, como a SHA3, onde a possibilidade de colisões é menor.</p><p>Você pode tentar gerar suas próprias funções de <em>hash </em>para SHA3 <a href="https://www.browserling.com/tools/sha3-hash">aqui</a> e para MD5 <a href="http://onlinemd5.com/">aqui</a>.</p><p>Você pode tentar fazer <em>hashes </em>de força bruta, mas isso leva muito tempo. A maneira mais rápida de se fazer isso é usando <a href="https://www.freecodecamp.org/news/why-a-little-salt-can-be-great-for-your-passwords/">tabelas arco-íris</a> (texto em inglês) – elas são semelhantes a ataques de dicionário.</p><h2 id="parece-realmente-f-cil-de-ser-invadido-devo-ficar-preocupado">Parece realmente fácil de ser invadido. Devo ficar preocupado?</h2><p>O mais importante a lembrar sobre o <em>hacking </em>é que ninguém quer fazer mais trabalho do que aquilo que tem que fazer. Por exemplo, os <em>hashes </em>de força bruta podem ser extremamente demorados e difíceis. Se houver uma maneira mais fácil de obter sua senha, provavelmente é isso que uma pessoa mal-intencionada tentará primeiro.</p><p>Isso significa que possibilitar as melhores práticas básicas de segurança cibernética é provavelmente a maneira mais fácil de evitar ser invadido. De fato, a Microsoft <a href="https://www.zdnet.com/article/microsoft-using-multi-factor-authentication-blocks-99-9-of-account-hacks/">relatou recentemente</a> (texto em inglês) que apenas habilitar o 2FA acabará bloqueando 99,9% dos ataques automatizados.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screen-Shot-2019-08-27-at-1.18.47-PM.png" class="kg-image" alt="Screen-Shot-2019-08-27-at-1.18.47-PM" width="464" height="288" loading="lazy"><figcaption><a href="https://xkcd.com/538/">https://xkcd.com/538/</a></figcaption></figure><p><strong>Leitura adicional (em inglês)<strong>:</strong></strong></p><p><a href="https://resources.infosecinstitute.com/10-popular-password-cracking-tools/">10 most popular password cracking tools</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Lista de processos do Linux – como verificar os processos em execução ]]>
                </title>
                <description>
                    <![CDATA[ Todos os dias, os desenvolvedores usam várias aplicações e executam comandos no terminal. Essas aplicações podem incluir um navegador, editor de código, terminal, aplicação de videochamada ou reprodutor de música. Para cada uma dessas aplicações de software que você abre ou comando que executa, ele cria um processo ou tarefa. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/lista-de-processos-do-linux-como-verificar-os-processos-em-execucao/</link>
                <guid isPermaLink="false">63d113f991baea05fef71c6f</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Sun, 07 May 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/article-banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/linux-list-processes-how-to-check-running-processes/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Linux List Processes – How to Check Running Processes</a>
      </p><p>Todos os dias, os desenvolvedores usam várias aplicações e executam comandos no terminal. Essas aplicações podem incluir um navegador, editor de código, terminal, aplicação de videochamada ou reprodutor de música.</p><p>Para cada uma dessas aplicações de software que você abre ou comando que executa, ele cria um <em><em>process</em>o</em> ou <em><em>ta</em>refa</em>.</p><p>Uma bela característica do sistema operacional Linux e dos computadores modernos em geral é que eles fornecem suporte para multitarefas. Assim, vários programas podem ser executados simultaneamente.</p><p>Você já se perguntou como você pode verificar todos os programas em execução na sua máquina? Se já fez isso, este artigo é para você, pois vou mostrar aqui como listar, gerenciar e eliminar todos os processos em execução em sua máquina Linux.</p><h2 id="pr-requisitos">Pré-requisitos</h2><ul><li>Uma distro Linux instalada.</li><li>Conhecimento básico em navegação pela linha de comando.</li><li>Um sorriso no rosto 😀</li></ul><h2 id="uma-introdu-o-r-pida-aos-processos-no-linux">Uma introdução rápida aos processos no Linux</h2><p>Um processo é uma instância de um programa de computador em execução que você pode encontrar em um programa de software ou comando.</p><p>Por exemplo, se você abrir o editor do Visual Studio Code, isso criará um processo que somente será finalizado uma vez que você termine ou feche o Visual Studio Code.</p><p>Da mesma forma, quando você executa um comando no terminal (tipo <code>curl ifconfig.me</code>), ele cria um processo que só vai parar quando o comando terminar de executar ou for finalizado.</p><h2 id="como-listar-os-processos-em-execu-o-no-linux-com-o-comando-ps">Como listar os processos em execução no Linux com o comando<strong> <code>ps</code></strong></h2><p>Você pode listar os processos em execução usando o comando <code>ps</code> (ps significa <em><em>process status</em></em>). O comando <code>ps</code> exibe seus processos em execução no momento e em tempo real.</p><p>Para testar isso, basta abrir o terminal e executar o comando <code>ps</code>, assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-3.25.33-PM.png" class="kg-image" alt="Screenshot-2021-06-28-at-3.25.33-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/Screenshot-2021-06-28-at-3.25.33-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/05/Screenshot-2021-06-28-at-3.25.33-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/05/Screenshot-2021-06-28-at-3.25.33-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-3.25.33-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1274" loading="lazy"></figure><p>Isto mostrará o processo que está em execução em quatro colunas:</p><ul><li><strong><strong>PID</strong></strong> retorna o ID exclusivo do processo</li><li><strong><strong>TTY</strong></strong> retorna o tipo de terminal em que você está logado</li><li><strong><strong>TIME</strong></strong> retorna a quantidade total de uso da CPU</li><li><strong><strong>CMD</strong></strong> retorna o nome do comando que iniciou o processo.</li></ul><p>Você pode escolher exibir um determinado conjunto de processos usando qualquer combinação das opções (como <code>-A</code> <code>-a</code>, <code>-C</code>, <code>-c</code>, <code>-d</code>, <code>-E</code>, <code>-e</code>, <code>-u</code>, <code>-X</code>, <code>-x</code>, entre outros).</p><p>Se você especificar mais de uma dessas opções, todos os processos que forem combinados por, pelo menos, uma das opções indicadas serão exibidas.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-3.55.10-PM.png" class="kg-image" alt="Screenshot-2021-06-28-at-3.55.10-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/Screenshot-2021-06-28-at-3.55.10-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/05/Screenshot-2021-06-28-at-3.55.10-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/05/Screenshot-2021-06-28-at-3.55.10-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-3.55.10-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1274" loading="lazy"><figcaption>A página do manual do comando <code>ps</code>.</figcaption></figure><blockquote>Digite <code>man ps</code> no seu terminal para ler o manual do comando <code>ps</code>, que tem uma referência completa para todas as opções e suas utilizações.</blockquote><p>Para mostrar todos os processos em execução para todos os usuários na sua máquina, incluindo os seus nomes de usuário, e para mostrar processos não conectados ao seu terminal, é possível usar o comando abaixo:</p><pre><code>ps aux</code></pre><p>Aqui está uma descrição do comando:</p><ul><li><code>ps</code>: é o comando de status do processo.</li><li><code>a</code>: exibe informações sobre os processos de outros usuários, bem como os seus.</li><li><code>u</code>: &nbsp;exibe os processos pertencentes aos nomes de usuário especificados.</li><li><code>x</code>: inclui processos que não possuem terminal de controle.</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-4.39.05-PM.png" class="kg-image" alt="Screenshot-2021-06-28-at-4.39.05-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/Screenshot-2021-06-28-at-4.39.05-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/05/Screenshot-2021-06-28-at-4.39.05-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/05/Screenshot-2021-06-28-at-4.39.05-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-4.39.05-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1274" loading="lazy"></figure><p>Isso exibirá o processo para o <em>shell </em>atual em onze colunas:</p><ul><li><strong><strong>USER</strong></strong> retorna o nome de usuário de quem está executando o processo</li><li><strong><strong>PID</strong></strong> retorna o ID de processo exclusivo</li><li><strong><strong>%CPU</strong></strong> retorna a porcentagem de uso da CPU</li><li><strong><strong>%MEM</strong></strong> retorna a porcentagem de uso da memória</li><li><strong><strong>VSV</strong></strong> retorna o tamanho virtual em Kbytes</li><li><strong><strong>RSS</strong></strong> retorna o tamanho do conjunto residente</li><li><strong><strong>TT</strong></strong> retorna o nome do terminal de controle</li><li><strong><strong>STAT</strong></strong> retorna o estado do processo simbólico</li><li><strong><strong>STARTED</strong></strong> retorna a hora de início</li><li><strong><strong>CMD</strong></strong> retorna o comando que iniciou o processo.</li></ul><h2 id="como-listar-processos-em-execu-o-no-linux-usando-os-comandos-top-e-htop">Como listar processos em execução no Linux usando os comandos<strong> <code>top</code> e <code>htop</code></strong></h2><p>Você também pode usar o comando <code>top</code> do gerenciador de tarefas no Linux para ver uma lista ordenada em tempo real dos processos principais que usam mais memória ou CPU.</p><p>Digite <code>top</code> em seu terminal e você terá um resultado como o que você vê na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-4.27.28-PM.png" class="kg-image" alt="Screenshot-2021-06-28-at-4.27.28-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/Screenshot-2021-06-28-at-4.27.28-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/05/Screenshot-2021-06-28-at-4.27.28-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/05/Screenshot-2021-06-28-at-4.27.28-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-28-at-4.27.28-PM.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1274" loading="lazy"></figure><blockquote>Você pode digitar <code>q</code> para sair da sessão.</blockquote><p>Uma alternativa ao <code>top</code> é o <code>htop</code> que fornece um monitor de sistema interativo para visualizar e gerenciar processos. Ele também exibe uma lista ordenada em tempo real de processos com base em seu uso de CPU. Você pode facilmente pesquisar, filtrar e matar processos em execução.</p><p>O <code>htop</code> não está instalado no Linux por padrão. Então, você precisa instalá-lo usando o comando abaixo ou baixar os binários para sua distro Linux preferida.</p><pre><code>sudo apt update &amp;&amp; sudo apt install htop</code></pre><p>Basta digitar <code>htop</code> em seu terminal e você terá um resultado como o que você vê na captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-29-at-4.49.09-AM.png" class="kg-image" alt="Screenshot-2021-06-29-at-4.49.09-AM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/Screenshot-2021-06-29-at-4.49.09-AM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/05/Screenshot-2021-06-29-at-4.49.09-AM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/05/Screenshot-2021-06-29-at-4.49.09-AM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/Screenshot-2021-06-29-at-4.49.09-AM.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1274" loading="lazy"></figure><h2 id="como-encerrar-processos-em-execu-o-no-linux">Como encerrar processos em execução no Linux</h2><p>Encerrar um processo significa que você termina uma aplicação ou comando em execução. Você pode encerrar um processo executando o comando <code>kill</code> com o ID do processo ou o comando <code>pkill</code> juntamente ao nome do processo, assim:</p><pre><code>kill [PID]</code></pre><p>ou</p><pre><code>pkill [COMMAND]</code></pre><p>Para encontrar o ID de um processo em execução, você pode usar o comando <code>pgrep</code> seguido do nome do processo, deste modo:</p><pre><code>pgrep iTerm2</code></pre><p>Para encerrar o processo iTerm2 na captura de tela acima, usaremos qualquer um dos comandos abaixo. Isto terminará e fechará automaticamente o processo iTerm2 (aplicação).</p><pre><code>kill 25781</code></pre><p>ou</p><pre><code>kill iTerm2</code></pre><h2 id="conclus-o">Conclusão</h2><p>Quando você lista processos em execução, geralmente é uma lista longa e agrupada. Você pode canalizá-la através de poucas palavras para exibir a saída do comando uma página de cada vez em seu terminal assim:</p><pre><code>ps aux | less</code></pre><p>Também é possível exibir apenas um processo específico que corresponda a um nome específico, assim:</p><pre><code>ps aux | grep Chrome</code></pre><p>Espero que, agora, você entenda o que são processos no Linux e como gerenciá-los usando os comandos <code>ps</code>, <code>top</code> e <code>htop</code>. Certifique-se de verificar o manual para cada comando, executando <code>man ps</code>, <code>man top</code> ou <code>man htop</code>, respectivamente. O manual inclui uma referência abrangente que você pode verificar se precisar de mais ajuda em qualquer ponto.</p><p>Obrigado pela leitura! Tudo de bom! 💙</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
