<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Guilherme Manzano</title>
    <description>The latest articles on DEV Community by Guilherme Manzano (@guilhermemanzano).</description>
    <link>https://dev.to/guilhermemanzano</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F485405%2F792fc32e-94cb-47c6-a0ba-456aa5efacb8.jpeg</url>
      <title>DEV Community: Guilherme Manzano</title>
      <link>https://dev.to/guilhermemanzano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guilhermemanzano"/>
    <language>en</language>
    <item>
      <title>Guia de estudos de React</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Sat, 20 Jul 2024 01:48:14 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/guia-de-estudos-de-react-456l</link>
      <guid>https://dev.to/guilhermemanzano/guia-de-estudos-de-react-456l</guid>
      <description>&lt;p&gt;Durante meus estudos de React, fiquei confuso com a quantidade de termos e bibliotecas que são utilizadas para desenvolver uma aplicação React completa, sem saber por onde começar.&lt;/p&gt;

&lt;p&gt;Após quebrar a cabeça com alguns cursos aleatórios, resolvi escrever uma guia com os termos mais importantes do universo React e as bibliotecas mais utilizadas (e algumas nem tanto, mas interessantes) para ter um norte.&lt;/p&gt;

&lt;p&gt;Este não é um roadmap de estudo de React, mas uma fonte rápida e concisa para consulta da terminologia e uma breve explicação sobre algumas bibliotecas interessantes. Recomendo utilizar este guia como um primeiro passo para se familiarizar com React e, depois, buscar cursos específicos sobre cada tema tratado aqui (além de consultar a documentação de cada biblioteca, que costuma ser uma ótima forma de aprofundar os estudos).&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; é uma biblioteca para desenvolvimento de aplicações web, desenvolvida pelo Facebook (atual Meta), sendo utilizada largamente para criar aplicações web complexas que precisam ser atualizadas em tempo real. Ele é uma biblioteca modular, o que permite que os seus componentes possam ser facilmente reutilizados e compartilhados entre diferentes partes da aplicação. Além disso, podemos utilizá-lo em conjunto com o React Native para o desenvolvimento de aplicativos móveis para Android e iOS. Para converter o código escrito em uma versão mais recente do ECMAScript para uma versão compatível com navegadores mais antigos, o React se utiliza do Babel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DOM (Document Object Model)&lt;/strong&gt; é uma estrutura hierárquica em forma de árvore que organiza elementos como HTML, CSS, e JavaScript. Ele captura e organiza esses elementos, criando a representação visual exibida no navegador. O objeto global "document" referencia o HTML e permite interagir com o conteúdo e elementos da página.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomia do React
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;componente funcional&lt;/strong&gt; é um tipo de componente no React que é definido como uma função Javascript, que recebe as propriedades como argumento e retorna o elemento React que deseja renderizar. Cada componente é um pedaço de código que segue um determinado padrão e, que pode ser reutilizado várias vezes ao longo de sua aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Props&lt;/strong&gt; são um tipo de dados que podem ser passados para um componente React, como texto, imagens, números ou outros componentes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React-DOM&lt;/strong&gt; é uma biblioteca que fornece métodos para manipular o DOM, permitindo renderizar os seus componentes utilizando dois métodos principais: createRoot e render. O método createRoot cria uma raiz do React, que é um ponto de entrada para o seu aplicativo React no DOM. Já o método render, renderiza um elemento React no DOM, usando a raiz do React criada pelo método createRoot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSX&lt;/strong&gt; é uma extensão da linguagem Javascript que é utilizada pelo React para criar interfaces de usuário, que permite misturar código Javascript com a sintaxe HTML, tornando mais fácil escrever componentes em um único arquivo de código. O TSX funciona da mesma forma, sendo uma extensão da linguagem Typescript. Exemplo:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Router DOM&lt;/strong&gt; refere-se aos métodos e funcionalidades nativas do DOM para manipulação do histórico de navegação no navegador, incluindo métodos como pushState, replaceState e popstate. Ele permite mudar o URL exibido no navegador e responder a essas mudanças sem uma página ser totalmente recarregada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ciclo de vida no React
&lt;/h2&gt;

&lt;p&gt;O ciclo de vida de um componente é o conjunto de etapas que um componente passa ao ser criado, montado, atualizado e desmontado em uma aplicação. Os componentes funcionais não possuem métodos de ciclo de vida como os componentes de classe, mas eles se utilizam de hooks para gerenciar o estado e executar ações em resposta às mudanças no estado ou nas propriedades.&lt;/p&gt;

&lt;p&gt;Os &lt;strong&gt;Reacts hooks&lt;/strong&gt; são funções que permitem utilizar o estado e outros recursos do React em componentes funcionais. Existem diversos hooks, cada um com um propósito específico. Os principais são: &lt;/p&gt;

&lt;p&gt;●&lt;strong&gt;useEffect&lt;/strong&gt;: permite executar código em resposta a mudanças no estado ou nas propriedades de um componente. Ele é bastante útil para executar ações assíncronas, como fazer requisições HTTP ou alterar o DOM quando o estado ou as propriedades mudam.&lt;/p&gt;

&lt;p&gt;●&lt;strong&gt;useLayoutEffect&lt;/strong&gt;: é semelhante ao useEffect, mas é chamado de forma síncrona após todas as mutações do DOM, sendo mais adequado para operações que precisam ler e escrever no DOM e garantir que as mudanças sejam aplicadas antes da próxima repintura;&lt;/p&gt;

&lt;p&gt;●&lt;strong&gt;useState&lt;/strong&gt;: permite adicionar estado a componentes funcionais, para manter e atualizar estados internos.&lt;/p&gt;

&lt;p&gt;●&lt;strong&gt;useRef&lt;/strong&gt;: permite criar uma referência persistente que pode ser anexada a um elemento DOM (permitindo manipulação direta, como foco, seleção, etc) ou armazenar valores mutáveis sem causar uma nova renderização do componente, sendo útil para acessar diretamente elementos DOM e para manter valores que não necessitam desencadear uma renderização quando alterados.&lt;/p&gt;

&lt;p&gt;●&lt;strong&gt;useMemo&lt;/strong&gt;: permite memorizar valores calculados para otimizar a performance de componentes funcionais, sendo utilizado para evitar cálculos "caros" ou operações intensivas de renderização em cada renderização, recalculando o valor apenas quando uma das dependências muda.&lt;/p&gt;

&lt;p&gt;●&lt;strong&gt;useCallback&lt;/strong&gt;: retorna uma versão memorizada de uma função de callback. Isso é útil para otimizar componentes que dependem de callbacks que, se recriados em cada renderização, poderiam causar renderizações desnecessárias de componentes filhos ou disparar efeitos colaterais adicionais.&lt;/p&gt;

&lt;p&gt;O hook &lt;strong&gt;useLayoutEffect&lt;/strong&gt;, quando criado com um array vazio, atua como o componentWillMount (invocado imediatamente antes do componente ser montado na DOM). É usado quando você precisa mudar algo visualmente antes do componente aparecer, para que não haja aquele problema da tela piscar assim que a tela carrega (por exemplo, para alterar o tema para light/dark).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useLayoutEffect(() =&amp;gt; {&lt;br&gt;
 …&lt;br&gt;
},[])&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;useEffect&lt;/strong&gt; com o array de dependências vazio atua como o componentDidMount, diferente do useLayoutEffect, ele executa assim que o componente é renderizado, normalmente é utilizado para fazer chamadas para o servidor ou fazer algum cálculo com props passados.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useEffect(() =&amp;gt; {&lt;br&gt;
 …&lt;br&gt;
}, [])&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;componentWillUpdate&lt;/strong&gt; pode ser feito tanto pelo useLayoutEffect quanto pelo useEffect, desde que tenha uma variável no array de dependências e, à partir da primeira execução, ambos atuarão como componentWillUpdate, sempre executando quando essa variável mudar.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useEffect(() =&amp;gt; {&lt;br&gt;
 …&lt;br&gt;
}, [variavel])&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para invocar o &lt;strong&gt;componentWillUnmount&lt;/strong&gt; em hooks, basta retornar uma função dentro do useEffect, pois desta forma, essa função dentro do return só será executada quando o componente estiver desmontando. É bastante usado para clearTimeout, clearInterval ou para enviar informações de acesso daquele componente para outro lugar.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useEffect(() =&amp;gt; {&lt;br&gt;
 return () =&amp;gt; {&lt;br&gt;
   …&lt;br&gt;
 }&lt;br&gt;
},[])&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Redux
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Redux&lt;/strong&gt; é uma biblioteca Javascript criada com o objetivo de resolver problemas de fluxo de informação de uma aplicação front-end, armazenando todos os estados de nossa aplicação e os disponibilizando em todo e qualquer componente. Os seus componentes principais são: a View, as Actions, os Dispatcher, os Reducers e o Store. Vejamos cada um com mais detalhes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc11hrbrm51qy9nbon7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc11hrbrm51qy9nbon7i.png" alt="Image description" width="585" height="438"&gt;&lt;/a&gt;&lt;br&gt;
Fonte: &lt;a href="https://redux.js.org/tutorials/fundamentals/part-1-overview" rel="noopener noreferrer"&gt;https://redux.js.org/tutorials/fundamentals/part-1-overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;View&lt;/strong&gt; é a parte visual, onde adicionamos nossos componentes React.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Action&lt;/strong&gt; são ações que devem ser disparadas quando queremos que algo seja mudado no nosso estado global. Ela é uma função que retorna um objeto, contendo um type e, opcionalmente, um payload. O objeto representa uma ação que será feita em um reducer.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Dispatch&lt;/strong&gt; é a ação de disparar uma action. A action sozinha é apenas um objeto com a "assinatura" que o redux aceita, já o dispatch é uma função que oficializa que aquela action está sendo disparada para o redux. É utilizado através do uso do hook useDispatch().&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reducers&lt;/strong&gt; são pequenos estados dentro do Store (são pedaços do nosso estado global), que permite sabermos o valor atual do estado e o que deve ser mudado, de acordo com cada action. São funções que aceitam um estado inicial (chamado de state) e as actions como argumentos e sempre retornam um novo estado.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Store&lt;/strong&gt; é o estado total do Redux, com todos os reducer e algumas funções utilitárias, como getState() e dispatch(), entre outras.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Outros Termos do Redux
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Immer&lt;/strong&gt; é uma biblioteca capaz de lidar com imutabilidade (ato de nunca alterar um dado) mais facilmente, para que você não precise se preocupar em estar mutando um estado ou não.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt; é um identificador de uma action, que será utilizado pelo reducer para identificar aquela ação e saber o que fazer com ela. Se o type é "incrementar" dentro do reducer deve haver um tratamento para caso a action seja do type incrementar. Caso esteja utilizando o Redux Toolkit, o type é criado automaticamente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useSelector&lt;/strong&gt; é um hook que permite acessar o state toda a aplicação. Com ele, é possível receber todo o estado de uma só vez ou pegar exatamente o que é preciso. É recomendável que seja utilizado para filtrar exatamente o necessário para o seu componente atual, visto que o seu componente fica "conectado" ao estado entregue ao useSelector, atualizando sempre que aquele estado mudar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt; normalmente se refere ao estado de um reducer (no contexto do Redux). Dentro de useSelector, ele representa o estado de todo o Store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial State&lt;/strong&gt; é o estado inicial de um reducer. Ele é obrigatório, pois é utilizado como o primeiro ponto de um estado antes das alterações que as actions disparadas farão.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provider&lt;/strong&gt; é um componente da biblioteca react-redux que permite prover o Store para todos os componentes que estão abaixo dele.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redux Toolkit&lt;/strong&gt; é uma biblioteca que facilita a criação de diversas coisas no Redux, como criar Reducers abstratos utilizando Slices, o que cria automaticamente actions, conseguindo resolver os estados com imutabilidade de forma automática.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slice&lt;/strong&gt; é o termo utilizado pelo React Toolkit para se referir ao pedaço que criamos que corresponderá ao Reducer, as Actions e as Actions types correspondentes àquele reducer. Ele é criado com a função createSlice do Redux Toolkit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt; se refere a uma camada intermediária de software que processa, modifica ou manipula dados enquanto eles estão sendo transferidos de uma parte do sistema para outra. Em aplicações frontend, o middleware pode ser usado para interceptar e processar requisições de API, adicionando cabeçalhos de autorização, manipulando tokens de autenticação, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redux Thunk&lt;/strong&gt; é um middleware poderoso que estende a capacidade do Redux de lidar com operações assíncronas de forma limpa e organizada. Ele permite que as action creators sejam usadas para fazer requisições assíncronas, mantendo o fluxo de dados previsível e síncrono, característico do Redux. Ao permitir que as ações sejam funções em vez de objetos simples, o Redux Thunk facilita a integração de operações assíncronas em aplicações Redux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bibliotecas essenciais no ecossistema React
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React Router&lt;/strong&gt; é uma biblioteca para gerenciamento de rotas no React. Ele abstrai e facilita o gerenciamento de navegação e URLs dentro de uma aplicação React.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PropTypes&lt;/strong&gt; é uma ferramenta de validação de tipos usada em componentes React para garantir que as props passadas para um componente tenham os tipos esperados. É uma forma de melhorar a robustez e a legibilidade do código, ajudando a capturar erros de tipo durante o desenvolvimento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Axios&lt;/strong&gt; é uma biblioteca de cliente HTTP baseada em Promises para fazer requisições HTTP no navegador e no Node.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Styled-components&lt;/strong&gt; é uma biblioteca que permite escrever estilos CSS reutilizáveis diretamente nos componentes, usando uma sintaxe similar ao CSS tradicional, mas com benefícios extras, como props dinâmicas e variáveis. Isso permite gerar estilos com base nas props dos componentes, facilitando a criação de designs dinâmicos e responsivos. É ideal para projetos que requerem uma abordagem mais orientada a componentes, com um foco maior na reutilização, manutenção e encapsulamento de estilos, especialmente em projetos maiores ou mais complexos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Query&lt;/strong&gt; é uma biblioteca para gerenciar o estado de dados assíncronos em aplicações React. Ela simplifica o processo de busca, armazenamento, sincronização e atualização de dados remotos, permitindo que você se concentre mais na lógica da aplicação e menos no gerenciamento de estado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jest&lt;/strong&gt; é uma biblioteca de testes unitários em Javascript, amplamente utilizada no React.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cypress&lt;/strong&gt; é uma ferramenta de teste E2E moderna e robusta para aplicações web. Ela é projetada para ser fácil de configurar e usar, oferecendo uma experiência de desenvolvimento rica para escrever testes E2E, testes de integração e testes unitários.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Hook Form&lt;/strong&gt; é uma biblioteca leve e simples que se concentra em usar hooks do React para criar formulários sem a necessidade de uma grande quantidade de código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Formik&lt;/strong&gt; é uma biblioteca mais completa e robusta que fornece uma solução mais tradicional para o gerenciamento de formulários em React.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yup&lt;/strong&gt; é uma biblioteca de validação de esquemas para JavaScript que permite definir regras de validação de forma simples e expressiva, garantindo que os dados de entrada atendam aos critérios especificados. Yup é comumente utilizado em conjunto com outras bibliotecas de formulários, como Formik e React Hook Form, para realizar validações de formulários de maneira eficaz e fácil.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;i18next&lt;/strong&gt; é uma biblioteca JavaScript para internacionalização (i18n) em aplicativos web. Ele fornece uma maneira simples e flexível de adicionar suporte a vários idiomas e localizações em seus projetos, permitindo que você traduza facilmente o conteúdo do seu aplicativo e adapte-o para diferentes regiões do mundo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ESLint&lt;/strong&gt; é uma ferramenta de linting para JavaScript e TypeScript. Seu principal objetivo é analisar o código para encontrar e corrigir problemas, garantindo que ele siga um conjunto definido de regras e padrões.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Biome.js&lt;/strong&gt; é uma ferramenta poderosa para formatação de código, linting e automação em projetos JavaScript. Ela combina várias funcionalidades úteis em uma única ferramenta, visando melhorar a qualidade do código e produtividade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bibliotecas auxiliares
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt; é uma biblioteca de estilos CSS utilitários. Em vez de fornecer componentes pré-estilizados, ele fornece uma ampla variedade de classes utilitárias que podem ser aplicadas diretamente ao HTML para estilizar os elementos. Normalmente é utilizado em projetos onde a velocidade de desenvolvimento e a flexibilidade são prioridades, especialmente em projetos menores ou onde a prototipagem rápida é necessária.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fuse.js&lt;/strong&gt; é uma biblioteca JavaScript de pesquisa baseada em fuzzy search (pesquisa aproximada) que permite buscar dados de forma eficiente mesmo quando há pequenas discrepâncias ou erros de digitação nas consultas de pesquisa. É especialmente útil quando você deseja proporcionar uma experiência de pesquisa robusta em aplicações web, onde os usuários podem cometer erros de digitação ou não conhecer a terminologia exata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Emotion&lt;/strong&gt; é uma biblioteca JavaScript para estilização de componentes em aplicações React (similar ao Styled-Component). Ela oferece uma maneira poderosa e flexível de adicionar estilos CSS aos componentes, utilizando uma combinação de CSS-in-JS, tagged templates e API simplificada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zod&lt;/strong&gt; é uma biblioteca de validação de esquemas altamente eficiente e tipada para o TypeScript. Ela foi projetada para tornar a validação de dados em projetos TypeScript mais simples, robusta e segura, fornecendo uma sintaxe expressiva e tipada para definir e validar esquemas de dados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Moment.js&lt;/strong&gt; é uma biblioteca JavaScript de análise, manipulação e formatação de datas e horas. Ela oferece uma série de recursos poderosos para lidar com datas, facilitando tarefas como análise de strings de data, cálculos de diferença entre datas, formatação de datas para diferentes formatos, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Humps&lt;/strong&gt; é uma biblioteca JavaScript que fornece funções utilitárias para converter chaves de objetos entre diferentes convenções de nomenclatura, como camelCase, snake_case e kebab-case. Essa biblioteca é especialmente útil quando você precisa interoperar com APIs ou bibliotecas que seguem convenções de nomenclatura diferentes das suas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ramda&lt;/strong&gt; é uma biblioteca JavaScript funcional que oferece uma série de funções utilitárias para manipulação de dados de forma funcional e declarativa. Ela é especialmente útil para projetos que adotam o paradigma de programação funcional e desejam aproveitar os benefícios da imutabilidade, composição de funções e currying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downshift&lt;/strong&gt; é uma biblioteca JavaScript para criar componentes de seleção (dropdowns) acessíveis, flexíveis e de alto desempenho em React. Desenvolvida pelo Airbnb, ela oferece uma abordagem simples e poderosa para construir componentes de seleção personalizados com suporte à acessibilidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recoil&lt;/strong&gt; é uma biblioteca para gerenciamento de estado em aplicações React (similar ao Redux), que oferece uma maneira simples e eficiente de gerenciar o estado da aplicação, especialmente em casos onde o estado precisa ser compartilhado entre vários componentes. Ela é uma excelente opção para projetos menores, ou para partes específicas de uma aplicação, onde a simplicidade, a flexibilidade e a acessibilidade são prioritárias. É uma escolha mais direta para quem está familiarizado com React Hooks e deseja uma experiência de desenvolvimento mais simplificada, comparada com o Redux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MUI (Material-UI)&lt;/strong&gt; é uma biblioteca de componentes React que implementa os princípios do Material Design, criado pelo Google. Ela fornece um conjunto robusto de componentes prontos para uso, altamente personalizáveis e acessíveis, que podem ser usados para criar interfaces de usuário modernas e consistentes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hoist-non-react-statics&lt;/strong&gt; é uma biblioteca JavaScript muito útil para copiar propriedades estáticas de um componente para outro componente. Isso é especialmente útil em situações onde você tem um componente de "alto nível" que contém funcionalidades ou métodos estáticos que você deseja expor em um componente "de baixo nível" que é renderizado dentro do componente de alto nível. Por exemplo, suponha que você tenha um componente HighOrderComponent com algumas propriedades estáticas importantes que você deseja expor em um componente LowOrderComponent:&lt;/p&gt;

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

&lt;p&gt;Dessa forma, &lt;strong&gt;LowOrderComponent&lt;/strong&gt; agora terá acesso à propriedade estática myStaticMethod definida em HighOrderComponent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outros Termos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Next.js&lt;/strong&gt; é um framework React que permite a construção de aplicações web modernas e otimizadas com funcionalidades adicionais fora da caixa, como renderização do lado do servidor (SSR), geração estática de páginas (SSG), suporte a rotas dinâmicas e API routes, entre outros. Desenvolvido e mantido pela Vercel, Next.js é projetado para fornecer uma excelente experiência de desenvolvedor e desempenho superior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create React App (CRA)&lt;/strong&gt; é uma ferramenta para configurar rapidamente uma nova aplicação React com uma configuração padronizada e zero de configuração manual. Ele abstrai toda a complexidade inicial de configuração, proporcionando um ambiente de desenvolvimento moderno, pronto para uso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vite&lt;/strong&gt; é uma ferramenta de build de desenvolvimento rápida e moderna para projetos front-end. Vite resolve alguns dos principais problemas enfrentados por ferramentas tradicionais como Webpack e CRA, oferecendo um desempenho significativamente melhorado e uma experiência de desenvolvimento mais fluida.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prop Drilling&lt;/strong&gt; é um processo de passar dados de um componente pai para um componente filho através de várias camadas de componentes intermediários. Isso pode levar a um código difícil de manter e a uma complexidade desnecessária quando muitos componentes intermediários não precisam diretamente dos dados ou funções que estão sendo passados. Um dos modos que podemos evitar prop drilling é através do React Context, que é uma forma de passar dados entre a árvore de componentes sem precisar passar props manualmente em cada nível.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context API&lt;/strong&gt; é uma funcionalidade do React que permite passar dados através da árvore de componentes sem a necessidade de passar props manualmente em cada nível. É uma maneira eficiente de compartilhar valores entre componentes que estão "distantes" na árvore de componentes, sem a necessidade de prop drilling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WAI-ARIA (Accessible Rich Internet Applications)&lt;/strong&gt; é uma especificação desenvolvida pelo W3C que define um conjunto de atributos adicionais que podem ser aplicados a elementos HTML para melhorar a acessibilidade de aplicativos da web. O seu objetivo principal é tornar aplicativos da web mais acessíveis para pessoas com deficiência, especialmente aquelas que usam tecnologias assistivas, como leitores de tela.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prettier&lt;/strong&gt; é um formatador de código opinativo que enfoca a consistência de estilo, independentemente das preferências individuais dos desenvolvedores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linter&lt;/strong&gt; é uma ferramenta que analisa o código-fonte para detectar erros de programação, violações de estilo, más práticas e outros problemas que podem causar bugs ou reduzir a qualidade do código. A principal função de um linter é ajudar os desenvolvedores a manter um código limpo, consistente e livre de erros.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSR (Server-Side Rendering)&lt;/strong&gt; é uma técnica usada no desenvolvimento web onde a renderização das páginas é feita no servidor, em vez de no cliente (navegador). Isso significa que o servidor gera o HTML completo para uma página e o envia ao cliente, em vez de enviar apenas os arquivos JavaScript e deixar que o cliente construa a página.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSR (Client-Side Rendering)&lt;/strong&gt; é uma técnica usada quanto a renderização é feita no cliente, com o navegador baixando os arquivos JavaScript e gerando o HTML. Isso pode resultar em tempos de carregamento iniciais mais longos, mas uma navegação subsequente mais rápida.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XMLHttpRequest (XHR)&lt;/strong&gt; é uma API disponível em navegadores que permite fazer requisições HTTP e HTTPS para servidores web. É uma parte fundamental do Ajax (Asynchronous JavaScript and XML), permitindo que as páginas web sejam atualizadas dinamicamente sem a necessidade de recarregar a página inteira. Com XHR, você pode enviar e receber dados de um servidor web de forma assíncrona.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lighthouse&lt;/strong&gt; é uma ferramenta automatizada e de código aberto desenvolvida pelo Google para melhorar a qualidade das páginas web. Ela pode ser executada em qualquer página da web, pública ou que exija autenticação. Lighthouse gera relatórios sobre o desempenho da página, acessibilidade, práticas recomendadas, SEO e PWA (Progressive Web Apps).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Definições e Termos de Java e Orientação a Objetos</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 01:04:02 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/definicoes-e-termos-de-java-e-orientacao-a-objetos-7n</link>
      <guid>https://dev.to/guilhermemanzano/definicoes-e-termos-de-java-e-orientacao-a-objetos-7n</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Classes: são abstrações de objetos do mundo real, que define um tipo de objeto e suas características (atributos) e as ações que o objeto realizam (métodos). As classes especificam a estrutura e o comportamento dos objetos, e os objetos são instâncias de classes. Todos objetos possui: identidade, estado e comportamento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instanciação: instanciar uma classe significa criar um novo objeto a partir da estrutura desta classe. Para instanciar com um construtor padrão (sem argumentos) utiliza-se esta sintaxe:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FvbuzY5T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxtrkw650mjhl9cyyvc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FvbuzY5T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxtrkw650mjhl9cyyvc9.png" alt="instância" width="309" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atributos: os atributos definem o estado interno de um objeto, ou seja, suas características. Exemplo: carro (cor, modelo, ano). Os atributos de um objeto só podem ser usados/acessados pelo próprio objeto (getters), ou seja, eles devem ser privados (private) ou protegidos (protected). Um atributo poderá ser do tipo protected a classe em que ele está será pai de outra classe (herança). Deve-se evitar o uso de atributos do tipo público (public). Exemplo de declaração de atributos de uma determinada classe:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bBvYahpA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlqhhli1jfmihpgpwlpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bBvYahpA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xlqhhli1jfmihpgpwlpm.png" alt="atributos" width="238" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Métodos: os métodos de um objeto são as funções que operam sobre este objeto. Exemplo: carro (dirigir, estacionar, parar). O tipo de valor de retornar void indica que o método não possui um retorno. Exemplo de um método:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qmfFFNty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbjinsomvkdqdn8twza0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qmfFFNty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbjinsomvkdqdn8twza0.png" alt="métodos" width="335" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encapsulamento: é o mecanismo utilizado para disponibilizar métodos, protegendo o acesso indevido aos atributos de uma instância (objeto). Por exemplo, a única maneira do objeto Pessoa alterar o valor do atributo saldo do objeto Carteira é acessando os métodos depositar (valor) ou retirar (valor) do objeto Carteira. Eles são declaradas através de métodos getter (para buscar os valores) e setter (para alterar os valores). Exemplo de encapsulamento de uma classe com dois atributos (nome do tipo String e hora do tipo int):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lfpr2OEp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2x89j62izwqdsnmz6rtp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lfpr2OEp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2x89j62izwqdsnmz6rtp.png" alt="encapsulamento" width="229" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Construtores: são métodos especiais que são chamados automaticamente quando instâncias são criadas através da palavra new. O código que eles contêm são executados antes de qualquer outro código em outros métodos. Pode haver vários construtores dentro de uma classe, desde que eles não possuam a mesma assinatura, ou seja, é necessário fazer a sobrecarga deles. Exemplo de uma classe com dois construtores, um com todos os parâmetros e outro sem parâmetros:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zHSPHN2h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojqc4wiseh4w8mskv5qd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zHSPHN2h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojqc4wiseh4w8mskv5qd.png" alt="construtores" width="406" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sobrecarga de métodos (overload): utilizando-se a sobrecarga, é possível passar mais ou menos argumentos em um método, contanto que suas assinaturas sejam diferentes. A assinatura de um método é composta de seu nome mais os tipos de argumentos que são passados para este método. Isso é bem útil para se criar métodos com menos argumentos, em situações específicas.&lt;/li&gt;
&lt;li&gt;Sobrescrita de métodos (override): a sobrescrita cria um novo método na classe filha (herança) que contém a mesma assinatura e o mesmo tipo de retorno do método sobrescrito. A anotação @Override é colocada em cima do método que será sobrescrito. Exemplo de sobrescrita de uma interface:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KVPDsD4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0h3ocn481dvplerppd9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KVPDsD4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0h3ocn481dvplerppd9v.png" alt="sobrecarga" width="370" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;this: um método pode chamar outro da mesma classe, mas um construtor não pode chamar outro construtor diretamente. Por isso, o Java cria para cada instância uma “autorreferência”, ou seja, uma referência à própria instância, utilizando a palavra this.&lt;/li&gt;
&lt;li&gt;Casting: permite atribuir o valor de um tipo da variável a outro tipo de variável, forçando-o a assumir um formato. Por exemplo, declarando um float com valor de 32.33, é possível fazer um casting e passar este número para inteiro, arredondando-o. Por exemplo, vamos fazer um casting de uma variável do tipo float (vfal) para o tipo int:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aqP9UmRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhk8l4vhcxa5vuoq4zbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aqP9UmRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhk8l4vhcxa5vuoq4zbv.png" alt="casting" width="171" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Campos estáticos (static): eles são compartilhados por todas as instâncias de uma determinada classe, ou seja, somente um valor será armazenado em um campo estático. Caso esse valor seja modificado por uma instância desta classe, isso se refletira em todas as outras instancias desta classe. Os campos estáticos são declarados com o modificador static e podem ser utilizados para gerenciar filas e compartilhar constantes que serão usadas por várias instâncias desta classe. Exemplo:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cyRxI5ow--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gn83yqv04248s2mj5jxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cyRxI5ow--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gn83yqv04248s2mj5jxx.png" alt="static" width="195" height="42"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Métodos estáticos (static): estes métodos podem ser chamados sem precisar criar instâncias das classes às quais pertencem. Sua aplicação mais frequente é a criação de bibliotecas de métodos (classe que contém somente métodos estáticos, geralmente agrupados por função). Por exemplo:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tipo primitivo: é um tipo que não representa classes e que definem de que tipo são as variáveis (int, float, char, …). É recomendado utilizar os tipos primitivos quando se for criar métodos que realizam cálculos matemáticos ou quando não queremos ter atributos nulos (atributo opcional).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Classe Wrapper: é uma classe que representa um tipo primitivo e possui como grande vantagem atribuir valor nulo (atributo opcional). São exemplos desta classe o Integer, Boolean, String, etc. Porém, caso ela não seja utilizada de forma correta, ela poderá gerar uma exceção do tipo NullPointerException. É possível transformar um Wrapper em tipo primitivo (e vice-versa) fazendo um Unboxing/Autoboxing. O Autoboxing é um recurso do compilador Java que faz a conversão entre tipos primitivos de dados e os respectivos objetos cujas classes acondicionam um determinado tipo primitivo (como converter um tipo primitivo int em um objeto cuja classe é Integer). Já o Unboxing, faz o processo inverso do Autoboxing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interface: são padrões definidos através de contratos ou especificações. Um contrato é responsável por definir um determinado conjunto de métodos que serão implementados nas classes que assinarem esse contrato. Os métodos dessa classe são sempre definidos como abstract e as variáveis são definidas por padrão como constantes (static final). As classes que implementam uma interface precisam adicionar todos os métodos da interface, ou se transformar em uma classe abstrata. Exemplo de uma interface:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DJwHrGGT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0cuifxh157hpfuw32t5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DJwHrGGT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0cuifxh157hpfuw32t5.png" alt="interface" width="302" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Classe abstrata: são classes que servem como modelo para outras classes que vão herdá-la e que não podem ser instanciadas. Para criar um objeto que usa uma classe abstrata, é preciso criar uma classe que vai herdar a classe abstrata e sobrescrever os métodos dela. Exemplo de uma classe abstrata:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9UqkyS_---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6gv2bmt2dnxomjcku36.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9UqkyS_---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6gv2bmt2dnxomjcku36.png" alt="abstract class" width="254" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;equals and hashCode: o hashCode é uma ferramenta da JVM utilizada para montar uma tabela hash (tabela onde as informações são armazenadas conforme um número hash calculado com base nas propriedades da informação) de forma completa. Isso permite que operações de comparação entre elementos seja feito de maneira muito mais rápida. Para isso funcionar, é necessário determinar primeiro a “região” em que um objeto está, que é um espaço dentro de uma coleção onde os objetos ficam agrupados por semelhança, facilitando a busca deles. A ideia da função hash é garantir que somente uma informação esteja em uma determinada “região”, mas isso nem sempre é possível. Quando mais de uma informação acaba chegando em uma mesma “região”, ocorre a chamada colisão da tabela hash. Para resolver o problema da colisão, é criado o método equals, que determina se os objetos de uma “região” são iguais. A ideia deste método é garantir que dois objetos são “significativamente iguais”, ou seja, que eles tenham um valor igual dada as suas propriedades.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4Z4ehZ75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ip33uem6973pxen4yg3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4Z4ehZ75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ip33uem6973pxen4yg3b.png" alt="equals and hashCode" width="635" height="657"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>poo</category>
    </item>
    <item>
      <title>Como criei um jogo de xadrez com Java</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:52:27 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/como-criei-um-jogo-de-xadrez-com-java-4g5h</link>
      <guid>https://dev.to/guilhermemanzano/como-criei-um-jogo-de-xadrez-com-java-4g5h</guid>
      <description>&lt;p&gt;Durante o curso de Java COMPLETO 2020 Programação Orientada a Objetos + Projetos da Udemy, tive a oportunidade de desenvolver um joguinho de Xadrez utilizando apenas Java, com o uso da IDE do Eclipse. É um jogo simples, que pode ser jogado através de um terminal. Neste projeto eu pude aprender mais sobre OO (em Java), boas práticas de programação, tratamento de erros, versionamento de código, correção de bugs e muita lógica de programação. O código e seus commit foram feitos todos em inglês, para ter uma experiência mais perto de um projeto real.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V7hl3WrD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nduevnlhf6bloexnseg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V7hl3WrD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nduevnlhf6bloexnseg1.png" alt="Tela Inicial" width="567" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eu levei 3 dias para concluir todo o projeto, todo o código e explicação detalhada do projeto podem ser conferidas no GitHub. A mecânica do jogo é baseada em linhas (1, 2, 3, 4, 5, 6, 7, 8) e colunas (a, b, c, d, e, f, g, h) e as peças estão são as iniciais das mesmas em inglês (vide tabela).&lt;/p&gt;

&lt;p&gt;Peças: Pawn (Peão), Rook (Torre), Knight (Cavalo), Bishop (Bispo), Queen (Rainha) e King (Rei).&lt;/p&gt;

&lt;p&gt;Este jogo de xadrez conta com as jogadas especiais (promoção, roque e en passant) e previsão de movimento das peças, marcando o caminho em azul onde a peça pode ir. Como as IDEs possuem fundo preto, as peças pretas foram representadas pela cor amarela (caso deseje rodar o jogo na sua máquina, recomendo utilizar o terminal do git bash, pois sua interface é colorida e poderá ver as peças de cor amarela e os caminhos em azul). Quando uma peça do adversário é capturada, é possível vê-las abaixo do tabuleiro, em captured pieces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JNPTvz9e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kvt5nnidayritwtqfua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JNPTvz9e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kvt5nnidayritwtqfua.png" alt="Tratamento de Erro, o rei amarelo (K) está tentando se colocar em posição de cheque avançando no Bispo branco&amp;lt;br&amp;gt;
Como jogar" width="567" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O jogo sempre começa com as peças brancas (conforme regra oficial do Xadrez). Para escolher uma peça, é necessário digitar suas coordenadas (linha e coluna), similar ao jogo de batalha naval. Por exemplo, para mover o primeiro peão das brancas é só digitar a2 para selecionar o peão e a4 para mover a peça a seu destino.&lt;/p&gt;

&lt;p&gt;Caso seja digitado alguma coordenada inválida ou jogada impossível, aparecerá uma mensagem de erro e basta apertar ENTER para recomeçar a jogada. Quando você fizer alguma jogada que gere a situação de Check ou CheckMate, será apresentado uma mensagem na tela avisando sobre isso. No caso do Check, você será obrigado a tirar o seu rei da posição de ameaça, capturando a peça inimiga ou movendo seu rei.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x5ub0VGV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b0oyvww3cc224rq09j3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x5ub0VGV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b0oyvww3cc224rq09j3.png" alt="Rei preto em Cheque!&amp;lt;br&amp;gt;
" width="567" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É possível realizar as jogadas especiais do Xadrez, como roque (trocar posição do rei e da torre), en passant (capturar o peão inimigo lateralmente) e promoção (levar o seu peão até o final do tabuleiro inimigo, promovendo ele a outra peça). Para ativar o roque, não pode mover o rei nem a torre que seja alvo, depois é só tirar o bispo e o cavalo que estão no meio do caminho e mover o rei em direção a torre, onde o movimento será concluído automaticamente. O promoção é ativado quando seu peão chegar ao final do tabuleiro inimigo, onde aparecerá uma mensagem para que você escolhe qual peça você quer que seu peão vire (Rainha, Bispo, Cavalo ou Torre). Por fim, para ativar o en passant, é só esperar o adversário colocar seu peão ao lado do seu, e, na sua vez, você escolhe o seu peão (que está do lado do peão inimigo) e aparecerá a casa em cima do peão adversário para você realizar a jogada.&lt;/p&gt;

&lt;p&gt;Explicando a interface&lt;/p&gt;

&lt;p&gt;Na tela do jogo, existem algumas palavras em inglês que mostram o que está acontecendo no jogo, segue uma breve explicação do conteúdo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MPAr6SiU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q8rq5krlylm1p666zqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MPAr6SiU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q8rq5krlylm1p666zqa.png" alt="Jogando…" width="567" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Captured pieces (Peças Capturadas): o jogo armazena as peças capturadas pelos dois times.&lt;/li&gt;
&lt;li&gt;Turn (Turno): exibe o turno (rodada) em que o jogo está, somando os dois times.&lt;/li&gt;
&lt;li&gt;Waiting player (Esperando Jogador): exibe qual é o jogador a jogar a próxima peça (brancas ou pretas).&lt;/li&gt;
&lt;li&gt;Source (Origem): é a peça no qual o jogador irá mover, escrita em coordenadas. Por exemplo, c8 (linha 8, coluna C).&lt;/li&gt;
&lt;li&gt;Target (Alvo): é o destino, ou seja, o local no qual o jogador irá mover a peça, escrita em coordenadas. Por exemplo, c5 (linha 5, coluna C), a peça irá mover da posição c8 para c5.&lt;/li&gt;
&lt;li&gt;Check (Cheque): gera a situação quando coloca um dos reis em cheque.&lt;/li&gt;
&lt;li&gt;CheckMate (Cheque Mate): o rei ficou encurralado, fim do jogo.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Anotações do curso de Angular</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:50:36 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/anotacoes-do-curso-de-angular-2mk2</link>
      <guid>https://dev.to/guilhermemanzano/anotacoes-do-curso-de-angular-2mk2</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iNl9833E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j26x2vovr3e9vvzznltb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iNl9833E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j26x2vovr3e9vvzznltb.png" alt="Image description" width="720" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vou compartilhar minhas anotações de um curso de Angular que fiz esta semana, como são mais alguns conceitos, é um artigo mais curto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Angular&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O angular é dividido em módulos, onde cada um deles é uma “parte” do código. Você pode importar/exportar quantos módulos desejar através do componente.module.ts. Ele é construído para ser uma SPA (Single Page Application), ou seja, consiste em uma única página.&lt;/p&gt;

&lt;p&gt;Anatomia de um módulo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declarations: são declarados todos os componentes (components) que fazem parte daquele módulo, também é onde são declaradas as diretivas e os pipes.&lt;/li&gt;
&lt;li&gt;Exports: colocando o código de um component dentro do exports, você poderá utilizar aquele módulo em outras partes do seu código. É possivel exportar o modulo inteiro ou apenas parte dele&lt;/li&gt;
&lt;li&gt;Imports: É onde são importados outros módulos dentro daquele que você está utilizando.&lt;/li&gt;
&lt;li&gt;Providers: é onde são declarados os services.&lt;/li&gt;
&lt;li&gt;Bootstrap: é onde definimos o componente principal, que será carregado quando a aplicação for iniciado (app component).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Elementos do Angular&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Diretiva de atributo foca em alterar a aparência (css) e o comportamento (diretiva que faz determinada ação no backend) de um elemento, componente ou outra diretiva. Ou seja, ele pode alterar a aparência do html ou uma ação, podendo ser usados em vários trechos de códigos diferentes.&lt;/li&gt;
&lt;li&gt;Diretiva estrutural altera o layout adicionando e removendo elementos da DOM (altera o HMTL). Ela é representada por um * na frente (como o &lt;code&gt;*ngIf&lt;/code&gt; e &lt;code&gt;*ngFor&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;O Property Binding faz a comunicação entre o HTML e o Typescritpt da aplicação, para ativá-lo, basta colocar o elemento entre colchetes em uma tag HTML. Por exemplo, em &lt;code&gt;&amp;lt;table [dataSource]=“products”&amp;gt;&amp;lt;/table&amp;gt;&lt;/code&gt;, o html procurará um atributo no Component que tenha o mesmo nome (products) e irá utiliza-lo.&lt;/li&gt;
&lt;li&gt;O Event Binding serve para ligar um evento no HMTL a um método que está dentro de um componente (typescript), utilizando os parênteses. Por exemplo, &lt;code&gt;&amp;lt;button (click)=”createProduct()”&amp;gt;&amp;lt;/button&amp;gt;&lt;/code&gt; e &lt;code&gt;createProduct(): void {}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No one way data binding, a informação é passada de um componente (typescript) para o html. Por exemplo, &lt;code&gt;&amp;lt;input [value]=”nome”&amp;gt;&lt;/code&gt; e &lt;code&gt;nome: string&lt;/code&gt; (no Componente), se no componente o nome for trocado para “Camila”, ele irá também alterar o nome exibido no html.&lt;/li&gt;
&lt;li&gt;No two way data binding, se o nome for alterado no html, o typescript será alterado e se alterar no typescript, o html que será atualizado. Para ativá-lo, basta colocar no html o &lt;code&gt;[(ngModel)]=”nome”&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;O decorator (similar a anotação do java) é um padrão de projeto que vem com objetivo evitar herança e diz que determinada classe exerce algum papel dentro do framework &lt;code&gt;(@Component — Componente, @Directive — Diretiva)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rotas servem para redirecionar os componentes para determinadas páginas. Por exemplo, em &lt;code&gt;&amp;lt;a routerLink=”/products”&amp;gt;Produtos&amp;lt;/a&amp;gt;&lt;/code&gt; o link vai procurar o caminho products nas rotas, que será declarada assim: &lt;code&gt;const routes: Routes [{ path: “products”, componente: ProductCrudComponent }]&lt;/code&gt;; O seletor &lt;code&gt;&amp;lt;router-outlet&amp;gt;&amp;lt;router-outlet&amp;gt;&lt;/code&gt; é responsável por encontrar o path de uma rota e substituir o trecho pelo Componente respectivo.&lt;/li&gt;
&lt;li&gt;Os Pipes são processamentos feitos em variáveis, fazendo uma interpolação das chaves duplas &lt;code&gt;{{ }}&lt;/code&gt;. É utilizado para exibir o valor de uma variável no html. Por exemplo: &lt;code&gt;&amp;lt;p&amp;gt;O vencimento é {{ produto.vencimento | date }}&amp;lt;/p&amp;gt;&lt;/code&gt;, onde date sinaliza que a resposta do banco será convertida para o formato de data.&lt;/li&gt;
&lt;li&gt;O Observer é um padrão orientado a evento. O subject é quem tem a capacidade de monitorar e detectar quando um evento acontece e os observer são os códigos que estão interessados em um determinado evento, eles precisam se registrar no subject dizendo que ele está interessado no evento (pode existir muitos observer). Depois do registro, o subject vai monitorar o evento, e quando ele detectar que o evento aconteceu, ele vai notificar todos os observadores que aquele evento ocorreu. Ou seja, ela espera o evento acontecer para agir (não fica monitorando toda hora o evento até ele acontecer).&lt;/li&gt;
&lt;li&gt;Callback é quando passamos uma função como parâmetro de outra função, ativando-a quando ocorrer um determinado evento.&lt;/li&gt;
&lt;li&gt;O promises é um objeto que representa a eventual conclusão ou falha de uma operação assíncrona. Mas só é possível usá-lo uma única vez (não sendo possível reutilizá-lo). Já o Observable, é similar as promisses, mas é possível utilizá-lo diversas vezes, com ele dá para usar com uma stream de dados e ele possui diversos operadores (map, filter, etc).&lt;/li&gt;
&lt;li&gt;Os Services são classes que têm como principal objeto organizar e compartilhar métodos e dados entre os componentes.&lt;/li&gt;
&lt;li&gt;Injeção de dependência é um padrão no qual as classes recebe as dependências de uma fonte externa ao invés de criar por conta própria. Por exemplo, um componente carro recebe as dependências do componente motor. No angular, ela é chamada pelo decorator @Injectable&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Guia completo dos serviços mais populares da AWS</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:43:28 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/guia-completo-dos-servicos-mais-populares-da-aws-10fm</link>
      <guid>https://dev.to/guilhermemanzano/guia-completo-dos-servicos-mais-populares-da-aws-10fm</guid>
      <description>&lt;p&gt;A AWS é uma plataforma de serviços de computação em nuvem criada pela Amazon e largamente utilizada pelas empresas mundo afora. Ela disponibiliza para seus usuários dezenas de serviços, para os mais variados usos, com a intenção de atender empresas de pequeno, médio e grande porte. Durante meus estudos teóricos sobre essa plataforma, resolvi compartilhar o resumo de alguns dos principais serviços ofertados por ela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3M8RSBGc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66j6rf5yoxgwe60kwq88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3M8RSBGc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66j6rf5yoxgwe60kwq88.png" alt="Image description" width="720" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Identity and Access Management (IAM) — é quem nos ajuda a controlar, com segurança, o acesso aos recursos da AWS. Com ele, nós precisamos saber quem vai acessar, o que ele pode fazer e como vai fazer. Os componentes presentes no IAM são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users (usuários);&lt;/li&gt;
&lt;li&gt;Groups (grupos de acesso);&lt;/li&gt;
&lt;li&gt;Roles (que são utilizados para liberar acesso a um recurso);&lt;/li&gt;
&lt;li&gt;Policy (acesso que deve ser dado a um user ou roles).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O role-based access control é o modelo de autorização utilizada pela AWS, e que permite liberar o acesso do usuário, levando em conta o seu papel (desenvolvedor, gerente, administrador, entre outros). E, por fim, o attribute-based access control (ABAC) é uma estratégia de autenticação baseada em atributos, que são chamados de tags.&lt;/p&gt;

&lt;p&gt;Elastic Compute Cloud (EC2) — este serviço nos fornece um servidor (através de uma máquina virtual), seguro e confiável, dentro do Data Center da AWS. Os tipos de configurações possíveis deste servidor são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uso geral;&lt;/li&gt;
&lt;li&gt;Otimização para computação (ideal para aplicações que necessitam de muito processamento de dados);&lt;/li&gt;
&lt;li&gt;Otimizado para memória;&lt;/li&gt;
&lt;li&gt;Otimizado para armazenamento;&lt;/li&gt;
&lt;li&gt;Computação acelerada (utilizada, por exemplo, para aplicações de inteligência artificial, computação quântica, entre outros).&lt;/li&gt;
&lt;li&gt;Com relação aos custos, a AWS oferece diversos tipos de precificação:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sob demanda (de acordo com o uso);&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spot (utiliza uma máquina que está ociosa, tendo um menor custo comparado com a sob demanda. Porém, se o proprietário daquela máquina solicitar seu funcionamento, você será desligado daquela máquina. Por conta disso, é recomendado utilizar apenas em ambiente de desenvolvimento ou teste);&lt;/li&gt;
&lt;li&gt;Reservado (ocorre quando se reserva uma máquina por um determinado período de tempo, como por exemplo, um ano. Assim, a AWS oferece um desconto maior, com base no tempo reservado);&lt;/li&gt;
&lt;li&gt;Compute saving plan (é similar ao reservado, mas nesse caso é possível escolher e trocar diferentes atributos e configurações da máquina reservado, ao longo do período reservado. Como, por exemplo, aumentar a memória ou o processamento, dentro de um range pré-estabelecido);&lt;/li&gt;
&lt;li&gt;Instância dedicada (utilizada quando a empresa quer que uma instância da AWS seja utilizada apenas por ela. Como exemplo de utilização, algumas empresas precisam garantir essa exclusividade, para ficarem aderentes as leis de proteções de dados de alguns países);&lt;/li&gt;
&lt;li&gt;Host dedicado (similar ao anterior, mas é quando a empresa quer reservar uma máquina física dentro dos servidores da AWS, e é onde a empresa colocará suas instâncias dedicadas);&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lightsail — é um serviço que fornece uma instância de servidor privado virtual (VPS), que é fácil de se utilizar e possui um preço mais econômico, se comparado com o EC2. Como ele é um ambiente mais simplificado e econômico que o EC2, é indicado para pequenas aplicações, que não necessitam de configurações avançadas ou mais robustez.&lt;/p&gt;

&lt;p&gt;Simple Storage Service (S3) — é um serviço de armazenamento de objetos, oferecem escalabilidade, disponibilidade, segurança e performance. Nele, podemos inserir arquivos de vídeos, imagens, texto, entre outros tipos. O S3 é dividido em algumas classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard (é a classe padrão. Quando colocamos um objeto nela, este objeto fica disponível em três zonas de disponibilidade, garantindo um sistema de backup eficaz. Por conta disso, essa é a opção mais segura e mais cara de todas);&lt;/li&gt;
&lt;li&gt;Standard-IA (IA se refere a Acesso Frequente, ou seja, é utilizada para inserirmos objetos que não são consultados constantemente, por conta disso, ele possui um pequeno delay para recuperação desses objetos, se comparado com o Standard, mas ele também possui três cópias do arquivo para backup, em cada uma das zonas de disponibilidade);&lt;/li&gt;
&lt;li&gt;One Zone-IA (é similar ao anterior, mas nele o objeto ficará disponível em apenas uma zona de disponibilidade, ou seja, não possui backup. Por conta disso, é bem mais barato se comparado com as classes anteriores);&lt;/li&gt;
&lt;li&gt;Intelligent Tiering (essa classe escolhe a melhor opção, de forma automática, conforme a disponibilidade e tipos de arquivos armazenados, sendo bastante utilizado para backups);&lt;/li&gt;
&lt;li&gt;Glacier (é um local para armazenamento de longa duração, sendo a opção mais barata dentre as disponíveis. Porém, possui um sistema de lenta recuperação dos objetos, podendo levar até 12 horas para recuperá-lo);&lt;/li&gt;
&lt;li&gt;Glacier Depth Archive (similar ao anterior, mas nele os objetos podem levar até 48 horas para serem recuperados. Por conta disso, essa é a opção mais barata dentre as disponíveis. É indicado para objetos que são acessados raramente, como uma ou duas vezes ao ano).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elastic Block Store (EBS) — é um serviço de armazenamento em bloco, que é fácil de usar, escalável e de alta performance. Os seus tipos são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSD (uso geral);&lt;/li&gt;
&lt;li&gt;SSD (IOPS provisionado, possui desempenho e custos maiores);&lt;/li&gt;
&lt;li&gt;HDD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse tipo de serviço é cobrado pelo volume que foi provisionado, ou seja, se for criado um volume de 1 TB mas está sendo utilizado apenas 100 Mb, a cobrança será em cima do 1 TB.&lt;/p&gt;

&lt;p&gt;Amazon Elastic File System (EFS) — é um serviço de armazenamento de arquivos sem servidor e totalmente elástico, que pode ser utilizado dentro do EC2, ECS, Lambda, entre outros. O EFS é muito robusto, possui um alto desempenho e permite uma alta escalabilidade.&lt;/p&gt;

&lt;p&gt;Amazon FSx — possui o mesmo papel que o EFS, porém, é voltado para servidores Windows, que utilizam o protocolo SMP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ek1xoOiR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yt1z2mlsjpzrnfkjfthg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ek1xoOiR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yt1z2mlsjpzrnfkjfthg.png" alt="Image description" width="385" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Virtual Private Cloud (VPC) — esse serviço permite definirmos uma rede e nela executar os recursos compartilhados da nossa empresa, através de uma rede privada. As subnets são divisões da rede definidas na VPC, onde indicamos em qual rede será executado os recursos computacionais. Como boa prática, a AWS recomenda que se tenha uma subnet privada (que não pode ser acessada diretamente via internet), onde pode ficar os bancos de dados; e uma subnet pública, que é quem se comunicará com a subnet privada e que pode ser acessada via API, por exemplo.&lt;/p&gt;

&lt;p&gt;Security Group — é um firewall que controla o tráfego de entrada e saída de recursos (como por exemplo, o E2C, RDS, entre outros). Suas características são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Somente regras de liberação;&lt;/li&gt;
&lt;li&gt;Por padrão, o tráfego de saída liberado;&lt;/li&gt;
&lt;li&gt;são stateful (ou seja, quando liberamos o tráfego de entrada, o da saída será liberado junto. E vice-versa).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Network Acess Control List (Network ACL) — é um firewall que controla o tráfego de entrada e saída da subnet. Suas características são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permite regras para liberar ou negar;&lt;/li&gt;
&lt;li&gt;Por padrão, o tráfego de entrada e saída são liberados;&lt;/li&gt;
&lt;li&gt;Não é stateful;&lt;/li&gt;
&lt;li&gt;Seguem uma sequência (o menor número será lido primeiro e, no momento que der match com o tráfego que está ocorrendo naquele momento, não vai ler as demais regras que estão na sequência).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k61TcdJ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yupq3okjegnon458gib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k61TcdJ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yupq3okjegnon458gib.png" alt="Image description" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Relational Database Service (RDS) — é um serviço de banco de dados relacionais gerenciado, que facilita a configuração, operação e escalabilidade. Existem duas formas de criarmos um banco relacional na AWS: utilizando o RDS ou criando uma instância EC2 (e dentro dela criar o banco de dados). A vantagem do EC2 é que com ele temos acesso a toda arquitetura de banco de dados que for criado, permitindo o acesso a configurações avançadas. Porém, a desvantagem do EC2 é que isso aumenta a complexidade de manter o banco de dados por nossa conta. A vantagem do RDS é que ele já vem completamente configurado e pronto para uso, além de ser compatível com o PostgreSQL, MariaDB, Oracle e Microsoft SQL Server.&lt;/p&gt;

&lt;p&gt;Amazon DynamoDB — é um banco de dados de chave-valor NoSQL totalmente gerenciado, projetado para alta performance, em qualquer escala. Suas características são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Totalmente gerenciado;&lt;/li&gt;
&lt;li&gt;Baixa latência;&lt;/li&gt;
&lt;li&gt;Alta disponibilidade;&lt;/li&gt;
&lt;li&gt;Medido por unidade R/W (é uma medida de performance e a cobrança de uso é calculada por leitura e escrita).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elastic Kubernets Service (EKS) — é um gerenciador de serviços do Kubernets que permite publicar, gerenciar e escalar aplicações de containers utilizando Kubernets, de forma rápida e fácil. É totalmente gerenciado, o que significa que não precisamos nos preocupar com gerenciamento e manutenção, por baixo da infraestrutura. Ele é projetado para alta disponibilidade e escalabilidade, além de suportar escalonamento automático, lançamento contínuo e self-healing (substitui automaticamente as instâncias que estão em falha).&lt;/p&gt;

&lt;p&gt;Elastic Container Service (ECS) — é um serviço de gerenciamento e orquestração de containers que permite definir tarefas com containers Docker, criar instâncias de um cluster EC2, além de lançar e gerenciar tarefas com o cluster.&lt;/p&gt;

&lt;p&gt;Lambda — é um serviço que permite a execução de códigos sem que seja preciso gerenciar ou provisionar servidores, tornando rápido e fácil a execução de programas. Nesse serviço, o usuário só paga pelo tempo de computação que foi utilizado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qH5waGLT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmax75h12lo47ve1qio9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qH5waGLT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmax75h12lo47ve1qio9.png" alt="Image description" width="720" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simple Queue Service (SQS) — é um serviço que permite transmitir dados para outros serviços usando filas de mensagens (mensageria), com ele, podemos enviar, armazenar e receber mensagens entre componentes de programação, independente do volume, e sem perda de dados. Além disso, é possível configurar uma DQL (Dead-Queue Letter), que é uma outra fila onde as mensagens que falharam durante o processamento são enviadas e podendo criar re-tentativas automáticas ou fazer análises manuais para apurar as causas da falha.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>amazon</category>
    </item>
    <item>
      <title>Resenhas e recomendações de cursos TI, focados para iniciantes em programação</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:34:10 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/resenhas-e-recomendacoes-de-cursos-ti-focados-para-iniciantes-em-programacao-4ja2</link>
      <guid>https://dev.to/guilhermemanzano/resenhas-e-recomendacoes-de-cursos-ti-focados-para-iniciantes-em-programacao-4ja2</guid>
      <description>&lt;p&gt;Comecei a estudar matérias de programação em 2019, e, apesar da fazer faculdade na área, a maior parte do conhecimento em programação que aprendi foi através de cursos. Hoje irei falar sobre minha opinião e recomendações dos cursos que fiz nesta área. No final do artigo, estarão os links de todos os cursos que mencionei.&lt;/p&gt;

&lt;p&gt;Obs: Estou dando minha opinião sobre os cursos que fiz, com base na minha experiência pessoal e profissional. Não pretendo desmerecer ou defender qualquer curso ou professor desta lista.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube — Curso em Vídeo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os primeiros cursos de programação que fiz foram do canal Curso em Vídeo, do professor Guanabara. Este canal é focado para iniciantes na área de TI, os cursos possuem uma didática de fácil compreensão e de alta qualidade, com seu conteúdo sendo explicado de forma clara e com inúmeros exemplos. Todos os cursos do canal são gratuitos e completos.&lt;/p&gt;

&lt;p&gt;O primeiro curso que fiz de programação foi o de Lógica de Programação, este é o primeiro curso indicado para iniciantes na área de programação. Lógica de programação é o modo como se escreve um programa de computador, é um algoritmo (sequência de passos para se executar uma função). Neste curso eu aprendi como elaborar a sequência de passos para resolver um problema.&lt;/p&gt;

&lt;p&gt;Depois, fiz o curso de HTML5. Neste curso, o professor Guanabara explica o básico de HTML, CSS e um pouco de Javascript. O curso começa com a história da internet e as tags básicas em HTML. Em seguida, ele fez o projeto de um site com menu lateral, cabeçalho, rodapé, listas, tabelas, botões, mapas de imagens, áudio e vídeo, formulários, entre outros assuntos. Apesar de HTML e CSS não ser programação propriamente dita, este curso ensina como funciona a estrutura de um código, sendo fundamental para quem quer seguir na área de desenvolvimento front-end e mobile. Para quem possui interesse em desenvolvimento back-end ou ciências de dados, este curso talvez não seja tão interessante.&lt;/p&gt;

&lt;p&gt;O curso de Python é o maior do canal, sendo dividido em três mundos e mais, uma playlist de exercícios. Python é uma linguagem muito boa para iniciantes, pois é de fácil compreensão e possui baixa curva de aprendizagem, sendo imprescindível seu estudo para quem deseja seguir na área de ciências de dados. O curso ainda não está completo, mas ele trata de diversos assuntos, como números, texto, condições, cores, repetições, listas, dicionários, tuplas, funções, módulos, etc. E por ter uma grande quantidade de exercícios, ajuda ainda mais na retenção do conteúdo apresentado.&lt;/p&gt;

&lt;p&gt;O curso de Banco de Dados MySQL ensina o básico de dados, manipulação de um banco de dados e como fazer o CRUD (Create, Read, Update e Delete) no MySQL (um dos bancos SQL mais utilizados no mundo). É um curso rápido, mas que dá uma boa noção para os iniciantes. Independente da área que escolher dentro da programação, um bom conhecimento vital é imprescindível, já que qualquer aplicação comercial vai exigir a criação e manipulação de dados.&lt;/p&gt;

&lt;p&gt;O curso de Javascript e ECMAscript ensina o básico de Javascript, é um curso rápido mas que possui bastante exercícios. É recomendado para quem nunca teve contato com a linguagem, mas é necessária complementar a aprendizagem com outros cursos, posteriormente. O Javascript é uma das linguagens mais utilizadas hoje em dia, sendo essencial para quem quer trabalhar com front-end.&lt;/p&gt;

&lt;p&gt;O curso de Java é indicado para quem deseja trilhar caminho na área de desenvolvimento back-end e mobile. Java é a linguagem mais utilizada no mundo e possui uma grande quantidade de vagas de trabalho disponíveis. Mas, por ser uma linguagem sólida com mais de 20 anos de vida, a curva de aprendizagem não é tão baixa, sendo necessário algumas centenas de horas de estudo e dedicação nesta linguagem para ser um bom programador. Este curso introduz a linguagem para os iniciantes, explicando os conceitos básicos de tipos de números e texto, classes, array, biblioteca Swing, etc. Há uma grande quantidade de exercícios e desafios, o que auxilia ainda mais na fixação do conteúdo.&lt;/p&gt;

&lt;p&gt;O curso de POO Java é a continuação do curso de Java, sendo um dos poucos cursos do canal de nível intermediário. É um curso excelente, recheado de exercícios e explicações de fácil entendimento sobre herança, polimorfismo, encapsulamento e classes. É um curso imprescindível para quem deseja seguir a área de desenvolvimento back-end, já que programação em classes é algo fundamental nesta área, pois diminui o retrabalho (reutilizando códigos das classes) e facilita na manutenção do mesmo.&lt;/p&gt;

&lt;p&gt;O curso de Wordpress ensina como utilizar esta ferramenta para criação de sites pré-prontos. É uma ótima ferramenta para quem deseja criar um site sem saber muita programação, além de possuir fácil manutenção. O curso é dividido em três módulos: o primeiro módulo explica como utilizar a ferramenta, alguns plug-ins e dicas; o segundo módulo trata sobre recursos mais avançados, como plug-ins de segurança, backup, cache, otimização de arquivos, tradução, etc; já o terceiro módulo é focado no plugin WooCommerce, utilizado para construir lojas virtuais.&lt;/p&gt;

&lt;p&gt;O curso de Marketing Digital é mais voltado para a área de marketing, mas, para quem tiver interesse em empreender, este curso é vital. O curso é um pouco extenso, passando desde a história do marketing, princípios, marketing digital, como utilizar o Mautic (ferramenta de automação de marketing), entre outros assuntos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube — Loiane Groner&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Loiane Groner é uma desenvolvedora de software com mais de 10 anos de mercado. Ela tem um canal do Youtube onde possui diversos cursos de alta qualidade e bem completos. Por enquanto, eu só fiz o curso de Angular, por ser uma necessidade do meu estágio. Este curso é o melhor que vi até agora sobre o assunto, começando com aulas desde a versão antiga do framework js, passando por conceitos básicos, orientação a objetos e conceitos mais avançados. O curso possui mais de 160 aulas e dezenas de horas de conteúdo, sendo constantemente atualizado. A Loiane explica o conteúdo de uma forma clara e de fácil entendimento, sendo ideal para iniciantes, mas também contribuindo muito para quem já está mais avançado. Mas, como o Angular é um framework de js e possui uma curva de aprendizagem um pouco alta, este curso não é indicado para quem está iniciando, sendo necessário ter um bom domínio de JS para poder aproveitar bem o conteúdo do curso. Como o Angular é um dos frameworks mais utilizados em js, é vital que quem deseja seguir em desenvolvimento front-end aprenda pelo menos o básico dele. Para quem está iniciando em programação, eu recomendo fazer primeiro o curso de HMTL e o de Javascript do Curso em Vídeo e, depois, procurar um curso um pouco mais avançado de JS. Um curso de Javascript que eu fiz e achei excelente foi o Web Moderno Completo com Javascript 2020 + Projetos (falarei mais sobre este curso ainda neste artigo) na Udemy, que é um curso pago, mas que explica detalhadamente a linguagem e seus frameworks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube — Rodrigo Branas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No canal do Rodrigo Branas, eu fiz apenas o curso de Vue, GraphQL e Node. Neste curso rápido, é criado um projeto de gerador de nomes para sites (juntando prefixos e sufixos gerados). O front é construído com Vue.js, o back com Node.js e utilizado GraphQL para banco de dados. É um ótimo curso para quem já possui um conhecimento intermediário em JS, pois poderá aprender dois frameworks muito utilizados (Vue e React) e construir um projeto prático.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube — Ionic 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No meu primeiro estágio, eu utilizava Ionic 4 para construir aplicativos móveis híbridos. Como ainda não conhecia esta linguagem, tive que aprende-la para poder utilizar no dia a dia. O Ionic 4 é construído em cima do Cordova e utilizando com Typescript (um Javascript melhorado) e um html um pouco modificado. Como não encontrei um bom curso gratuito de Ionic 4 em português, procurei por cursos em Inglês e encontrei o canal do Simon Grimm. Apesar de não ser um curso propriamente dito, ele tem excelentes vídeos explicados como implementar diversas funcionalidades em Ionic 4, o que acabou me ajudando muito durante meu estágio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube — Ignorância Zero&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Após o curso de Python do Curso em Vídeo, eu quis me aprofundar mais nesta linguagem e procurei por algum curso mais avançado. Acabei encontrando o canal Ignorância Zero, que possui mais de 100 vídeos de programação em Python. Este curso vai do básico ao avançado na linguagem, a qualidade do áudio dos vídeos é bem ruim, mas é possível entender o que está sendo dito. Apesar do áudio, o conteúdo do curso em si é muito bom. Este curso é recomendado para quem deseja seguir em Ciências de Dados ou até Back-End, pois apresenta um conteúdo mais avançado que o curso do professor Guanabara.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube — Fábio Akita&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O canal do Fábio Akita apresenta conteúdos de excelente qualidade, com vídeos longos e que mostram a realidade da área de programação. A playlist Programação para Iniciantes explica como funciona o mercado de TI e tem várias aulas sobre a base da programação, o que é algo essencial para todos os programadores saberem. Além disso, o canal possui excelentes vídeos sobre carreira, mercado, tecnologia e dicas profissionais.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Git e Github para iniciantes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este curso ensina o que é git e como utilizar o Github para armazenar os códigos. Nos dias de hoje, é vital saber bem como usar o git para trabalhar em equipes, pois isso mantém um histórico de alteração do código e backup, além de permitir que o código seja editado por diversos programadores ao mesmo tempo. O site mais utilizado para versionamento de código é o Github, sendo interessante até subir seus projetos pessoais para manter um portfólio. É um curso rápido e bem explicado, ideal para iniciantes de qualquer área de programação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Design de Interfaces&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este curso é pago. É um curso voltado para quem deseja seguir uma carreira mais de designer, porém, um programador front-end ou mobile que saiba desenhar telas com harmonia de cores, elementos, fontes e imagens bem feitas, costumam ser mais bem remunerados e disputados por empresas. Para quem está no início de carreira e deseja ser programador, talvez esse não seja o melhor curso, sendo indicado fazer um curso deste após pegar uma boa experiência em front-end. Também é um curso interessante caso deseje empreender ou trabalhar como freelancer. O curso é bem completo, ensinando o básico de Photoshop, Ilustrator, ferramentas de prototipagem, ferramentas de designers e projetos completos. E, mesmo quem nunca teve contato com a área de designer, consegue acompanhar o conteúdo sem muitas dificuldades.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Introdução a banco de dados com MySQL e PHPMyAdmin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este curso ensina o básico de banco de dados e como utilizar o MySQL e PHPMyAdmin para a manipulação dos dados, é um curso bem completo e bem explicado. Para quem deseja um conhecimento um pouco mais completo, é melhor que o curso do professor Guanabara (que é bem básico).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Web Moderno Completo com Javascript 2020 + Projetos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curso pago da Udemy. É um dos melhores que vi até agora na área de desenvolvimento front-end, e o curso é bem extenso, chegando a quase 100 horas de aulas. Ele passa por toda parte de desenvolvimento front-end (e um pouco de back-end), com Javascript, HTML, CSS, AJAX, Bootstrap, jQuery, Angular, Electron, React, React Native, Gulp, SASS, Vue, Node, Express, etc. O professor explica muito bem, mas cita alguns termos técnicos e procedimentos ao longo do curso que, para quem ainda está iniciando na área, possivelmente ainda não aprendeu. O curso é realmente muito bom, sempre que tenho dúvidas sobre algum framework ou procedimento eu volto nas aulas para revê-las. Mas, para quem ainda está bem no começo do aprendizado, eu recomendo que façam primeiro os cursos do Curso em Vídeo e a playlist do Fábio Akita, para ter uma base melhor para acompanhar o curso. Para quem tem conhecimento um pouco mais intermediário e deseja fazer carreira no desenvolvimento front-end, eu recomendo este curso de olhos fechados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Android do Absoluto Zero para Iniciantes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curso pago, focado no desenvolvimento de aplicativos Android utilizando a linguagem Java. É um curso muito bom para quem deseja seguir a área de desenvolvimento de apps nativos. O curso ensina Java, como utilizar o Android Studio, banco de dados, Web Services, publicação do app, possui diversos projetos, testes, debug, permissões, arquitetura, APIs, etc. Até agora, eu assisti até metade do curso, mas gostei bastante da didática do professor. Ele explica de forma clara e também explica o porquê está usando cada uma das funcionalidades e comandos, além das melhores práticas de programação. O curso é bem extenso, com quase 70 horas de aulas e conteúdo novo sendo inserido constantemente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Desenvolvimento de Aplicativos Android com Kotlin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curso pago, focado no desenvolvimento de aplicativos Android utilizando a linguagem Kotlin. O curso possui quatro projetinhos bem legais e completos, com nível crescente de dificuldade, além dos módulos de geração, monetização e publicação do aplicativo na Google Play Store. É um curso relativamente rápido, e gostei bastante dos projetos. Mas, o professor não explica muito bem o que está programando, eu acabei tendo que pesquisar muita coisa por fora para entender o que estava acontecendo. Apesar dos projetos contribuírem bastante para o portfólio pessoal e ser um ótimo treino para quem já entende um pouco da linguagem, eu não recomendo para iniciantes. Acredito que este curso seja voltado para quem já sabe usar o Android Studio ou que já programa em Java (devido à similaridade com a linguagem Kotlin).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Udemy — Construa aplicativos mobile do zero com React Native e Redux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curso pago da Udemy, focado em desenvolvimento mobile híbrido utilizando a biblioteca JS React Native com Redux. O curso é bem completo, com vários projetos e exemplos. Mas, eu acabei desistindo do curso, pois a didática do professor Renan é voltada para quem já tem um bom conhecimento em Javascript, HMTL e CSS, além de um conhecimento básico em React.js e React Native. Como estou estudando Javascript e seus frameworks com mais calma agora, pretendo dar uma segunda chance para este curso no futuro, e volto para compartilhar minhas opiniões. Até a aula que assisti me pareceu ser um bom curso, o professor Renan demostrou ter um grande domínio na ferramenta, mas, definitivamente não recomendaria para iniciantes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fundação Bradesco — Linguagem de Modelagem Unificada (UML)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curso gratuito da Fundação Bradesco. É um curso rápido e interativo, explicando o básico sobre Diagramas UML e como fazer o planejamento de projetos técnicos. O curso é bem explicado, de fácil entendimento e mais voltado para iniciantes. Para quem faz faculdade na área, o curso faz um bom resumo desta tecnologia. Para quem não faz faculdade e deseja trabalhar nerstaa área, eu recomendo fazer este curso para ter pelo alguma noção de como são feitas as especificações e planejamento de um projeto real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Digital Innovation One — Especialista em Inovação Digital&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Curso gratuito de Digital Innovation One (é necessário se cadastrar no site para assistir), mais voltado para a área de gestão/empreendedorismo. O curso mostra a visão dos fundadores de grandes startups, mostrando suas metodologias, técnicas, modo de pensar, dicas e estruturação dos negócios. Curso vital para quem deseja empreender na área, aprendendo como as empresas de tecnologia pensam e agem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links para os cursos citados&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Curso em Vídeo — &lt;a href="https://www.youtube.com/cursoemvideo"&gt;https://www.youtube.com/cursoemvideo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso Angular (Loiane Groner) — &lt;a href="https://www.youtube.com/watch?v=tPOMG0D57S0&amp;amp;list=PLGxZ4Rq3BOBoSRcKWEdQACbUCNWLczg2G"&gt;https://www.youtube.com/watch?v=tPOMG0D57S0&amp;amp;list=PLGxZ4Rq3BOBoSRcKWEdQACbUCNWLczg2G&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso Vue.js, GraphQL e Node (Rodrigo Branas) — &lt;a href="https://www.youtube.com/watch?v=TSX_hMfL13U&amp;amp;list=PLQCmSnNFVYnTiC-pPY0SySbf-ZNGBwnaG&amp;amp;index=1"&gt;https://www.youtube.com/watch?v=TSX_hMfL13U&amp;amp;list=PLQCmSnNFVYnTiC-pPY0SySbf-ZNGBwnaG&amp;amp;index=1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Ionic 4 (Simom Grimm, em inglês) — &lt;a href="https://www.youtube.com/watch?v=3f8DjnByp5U&amp;amp;list=PLNFwX8PVq5q7S-p_7zO99xdauhDsnMPw0"&gt;https://www.youtube.com/watch?v=3f8DjnByp5U&amp;amp;list=PLNFwX8PVq5q7S-p_7zO99xdauhDsnMPw0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso Python (Ignorância Zero) — &lt;a href="https://www.youtube.com/watch?v=lJjR906426o&amp;amp;list=PLfCKf0-awunOu2WyLe2pSD2fXUo795xRe"&gt;https://www.youtube.com/watch?v=lJjR906426o&amp;amp;list=PLfCKf0-awunOu2WyLe2pSD2fXUo795xRe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Playlist Programação para Iniciantes (Fábio Akita) — &lt;a href="https://www.youtube.com/watch?v=O76ZfAIEukE&amp;amp;list=PLdsnXVqbHDUc7htGFobbZoNen3r_wm3ki"&gt;https://www.youtube.com/watch?v=O76ZfAIEukE&amp;amp;list=PLdsnXVqbHDUc7htGFobbZoNen3r_wm3ki&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso de Git e Github para Iniciantes — &lt;a href="https://www.udemy.com/course/git-e-github-para-iniciantes/"&gt;https://www.udemy.com/course/git-e-github-para-iniciantes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso Completo de Design de Interface — &lt;a href="https://www.udemy.com/course/design-de-interface/"&gt;https://www.udemy.com/course/design-de-interface/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso Introdução a banco de dados com MySQL &amp;amp; PHPMyAdmin — &lt;a href="https://www.udemy.com/course/mysql_phpmyadmin/"&gt;https://www.udemy.com/course/mysql_phpmyadmin/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Curso de Desenvolvimento de Aplicativos Android com Kotlin — &lt;a href="https://www.udemy.com/course/curso-de-kotlin-para-android/"&gt;https://www.udemy.com/course/curso-de-kotlin-para-android/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Web Moderno Completo com Javascript 2020 + Projetos — &lt;a href="https://www.udemy.com/course/curso-web/"&gt;https://www.udemy.com/course/curso-web/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Android do Absoluto Zero para Iniciantes — &lt;a href="https://www.udemy.com/course/desenvolvimento-android-do-absoluto-zero-para-iniciantes/"&gt;https://www.udemy.com/course/desenvolvimento-android-do-absoluto-zero-para-iniciantes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Construa aplicativos mobile do zero com React Native e Redux — &lt;a href="https://www.udemy.com/course/construa-aplicativos-mobile-do-zero-com-react-native/"&gt;https://www.udemy.com/course/construa-aplicativos-mobile-do-zero-com-react-native/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Linguagem de Modelagem Unificada (UML) — &lt;a href="https://www.ev.org.br/curso/informatica/desenvolvimento-de-sistemas/linguagem-de-modelagem-unificada-uml?return=/cursos/informatica&amp;amp;cst=528"&gt;https://www.ev.org.br/curso/informatica/desenvolvimento-de-sistemas/linguagem-de-modelagem-unificada-uml?return=/cursos/informatica&amp;amp;cst=528&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;· Especialista em Inovação Digital — &lt;a href="https://www.ev.org.br/curso/informatica/desenvolvimento-de-sistemas/linguagem-de-modelagem-unificada-uml?return=/cursos/informatica&amp;amp;cst=528"&gt;https://www.ev.org.br/curso/informatica/desenvolvimento-de-sistemas/linguagem-de-modelagem-unificada-uml?return=/cursos/informatica&amp;amp;cst=528&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Construindo gráficos utilizando o Chart.js (com legenda)</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:31:17 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/construindo-graficos-utilizando-o-chartjs-com-legenda-4p08</link>
      <guid>https://dev.to/guilhermemanzano/construindo-graficos-utilizando-o-chartjs-com-legenda-4p08</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dUdbH7eu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4okg2giosq3uvcn0clj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dUdbH7eu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4okg2giosq3uvcn0clj2.png" alt="Image description" width="720" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Criar gráficos em Javascript nunca foi tão fácil, irei demostrar agora como criar um gráfico de pizza utilizando as tecnologias do HTML5, canvas e a biblioteca Javascript Chart.js.&lt;/p&gt;

&lt;p&gt;A biblioteca Chart.js é utilizada para auxiliar na criação de gráficos, utilizando apenas HTML, CSS e JS, para renderizar os gráficos na tela do usuário. Para isso, ela se utiliza do elementos canvas, do HTML5. No exemplo a seguir, utilizei a biblioteca Chart.js em cima do Typescrip e Ionic, para cria-lo num aplicativo mobile híbrido e PWA.&lt;/p&gt;

&lt;p&gt;O Chart.js possui diversos temas diferentes para gráficos, como de barra, de pizza, de linha, rosquinha, polar, bolhas, área, entre tantos outros, mostrando-se ser uma biblioteca dinâmica e versátil, para poder atender as mais diversas necessidades. Além disso, é possível criar gráficos interativos e modulares, legendas e adicionar diversos tipos de informações.&lt;/p&gt;

&lt;p&gt;Para saber mais sobre a biblioteca e todos seus recursos, recomendo acompanhar o artigo junto com o site oficial da biblioteca, o &lt;a href="http://www.chartjs.org"&gt;www.chartjs.org&lt;/a&gt; (em inglês). Agora irei explicar, com comentários, a criação do gráfico utilizando o Typescript e Ionic e, depois, mostrarei o HMTL e CSS respectivo do nosso projeto. O editor de código utilizado para realizar estes gráficos foi o Visual Studio Code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código em Javascript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ChartDataLabels from 'chartjs-plugin-datalabels';
import { Component, ViewChild } from '@angular/core';
import * as Chart from 'chart.js';

@Component({
  selector: comida,
  templateUrl: './comida.page.html',
  styleUrls: ['./comida.page.scss'],
})
export class ComidaPage {

  @ViewChild('barChart', { static: false }) barChart;
  barras: any;
  colorArray: any;
  array: any;

this.array = [37, 48, 69, 21];

  createBarChart() {
    //Pega 4 cores do array de cores que foi definida em outra função
    this.generateColorArray(4);
    this.barras = new Chart(this.barChart.nativeElement, {
      type: 'pie',
    //Plugin para criação das legendas 
      plugins: [ChartDataLabels],
//Label se refere ao nome de cada parte do gráfico e data e a quantidade de cada “fatia” do gráfico
      data: {
        labels: [‘Pizza’, ‘Hambúrguer’, ‘Isca de Peixe’, ‘Batata Frita’],
        datasets: [{
          label: 'Tipos de Comida,
          data: [this.array],
        //busca as cores pré-selecionadas
          backgroundColor: this.colorArray,
          borderColor: '#ffffff',
          borderWidth: 2
        }]
      },
    //Opções e formatação da legenda
      options: {
        responsive: true,
        plugins: {
          datalabels: {
            color: "black",
            textAlign: "center",
            font: {
              weight: "bold",
              family: "Times New Roman",
              size: 14
            },
          }
        }
      }
    });
  }

  //Busca n cores dentro deste array, que podem ser pré-definidas ou    sortidas.
  generateColorArray(num) {
    this.colorArray = ['#2980B9', '#73f2a9', '#ffa54f', '#db7093', '#27408b', '#008b45', '#ff7400', '#dcce76', '#330033', '#FFFF66', '#455A64',
      '#D32F2F', '#81D4FA', '#6600CC', '#CCFFCC', '#795548', '#4A235A'];
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, nós temos o código HTML de nosso gráfico, com o respectivo título e chamando a função de gráficos, em canvas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código em HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
&amp;lt;!--Título da página --&amp;gt;
  &amp;lt;ion-toolbar color="tertiary"&amp;gt;
    &amp;lt;div class="headerTittle"&amp;gt;
      &amp;lt;h1&amp;gt;Comida&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/ion-toolbar&amp;gt;
&amp;lt;/ion-header&amp;gt;

&amp;lt;ion-content&amp;gt;
  &amp;lt;div class="titulo"&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;ion-label&amp;gt;Tipos de Comida&amp;lt;/ion-label&amp;gt;
  &amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;!--Utilizando a biblioteca Chart.js--&amp;gt;
  &amp;lt;canvas #barChart&amp;gt;&amp;lt;/canvas&amp;gt;
  &amp;lt;script src="https://cdn.jsdelivr.net/npm/chart.js@2.7.3/dist/Chart.min.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/ion-content&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Este código CSS é utilizado para estilizar o título do gráfico.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.titulo {
    font-size: 20px;
    font-weight: bold;
    color: blue;
    text-align: center;
    margin-bottom: 10x;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Como fazer um validador de CPF em Tyepscript</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:28:26 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/como-fazer-um-validador-de-cpf-em-tyepscript-29d</link>
      <guid>https://dev.to/guilhermemanzano/como-fazer-um-validador-de-cpf-em-tyepscript-29d</guid>
      <description>&lt;p&gt;É comum que um programador se depare, mais cedo ou mais tarde, com um problema onde terá que fazer uma validação de CPF (Cadastro de Pessoa Física) ou CNPJ (Cadastro Nacional de Pessoa Jurídica), seja no trabalho ou na faculdade. Apesar de parecer um problema complexo, a validação é feita com base em um cálculo matemático, e pode ser replicada em qualquer linguagem de programação sem muitas dificuldades. Há pouco tempo atrás, tive que implementar um validador de CPF e CNJP na empresa em que trabalho, utilizando Ionic e Typescript. E, neste mês, também me deparei com o mesmo problema durante uma aula da faculdade, mas em linguagem C. Hoje trarei a solução de como fazer um validador de CPF para Typescript e Ionic, que pode ser utilizado tanto para aplicações PWA, Web ou Mobile. No próximo artigo, trarei a solução de como implementar um validador de CNPJ, que possui lógica bem similar.&lt;/p&gt;

&lt;p&gt;Antes de exibir o código, farei uma breve explicação sobre como funciona esta fórmula matemática para validação do CPF. A fórmula para validar um número de CPF é conhecida por “módulo 11”, que consiste em gerar um número multiplicando cada dígito por um fator de acordo com a sua posição. Depois, é realizado uma divisão por 11 e é gerado o dígito verificador baseado em uma regra usando o resto da divisão. Os dois últimos números do CPF são os dígitos verificadores, cada um deles é calculado utilizando esta regra, mas com fatores distintos. O cálculo do primeiro dígito leva em conta os nove primeiros números do CPF, o cálculo do segundo dígito leva em consideração os nove primeiros números novamente e mais o primeiro dígito verificador. Mas não vou entrar em muitas detalhes e demonstrações matemáticas aqui.&lt;/p&gt;

&lt;p&gt;Apenas como curiosidade, é possível saber o estado de origem do CPF da pessoa apenas verificando o número do mesmo, pois o nono algarismo do CPF representa o estado de origem. Por exemplo, considerando o CPF 123.456.789–00, o nono algarismo é o 9, indicando que a origem do CPF é do estado do Paraná ou Santa Catarina. Para saber qual o estado de origem de um determinado CPF, é utilizada a seguinte lista: 1. Distrito Federal, Goiás, Mato Grosso do Sul e Tocantins; 2. Pará, Amazonas, Acre, Amapá, Rondônia e Roraima; 3. Ceará, Maranhão e Piauí; 4. Pernambuco, Rio Grande do Norte, Paraíba e Alagoas; 5. Bahia e Sergipe; 6. Minas Gerais; 7. Rio de Janeiro e Espírito Santo; 8. São Paulo; 9. Paraná e Santa Catarina; 0. Rio Grande do Sul. Segue então o código comentado de validação de CPF em Typescript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
  &amp;lt;ion-toolbar color="tertiary"&amp;gt;
    &amp;lt;div class="headerTittle"&amp;gt;
      &amp;lt;h1&amp;gt;CPF na Nota&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/ion-toolbar&amp;gt;
  &amp;lt;ion-toolbar&amp;gt;
    &amp;lt;!-- Botão que ativará a função para testar o CPF --&amp;gt;
    &amp;lt;div class="headerButton" (click)="testaCPF()"&amp;gt;
      Inserir CPF
    &amp;lt;/div&amp;gt;
  &amp;lt;/ion-toolbar&amp;gt;
&amp;lt;/ion-header&amp;gt;

&amp;lt;ion-content&amp;gt;
  &amp;lt;!--Neste campo, o usuário irá inserir o CPF, que será guardado  na variável cpf--&amp;gt;
  &amp;lt;ion-input class="cpf" placeholder="Insira o CPF" name="cpf" type="text" [(ngModel)]="cpf"&amp;gt;&amp;lt;/ion-input&amp;gt;
&amp;lt;/ion-content&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Código em typescript, com Ionic&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { ModalController, AlertController, NavParams } from '@ionic/angular';

@Component({
  selector: 'nota-fiscal',
  templateUrl: './nota-fiscal.component.html',
  styleUrls: ['./nota-fiscal.component.scss'],
})

export class NotaFiscalComponent {

  cpf: any;
  strCPF: any;

  constructor(
    private modalController: ModalController,
    public globalS: GlobalService,
    private alertController: AlertController,
  ) { }

  //Exibe uma mensagem de alerta ao usuário, caso o número do CPF seja inválido
  async myDismiss() {
    this.cpf = null;
    await this.modalController.dismiss(this.cpf);
  }

  //Função que irá testar se o CPF é valido 
  testaCPF() {
    var Soma = 0;
    // Verifica se a variável cpf é igual a "undefined", exibindo uma msg de erro
    if (this.cpf === undefined) {
      this.cpfAlert();
      return false;
    }

    // Esta função retira os caracteres . e - da string do cpf, deixando apenas os números 
    var strCPF = this.cpf.replace('.', '').replace('.', '').replace('-', '');
    // Testa as sequencias que possuem todos os dígitos iguais e, se o cpf não tem 11 dígitos, retorna falso e exibe uma msg de erro
    if (strCPF === '00000000000' || strCPF === '11111111111' || strCPF === '22222222222' || strCPF === '33333333333' || 
    strCPF === '44444444444' || strCPF === '55555555555' || strCPF === '66666666666' || strCPF === '77777777777' || strCPF === '88888888888' || 
    strCPF === '99999999999' || strCPF.length !== 11) {
      this.cpfAlert();
      return false;
    }

    // Os seis blocos seguintes de funções vão realizar a validação do CPF propriamente dito, conferindo se o DV bate. Caso alguma das funções não consiga verificar
    // o DV corretamente, mostrará uma mensagem de erro ao usuário e retornará falso, para que o usário posso digitar novamente um número para ser testado

    //Multiplica cada digito por numeros de 1 a 9, soma-os e multiplica-os por 10. Depois, divide o resultado encontrado por 11 para encontrar o resto
    for (let i = 1; i &amp;lt;= 9; i++) {
      Soma = Soma + parseInt(strCPF.substring(i - 1, i)) * (11 - i);
    }

    var Resto = (Soma * 10) % 11;
    if ((Resto === 10) || (Resto === 11)) {
      Resto = 0;
    }

    if (Resto !== parseInt(strCPF.substring(9, 10))) {
      this.cpfAlert();
      return false;
    }

    Soma = 0;
    for (let k = 1; k &amp;lt;= 10; k++) {
      Soma = Soma + parseInt(strCPF.substring(k - 1, k)) * (12 - k)
    }

    Resto = (Soma * 10) % 11;
    if ((Resto === 10) || (Resto === 11)) {
      Resto = 0;
    }

    if (Resto !== parseInt(strCPF.substring(10, 11))) {
      this.cpfAlert();
      return false;
    }

    //a função this.update() será chamada, caso a validação do Dígito Verificador seja feita com sucesso
    this.update();
    return true;
  }
    //Caso o CPF será valido, irá realizar a gravação do mesmo na variável strCPF
  async update() {
    await this.modalController.dismiss(this.strCPF);
  }

  async cpfAlert() {
    const alert = await this.alertController.create({
      header: 'CPF Inválido!',
      message: 'Digite um número de CPF válido para prosseguir',
      buttons: ['OK']
    });
    await alert.present();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Como fazer um validador de CNPJ em Tyepscript e Ionic 4</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 25 Oct 2023 00:26:17 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/como-fazer-um-validador-de-cnpj-em-tyepscript-e-ionic-4-1pag</link>
      <guid>https://dev.to/guilhermemanzano/como-fazer-um-validador-de-cnpj-em-tyepscript-e-ionic-4-1pag</guid>
      <description>&lt;p&gt;Neste artigo, irei ensinar como fazer a validação do CNPJ (Cadastro Nacional da Pessoa Física), que possui uma lógica similar, utilizando uma fórmula matemática para verificar o DV (Dígito Verificador) do CNPJ, que é conhecida como “módulo 12”.&lt;/p&gt;

&lt;p&gt;O CNPJ é formado por 14 dígitos, divididos em três blocos. Usando como exemplo o CNPJ fictício 11.222.333/0001–44, temos que, o primeiro bloco (11.22.333) representa o número da inscrição da empresa; o segundo bloco (0001), localizado após a barra, representa um código único que identifica a matriz/filial da empresa; por fim, o terceiro bloco (44), que são os dois dígitos finais, são os dígitos verificadores. O cálculo do DV é feito de maneira similar ao do CPF, mas não entrarei em detalhes neste artigo. Vamos então ao código comentado de validação de CPF em Typescript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Código em typescript, com Ionic&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { ModalController, AlertController, NavParams } from '@ionic/angular';

@Component({
  selector: 'nota-fiscal-empresa',
  templateUrl: './nota-fiscal-empresa.component.html',
  styleUrls: ['./nota-fiscal-empresa.component.scss'],
})

export class NotaFiscalEmpresaComponent {
  cnpj: any;
  strCNPJ: any;

  constructor(
    private modalController: ModalController,
    private alertController: AlertController,
  ) { }

  //Função que irá testar se o CNPJ é valido 
  testaCNPJ() {
    // Verifica se a variável cnpj é igua a "undefined", exibindo uma msg de erro
    if (this.cnpj === undefined) {
      this.cnpjAlert();
      return false;
    }

    // Esta função retira os caracteres . / - da string do cnpj, deixando apenas os números 
    var strCNPJ = this.cnpj.replace('.', '').replace('.', '').replace('/', '').replace('-', '');

    // Testa as sequencias que possuem todos os dígitos iguais e se o cnpj não tem 14 dígitos, retonando falso e exibindo uma msg de erro
    if (strCNPJ === '00000000000000' || strCNPJ === '11111111111111' || strCNPJ === '22222222222222' || strCNPJ === '33333333333333' ||
      strCNPJ === '44444444444444' || strCNPJ === '55555555555555' || strCNPJ === '66666666666666' || strCNPJ === '77777777777777' ||
      strCNPJ === '88888888888888' || strCNPJ === '99999999999999' || strCNPJ.length !== 14) {
      this.cnpjAlert();
      return false;
    }

    // A variável numeros pega o bloco com os números sem o DV, a variavel digitos pega apenas os dois ultimos numeros (Digito Verificador).
    var tamanho = strCNPJ.length - 2;
    var numeros = strCNPJ.substring(0, tamanho);
    var digitos = strCNPJ.substring(tamanho);
    var soma = 0;
    var pos = tamanho - 7;

    // Os quatro blocos seguintes de funções irá reaizar a validação do CNPJ propriamente dito, conferindo se o DV bate. Caso alguma das funções não consiga verificar
    // o DV corretamente, mostrará uma mensagem de erro ao usuário e retornará falso, para que o usário posso digitar novamente um número 
    for (let i = tamanho; i &amp;gt;= 1; i--) {
      soma += numeros.charAt(tamanho - i) * pos--;
      if (pos &amp;lt; 2) {
        pos = 9;
      }
    }

    var resultado = soma % 11 &amp;lt; 2 ? 0 : 11 - soma % 11;
    if (resultado != digitos.charAt(0)) {
      this.cnpjAlert();
      return false;
    }

    tamanho = tamanho + 1;
    numeros = strCNPJ.substring(0, tamanho);
    soma = 0;
    pos = tamanho - 7;
    for (let k = tamanho; k &amp;gt;= 1; k--) {
      soma += numeros.charAt(tamanho - k) * pos--;
      if (pos &amp;lt; 2) {
        pos = 9;
      }
    }

    resultado = soma % 11 &amp;lt; 2 ? 0 : 11 - soma % 11;
    if (resultado != digitos.charAt(1)) {
      this.cnpjAlert();
      return false;
    }

    this.update();
    return true;
  }

  //Caso o CNPJ será valido, irá realizar a gravação do mesmo na variável strCNPJ
  async update() {
    await this.modalController.dismiss(this.strCNPJ);
  }

  //Exibe uma mensagem de alerta ao usuário, caso o número do CNPJ seja inválido
  async cnpjAlert() {
    const alert = await this.alertController.create({
      header: 'CNPJ Inválido!',
      message: 'Digite um número de CNJP válido para prosseguir',
      buttons: ['OK']
    });
    await alert.present();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Código HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
  &amp;lt;ion-toolbar color="tertiary"&amp;gt;
    &amp;lt;div class="headerTittle"&amp;gt;
      &amp;lt;h1&amp;gt;CNPJ na Nota&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/ion-toolbar&amp;gt;
  &amp;lt;ion-toolbar&amp;gt;
    &amp;lt;!-- Botão que ativará a função para testar o CNPJ --&amp;gt;
    &amp;lt;div class="headerButton" (click)="testaCNPJ()"&amp;gt;
      Inserir CNPJ
    &amp;lt;/div&amp;gt;
  &amp;lt;/ion-toolbar&amp;gt;
&amp;lt;/ion-header&amp;gt;

&amp;lt;ion-content&amp;gt;
  &amp;lt;!--Neste campo, o usuário irá inserir o CNPJ, que será guardado  na variável cnpj--&amp;gt;
  &amp;lt;ion-input class="cnpj" placeholder="Insira o CNPJ" name="cnpj" type="text" [(ngModel)]="cnpj"&amp;gt;&amp;lt;/ion-input&amp;gt;
&amp;lt;/ion-content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Tudo o que você precisa saber sobre Algoritmos e Estrutura de Dados</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Sat, 07 Oct 2023 02:49:51 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/tudo-o-que-voce-precisa-saber-sobre-algoritmos-e-estrutura-de-dados-2be4</link>
      <guid>https://dev.to/guilhermemanzano/tudo-o-que-voce-precisa-saber-sobre-algoritmos-e-estrutura-de-dados-2be4</guid>
      <description>&lt;p&gt;Algoritmo é que um conjunto de instruções que realizam uma determinada tarefa. Eles são uma das bases da programação. Pensando em um exemplo, para fazermos uma receita culinária, nós precisamos dos ingredientes e de um conjunto de instruções, descrevendo o passo a passo para a sua confecção, que podemos chamar de algoritmo. Através dos algoritmos, escrevemos instruções para que os computadores possam resolver um problema específico.&lt;br&gt;
Estrutura de dados é o ramo da computação que estuda os diversos mecanismos de organização de dados para atender aos diferentes requisitos de processamento, ou seja, é a forma como organizamos os dados.&lt;/p&gt;

&lt;p&gt;Imagine que temos uma tabela com um milhão de registros e precisamos encontrar um determinado valor nela. Se buscarmos esse valor de forma sequencial, podemos demorar até um milhão de passos para encontrar o dado que queremos (considerando o pior caso, caso esteja na última posição). Por isso, é importante estruturarmos os dados de forma eficiente, além de utilizar algoritmos eficientes, para otimizar nossos serviços. Esse é um tópico extremamente importante, que todo programador precisa conhecer para evoluir na carreira.&lt;/p&gt;

&lt;p&gt;Neste artigo, preparei um resumo com as principais estruturas de dados utilizadas. Se vocês gostarem desse conteúdo, posso escrever outros artigos com a implementação dos algoritmos descritos, em Java ou Kotlin. Não deixem de me seguir e interagir com esse conteúdo, para que eu possa trazer mais conteúdos de programação e tecnologia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notação Big O (Big-O Notation)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A notação Big O é uma notação especial que diz o quão rápido é um algoritmo, sendo utilizada para comparar o número de operações necessárias para um algoritmo encontrar um determinado elemento em uma busca. Esta notação leva em conta a pior cenário de busca (caso não encontre o elemento ou ele esteja na última posição do array), apesar de também ser necessário estudar o tempo de execução para o “caso médio”, na comparação dos algoritmos de busca.&lt;/p&gt;

&lt;p&gt;O O(1) representa o algoritmo perfeito, onde precisaríamos de apenas um passo para encontrar um elemento qualquer, independentemente do tamanho do array (representado pela cor verde, na imagem abaixo). Já o O(n!) representa os piores algoritmos, onde a quantidade de passos necessários para se encontrar determinado elemento aumenta de forma fatorial, de acordo com a quantidade de elementos presentes no array (n é o tamanho do array.) Na imagem a seguir, é representado pela linha vertical esquerda, dentro da cor rosa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uQDTUmty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9i3ec20bwakbdxya926.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uQDTUmty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9i3ec20bwakbdxya926.jpg" alt="Image description" width="800" height="556"&gt;&lt;/a&gt;&lt;br&gt;
Fonte: &lt;a href="https://www.freecodecamp.org/portuguese/news/content/images/2021/12/1_KfZYFUT2OKfjekJlCeYvuQ.jpeg"&gt;https://www.freecodecamp.org/portuguese/news/content/images/2021/12/1_KfZYFUT2OKfjekJlCeYvuQ.jpeg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algoritmos de Busca&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Busca Linear (Linear Search)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um algoritmo que busca elementos de um array de forma sequencial (do início para o fim ou do fim para o início). Como ele busca os elementos um a um, é um algoritmo bem lento, sua complexidade é O(n). Vamos ver um exemplo onde queremos buscar o elemento 3 em um array que contém 5 elementos, a busca linear ficaria assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VQB66GBg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu5aeeb8pesg9u1f0tah.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VQB66GBg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu5aeeb8pesg9u1f0tah.jpg" alt="Image description" width="578" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como o elemento estava na penúltima posição do array, foi preciso realizar quatro passos até encontrá-lo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Busca Binária (Binary Search)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A busca binária só funciona quando a lista está ordenada (em sequência crescente) e é um dos algoritmos mais performáticos para buscas. Quando queremos verificar se um determinado elemento está em um vetor e em qual posição, podemos utilizar este algoritmo. Para realizar a busca, o primeiro passo é buscar um elemento qualquer no vetor (normalmente, buscamos o elemento que está no meio) e verificar se este elemento é maior ou menor que o elemento que estamos buscando. Se o valor procurado for maior que o elemento que estamos comparando, o algoritmo vai eliminar a metade da lista que está a sua esquerda. Caso o elemento procurado for menor que o elemento que estamos comparando, então vai eliminar a metade da lista que está a sua direita. Em seguida, vamos repetir essa sequência até encontrar o elemento desejado, sempre eliminando metade das possibilidades a cada passo.&lt;/p&gt;

&lt;p&gt;Caso o elemento que estamos buscando estiver na lista, a busca binária retornará sua localização. Mas, caso o elemento não seja encontrado, a busca vai retornar None. A desvantagem algoritmo é que a lista precisa estar ordenada para poder fazermos a busca. Por isso que, normalmente, escolhemos o elemento que está no meio do vetor para realizar a comparação, já que isso elimina metade das possibilidades a cada passo.&lt;/p&gt;

&lt;p&gt;Vamos pensar em um exemplo, se temos 100 elementos em uma lista e estamos buscando o 63, primeiro o algoritmo vai buscar no elemento 50. Como 63 está acima de 50, vamos eliminar todos os elementos que estão a sua esquerda (menores que 50). Em seguida, vamos buscar novamente o número 63 comparando-o com o elemento que está no meio do array, que é o número 75. Como 63 é menor que 75, dessa vez vamos eliminar todos os elementos que estão à sua direita (maiores que 75). Depois, continuamos a pesquisar o elemento no array que restou até o encontrarmos ou sobrar apenas um elemento no array.&lt;/p&gt;

&lt;p&gt;De maneira geral, para uma lista de n números, a pesquisa binária precisa de log(2n) para retornar o valor correto, enquanto a pesquisa simples precisa de n etapas. A complexidade desse algoritmo é de O(log n). Utilizando o mesmo exemplo da busca linear, vamos buscar o elemento 3 no mesmo array que usamos na pesquisa linear (após ordenar o array):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cr7KAFkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8cwkmsngle591n0fzxt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cr7KAFkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8cwkmsngle591n0fzxt.jpg" alt="Image description" width="538" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como podemos ver, foi necessários apenas dois passos para encontrar o elemento utilizando busca binária, enquanto na busca linear foram necessários 4 passos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pilha (LIFO - Last in, first out)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A pilha é considerada um tipo abstrato de dados, pois não precisa de nada novo para armazenar os dados. É baseada na lista encadeada, onde o último elemento inserido será o primeiro que será lido (não é possível pesquisar algum elemento no meio de uma pilha, por exemplo). Os métodos possíveis para manipulação de uma pilha são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Método Top: utilizado para verificar qual é o primeiro elemento da pilha (que está no topo). Por exemplo, pilha.top() recebe a referência do topo da pilha;&lt;/li&gt;
&lt;li&gt;Método Pop: tira, de fato, o primeiro elemento da pilha. Por exemplo, pilha.pop(), após remover o elemento, a referência de topo passa para o próximo elemento da pilha;&lt;/li&gt;
&lt;li&gt;Método Push: adiciona um novo elemento na pilha;&lt;/li&gt;
&lt;li&gt;Método isEmpty: verifica se a referência para a entrada da pilha está nula (ou seja, se há ou não uma pilha);&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vejamos um exemplo de Pilha:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f0aU1KVa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k78m2hpj9o0g2clfjp1v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f0aU1KVa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k78m2hpj9o0g2clfjp1v.jpg" alt="Image description" width="697" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fila (FIFO - First in, first out)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Também é considerado um tipo abstrato de dado (por exemplo, é possível criar uma fila utilizando uma lista ligada, um vetor, etc.). Na fila, o primeiro elemento inserido será o primeiro a ser lido (como ocorre em uma fila qualquer como, por exemplo, em uma fila de banco, onde o último que entrar será o último a ser atendido). Vejamos um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CZKbwsGS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0e15sqyr5gena5v2jkxu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CZKbwsGS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0e15sqyr5gena5v2jkxu.jpg" alt="Image description" width="680" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algoritmos de Ordenação&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vetor (Array)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O vetor é considerado um tipo de lista (representado por um objeto) que permite armazenar diversos elementos. Os elementos são inseridos de acordo com o índice e possui um tamanho fixo. Caso precise adicionar novos elementos, mas não tiver mais espaços livres, será preciso criar um novo array com tamanho maior que o anterior, depois precisamos copiar todos os elementos do array antigo para o novo e, por fim, adicionar os novos elementos ao novo array. Por conta disso, o array é considerado rápido para realizar buscas, mas lento para inserção e deleção de elementos. Vejamos uma representação de um array:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eyHYN4R9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2rp7m7n2gpoghy98o12.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eyHYN4R9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2rp7m7n2gpoghy98o12.jpg" alt="Image description" width="557" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lista Encadeada (ou Ligada)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É uma lista de tamanho dinâmico, onde cada elemento conhece o endereço do elemento predecessor. Seu funcionamento é similar ao do array, porém, é recomendada sua utilização quando for preciso realizar muitas inserções e não sabemos qual o total de elementos a ser inserido. Porém, quando é necessário buscar um elemento, é preciso começar buscando o primeiro elemento, que vai buscar o segundo, que vai buscar o terceiro, e assim por diante, até encontrar o elemento desejado. Ou seja, ele é muito rápido para inserções, mas lento para buscas.&lt;br&gt;
É possível utilizamos o iterator, que é um padrão utilizado para buscar elementos dentro de uma lista. O iterator guarda apenas o elemento atual e possui métodos para verificar se há mais elementos naquela lista. Vamos ver um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L0Q0h4ZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/forg0m3cn4a97uu7z0by.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L0Q0h4ZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/forg0m3cn4a97uu7z0by.jpg" alt="Image description" width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lista Duplamente Encadeada&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É utilizada quando precisamos seguir a sequência de elementos em ambos os sentidos. Ou seja, cada elemento vai conhecer o elemento anterior e o predecessor. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nl97VkqP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmw42sudde6xy2eit84l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nl97VkqP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmw42sudde6xy2eit84l.jpg" alt="Image description" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listas Circulares&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É quando o último elemento da lista aponta para a referência do primeiro elemento. Sendo que, o último elemento é chamado de “Cabeça” e o primeiro de “Cauda”. Temos também uma referência de entrada para o primeiro nó, onde entramos na lista pela Cauda. Os métodos utilizados são remove(element), get(index), add(element) e isEmpty(). Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tg8naodX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33jczcpgidzt8t0f16yl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tg8naodX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33jczcpgidzt8t0f16yl.jpg" alt="Image description" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordenação Bolha (Bubble Sort)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um algoritmo de ordenação que funciona comparando dois elementos de cada vez: um elemento fica “parado”, enquanto um ponteiro percorre o vetor comparando o elemento que está parado com esse elemento da vez. Caso o elemento apontado for menor que o elemento índice (que está parado), movemos ele para antes desse elemento. &lt;br&gt;
Quando o ponteiro percorrer todos os elementos daquele vetor, o próximo elemento será o índice e o ciclo irá recomeçar, até que todos os elementos estejam ordenados corretamente. Por conta do seu funcionamento, este algoritmo é considerado bem lento, sendo a complexidade do pior caso O(n^2).&lt;/p&gt;

&lt;p&gt;Pensando em sua implementação em uma linguagem como Java ou Kotlin, podemos utilizar um laço de repetição for com um elemento i, que será o nosso elemento índice, e dentro deste loop criamos um outro laço for com um elemento j, para ser o ponteiro com o elemento que vamos comparar, em cada passo. Vamos ver um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mnjn4qeX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6sca2frcrpajx7xbnf5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mnjn4qeX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6sca2frcrpajx7xbnf5.jpg" alt="Image description" width="721" height="733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordenação Rápida (Quick sort)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É considerado um dos algoritmos de ordenação mais rápido. O Quick Sort funciona através da estratégia de dividir o problema em problemas menores, diminuindo a quantidade de comparações. Ao invés de ordenar o vetor inteiro, declaramos um elemento como pivô (normalmente, é escolhido o elemento do meio) e, os elementos menores que ele vai ficar do seu lado esquerdo, e os vão maiores que eles vão ficar do seu lado direito. Após isso, cada lado será considerado um subarray e um novo elemento será definido como pivô, em cada um dos subarrays, e o processo será reiniciado (elementos menores que o pivô para o lado esquerdo e os maiores para o lado direito). Isso é feito recursivamente, até todos os elementos serem ordenados. Considerando seu pior caso, possui uma complexidade de O(n^2) e, considerando a média, tem uma complexidade de O(log n). Vejamos um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lqs9-6oh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gld74yy8scm367ndme0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lqs9-6oh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gld74yy8scm367ndme0.jpg" alt="Image description" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordenação por seleção (Selection Sort)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um algoritmo de ordenação que compara o elemento a ser ordenado com cada um dos elementos da lista, um a um. Ou seja, se ele encontrar um elemento menor que ele, vai movê-lo para o início do vetor, colocando-o na sequência correta. Vamos ver um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PI02mEnm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewxl2i3uyfe8s973yab1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PI02mEnm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewxl2i3uyfe8s973yab1.jpg" alt="Image description" width="346" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordenação em Heap (Heap Sort)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um algoritmo de ordenação do tipo árvore, em que o elemento pai sempre será maior que o filho que está a sua direita e menor que o filho que está a sua esquerda. Em um heap máximo, sempre o elemento pai será maior do que seus filhos. Para montar a árvore de acordo com os elementos do array, utilizamos a fórmula: 2i + 1 . Após ordenar os filhos da árvore, o algoritmo é chamado novamente, de forma recursiva, até ordenarmos todo o vetor corretamente. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NX0zszXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihshfvy5jrhkroj7c68.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NX0zszXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihshfvy5jrhkroj7c68.jpg" alt="Image description" width="573" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordenação por Intercalação (Merge Sort)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A ideia básica deste algoritmo é intercalar duas metades de uma lista que já estão ordenadas. Funciona com base na recursão, utilizando a estratégia de dividir para conquistar. O problema é quebrado em subproblemas, que são similares ao problema original. Recursivamente, o algoritmo resolve os subproblemas e, depois, combina as soluções para resolver o problema original. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--giUaWNj4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2mmkvbk48zi366mxq1v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--giUaWNj4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2mmkvbk48zi366mxq1v.jpg" alt="Image description" width="675" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordenação por Inserção (Insertion Sort)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Seu funcionamento é bem simples, tendo uma complexidade similar à do Bubble Sort. Este algoritmo é utilizado quando precisamos inserir um novo elemento em um vetor que já está ordenado. Primeiro, precisamos aumentar o tamanho do vetor em um (lenght+1), em seguida, precisamos verificar se o elemento a ser inserido é menor que o primeiro elemento do array. Caso seja, esse elemento inserido passa a ocupar essa posição e passa os demais elementos para frente. Caso contrário, ele passa a comparação para o elemento seguinte, até encontrar o elemento menor que ele, ou então assume a última posição no array. Sua complexidade para o melhor caso é de O(n) e, para o pior caso, é de O(n^2). Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5TmOfCMz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezx89m0boc2ayl1iy637.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5TmOfCMz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezx89m0boc2ayl1iy637.jpg" alt="Image description" width="326" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tabela de Dispersão (Hash Table)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A tabela de dispersão (hash table) é uma estrutura de dados especial, que associa chaves de pesquisa a valores de busca de um vetor não-ordenado. Quando precisamos inserir um novo elemento dentro de uma tabela hash, precisamos utilizar uma função matemática que vai gerar um índice válido no array, com base no valor do elemento a ser inserido. A essa função damos o nome de função hash / função de espalhamento / função mapeamento. Usando essa função, conseguimos mapear as chaves para os índices do array e armazenar os objetos (que são chamados de valores) em pares de . Para criarmos uma função hash, precisamos levar em consideração as seguintes regras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deve ser determinística. Ou seja, para uma determinada chave, a função sempre retorna o mesmo valor de hash;&lt;/li&gt;
&lt;li&gt;Deve ser sempre executada em tempo constante O(1) ;&lt;/li&gt;
&lt;li&gt;Deve sempre retornar um valor de hash dentro dos limites da tabela [0,N−1] , onde N é o tamanho da tabela.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esta estrutura de dados é considerada muito rápida, tanto para buscas, quanto para inserções. Vamos pensar em um exemplo onde queremos armazenar os nomes de algumas pessoas em uma tabela hash. Primeiramente, precisamos criar uma função hash, que será responsável por calcular o índice (posição), de onde o elemento será armazenado. Para a função, podemos pegar o tamanho de cada nome (string) e transforma-lo em um número inteiro, subtraindo um, que pode ser representada pela seguinte fórmula: índice = quantidade_de_letras − 1. &lt;/p&gt;

&lt;p&gt;Vamos inserir os nomes Bia, Caio, Paula, Carlos e João nessa tabela. Aplicando a função para nome, receberemos os seguintes índices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bia = 3 letras - 1 = índice 2;&lt;/li&gt;
&lt;li&gt;Caio = 4 letras - 1 = índice 3;&lt;/li&gt;
&lt;li&gt;Paula = 5 letras - 1 = índice 4;&lt;/li&gt;
&lt;li&gt;Carlos = 6 letras - 1 = índice 5; &lt;/li&gt;
&lt;li&gt;João = 4 letras -1 = índice 3;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como podemos notar, quando calculamos o índice para o João, recebemos o mesmo valor que o do Caio. Isso significa que, quando tentarmos inserir o João na tabela, teremos uma colisão. Após as inserções, nossa tabela vai ficar assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EhhQveUi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8pm82xx58799xd8bjam.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EhhQveUi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8pm82xx58799xd8bjam.jpg" alt="Image description" width="616" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para buscar um elemento, basta aplicar a função novamente, passando o nome e recebendo a posição. Por exemplo, para buscar a Bia, sabemos que o tamanho do nome é 3 e que, aplicando a fórmula, teremos o índice 2 como resposta. De acordo com a tabela, podemos ver que na posição 2 se encontra exatamente a Bia. Caso ele não encontrasse a Bia nesta posição, significa que ela não está na tabela. E, caso encontrasse outro nome, significa que houve uma colisão e existem mais nomes naquele índice. Uma função hash é considerado boa se ela for capaz de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Produzir um baixo número de colisões;&lt;/li&gt;
&lt;li&gt;Ser facilmente computável (não levar um tempo muito elevado para calcular o índice de um novo elemento); &lt;/li&gt;
&lt;li&gt;Ser uniforme (levar um tempo constante para transformar qualquer chave em um valor).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para sabermos se uma função hash é boa, podemos calcular o seu fator de carga, que é a quantidade de elementos de uma tabela hash, dividido pelo tamanho do vetor (levando em conta que o tamanho do vetor precisa ser maior que o número de elementos). Por exemplo, se temos 4 elementos e um vetor de 6 posições, teremos o seguinte fator de carga: Fc = 4/6 = 0,67.&lt;/p&gt;

&lt;p&gt;Quanto mais perto do 1 o fator de cargo estiver, menos espaços vazios vamos ter na tabela, o que pode gerar mais colisões. E, quanto mais perto estiver do 0, teremos uma grande quantidade de espaços vazios, o que diminui a possibilidade de colisões. Porém, isso significa que teremos um maior desperdício de memória, com muitos espaços não utilizados do vetor. Quando ocorrer uma colisão, existem basicamente duas estratégias para resolução:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encadeamento Exterior ou Separado: Listas encadeadas;&lt;/li&gt;
&lt;li&gt;Encadeamento Interior ou Aberto: Heterogêneo e Homogêneo (Teste Linear).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;strong&gt;encadeamento exterior com listas encadeadas&lt;/strong&gt; vamos armazenar os elementos fora do array, utilizando ponteiros. Quando um elemento for adicionado ao vetor, vamos calcular o seu índice de acordo com a função hash e, ao invés de colocar este elemento diretamente na posição, criamos uma lista encadeada externa, colocando o novo elemento como a primeira posição da lista. E, na posição do array referente aquele índice, teremos um ponteiro que indicará qual o endereço daquela lista encadeada. Cada elemento da lista encadeada (nó) possui duas informações, o valor armazenado e o endereço para o próximo elemento da lista. Quando um índice do array não tiver um ponteiro ou um elemento da lista não tiver o endereço para o próximo, retornaremos um nulo, indicando que não há mais valores naquela lista. Quando um elemento for removido de uma lista encadeada, o elemento anterior a ele terá o endereço para o próximo atualizado, apontando para o elemento posterior ao que foi removido.&lt;/p&gt;

&lt;p&gt;Pensando em um exemplo, vamos criar uma tabela hash com seis posições. Para isso, precisamos primeiro criar uma função que vai utilizar o módulo seis (pois é o tamanho do vetor) do elemento a ser inserido, retornando um número inteiro (índice). Agora, vamos inserir os números 12, 21, 10, 9 e 33 nessa tabela:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RcnwWiQ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ofvw2jq4blw2kbo2khg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RcnwWiQ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ofvw2jq4blw2kbo2khg.jpg" alt="Image description" width="517" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No &lt;strong&gt;encadeamento interior heterogêneo&lt;/strong&gt; temos um vetor com algumas posições a mais, que é onde iremos inserir os elementos que colidirem. Ou seja, quando ocorrer uma colisão, o elemento será inserido no próximo espaço reservado vazio. Para fazer a busca, primeiro utilizamos a função hash para calcular o índice. Caso o número retornado não esteja no índice, significa que precisamos procurá-lo por ele dentro do espaço reservado a colisões, onde iremos procurá-lo de forma sequencial. Por conta disso, se tivermos muitas colisões na tabela hash, a busca ou remoção de um elemento ficará muito mais lenta, pois terá o mesmo tempo de execução que a busca sequencia).&lt;br&gt;
Quando removermos um elemento, diferenciamos aquele espaço de uma outra forma (como, por exemplo, colocando um número negativo) pois, se durante a busca o algoritmo entrar no espaço de colisão e se deparar com um espaço vazio, vai interromper a busca e retornar que o elemento não foi encontrado. Vamos ver um exemplo:&lt;/p&gt;

&lt;p&gt;No &lt;strong&gt;encadeamento interior homogêneo&lt;/strong&gt;, quando ocorre uma colisão, vamos utilizar o teste linear, inserido o elemento no próximo que espaço vazio ou disponível. Como no tipo anterior, se houver muitas colisões, o algoritmo de busca/remoção ficará com a mesma velocidade que a busca sequencial.&lt;/p&gt;

&lt;p&gt;Como as tabelas hash são arrays (possuem um tamanho fixo), não conseguimos adicionar mais elementos que a quantidade de espaços disponíveis. Para resolver isso, precisamos criar uma tabela maior que a original e realocar os elementos para essa nova tabela. A isso damos o nome de resize. É importante mencionar que, os elementos não serão alocados nas posições originais, pois ao criar uma nova tabela, precisamos criar uma nova função hash (já que o tamanho do array mudou e a função usa esse número como base). A criação dessa nova função é chamada de rehash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Árvores&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uma árvore é uma estrutura de dados bidimensional, não linear e constituída de nós que representam um modelo hierárquico (armazenam os dados com base em relações de dependências). Elas são formadas por nó, raiz e folhas. Seu elemento inicial é chamado de raiz e seus filhos são chamados de folhas. &lt;/p&gt;

&lt;p&gt;A altura de um nó é a distância desse nó até a raiz. Um conjunto de nós com a mesma profundidade é denominado nível da árvore e a maior profundidade de um nó é a altura ou profundidade máxima da árvore. E o ponteiro de um nó é a distância do nó até a raiz. A árvore é sempre estruturada através de uma ordem (por exemplo, se os elementos da esquerda forem menores que o elemento raiz, os elementos da direita serão maiores que ele). Em uma árvore, cada elemento possui três informações: o seu próprio valor, um ponteiro para o nó da esquerda e outro ponteiro para o nó da direita. Quanto mais relações um elemento tem, mais ponteiros para os nós ele terá. Quando um elemento não tem um próximo elemento associado a ele, ele é chamado de nó folha. Seja x um vértice (nó) de uma árvore com raiz (r), temos a ancestralidade da árvore como:&lt;/p&gt;

&lt;p&gt;• Ancestral: é qualquer nó y no caminho de r a x;&lt;br&gt;
• Descendente: x é uma descendente de y se y é ancestral de x;&lt;br&gt;
• Filho: x é filho de y se ele tem é um descendente direto; &lt;br&gt;
• Pai: é o ancestral mais próximo. A raiz é o único nó sem pai;&lt;br&gt;
• Folha: é um nó sem filhos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m60HuWgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l59jl2agk7bsczkklgl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m60HuWgf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l59jl2agk7bsczkklgl.jpg" alt="Image description" width="789" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Árvore de busca binária (BST)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A árvore binária ocorre quando cada nó tem, no máximo, dois filhos. Neste tipo de árvore, caso ela tenha 0 ou 1 filho, o ponteiro para o lado sem filhos terá o valor null, sendo que os do lado esquerdo serão sempre menores que ele e os do lado direito, serão sempre maiores que ele.&lt;/p&gt;

&lt;p&gt;Em uma árvore binária ordenada (onde os elementos na árvore estão ordenados), para remover um elemento, precisamos verificar se o elemento a ser removido possui um filho ou não. Caso não possua, basta removê-lo da árvore. Mas, caso possua ramificações, precisamos trazer o elemento mais próximo do elemento que será removido (pois não podemos deixar em espaço vago). Para isso, precisamos percorrer a árvore (a partir do elemento removido) tudo para a esquerda e, depois, tudo para a direita. Existem três formas de se percorrer uma árvore binária:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--330SLMkk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qoytqvle97hkvtr0ruy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--330SLMkk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qoytqvle97hkvtr0ruy.jpg" alt="Image description" width="622" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Árvore AVL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Árvore AVL é uma árvore binária de busca balanceada, que tenta minimizar o número de comparações efetuadas no pior caso para uma busca. Contudo, para garantir essa propriedade, é preciso reconstruir a árvore para seu estado ideal a cada operação sobre seus nós (inclusão ou exclusão), o que causa um aumento no tempo computacional. Neste tipo de árvore, cada nó precisa de 2 bits de memória adicionais, o que acaba tomando mais espaço que a árvore rubro-negro (que falarei em seguida). O fator de balanceamento de um nó em uma árvore binária é a diferença de altura entre as subárvores da direita e da esquerda, dado pela fórmula: Fb = Hd − He. Onde Hd é a altura da subárvore à direito do nó e He é a altura da subárvore à esquerda, sendo que, a direita terá uma altura positiva e a esquerda terá uma altura negativa. Quanto maior for o fator de balanceamento, significa que a árvore está mais desbalanceada para a direita, e quanto mais negativo o fator de carga, mais desbalanceada para a esquerda a árvore está. Em uma árvore AVL, o fator de balanceamento de cada nó deve ficar entre 1 e -1. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KSByFSMG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgeylm21rau7mdx10iob.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KSByFSMG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgeylm21rau7mdx10iob.jpg" alt="Image description" width="419" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como o nó folha é o último elemento, seu fator de balanceamento sempre será 0. Quando precisamos inserir um novo elemento, sempre vamos inseri-lo a partir de um nó folha, o que afetará o fator de balanceamento do seu elemento pai. Quando uma árvore AVL possui um fator de balanceamento maior que 2 ou menor que -2, precisamos realizar um desbalanceamento da árvore. Caso o fator de balanceamento seja menor que -2, precisamos fazer uma rotação para direita para balanceá-la. Vamos ver um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMCdLs27--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyxffxhdhzgohijc16he.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMCdLs27--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyxffxhdhzgohijc16he.jpg" alt="Image description" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso o fator de balanceamento seja maior que 2, precisamos fazer uma rotação para esquerda, vide exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4P6KlLkt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbleaioq2nzxc5koi1iw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4P6KlLkt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbleaioq2nzxc5koi1iw.jpg" alt="Image description" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dependendo do balanceamento da árvore, precisamos primeiro fazer uma rotação para direita, seguido de outra para a esquerda, para não ultrapassar o fator máximo de balanceamento. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KTRmJ-ia--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1g2ionsigjyjp0f65ma.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KTRmJ-ia--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q1g2ionsigjyjp0f65ma.jpg" alt="Image description" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em alguns casos, vamos precisar fazer primeiro uma rotação para a esquerda, depois outra para a direita. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sBmWwhlx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jz8w0q6p1lsz36fxcma.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sBmWwhlx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jz8w0q6p1lsz36fxcma.jpg" alt="Image description" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Árvore Rubro-Negra (RB Tree)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O node (nó) da árvore rubro-negra contém um campo extra de um bit que pode ser 0 ou 1 (representando a cor). O node raiz é sempre preto e, por padrão, todo node novo será da cor vermelha. Mas, depois de inserido na árvore, precisamos checar a cor do pai e dos filhos (pois um node vermelho só pode ter pais e filhos da cor preta). Se, depois de inserir um novo elemento, essa regra não estiver sendo seguida, precisamos repintar os nodes para rebalancear a árvore. Todo node no final da árvore (as folhas) que terminariam com os ponteiros sendo nulo, precisam apontar para um node de serviço chamado null node (isso é necessário para que eles sigam a regra de ordem das cores). Em uma representação gráfica, parece que temos vários null nodes no final, mas eles são apenas um ponteiro para um único null node (sendo representado dessa forma para uma melhor visibilidade da árvore, graficamente).&lt;/p&gt;

&lt;p&gt;Se contarmos os nodes entre a raiz e o node nulo, deve sempre ter o mesmo número de nodes pretos (o que ocorre apenas se a árvore tiver a altura balanceada). Para balancearmos a árvore, precisamos fazer a rotação dos nós não-balanceados e, essa rotação, tem complexidade O(1), independentemente do tamanho da árvore.&lt;/p&gt;

&lt;p&gt;Neste tipo de árvore, precisamos de apenas um bit a mais de espaço extra para cada node, além dos ponteiros para o node nulo de cada folha. O tempo de inserção é um pouco mais alto, na ordem de grandeza de logaritmo, em comparação com a árvore desbalanceada. A busca nesse tipo de árvore é similar a árvore binária e, a remoção, é um pouco mais lenta, visto que é necessário checar se precisamos rebalancear a árvore após cada remoção. As árvores rubro-negras e as árvores AVLs têm o objetivo de chegar em uma árvore de procura binária, só que balanceada, oferecendo o menor tempo médio de procura binária.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Árvore B (B-Tree)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As árvores B são estruturas utilizadas para implementar tabelas de símbolos muito grandes, além de serem auto balanceadas. Ao contrário das árvores binárias que vimos anteriormente, nesse tipo de árvore os node podem ter n filhos. Essa estrutura é utilizada para armazenar grande quantidade de dados em disco e em memória secundária, sendo muito utilizada em banco de dados e em sistemas de arquivos, que manipulam grandes conjuntos de dados. Ela tenta equilibrar o custo de processamento com o custo de sistemas de busca e indexação, onde é utilizada para criar índices que permitem a recuperação rápida e eficiente de dados. Vejamos um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QKETWLOt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1a5a7qw0t6qeajrtfsxi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QKETWLOt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1a5a7qw0t6qeajrtfsxi.jpg" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Árvore B+ (B+ Tree)&lt;/strong&gt;&lt;br&gt;
As árvores B+ (B plus tree) são um tipo de árvore B, onde os nodes não contêm os valores em sim, mas sim, apontam para os nós folhas, que contém os valores que queremos armazenar (os nós pais terão apenas as chaves que identificam esses valores). Esse tipo de árvore é utilizado em todos sistemas que utilizam armazenamento orientado a blocos, como no armazenamento de dados em disco, por exemplo. Vamos ver um exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zcNqkHP---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d3pxq24hc3umcmvwt9id.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zcNqkHP---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d3pxq24hc3umcmvwt9id.jpg" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grafos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O grafo é uma estrutura de dados composta de vértices (ou nós) e arestas (ou arcos), em que cada aresta conecta dois vértices. Grafos sem laços ou arestas múltiplas (ou paralelas), são chamados de grafos simples. A ordem de um grafo é a quantidade de vértice que ele possui. O número de vezes que as arestas incidem sobre o vértice v é chamado de grau do vértice v, sendo que, o laço conta como dois graus. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tTLmUaC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qxyhp8tfcm1925vz8669.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tTLmUaC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qxyhp8tfcm1925vz8669.jpg" alt="Image description" width="560" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No &lt;strong&gt;grafo direcionado&lt;/strong&gt;, as arestas possuem uma direção específica e, cada vértice terá um grau de entrada (quantidade de arestas que entram no vértice) e um grau de saída (quantidade de arestas que saem de um vértice). Um passeio (ou percurso) é uma sequência de arestas do tipo (V0, V1) ,(V1, V2) ,...,(VS − 1,VS) . Sendo que, V0 é o início do passeio e o V1 é o fim, e  S é o comprimento de passeio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AhqmYjDk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdxvt6crc2pl33by4h80.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AhqmYjDk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdxvt6crc2pl33by4h80.jpg" alt="Image description" width="734" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já no &lt;strong&gt;grafo não-direcionado&lt;/strong&gt;, não há uma direção específica para percorrê-lo. O grafo pode possuir um peso, que é um valor, seja na aresta ou no nó. O grafo é utilizado, por exemplo, para calcular a rota mais rápida entre dois pontos em um sistema de GPS, onde cada vértice/nó poderia representar as esquinas e as arestas seriam as ruas). As representações de um grafo podem ser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Representação Gráfica: é representado através de pontos e linhas, como nas imagens acima;&lt;/li&gt;
&lt;li&gt;Relação de Vértices e Arestas: é representado matematicamente como, por exemplo: V = {6A,6B,7A,7B}; &lt;/li&gt;
&lt;li&gt;Matriz de Adjacências: é representado por uma matriz, onde cada linha é representada por um vértice e, cada coluna, também vai representar um vértice. Quando um vértice se conectar a outro, vamos marcar o um naquela posição. Caso contrário, marcamos o 0. 
Vejamos um exemplo: &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BRLNH8G7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzjxv78bwjhqfjte1m0q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BRLNH8G7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzjxv78bwjhqfjte1m0q.jpg" alt="Image description" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso a diagonal principal da matriz de adjacências só possua números 0, significa que o grafo não possui laços. E, caso o grafo possua arestas múltiplas, teremos valores maiores que um. Caso a matriz seja espelhada, ou seja, se a dividirmos em duas partes cortando pela diagonal principal e ambas as metades sejam iguais, indica que a matriz é simétrica e que estamos diante de uma matriz de adjacências simples de um grupo não direcionado. Além disso, nas linhas, temos o grau de saída e, na coluna, temos o grau de entrada.&lt;/p&gt;

&lt;p&gt;4 - Lista de Adjacências: ocorre quando criamos uma lista encadeada para cada um dos vértices de um grafo. Por exemplo, o vértice A têm arestas com o B e o C. Quando temos um laço, representamos chamando o vértice de forma recursiva, como no caso de D, que têm relação com E e com ele mesmo.&lt;/p&gt;

&lt;p&gt;Um vértice de grau 0 é chamado de isolado e, um de grau 1, é chamado de pendente (ou folhas). O menor grau de um vértice em G é o grau mínimo, denotado δG, e o maior é o grau máximo, denotado Δ(G) . Um grupo é considerado conexo se existir um caminho entre qualquer par de vértices, caso contrário, ele é chamado de desconexo. Por fim, podemos dizer que dois vértices estão conectados se existe um caminho entre eles no grafo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Busca (ou Pesquisa) em Largura&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para percorrer um grafo, precisamos definir primeiro o vértice. Em seguida, podemos utilizar a busca em largura ou a busca em profundidade para percorrê-lo. A busca em profundidade ocorre quando pegamos um vértice e vamos percorrendo os demais vértices, de acordo com a sequência do grafo. Já na busca em largura, buscamos apenas os vizinhos mais próximos daquele vértice e, quando não houver mais vizinhos, elegemos um novo vértice como centro das buscas e recomeçamos o processo, até percorrermos todos os elementos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QLh9UYkx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pa6vlpt0t7bewatr69pm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QLh9UYkx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pa6vlpt0t7bewatr69pm.jpg" alt="Image description" width="615" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algoritmo de Dijkstra&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O algoritmo de Dijkstra é utilizado quando queremos encontrar o caminho mais rápido entre dois vértices, em um grafo com pesos (peso é um número associado a cada aresta deste grafo). Um grafo com pesos é chamado de grafo ponderado ou valorado, e um grafo sem pesos é chamado de grafo não ponderado ou não valorado. Um ponto importante é que esse algoritmo só vai funcionar se todos os pesos do grafo forem positivos. Se o grafo tiver pesos negativos, é necessário utilizar o algoritmo de Bellman-Ford. A complexidade de tempo em um caso geral é O(V²), onde V é o número de vértices. Esse algoritmo tem quatro passos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Encontre o vértice mais "barato". Esse é o vértice em que você consegue chegar no menor tempo possível;&lt;/li&gt;
&lt;li&gt;Verifique se há um caminho mais barato para os vizinhos desse vértice. Caso exista, atualize os custos dele;&lt;/li&gt;
&lt;li&gt;Repita até que você tenha feito isso para cada vértice do grafo;&lt;/li&gt;
&lt;li&gt;Calcule o caminho final.
Vamos ver um exemplo de grafo em que podemos aplicar este algoritmo:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tGep_PAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lx44stfsw0rcaldt9pb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tGep_PAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lx44stfsw0rcaldt9pb.jpg" alt="Image description" width="603" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algoritmo de Bellman-Ford&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um algoritmo que encontra o caminho mais curto em um grafo direcionado ponderado com pesos negativos, que funciona de forma similar ao algoritmo de Dijkstra. Ele começa definindo a distância de todos os vértices do grafo em relação ao vértice de origem como infinito, exceto para o vértice de origem, que é definido como 0. Em seguida, o algoritmo atualiza a distância de todos os vértices no grafo iterativamente, relaxando as arestas do grafo uma a uma, até que não haja mais atualizações a serem feitas. Este algoritmo é muito utilizado em redes de computadores (para calcular a rota mais curta em uma rede), sistema de transporte, rede de distribuição de energia, processamento de imagem, entre outros.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algoritmos Gulosos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os algoritmos gulosos são utilizados em problemas que não têm um algoritmo de solução rápidas (problemas NP-completo). Esses algoritmos enxergam apenas um passo de cada vez ao invés de se concentrar no todo, as duas premissas principal deste algoritmo são:&lt;/p&gt;

&lt;p&gt;• Sempre procurar a solução ideal em um dado passo;&lt;br&gt;
• E executar o passo.&lt;/p&gt;

&lt;p&gt;Os problemas NP-completos são problemas complexos e de difícil resolução, onde não existe um algoritmo que consiga resolvê-lo de forma rápida. Um exemplo é o problema do caixeiro-viajante, que falarei a seguir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problema do Caixeiro-Viajante (Traveling Salesman)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suponha que um caixeiro viajante tenha de visitar n cidades diferentes, iniciando e encerrando sua viagem na primeira cidade. Suponha, também, que não importa a ordem com que as cidades são visitadas e que de cada uma delas pode-se ir diretamente a qualquer outra. O problema do caixeiro viajante consiste em descobrir a rota que torna mínima a viagem total. Se ele precisar percorrer três cidades, precisamos de apenas seis operações para descobrir qual a melhor rota. Mas se tivermos cinco cidades, seriam necessárias 120 operações, e se fossem 8 cidades, seriam necessárias 40430 operações para calcularmos a melhor rota! &lt;br&gt;
Podemos ver que, à medida que a quantidade de cidades a se percorrer sobe, as operações sobem de forma exponencial, inviabilizando o cálculo da rota em um problema que possua com centenas ou milhares de cidades. Por conta disso, esse problema tem uma performance de O(n!). Vamos ver como ficaria um exemplo de rotas ao passar por determinadas cidades nos Estados Unidos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nDBcmQAI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9lz7wf9nr2059z2yren.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nDBcmQAI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9lz7wf9nr2059z2yren.png" alt="Image description" width="560" height="420"&gt;&lt;/a&gt;&lt;br&gt;
Fonte: &lt;a href="https://nature.berkeley.edu/getz/dominance/GA/gads/gadsdemos/html/traveling_salesman_demo.html"&gt;https://nature.berkeley.edu/getz/dominance/GA/gads/gadsdemos/html/traveling_salesman_demo.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;K-Vizinhos mais próximos (KNN)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O algoritmo dos k-vizinhos mais próximos é utilizado na classificação (classificar em grupo) e também na regressão (adivinhar uma resposta, como um número). Este algoritmo tenta classificar cada amostra de um conjunto de dados avaliando sua distância em relação aos vizinhos mais próximos. Se os vizinhos mais próximos forem majoritariamente de uma classe, a amostra em questão será classificada nesta categoria. Ao trabalhar com esse algoritmo, é muito importante saber escolher as características certas para serem comparadas, que são:&lt;/p&gt;

&lt;p&gt;• Características diretamente correlacionados aos objetos que você está tentando recomendar (como filmes, por exemplo);&lt;br&gt;
• Características imparciais (por exemplo, se as únicas opções fornecidas aos usuários forem séries de drama, esta avaliação não fornecerá nenhuma informação útil em relação a animes).&lt;/p&gt;

&lt;p&gt;Este algoritmo é muito utilizado em sistemas de recomendações como, por exemplo, em plataformas de streaming de vídeo e aprendizado de máquina. Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--by5vwrG0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mj3a1h8184kgsxwpjm7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--by5vwrG0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mj3a1h8184kgsxwpjm7w.png" alt="Image description" width="643" height="535"&gt;&lt;/a&gt;&lt;br&gt;
Fonte: &lt;a href="https://medium.com/@msremigio/aprendizagem-baseada-em-inst%C3%A2ncias-knn-7e2c6f0778bc"&gt;https://medium.com/@msremigio/aprendizagem-baseada-em-inst%C3%A2ncias-knn-7e2c6f0778bc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Estrutura de Dados é um assunto complexo, que todo programador acaba tendo contato em algum momento da sua carreira. Este artigo cobriu apenas os conceitos básicos de algoritmos e estruturas de dados. Dito isto, pretendo trazer a implementação de algumas dessas estruturas de dados em Java ou Kotlin, para alinhar a teoria e prática, em artigos futuros. Quase todas as imagens deste artigo foram desenhadas por mim, utilizando a ferramenta Excalidraw e as imagens e o gif que peguei da internet estão referenciados na próxima legenda. Fiquem à vontade para comentarem sobre eventuais erros que encontrarem neste artigo ou apenas para opinarem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências Utilizadas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Livro Entendendo Algoritmos: Um Guia Ilustrado Para Programadores e Outros Curiosos - Autor Aditya Y. Bhargava&lt;br&gt;
Livro Estruturas de Dados e Seus Algoritmos - Autores Jayme Luiz Szwarcfiter e Lilian Markenzon&lt;br&gt;
Artigo Tabelas Hash - Autor João Arthur Brunet - Link: &lt;a href="https://joaoarthurbm.github.io/eda/posts/hashtable/"&gt;https://joaoarthurbm.github.io/eda/posts/hashtable/&lt;/a&gt;&lt;br&gt;
Artigo O que é e como funciona o algoritmo KNN? – Link: &lt;a href="https://didatica.tech/o-que-e-e-como-funciona-o-algoritmo-knn/"&gt;https://didatica.tech/o-que-e-e-como-funciona-o-algoritmo-knn/&lt;/a&gt;&lt;br&gt;
Artigo Tudo o que você precisa saber sobre estruturas de dados em árvore - Autor TK - Link: &lt;br&gt;
&lt;a href="https://www.freecodecamp.org/portuguese/news/tudo-o-que-voce-precisa-saber-sobre-estruturas-de-dadosem-arvore/"&gt;https://www.freecodecamp.org/portuguese/news/tudo-o-que-voce-precisa-saber-sobre-estruturas-de-dadosem-arvore/&lt;/a&gt;&lt;br&gt;
Artigo Aprendizagem Baseada em Instâncias KNN – Autor Matheus Remigio – Link: &lt;a href="https://medium.com/@msremigio/aprendizagem-baseada-em-inst%C3%A2ncias-knn-7e2c6f0778bc"&gt;https://medium.com/@msremigio/aprendizagem-baseada-em-inst%C3%A2ncias-knn-7e2c6f0778bc&lt;/a&gt;&lt;br&gt;
Canal Fábio Akita - O que vem DEPOIS do Hello World | Consertando meu C - &lt;a href="https://www.youtube.com/watch?Fv=9GdesxWtOgs&amp;amp;ab_channel=FabioAkita"&gt;https://www.youtube.com/watch?Fv=9GdesxWtOgs&amp;amp;ab_channel=FabioAkita&lt;/a&gt;&lt;br&gt;
Canal Fábio Akita - Hello World Como Você Nunca Viu! | Entendendo C - &lt;a href="https://www.youtube.com/watch"&gt;https://www.youtube.com/watch&lt;/a&gt;? v=9GdesxWtOgs&amp;amp;ab_channel=FabioAkita&lt;br&gt;
Canal Fábio Akita - Árvores: O Começo de TUDO | Estruturas de Dados e Algoritmos - &lt;a href="https://www.youtube.com/watch"&gt;https://www.youtube.com/watch&lt;/a&gt;? v=9GdesxWtOgs&amp;amp;list=RDCMUCib793mnUOhWymCh2VJKplQ&amp;amp;index=12&amp;amp;ab_channel=FabioAkita&lt;br&gt;
Canal Professor Douglas Maioli - Playlist Estrutura de Dados - &lt;a href="https://www.youtube.com/watch?v=twvgnfOnVQ&amp;amp;list=PLrOyM49ctTx_AMgNGQaic10qQJpTpXfn_&amp;amp;index=1&amp;amp;ab_channel=ProfessorDouglasMaioli"&gt;https://www.youtube.com/watch?v=twvgnfOnVQ&amp;amp;list=PLrOyM49ctTx_AMgNGQaic10qQJpTpXfn_&amp;amp;index=1&amp;amp;ab_channel=ProfessorDouglasMaioli&lt;/a&gt;&lt;br&gt;
Canal Professor Douglas Maioli - Playlist de Teoria de Grafos - &lt;a href="https://www.youtube.com/watch"&gt;https://www.youtube.com/watch&lt;/a&gt;?&lt;br&gt;
v=T6yKp82k9vM&amp;amp;list=PLrOyM49ctTxxtyVeuO7ylclgXHd4ws9a&amp;amp;index=2&amp;amp;ab_channel=ProfessorDouglasMaiol Canal 2Guarinos - Playlist Estrutura de Dados com Java - &lt;a href="https://www.youtube.com/watch"&gt;https://www.youtube.com/watch&lt;/a&gt;? v=8zVdz6TyV_c&amp;amp;list=PLTLAlheiUm5FRR5BNn4iBFwzYHiNq2Iv2&amp;amp;ab_channel=2Guarinos&lt;br&gt;
Canal Loiane Groner - Playlist Curso Estrutura de Dados e Algoritmos Java - &lt;a href="https://www.youtube.com/watch?v=N3K8PjFOhy4&amp;amp;list=PLGxZ4Rq3BOBrgumpzzl8kFMw2DLERdxi&amp;amp;ab_channel=LoianeGroner"&gt;https://www.youtube.com/watch?v=N3K8PjFOhy4&amp;amp;list=PLGxZ4Rq3BOBrgumpzzl8kFMw2DLERdxi&amp;amp;ab_channel=LoianeGroner&lt;/a&gt;&lt;/p&gt;

</description>
      <category>datastructures</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Resumo estudos AZ-900</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Sun, 13 Mar 2022 16:52:39 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/resumo-estudos-az-900-12l3</link>
      <guid>https://dev.to/guilhermemanzano/resumo-estudos-az-900-12l3</guid>
      <description>&lt;p&gt;Estou estudando para a prova de certifação Cloud da Azure (AZ-900) e resolvi compartilhar minhas anotações de estudo, espero que sejam úteis para quem for fazer a prova também&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Módulo 01: Cloud Concepts&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Capex Expenditure (CapEx) — Gasto de Capital x Operational Expenditure (OpEx) — Gasto Operacional&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para a Nuvem Pública é quase sempre do tipo OpEx, que é quando eu gasto em serviços de acordo com a necessidade. Já no CapEx, é quando é feito um gasto com arquitetura física.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MODELOS DE NUVEM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nuvem Pública é quando alguém, alguma empresa é dona da infra, que precisa ser conectada via uma rede segura. Nuvem privada é quando é operado pela própria empresa&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Módulo 02: Core Azure Services&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;COMPONENTES DE ARQUITETURA&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Region representam uma coleção de datacenters, existem 54 regiões no mundo para a Azure. Nem todas as features estão disponíveis em todas as regiões, algumas são especificações de algumas regiões.&lt;br&gt;
Region Pair diz que cada região possui um par em outra região, garantindo replicação automática dos dados, em caso de queda uma das regiões terá prioridade para voltar, as atualizações são feitas em apenas uma região do par e replicada se ela for bem-sucedida e, geralmente, os pares estão na mesma região geográfica ou país, com exceção do Brasil.&lt;/p&gt;

&lt;p&gt;Geography são grupos de regiões, categorizadas como America, Europa, Asia Pacífico, Middle East e Africa. Elas contêm duas ou mais regiões&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OPÇÕES DE DISPONIBILIDADE (SLA)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Single VM tem SLA de 99.9%;&lt;br&gt;
Availability Sets (Protege de falhas em Data Centers) tem SLA de 99.5%; Availability Zones (Zona de VMs) tem SLA de 99.99%;&lt;br&gt;
Region Pairs (evita falhas em geral).&lt;br&gt;
Availability Sets é composto de duas features que é preciso configurar: Update domains (UD) que serve para agentar manutenção, performace ou updates de segurança e Fault domains (FD) que provê uma separação fisica de workloads entre diferentes máquinas em um datacenter&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource Groups&lt;/strong&gt; é qualquer coisa que você provisionar na Azure (banco de dados, VM, web, etc), pode ser criado por grupos, áreas, projetos, etc. Se você aplicar segurança em um nível pai, todas as VMs do grupo vão herdar aquela segurança&lt;br&gt;
Azure Resource Manager (ARM) é uma camada de gestão que habilita a gerenciar as coisas na Azure (criar, configurar, gerenciar, deletar, permissionar recursos)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE COMPUTE (Entrega serviços sob demanda)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure VMs (maquinas virtuais): é um serviço do tipo IaaS;&lt;br&gt;
· VM scale sets: ajudam na escalabilidade automática;&lt;br&gt;
· App services: é um serviço do tipo PaaS, que oferece build, deploy and scale;&lt;br&gt;
· Functions: é um código que executa determinadas tarefas, disparados através de eventos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONTAINER SERVICES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os containers services são ambientes virtualizados onde fazemos o deploy de containers (imagens) e que podem ser de dois tipos:&lt;br&gt;
· Azure Container Instances (ACI): Conseguimos subir uma imagem qualquer;&lt;br&gt;
· Azure Kubernetes Service (AKS): Plataforma de kubernetes gerenciado pela Microsoft (orquestrador de containers).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE NETWORK SERVICES (serviços de rede)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure Virtual Network (VNET): permite comunicação entre recursos/componentes da Azure;&lt;br&gt;
· Azure Load Balancer: recebe acessos do usuário e faz o balanceamento de carga (tráfego) entre as aplicações;&lt;br&gt;
· VPN Gateway: é a maneira que existe de habilitar a comunicação entre o mundo On Promisse as VNET (da nuvem Microsoft);&lt;br&gt;
· Azure Application Gateway: é um outro tipo de loadbalancer, porém, na camada de aplicação. Ele pode trabalhar em conjunto com o load balancer do cloud provder e também vai distribuir o tráfego pelo pool dos servidores (baseado em outros tipos de informação, como a rota, por exemplo);&lt;br&gt;
· Content Delivery Network (Rede de entrega de conteúdo): cria uma cópia (faz cash) de infomarmação da aplicação, por exemplo, em pontos físicos (perto dos seus clientes de onde está vindo aquele request).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE DATA CATEGORIES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Structured data: Qualquer tipo de dato que seja aderente a Schema;&lt;br&gt;
· Semi-structured data: Dados que não são dependentes de schema rígido (dados NoSQL);&lt;br&gt;
· Unstructured data: Qualquer tipo de arquivo (imagem, vídeo, áudio, etc)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE STORAGE SERVICE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· IaaS (Disks): é um disco virtual que vai colocar na VMs, muito utilizado para quem quer migrar do On Promisse para a Cloud;&lt;br&gt;
· IaaS (Files): SMB e acesso REST (compartilhador), acesso em qualquer lugar, acesso seguro;&lt;br&gt;
· PaaS (Containers): é para armazenar qualquer tipo de dado e o pagamento é pelo o que for usado e pelas operações de leitura, escrita, etc;&lt;br&gt;
· PaaS (Tables): é para armazenamento de informação do tipo NoSQL;&lt;br&gt;
· PaaS (Queues): é para se trabalhar com mensagens (fila).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE DATABASE SERVICES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure Cosmos DB: é um banco de dados NoSQL da Microsoft globalmente distribuído (é possível migrar informações de uma conta para qualquer outra região);&lt;br&gt;
· Azure SQL Database: é um banco relacional como serviço (DaaS) baseado na última versão estável do Microsoft SQL Server;&lt;br&gt;
· Azure Database Migration: serviço de migração de SQL e NoSQL mais antigos para mais novos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;INTERNET OF THINGS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure IoT Central: é um sistema completo que permite que você desenvolva sua aplicação IoT de ponta a ponta;&lt;br&gt;
· Azure IoT Hub: serviço gerenciado para hub de mensagens, que trabalha no modelo de publish-subscribe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BIG DATA AND ANALYTICS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure SQL Data Warehouse: é um serviço de Data Warehouse as a Service (processamento paralelo e massivo de queries);&lt;br&gt;
· Azure HDInsight: baseado no Hadoop, para processar grande volume de dados (Cluster as a Service);&lt;br&gt;
· Azure Data Lake Analytics: job analítico sob demanda que simplifica big data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ARTIFICIAL INTELLIGENCE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure Machine Learning service: provê um ambiente cloud para desenvolver, testar, treinar, deploy, gerenciar e monitorar modelos de machine learning;&lt;br&gt;
· Azure Machine Learning Studio: é um colaborativo wokspace visual onde podemos construir, testar e fazer o deploy de soluções de machine learning sem escrever código (drag-and-drop).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SERVLESS COMPUTING&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure Functions: é codificar aplicações e rodá-las na cloud;&lt;br&gt;
· Azure Logic Apps: é um serviço cloud que ajuda você a automatizar e orquestrar tarefas, processos de negócio e fluxos de trabalho quando precisar integrar apps, dados, sistemas e serviços (drag-and-drop);&lt;br&gt;
· Azure Event Grid: baseado em eventos (utiliza publish-subscribe) e atua entre o que você está ouvindo e disparar uma ação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DEVOPS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure DevOps services: tem integração com todas as ferramentas disponíveis na Azure, incluindo pipelines, Git, Kanban, etc;&lt;br&gt;
· Azure DevTest Labs: permite criar rapidamente ambientes no Azure enquanto minimiza o desperdício e custo (laboratório de teste);&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE MANAGEMENT TOOLS (ferramentas de gerenciamento)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;· Azure portal;&lt;br&gt;
· Azure PowerShell and Azure Command-Line Interface (CLI);&lt;br&gt;
· Azure Cloud Shell;&lt;br&gt;
· Azure mobile app;&lt;br&gt;
· Azure Rest API;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE ADVISOR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ele varre seu Azure e dá dica em diversas áreas de como melhorar a segurança, disponibilidade, desempenho, custo, etc;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Módulo 03: Security, privacy, compliance and trust&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DEFENSE IN DEPTH&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Diz respeito a um sistema em camadas de segurança (segurança física, identidade e acesso, perímetro, rede, computador, aplicação, dados), que provê múltiplos níveis de proteção&lt;br&gt;
AZURE DISTRIBUTED DENIAL OF SERVICE (DDoS) protection&lt;br&gt;
Proteção contra ataques de DDoS, através das proteções básicas e uso de inteligência artificial&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NETWORK SECURITY GROUPS (NSGs)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Filtra tráfego de rede entre recursos Azure na Azure Virtual Networks (conjunto de regras que habilitam ou não a comunicação entre os componentes do Azure)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APPLICATION SECURITY GROUPS (ASGs)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É quando agrupamos os nossos servidores para aplicar as regras de segurança de maneira comum a todos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CHOOSING AZURE NETWORK SECURITY SOLUTIONS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure suporta combinar estes quatro tipos de segurança vistos anteriormente de maneira conjunta. Na camada de perímetros é possível proteger sua rede com o Azure DDoS Protection e Azure Firewall. E na camada de rede (networking layer) permite apenas tráfego passar entre recursos de rede com o Network Security Group (NSG).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE ACTIVE DIRECTORY (AD)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Serviço de gestão de acesso (autenticação), gestão de aplicativos, gerenciamento de aplicações, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE MULTI-FACTOR AUTHENTICATION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provê segurança adicional para suas identidades, através do pedido de dois os mais elementos para uma autenticação completa (como algo que você sabe, que você tem ou que você é).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE SECURITY CENTER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Protege os clientes Azure de ameaças, ele varre seu ambiente, monitora-o e dá dicas de como melhorá-lo, sob diversos aspectos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE KEY VAULT (AKV)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Local central para armazenar tudo que diz respeito a certificados, secrets, key, credenciais, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE INFORMATION PROTECTION (AIP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Proteção de documentos e e-mails (definindo e aplicando regras)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE ADVANCED THREAT PROTECTION (Azure ATP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um serviço que ajuda a identificar identidades comprometidas dentro do ambiente Azure, além de ações maliciosas (internas ou externas). E também tentativas de login. Eles possuem um portal dedicado para monitorar e responder as atividades suspeitas, sensores instalados sob seu controle e os serviços cloud rodam na infraestrutura da Azure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lição 5: Governança&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE POLICY&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implementar políticas para organizar o ambiente Azure (segurança, documentos, provisionar recursos apenas em determinada região, etc)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;POLICY INITIATIVES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;São agrupamento de políticas, que valem para um mesmo grupo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RESOURCE LOCKS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cadeados para proteger recursos de deleção acidental ou modificações.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SUBSCRIPTION GOVERNANCE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Governança de assinaturas, onde existem três aspectos que precisamos nos atentar:&lt;br&gt;
· Biling: monitoramento do custo de cada serviço;&lt;br&gt;
· Acess Control: serve como fronteira de controle de acesso;&lt;br&gt;
· Subscription Limits: criar limites dentro da subscrição, tanto financeiro quanto limite de objetos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lição 6: Monitorando e reportando na Azure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TAGS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;São utilizadas para monitorar e reportar em cima dos recursos Azure. As tags ajudam a criar metadados de qualquer coisa provisionada, baseado em sistema de base e valor. É possível criar até 50 tags para cada objeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE MONITOR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Coleta, analisa e age na telemetria que estão na Cloud ou On Promise, monitorando as máquinas virtuais (performance e outras métricas). Além disso, há o log de atividade, qualquer tentativa de criar, alterar ou deletar qualquer coisa no Azure vai gerar uma atividade log. Integrando o Azure Monitor com outros seriços Azure é possível aumentar a capacidade de monitoramento dos dados, através de análises, criação de alertas, criar visualizações (gráficos) e integrar com outros sistemas para visualizar as métricas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE SERVICE HEALTH&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avalia a saúde dos serviços Azure que estão sendo monitorados (site Azure Status).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lição 7: Privacidade, compliance e padrões na proteção de dados&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;COMPLIANCE TERMS AND REQUIREMENTS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Azure suporta mais de 90 padrões/normas de indústrias e governos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MICROSOFT PRIVACY STATEMENT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Site que mostra todas as políticas de privacidade que a Microsoft utiliza para lidar com os dados dos produtos e serviços coletados, que explica quais dados a Microsoft processa, como ela processa e qual o propósito deles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TRUST CENTER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repositório central da Azure mostrando tudo sobre segurança, privacidade, compliance, políticas, features e práticas através dos produtos cloud da Microsoft.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SERVICE TRUST PORTAL (STP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Outro portal da Microsoft que traz informações sobre a confiança dos dados (compliance data).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;COMPLIANCE MANAGER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dashboard que mostra o status de compliance e como melhorar a proteção dos seus dados, além do status de compliance que você deveria ter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE GOVERNMENT SERVICES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apresentam as normas específicas para o governo dos Estados Unidos, mostrando para entidades governamentais informações específicas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE CHINA 21VIANET&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apresentam as normas específicas e regulatórios do governo chinês.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Módulo 04: Azure Pricing and Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lição 2: Azure subscription&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE SUBSCRIPTION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É o que permite a gente se autenticar e ter acesso as funcionalidades do Azure, permitindo gerenciar várias assinaturas de uma única conta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TIPOS DE SUBSCRIÇÃO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os tipos são: Grátis; Pago por uso; Acordo empresarial e Estudante. E uma conta pode ter várias subscrições. Os limites da conta gratuita são: 200 dólares de crédito ou 30 dias grátis, doze meses de serviços populares de alguns produtos e os produtos que são sempre grátis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GRUPOS DE GERENCIAMENTO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Eles estão acima das subscrições, ou seja, qualquer coisa que você aplique nesse nível a subscrição vai herdar. É possível ter grupos de gerenciamentos dentro de outros.&lt;br&gt;
Lição 3: Planning and managing costs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;COMPRANDO PRODUTOS E SERVIÇOS AZURE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Há três tipos principais de tipos de clientes:&lt;br&gt;
· Enterprise: acordo empresarial que é possível negociar níveis de descontos e créditos Azure;&lt;br&gt;
· Web direct: portal direto de acesso para a Azure, acessando o site oficial;&lt;br&gt;
· Cloud solucton providers (CSPs): parceiros Microsoft que fazem o meio de campo entre as empresas e a Microsoft.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FATORES QUE AFETAM OS CUSTOS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Há três principais fatores que afetam os custos:&lt;br&gt;
· Resource Type: também tem relação com os recursos escolhidos de cada serviço;&lt;br&gt;
· Services: tem a ver com os tipos de clientes e serviços usados;&lt;br&gt;
· Location: cada localidade cobra um valor diferente, mesmo dentro do mesmo país;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ZONAS PARA PROPÓSITO DE CONTAS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tem relação com cobrança de dados de saída, ou seja, qualquer query feita em uma região é cobrada (outbound traffic), variando conforme as zonas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CALCULADORA DE PREÇO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oferece uma aplicação web para calcular uma estimativa dos gastos de infraestrutura e produtos Azure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TOTAL COST OF OWNERSHIPT CALCULATOR (TCO)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É um outro tipo de calculado de custo que ajudam a estimar a economia quando você vai migrar o seu Datacenter para a nuvem Azure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MINIMIZANDO CUSTOS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tópicos importantes para uma melhor economia financeira: performar (use as calculadoras para calcular os valores), monitorar, usar (use limites de despesa para acompanhamento de consumo, usar reservas sempre que possível e usar os benefícios da Azure híbrida — licenças Windows), escolha (escolher localidade de baixo custo), manter (mantenha-se atualizado sobre todas as ofertas de assinaturas) e aplicar (tagear qualquer recurso que você provisionar, para monitorar melhor);&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AZURE COST MANAGEMENT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ferramenta nativa para controlar os custos, visualizando relatórios, alertas, recomendações, orçamentos, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OPÇÕES DE SUPORTE DISPONÍVEIS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Existem cinco categorias de suporte:&lt;br&gt;
· Basic: disponível para todas as contas Microsoft Azure;&lt;br&gt;
· Developer: Ambientes não produtivos, suporte via email em horário comercial;&lt;br&gt;
· Standard: Ambiente de Produção. Suporte 24x7 via email e telefone;&lt;br&gt;
· Professional Direct: Dependências críticas de négocio. Suporte 24x7 via email e telefone;&lt;br&gt;
· Premier&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KNOWLEDGE CENTER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repositório central de informações sobre Azure&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lição 5: AZURE SERVICE LEVEL AGREEMENTS (SLAs)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SERVICE LEVEL AGREEMENTS (SLAs)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SLAs documentam termos específicos para cada padrão de serviço. Ele indica para cada serviço, qual o tempo de uptime, latência prevista, throughput, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SLAs FOR AZURE PRODUCTS AND SERVICES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Precisamos saber que tipo de target estamos buscando para aquele serviço (uptime, latência, conectividade, etc), qual é o range (99.9% to 99.999%) e qual é o percentual que a Microsoft vai devolver de crédito mensalmente se falhar&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SLAs PARA APLICAÇÕES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O SLA é requerimento para se construir uma aplicação, para desenhar a melhor solução para disponibilidade e resilência, é preciso também estabelecer metas de disponibilidade, como mean time to recovery (MTTR) e mean time between failures (MTBF).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PUBLIC AND PREVIEW FEATURES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uma vez que o projeto novo está na fase de teste, antes de ir para produção, ele é colocado em uma fase chamado private preview (que é quando alguns clientes selecionados testam a aplicação) e, depois de aprovado, ele vai para a fase de public preview (que é disponibilizada para todo mundo, mas ainda em preview). Depois de passar por essas etapas, ela vai para a etapa de produção General Availability (GA).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Padrões e Estilos de Arquitetura de Software</title>
      <dc:creator>Guilherme Manzano</dc:creator>
      <pubDate>Wed, 23 Feb 2022 22:54:03 +0000</pubDate>
      <link>https://dev.to/guilhermemanzano/padroes-e-estilos-de-arquitetura-de-software-1498</link>
      <guid>https://dev.to/guilhermemanzano/padroes-e-estilos-de-arquitetura-de-software-1498</guid>
      <description>&lt;p&gt;&lt;strong&gt;Arquitetura&lt;/strong&gt; é um conjunto de partes que compõem o sistema e o ambiente em que está inserido, suas responsabilidades e seus relacionamentos.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Estilos e Padrões Arquiteturais de Software&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os sistemas seguem um estilo de organização estrutural, ou seja, são como "templates" para arquiteturas concretas que expressam uma organização estrutural, apresentando um conjunto pré-definidos de subsistemas e suas responsabilidades. &lt;/p&gt;

&lt;p&gt;Um &lt;strong&gt;padrão arquitetural&lt;/strong&gt; é uma solução que já foi estudada, testada e documentada de um problema recorrente. O modelo ajuda na tomada de decisões do projeto de software, como qual será sua utilidade e as funções e relacionamentos de cada subsistema, ou seja, é quem define a estrutura fundamental do programa.&lt;/p&gt;

&lt;p&gt;Segue um resumo dos principais estilos e padrões de arquitetura de software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Camadas&lt;/strong&gt;: estrutura aplicações que podem ser decompostas em grupos de subtarefas hierarquicamente. Cada camada oferece serviço à camada acima dela, e serve como cliente da camada inferior. Suas vantagens são: permite particionar problemas complexos em uma sequência de passos incrementais; mudanças em uma camada afetam, no máximo, duas camadas adjacentes; permite projetos baseados em níveis crescentes de abstrações; suas desvantagens são: é difícil encontrar níveis corretos de abstração; nem todos os sistemas são facilmente estruturas em forma de camadas. Exemplo: Modelo OSI;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cliente-Servidor&lt;/strong&gt;: é baseado em programas servidores (aguarda mensagens, executa serviços e retorna resultados) e programas clientes (estabelece conexão, envia mensagens para servidor, aguarda mensagens de resposta). Vantagens: utilização dos recursos do servidor; escalabilidade; aumentando a capacidade computacional do servidor; Desvantagens: aumenta a complexidade e os custos de comunicação;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tubos e filtros&lt;/strong&gt;: divide a tarefa entre várias etapas de processamento sequencial, pois a saída de uma etapa é a entrada da etapa seguinte. Cada etapa de processamento é implementada pelo filtro, que consome e entrega os dados de forma incremental, em vez de todos os dados de uma só vez. O fluxo de dados é implementado pelos tubos. Exemplo: compilador; Vantagens: flexibilidade na troca de filtros e recombinação; eficiência em processamento em paralelo; vários filtros consumindo e produzindo dados em paralelos. Desvantagens: gerenciamento de erros e ausência de um estado global compartilhado;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Micro serviços&lt;/strong&gt;: refere-se a um estilo de arquitetura para construção de software que decompõe o domínio de negócio em pequenos blocos, transaccionalmente consistentes e com contexto próprio;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Publish-Subscriber&lt;/strong&gt;: é um modelo de comunicação assíncrono e fracamente acoplado, no qual uma aplicação gera eventos que serão processados por outras aplicações que tiverem interesse nele;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Representational State Transfer (REST)&lt;/strong&gt;: é um estilo de arquitetura utilizado para fornecer padrões entre sistemas de computador na web, facilitando a comunicação entre os mesmos. Neste estilo, a implementação do cliente e do servidor pode ser feita de forma independente, sem que um conheça o outro. A grande vantagem é que isso permite que o código de um dos lados pode ser alterado sem afetar o outro;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Arquitetura Orientada a Serviços (SOA)&lt;/strong&gt;: é um tipo de design de software que torna os componentes reutilizáveis, utilizando interfaces de serviços como uma linguagem de comunicação em uma rede. Ou seja, o SOA integra os componentes de software que foram implementados e são mantidos separadamente, permitindo que eles se comuniquem e trabalhem juntos para formar aplicações que funcionam em sistemas diferentes;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model-View-Controller&lt;/strong&gt;: neste estilo a aplicação é dividida em 3 camadas - Model (contém as funcionalidades principais e os dados), View (camada de exibição dos dados aos usuários), Controller (liga a model e a view, trafegando os dados entre as camadas). Vantagens: organização clara das abstrações, permite múltiplas views em um mesmo modelo e as views são sincronizadas. Desvantagens: aumenta a complexidade;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Broker&lt;/strong&gt;: estrutura sistemas distribuídos que precisam interagir através de invocação remota de serviços (desacopla servidores de clientes e coordena a comunicação entre componentes). Exemplo: serviços de busca. Vantagens: transparência de localização dos serviços, flexibilidade, portabilidade. Desvantagens: sobrecarga de processamento;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Arquitetura Orientada a Eventos&lt;/strong&gt;: é um método de desenvolvimento de software para criar aplicações que se comunicam ou se integram de forma assíncrona com outras aplicações e sistemas através de eventos. Ela é composta por produtores de eventos (enviam as mensagens), canais de eventos e seus consumidores (consomem as mensagens). A utilização de canais de eventos como intermediário permite que os produtores sejam dissociados dos consumidores, permitindo assim, que eles possam agir independentemente uns dos outros (o que possibilita maior escalabilidade e tolerância a falhas). Além disso, a organização de aplicações envolvendo eventos também permite que o código seja executado de forma assíncrona e automática, sem interação do usuário;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CQRS&lt;/strong&gt; (Comand and Query Responsibility Segregation): este padrão é sobre separar a responsabilidade e escrita e leitura de seus dados. A ideia é segregar as responsabilidades da aplicação em Command (operações que modificam o estado dos dados na aplicação) e Query (operações que recuperam informações dos dados na aplicação);&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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