<?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: Natália Oliveira</title>
    <description>The latest articles on DEV Community by Natália Oliveira (@nfo94).</description>
    <link>https://dev.to/nfo94</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%2F59463%2F24657515-ec00-4437-a5e2-ae409dc8bd36.png</url>
      <title>DEV Community: Natália Oliveira</title>
      <link>https://dev.to/nfo94</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nfo94"/>
    <language>en</language>
    <item>
      <title>Resumindo características da linguagem Python</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Mon, 03 Mar 2025 19:18:43 +0000</pubDate>
      <link>https://dev.to/nfo94/resumindo-caracteristicas-da-linguagem-python-378h</link>
      <guid>https://dev.to/nfo94/resumindo-caracteristicas-da-linguagem-python-378h</guid>
      <description>&lt;p&gt;Python é uma linguagem de &lt;strong&gt;propósito geral, multiparadigma, de alto nível, de tipagem dinâmica, fortemente tipada, que roda em diferentes plataformas e é interpretada (com um passo de compilação)&lt;/strong&gt;. Vamos destrinchar esses conceitos utilizando principalmente o livro "Python in a Nutshell", documentações da linguagem e as aulas incríveis do &lt;a href="https://www.youtube.com/@Dunossauro" rel="noopener noreferrer"&gt;Eduardo Mendes&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Propósito geral e alto nível&lt;/li&gt;
&lt;li&gt;Tipagem dinâmica e forte&lt;/li&gt;
&lt;li&gt;Linguagem intepretada com um passo de compilação&lt;/li&gt;
&lt;li&gt;Roda em diferentes plataformas&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Propósito geral e alto nível
&lt;/h2&gt;

&lt;p&gt;Consideramos Python como de &lt;strong&gt;propósito geral&lt;/strong&gt; pois suas características são úteis para diversas áreas de software. Iremos encontrar Python em REST APIs, scripts, machine learning, análises estatísticas, web scraping, etc. Python já era bastante utilizada na área de inteligência artificial e, com o &lt;em&gt;boom&lt;/em&gt; dos LLMs, me parece que muitas áreas tornamram a linguagem como o padrão de uso. Se procurarmos por vagas de machine learning engineer, data engineer e por aí vai é muito comum encontrar o Python como requisito.&lt;/p&gt;

&lt;p&gt;A consideramos como de &lt;strong&gt;alto nível&lt;/strong&gt; por possuir um &lt;strong&gt;alto nível de abstração&lt;/strong&gt;, se afastando bastante da linguagem de máquina que um computador de fato entende. Além disso, a linguagem é bem "parecida" com uma leitura em inglês, o que é muito atrativo. Outros exemplos de linguagens de alto nível são Java, JavaScript, entre outras.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Tipagem dinâmica e forte
&lt;/h2&gt;

&lt;p&gt;Acredito que esse tópico gere uma certa dúvida. Eu particularmente precisei revisitar esses conceitos diversas vezes até entender. O Python tem &lt;strong&gt;tipagem dinâmica&lt;/strong&gt;, ou seja, não te obriga a declarar o tipo de uma variável, você pode declarar um &lt;code&gt;a = "texto"&lt;/code&gt; e o interpretador, por debaixo dos panos, vai inferir que a variável é do tipo &lt;code&gt;string&lt;/code&gt;. Ao mesmo tempo, é &lt;strong&gt;fortemente tipada&lt;/strong&gt;, pois o interpretador mantém controle dos tipos de variáveis que estão sendo declaradas no programa, coisa que não acontece numa linguagem fracamente tipada como o JavaScript, por exemplo. No JavaScript você pode fazer &lt;code&gt;'x' + 3&lt;/code&gt; resultar em &lt;code&gt;'x3'&lt;/code&gt; e não dará erro; se você tentar fazer isso em Python verá:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;TypeError: can only concatenate str &lt;span class="o"&gt;(&lt;/span&gt;not &lt;span class="s2"&gt;"int"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; to str
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sobre ser dinamicamente tipada e fortemente tipada ao mesmo tempo, vejamos esse excerto do &lt;a href="https://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language" rel="noopener noreferrer"&gt;Wiki do Python&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Python é fortemente tipado, pois o interpretador mantém o controle de todos os tipos de variáveis. Ele também é muito dinâmico, pois raramente usa o que sabe para limitar o uso de variáveis. Em Python, é responsabilidade do programa usar funções internas como &lt;code&gt;isinstance()&lt;/code&gt; e &lt;code&gt;issubclass()&lt;/code&gt; para testar tipos de variáveis ​​e uso correto. Python tenta ficar fora do seu caminho enquanto fornece tudo o que você precisa para implementar a verificação de tipo forte.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Falando em &lt;em&gt;"Python tenta ficar fora do seu caminho enquanto fornece tudo o que você precisa para implementar a verificação de tipo forte"&lt;/em&gt;, pegamos o gancho para falar de "type hints" ou "&lt;strong&gt;type annotations&lt;/strong&gt;". Type annotations são uma feature mais "recente" (&lt;a href="https://peps.python.org/pep-0484/" rel="noopener noreferrer"&gt;PEP 484 de de 2014&lt;/a&gt;) do Python que nos permite "anotar" o tipo de dado que estamos lidando no código. Do livro "Python in a Nutshell":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anotar seu código Python com informações de tipo é uma etapa opcional que pode ser muito útil durante o desenvolvimento e a manutenção de um projeto grande ou de uma biblioteca. Verificadores de tipo estático e ferramentas lint ajudam a identificar e localizar incompatibilidades de tipo de dados em argumentos de função e valores de retorno. IDEs podem usar essas anotações de tipo (também chamadas de dicas de tipo) para melhorar o preenchimento automático e fornecer documentação pop-up. Pacotes e frameworks de terceiros podem usar anotações de tipo para personalizar o comportamento do tempo de execução ou para gerar automaticamente código com base em anotações de tipo para métodos e variáveis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;É daí que temos libs como &lt;a href="https://github.com/python/mypy" rel="noopener noreferrer"&gt;&lt;code&gt;mypy&lt;/code&gt;&lt;/a&gt; e &lt;a href="https://github.com/pydantic/pydantic" rel="noopener noreferrer"&gt;&lt;code&gt;Pydantic&lt;/code&gt;&lt;/a&gt; para checar e validar tipos.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Linguagem intepretada com um passo de compilação
&lt;/h2&gt;

&lt;p&gt;O Python é considerado &lt;strong&gt;interpretado&lt;/strong&gt; com um passo de &lt;strong&gt;compilação&lt;/strong&gt;: uma linguagem ser interpretada significa que ela não é executada diretamente pela máquina, e sim é interpretada e executada por outro programa. Aqui temos um &lt;em&gt;catch&lt;/em&gt; que confunde bastante, pois na real o CPython, que é o interpretador referência da linguagem, é um compilador de&lt;br&gt;
bytecode e também interpretador: ele compila o código Python e, com o resultado dessa compilação (que chamamos de bytecode ou &lt;em&gt;intermediary language&lt;/em&gt;), roda esse resultado diretamente em uma máquina virtual. Recomendo fortemente a &lt;a href="https://www.youtube.com/watch?v=pxfZTAJDipY&amp;amp;t=946s" rel="noopener noreferrer"&gt;aula do Eduardo Mendes&lt;/a&gt;&lt;br&gt;
sobre isso:&lt;/p&gt;

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

&lt;p&gt;Aí você pode ser perguntar:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Mas qual a diferença entre esse processo e um processo de compilação de um linguagem como Java?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para ficar mais claro, veja que em uma linguagem 100% compilada a linguagem intermediária é transformada para linguagem de máquina, para então ser rodada pelo computador de fato. Para ilustrar um pouco melhor esse processo acompanhe esse slide da &lt;a href="https://www.youtube.com/watch?v=pxfZTAJDipY&amp;amp;t=789s" rel="noopener noreferrer"&gt;aula do Eduardo Mendes&lt;/a&gt;:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Roda em diferentes plataformas
&lt;/h2&gt;

&lt;p&gt;Se você viu essa afirmação em algum lugar, perceba que isso é dito pois você pode escrever e rodar um programa Python em qualquer computador moderno que tenha Python instalado. "Instalar" significa ter o interpretador Python para rodar a linguagem. Em computadores com sistema operacional baseado em Unix, como Linux e MacOS, é comum que o interpretador Python já esteja instalado em alguma versão. No caso de Windows, até onde sei, você precisa ir lá no site no Python, baixar e instalar o interpretador.&lt;/p&gt;




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com.br/Python-Nutshell-English-Alex-Martelli-ebook/dp/B0BRYRD295/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.1GrWfyxGQAtCbzVANdvWpIhsGUkbRmGr3ML2fa9FpnVxX7qlzYtkK_-90G8PkjJjgguYnjmO95dfRwRYpxq_KjO-ymBjxJUMcAg0yT84C9fRPz6a3nBhAM8lSKKrFvF3hGlrKUcoMemKQysYgZfgry8iAMCF6td3Hxgn2ewAhQvhBTq7b2NgOPNn467iWo-9eJLV3dAY2oXJNBL2Z2V7IeuYejkKm7JPGhoPmIqu3keAuUEQVk088S7ZYYoK5WLR9GjCa2Do0sSEha3oWfbMz-FHIk0a9t-LOEqeVc2r-Tg.w512AtUskmia2OZ6AWaNIM0RwlmCrPBH-66aAFwmhEI&amp;amp;qid=1732842474&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Python in a Nutshell&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language" rel="noopener noreferrer"&gt;Why is Python a dynamic language and also a strongly typed language&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/3265357/compiled-vs-interpreted-languages" rel="noopener noreferrer"&gt;StackOverflow Compiled vs. Interpreted Languages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=pxfZTAJDipY" rel="noopener noreferrer"&gt;Como o interpretador do Python funciona? Live de Python #218&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
    </item>
    <item>
      <title>Leituras técnicas de 2024</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Wed, 29 Jan 2025 12:44:37 +0000</pubDate>
      <link>https://dev.to/nfo94/leituras-tecnicas-de-2024-2ld2</link>
      <guid>https://dev.to/nfo94/leituras-tecnicas-de-2024-2ld2</guid>
      <description>

&lt;p&gt;&lt;a href="https://nfo94.github.io/2024/12/31/leituras-t%C3%A9cnicas-de-2024.html" rel="noopener noreferrer"&gt;&lt;em&gt;Texto originalmente publicado aqui&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Faz algum tempo que comecei a perceber minha falta de paciência para prestar atenção em conteúdos escritos, coisa que não acontecia antes. Acredito que fiquei mal acostumada a buscar informações em vídeo e, quanto mais avanço na área, mais percebo que conteúdos&lt;br&gt;
escritos às vezes são a única fonte de informação para determinados assuntos. Com isso, no início de 2024, me propus a ler mais livros, para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fortalecer o foco e forçar a atenção em conteúdos mais difíceis de se consumir;&lt;/li&gt;
&lt;li&gt;Exercitar o "não" a conteúdos de rede social/de conteúdo (exemplo: antes de ir dormir, ler, ao invés de ficar olhando o celular);&lt;/li&gt;
&lt;li&gt;Exercitar meu vocabulário (inglês e português);&lt;/li&gt;
&lt;li&gt;Ter contato inicial com temas específicos;&lt;/li&gt;
&lt;li&gt;Exercitar a reflexão.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resolvi unir o últil ao agradável e separar alguns livros técnicos para ler durante o ano, por completo. Essas foram as leituras que fiz em 2024:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing Data-Intensive Applications&lt;/li&gt;
&lt;li&gt;Artificial Intelligence Basics&lt;/li&gt;
&lt;li&gt;Database Internals&lt;/li&gt;
&lt;li&gt;Criando Microsserviços&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E por fim separei algumas menções honrosas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Designing Data-Intensive Applications
&lt;/h2&gt;

&lt;p&gt;De longe o melhor que eu li no ano. É o tipo de livro para ser relido pelo menos umas 3 vezes, e isso é o que pretendo fazer. Foi graças a esse livro que consegui entender uma apresentação sobre um tema super complexo envolvendo escalabilidade em escrita de dados de um time no trabalho. É também uma excelente forma de revisão sobre sistemas distribuídos, assunto que geralmente é tratado na faculdade.&lt;/p&gt;

&lt;p&gt;O autor, Martin Kleppmann, escreve muito bem e a leitura não é de um &lt;em&gt;feeling&lt;/em&gt; pesado acadêmico, é algo simples de ler com vários exemplos de tecnologias usadas hoje em dia. Não é a toa que esse livro já vendeu muito e tem trocentos bons reviews em várias plataformas. Recomendo a leitura.&lt;/p&gt;

&lt;p&gt;Obs.: tem uma nova edição desse livro no forno prevista para dezembro de 2025 e espero que essa edicão seja traduzida para o português.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Designing-Data-Intensive-Applications-Reliable-Maintainable-ebook/dp/B06XPJML5D/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.uKKyaNHuzp5D7DchHIgwHtXJv8tk_RD31Eetcm-YM317qEFGsD6Tq8EXynYuUFgG2U60SDWNVKMMtCkNGeHhauCgDO8KiyDBJAzyg0MdQ6aGORrnUGA7gle55HimQdB3T8YzwQb40LbedZQP54uTEbspTsMH-UnTcrtVoQbhIdU5cvoyTQIrTj_zWpH4xHMdcxEbgbW1ubwle-L7DjEjcBOey9AOAMbyEvm3zcNgMl-fO3MpzZoiiTGurcOwM1KA0BuW4e3Ri9V1IfqQS9dLGi4jEevLKujETxx4WK0vTk9Vpz5zKvZjAyhDw_cOLdgOg2vAvOtaApmfh2CnoEDBFD_mv7zo8XnR9wzdBV7lX8MYBrDPnboDwCIYyaWtFHkR3eg0fjDAPQID-vLAwe9CsMm4ZFzEihannjz_9ujWM5cjzkpuGYBEYSLaLWQNOEPh.imRmUHBJGkV1Btbrug3EDo_o23CRxdYv9YwPmwwS--A&amp;amp;qid=1735228860&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Link para o livro Designing Data-Intensive Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Artificial Intelligence Basics
&lt;/h2&gt;

&lt;p&gt;Fui de uma leitura bastante técnica e primorosa para um livro OK. Esse livro é bom para deixar a gente refletindo e ter algumas noções básicas sobre o assunto, mas não sei se é uma leitura útil para todas as pessoas da área tech. Para alguém de fora da área pode ser mais interessante. No meu caso foi últil para refletir sobre o assunto, apenas como leitura superficial mesmo, mas achei o último capítulo meio abaixo do resto. No geral, pessoalmente valeu a pena, por ser uma leitura leve e com alguns conceitos introdutórios.&lt;/p&gt;

&lt;p&gt;Vale frisar que esse livro foi publicado em 2019, antes do hype de generative AI, então o autor, Tom Taulli, não estava apenas surfando a onda.&lt;/p&gt;

&lt;p&gt;Se você é da área tech e quer ler algo profundo sobre AI, vá ler &lt;a href="https://www.amazon.com.br/Artificial-Intelligence-Modern-Approach-English-ebook/dp/B092QVWSNX/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.p6JTNZQOtrZx-r90u2ah_vAjmfHiZ7Ncd2HnQlawuao_QUC6esfn_bjTAxGihdxFrlwwSfT4w-arxRxtxEHbmyfnUybF39eu_zZ-qd1q5pWtHpPp-_4eqMOiY1bMVsebhKEyrR8zquobm6gq33-Kbt7CBbM-dFjAJ8OgTc3Ha3Gg7CkOOXBCkkP-4bkDMrLCSI-EbWfCN8NpGbRrpkgYfBA_Czygi8-IZOZxuipU-KBoR8zxeJ9muY8c4zsw13dYXaWIeiHByOk2FM9pm7x17f8d-os9uU1LI9nri549-bbfPICKVgTsF3yudjCyNO-GIglRnlrNkfkc4G1oRt-gxd1TGDdZdUvd5O9CXDlwwrbGavY-lFHoP_6IA5A2zZhGdhRrFPwbUHzL2TbessByuumh4MZzbP3-iOZV7Umly2yPfKFWJkYXqIlQunO4zGAJ.ev32P58-2YIzcDv8CDAMDh4-EXNW90ztOiMiXcoxkPo&amp;amp;qid=1735229802&amp;amp;sr=8-2" rel="noopener noreferrer"&gt;Norvig e Russell&lt;/a&gt;. Se quer colocar a mão na massa com algo atual, estou vendo bons reviews sobre &lt;a href="https://www.amazon.com.br/Build-Large-Language-Model-Scratch/dp/1633437167/ref=tmm_pap_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.f_1HBi0zdrW6-jWiZT7RBHljTbR18kiiPVoB6pRvXlbJ8xNArtegOgTY80rMoraAm5jtsYcbvKBNWRzWkzDg4HZN5AgjTz5MIrIQWu_UOlnIKgXI4mBpsQ31wpgohh-ZD7i4jkqc6oXjhcjEmg8ImuRFFnutFXU6Bu0lpuXoE2ihGF642EQUx9czikkzViRAfrtWJY9QPCUMeXlzDJSVzkSZB5wLp7iXiFfUF5Q6GXuntzYElWgeQC295z71BUf_m6TOO2n3pUxfOfptJydpl-HTRzY5k0rQ38eyf5ot7F4ITaE6NSH7SxNAJ8qRWZkoE0CqrZc-axbbYZnPZX9ap_UE-twprAZqEmwJrjoz1ddKwz_nZNyOVej8s65TGEMWrgnmPzBX3aL_kwCai20vtr1eGJ_XGDz8BQZ5l39fdbrtzFoUqMCjeiQUZ6i0Mxwi._On-gcHhocJ7kyszKXq1VlWT9OpQcuVDKQ4eLikMJRQ&amp;amp;qid=1735230107&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Build a Large Language Model (from Scratch)&lt;/a&gt; do Sebastian Raschka.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Artificial-Intelligence-Basics-Non-Technical-Introduction-ebook/dp/B07VY31R29/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.jt4CqVTrLNenFCBEI6nCEdIJw-P_AqzN8WZDreOP2ipZYiDjG2ds9s_nPg-P47vstmoVP3NrMiG15aBX2P7GEXSjYjxNsi21buM50tGwWBulGMJQJWETWuO0YYMe9M2XzTMJECwvfLRCRRySi9M2yN5ZSjgjG7709n4Dmt7ovac8DN_BLgTAm1M-t9kl4VxJDQ0xwUWYpOAi5gynZhis2iSCqWWvzZ4v_0mBZgXmAhgBVFpRFOlK5gV-nT8d-pO3uzn3sF7hwCk_9J2edLhDDCdFwZ8rO8jmHV6BpWO_j-zGvEFkV_jo7Kmhc5ig4jbasXKQNjecYmcLJ5aIeBE650zbKgeClOf_5deanxNQ5q4OC9_vo1lY0CeMuUALGZ9BSEZIVAuk-ipHjXoklOl1ApVlc5C8ZaZpYCxbQ3EIEASqMPWsXfNW-O2f4DpxmIbk.1MlPVNtrWiX-rMsupMA5N6GxeCRNSOVR3GArVbhKX14&amp;amp;qid=1735229354&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Link para o livro Artificial Intelligence Basics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Database Internals
&lt;/h2&gt;

&lt;p&gt;É um livro bastante enxuto para os conceitos que trata. Em outras palavras, leitura extremamente difícil para mim, pois me faltavam vários conhecimentos prévios para entender o livro. Exemplo: funcionamento da estrutura de dados b-tree. O livro é pequeno e demorei horrores para terminar, pois estava voltando alguns parágrafos, pesquisando artigos na internet e olhando vídeos no YouTube toda hora para consolidar o entendimento. Felizmente isso me fez encontrar canais bem legais no YouTube como o &lt;a href="https://www.youtube.com/@SpanningTree" rel="noopener noreferrer"&gt;Spanning Tree&lt;/a&gt;, com uma &lt;a href="https://www.youtube.com/watch?v=K1a2Bk8NrYQ" rel="noopener noreferrer"&gt;explicação visual bem legal sobre b-trees&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Recomendo para pessoas curiosas, quem trabalha na área de dados, banco de dados, etc. Pode ser uma leitura útil e interessante, mas vai depender bastante da pessoa. No meu caso posso dizer que valeu a pena, mas definitivamente não foi uma leitura que posso considerar "agradável", já que fiquei empacando.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Database-Internals-Distributed-Systems-English-ebook/dp/B07XW76VHZ/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.pVEOjduOXDM_zskjXBld1F3o9TiB-7TOz4x9sLerf5grnu7lgPObDlyGqkY8N34_afgJlFRYMApte6ej-isrEB6qHh_nAcW0AS6E1e6aUEgwxNkbHqkMIO0mzQhti4TKQdt--mennr4o1Q5Bncqdf0LSODOGAvG7GYyYk7RGZtVN0DZ5RY-IfAoAT92h4SoM6KAXO0i3mWYeOf7uueGZauFRD2WVCf4Su9Lc777IAsTvE1VUlltwu2YjC8Bkeosl_K4CmVbuMII7zIG5_FH11gODGowJaE_lUnK2IzWYp-6-j7wzLV_O6Y_aDNVgKBWe6eROq0HArVdSkRvz_eALQuaIyRxJ6oHN2h9q05m3yMY2HL-RqegcPsr-QqFg3L1nJMu_pzStmCOy9s1boGPsQlfTOUawwrVpvV_NVkaghjilev7H83KNMCpmVwldOwmX.oxIzW6k7ym1iBmbF_JqQxkdvavvTIVU5u83A2DOBRAI&amp;amp;qid=1735230384&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Link para o livro Database Internals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Criando Microsserviços
&lt;/h2&gt;

&lt;p&gt;Livro de referência completa para microsserviços e creio que o livro por si só já tenha esse &lt;em&gt;status&lt;/em&gt;, a julgar pelos reviews e pelas vezes que já vi sendo citado. A leitura foi bem fácil e fluida, não só pela escrita, mas pelo fato da maioria dos temas e tecnologias já fazerem parte do meu dia a dia, ou pelo menos já ouvi falar e está próximo de mim. Li a versão em português e notei alguns erros, além da sensação esquisita de ver alguns termos&lt;br&gt;
traduzidos que eu só vejo em inglês no dia a dia, mas não foi nada que atrapalhasse a leitura.&lt;/p&gt;

&lt;p&gt;Recomendo a leitura.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Criando-Microsservi%C3%A7os-Projetando-Componentes-Especializados/dp/6586057884/ref=tmm_pap_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.dvx4HFxiyI6I07qs7oxjtEYEFK633haephUjCZ4vxYi09x0Dzw5qihvccH3JoSCKpQpIknHQAz36glIWaeJtEoxcFKx6iXgLL0DDX-7a3BM-vz1pqNzK8yc5KmMzAZKHs7PB9QExtMxiWxnMNPZoOglcV4YCfNhsCeV5jM7C8nJxaeoRoIcLUSgdmO11kR4hwEiw1C_IBnbHlyMMEd-ckk8GloqRDzm2bz2ktxIJUquLNH73o6zuXzt4KkHCKip7YGgFk5VtiiwspfKa11HErOnW6yy5koQJMO03pa9Pzyzmy0qqmHehpfg7la-MI53t9pzoq5ht57MEK1yvAJAH_OGZUQB5G5f-eVyJIag9IVaxxA8tM9O_O6pWGZWbKKrX.93vvDhRHRpM26LH-BzkSsj78tQ0-P5pJxHzVSGOOzSA&amp;amp;qid=1735739451&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Link para o livro Construindo Microsserviços&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Menções honrosas
&lt;/h3&gt;

&lt;p&gt;Precisei ler alguns capítulos de uns livros para a pós-gradução, então não li estes por completo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com.br/Cassandra-Definitive-Guide-Revised-Distributed/dp/1492097144/ref=sr_1_2?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=1G9IQ2FQ24KAB&amp;amp;dib=eyJ2IjoiMSJ9.jBo07BQNSuzzYY4HqTN1iz3IAj_vf-b0vv8ucp0WTy8k7JPxLg3KzDwZszfFjb5LYLDYr-i95mq3HXWTFgCffLfgcWZ2X3_yyolAZ5OFh9mkzOM71PqstyDjgiuBTJ6zi0tqF-nAJu6j-_pkUaDdI8n1J3ZMpOFHF5lWyiiCLXJYj78Cn3-XWsyV5_GJOf8Kw-ccxJay0BQz3vH5DDg2iCq-KH_WMbm4ABfJPbiNHB1QTrk_HbCgUlJCYVe5QwqxvZdmYR5brhI8MgxVE3VELwx9S6PVKaaPQKD6m2Qsw50nYyYnNRgBPC9WDGGaWcsQc_BUDd46z3t7PSV2zAQhvDopKrBlS4GFiLEeiYBpCuU-2elvKbPXnrWxTjAAJkar0uPmCeKQka6D9QN9lsU6FLoJ2CAgJoKJ-lZLBW7ctoPTZcIwJfSlS6ijrjQFsS5H.Y4hRmGEepsu669XnnZr9NLpoFO-As-JwCkNg3AejWP4&amp;amp;dib_tag=se&amp;amp;keywords=apache+cassandra&amp;amp;qid=1735224364&amp;amp;sprefix=apachecassandra+%2Caps%2C183&amp;amp;sr=8-2&amp;amp;ufe=app_do%3Aamzn1.fos.e05b01e0-91a7-477e-a514-15a32325a6d6" rel="noopener noreferrer"&gt;Cassandra The Definitive Guide&lt;/a&gt;: livro excelente e completo sobre o Apache
Cassandra. Achei bem complexo entender o Cassandra e esse livro ajudou muito;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com.br/MongoDB-Definitive-Powerful-Scalable-Storage-ebook/dp/B082J7DMBX/ref=sr_1_2?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=3U8GSO108UJ68&amp;amp;dib=eyJ2IjoiMSJ9.WJpjFIYDai0U8v6hRylC75yuoja2kamkMexqW3-bieQGHGBuX5J7exrfFoKWvuZQ_SrLN8dJBOgsdamuUreWjb5ZTHoLM7nXLqWi-sf0z8ck_SVz5r1ccrHU3IJ6rrTW3JHBY-KpOmYPD0C9MAuyVsgbQVlaEfQsArvNSPb98gEYK_WWMfd1wNrTLImu8cKmyCIS2Wez0cI--4Gcda9q6uZcv8udy_W5jmSLFpBHy6Ib6OGrT-gtOgDzYq4XDhhMg7RfUcO1-dkdf5qVEbkygcxGgFY7AZVMZK4srDXVR4I9NC9BQ4rSJJO1Z9HzEXxt176qckpfQuz--eZjK28aYU41qmzKq7_YnJl5EjzficGyzTf8rtnfMTn0FayWcSqGNQQkIUNYv-n93XMtONNSUSg9AouHHWu60bKLFX909-XawEQmtVuFje63hn2O3KKt.ZBo-s-Tk00KMPHHkojkbAQm24h4XRVq_rt0xlD5NdoI&amp;amp;dib_tag=se&amp;amp;keywords=mongodb&amp;amp;qid=1735224395&amp;amp;sprefix=mongod%2Caps%2C174&amp;amp;sr=8-2" rel="noopener noreferrer"&gt;MongoDB The Definitive Guide&lt;/a&gt;: livro completinho sobre MongoDB, me ajudou não só com a parte teórica, mas também tirei várias dúvidas quando estava fazendo o projeto prático.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>livros</category>
    </item>
    <item>
      <title>Infraestrutura para análise de dados com Jupyter, Cassandra, Pyspark e Docker</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Wed, 15 Jan 2025 10:47:46 +0000</pubDate>
      <link>https://dev.to/nfo94/infraestrutura-para-analise-de-dados-com-jupyter-cassandra-pyspark-e-docker-2ap2</link>
      <guid>https://dev.to/nfo94/infraestrutura-para-analise-de-dados-com-jupyter-cassandra-pyspark-e-docker-2ap2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnd4pi217xqjplkxo37rd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnd4pi217xqjplkxo37rd.png" alt="jupyter-notebook" width="800" height="274"&gt;&lt;/a&gt;&lt;br&gt;Imagem retirada do site do Jupyter Notebooks
  &lt;/p&gt;




&lt;p&gt;&lt;a href="https://nfo94.github.io/2024/11/27/infraestrutura-para-analise-de-dados-com-jupyter-cassandra-pyspark-docker.html" rel="noopener noreferrer"&gt;&lt;em&gt;Texto originalmente publicado aqui&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Hoje vou mostrar como configurar um projeto para análise de dados com o Cassandra e o Jupyter Notebook com Pyspark, usando tudo no Docker. Vamos abordar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurando o Apache Cassandra com Docker&lt;/li&gt;
&lt;li&gt;O que é o Spark?&lt;/li&gt;
&lt;li&gt;Configurando o Jupyter com Pyspark no Docker&lt;/li&gt;
&lt;li&gt;Iniciando um sessão Spark conectada no Cassandra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antes de começar, essa é a estrutura de pastas do projetinho:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cassandra-jupyter-spark-python
├── .gitignore
├── Makefile
├── README.md
├── data
│   └── csv-here.md
├── docker-compose.yml
├── jupyter
│   └── Untitled.ipynb
└── pyproject.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode encontrar um projeto similiar a esse, completo, com análise de dados (porcamente feita por mim) no &lt;a href="https://github.com/nfo94/infraestrutura-cassandra-pd" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Configurando o Apache Cassandra com Docker
&lt;/h2&gt;

&lt;p&gt;O Cassandra é um &lt;strong&gt;banco de dados NoSQL decentralizado, com escalabilidade elástica, altamente disponível, tolerante a falhas e orientado a linhas particionadas&lt;/strong&gt;; escrevi um &lt;a href="https://nfo94.github.io/2024/10/27/o-que-e-o-apache-cassandra-e-quando-usar.html" rel="noopener noreferrer"&gt;texto sobre o Cassandra aqui&lt;/a&gt; e você pode verificar a &lt;a href="https://cassandra.apache.org/doc/latest/" rel="noopener noreferrer"&gt;documentação do Cassandra aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para subir o Cassandra com Docker podemos fazer o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cassandra1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cassandra:4.0.14&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cassandra1&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cassandra_network&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_CLUSTER_NAME=cassandra_cluster&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_SEEDS=cassandra1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_DC=datacenter1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_RACK=rack1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/data&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9042:9042"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima estamos criando um node do Cassandra 4.0.14 (versão escolhida para evitar problemas de compatibilidade nesse projeto) numa rede Docker chamada &lt;code&gt;cassandra_network&lt;/code&gt;. Explicando as variáveis de ambiente no &lt;code&gt;environment&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CASSANDRA_CLUSTER_NAME&lt;/code&gt;: define o nome do cluster onde um ou mais nodes do Cassandra irão rodar. Cluster se refere a mais de uma máquina, geralmente para se referir a um sistema distribuído. No “docker-compose” do projeto chamamos de “cassandra_cluster”;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CASSANDRA_SEEDS&lt;/code&gt;: indica os serviços (ou IPs) usados pelo gossip do Cassandra, para adicionar novos nodes ao cluster. O gossip é um protocolo utilizado para manter informações sobre o status dos nodes no cluster, para dar suporte a descentralização e tolerância a particionamento;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CASSANDRA_DC&lt;/code&gt;: define o data center do node, que é um agrupamento lógico de racks. Não é necessário para rodar essa infraestrutura localmente em um notebook, como é o caso atual, mas seria utilizado caso estivéssemos utilizando o Cassandra com o uso adequado a que se propõe;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CASSANDRA_RACK&lt;/code&gt;: define o rack do node, que é um agrupamento lógico de nodes. Novamente, não é necessário para a situação atual, mas seria utilizado em um caso real;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CASSANDRA_ENDPOINT_SNITCH&lt;/code&gt;: define a implementação de snitch que esse node irá utilizar. O snitch provê informações sobre a topologia da rede onde o Cassandra está para redirecionar requisições de forma mais eficiente. Nesse caso aqui configuramos como “GossipingPropertyFileSnitch”, geralmente usado em produção, para considerar as informações de rack e datacenter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O volume &lt;code&gt;./data:/data&lt;/code&gt; serve para que você coloque, por exemplo, arquivos &lt;code&gt;.csv&lt;/code&gt; parte da sua análise de dados. No meu caso, &lt;a href="https://github.com/nfo94/infraestrutura-cassandra-pd" rel="noopener noreferrer"&gt;criei um projeto para a pós-graduação&lt;/a&gt;, onde usei o comando &lt;code&gt;COPY&lt;/code&gt; para repassar os dados tratados do &lt;code&gt;.csv&lt;/code&gt; para o Cassandra.&lt;/p&gt;

&lt;p&gt;Agora, criando um segundo node Cassandra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;cassandra2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cassandra:4.0.14&lt;/span&gt;
  &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cassandra2&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cassandra_network&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_CLUSTER_NAME=cassandra_cluster&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_SEEDS=cassandra1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_DC=datacenter1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_RACK=rack1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch&lt;/span&gt;
  &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/data&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9043:9042"&lt;/span&gt;
  &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cassandra1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode usar somente um node, já que está rodando em seu computador, mas vale lembrar que um node só perde o propósito de uso do Cassandra. Esse banco é feito para ter diversos nodes no cluster.&lt;/p&gt;

&lt;p&gt;Veja que esse segundo node aponta os seeds para o outro node. Isso é para que o &lt;code&gt;cassandra2&lt;/code&gt; se conecte com o &lt;code&gt;cassandra1&lt;/code&gt;, para descrobrir a topologia do cluster e se unir a esse cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é o Spark?
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://spark.apache.org/" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt; é uma engine para engenharia e análise de dados, ciência de dados e machine learning em larga escala, onde é possível rodar para máquinas com um único nó ou cluster. Podemos usar Python, SQL, Scala, Java e R para interagir com o Spark, e aqui nesse projeto usaremos Python, com Pyspark.&lt;/p&gt;

&lt;p&gt;Usos do Spark, segundo sua documentação:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Batch/streaming: unifica o processamento dos dados em lotes e streaming em tempo real, usando Python, SQL, Scala, Java ou R&lt;/li&gt;
&lt;li&gt;Análise de SQL: executa consultas ANSI SQL rápidas e distribuídas para painéis e relatórios &lt;em&gt;ad-hoc&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Ciência de dados em escala: executa Análise Exploratória de Dados (EDA) em dados em escala de petabytes sem precisar recorrer à redução de amostragem&lt;/li&gt;
&lt;li&gt;Aprendizado de máquina: treine algoritmos de aprendizado de máquina em um laptop e use o mesmo código para escalar para clusters tolerantes a falhas de milhares de máquinas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Configurando o Jupyter com Pyspark no Docker
&lt;/h2&gt;

&lt;p&gt;O Jupyter é uma tecnologia para computação interativa onde usamos uma linguagem de programação para, geralmente, fazer análises de dados e experimentos do tipo. Para rodá-lo no Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# Docker Hub Image. Uses spark-3.5.0-bin-hadoop3&lt;/span&gt;
  &lt;span class="na"&gt;jupyter_pyspark&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jupyter/pyspark-notebook:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;juptyer_pyspark&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;JUPYTER_ENABLE_LAB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yes"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8888:8888"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cassandra_network&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./jupyter:/home/jovyan&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cassandra1&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cassandra_network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa imagem do Jupyter já vem com o Spark, mas vale apontar que aqui estamos usando a imagem do &lt;a href="https://hub.docker.com/r/jupyter/pyspark-notebook/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;, que não recebe atualizações e está parada no Spark 3.5.0 e Hadoop 3, e não da &lt;a href="https://quay.io/repository/jupyter/pyspark-notebook" rel="noopener noreferrer"&gt;Quay&lt;/a&gt;, que recebe atualizações. Tive muitos problemas tentando manter a compatibilidade entre as ferramentas, e a imagem do Docker Hub funcionou para o propósito.&lt;/p&gt;

&lt;p&gt;O volume, assim como nos cassandras, é para poder salvar os notebooks no host. O container está na mesma rede que os outros e o &lt;code&gt;JUPYTER_ENABLE_LAB&lt;/code&gt; é para que a gente não precise fazer login ou usar token, bastará abrir o browser no &lt;code&gt;http://localhost:8888&lt;/code&gt;:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Iniciando uma sessão Spark conectada no Cassandra
&lt;/h2&gt;

&lt;p&gt;Com o &lt;code&gt;docker-compose.yml&lt;/code&gt; finalizado, podemos rodar os containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;http://localhost:8888&lt;/code&gt;, abrindo um novo arquivo no Jupyter, vamos importar uma sessão Spark da lib &lt;code&gt;pyspark&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from pyspark.sql import SparkSession
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E configurar a sessão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spark = SparkSession.builder.appName("test").config("spark.jars.packages", "com.datastax.spark:spark-cassandra-connector_2.12:3.5.0").config("spark.cassandra.connection.host", "cassandra1").config("spark.cassandra.connection.port", "9042").getOrCreate()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Muita atenção aqui nessa parte. O código acima está:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Iniciando uma sessão Spark&lt;/li&gt;
&lt;li&gt;Criando um novo "app" (o projeto em si) chamado "test"&lt;/li&gt;
&lt;li&gt;Configurando o Spark com um pacote jar, utilizando um conector de Spark para Cassandra&lt;/li&gt;
&lt;li&gt;Conectando com o serviço Cassandra chamado &lt;code&gt;cassandra1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Configurando a porta da conexão para o 9042, que é onde está nosso container&lt;/li&gt;
&lt;li&gt;Criando a conexão&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note que estamos usando um conector específico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spark-cassandra-connector_2.12:3.5.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos olhar essas versões &lt;a href="https://mvnrepository.com/artifact/com.datastax.spark/spark-cassandra-connector" rel="noopener noreferrer"&gt;no site do Maven&lt;/a&gt;, e aqui nesse ponto foi onde mais topei com erros, especialmente de compatibilidade.&lt;/p&gt;

&lt;p&gt;Se tudo der certo no comando anterior, depois rode esse comando para ver a sessão&lt;br&gt;
ativa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spark.active()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você verá algo assim:&lt;/p&gt;

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




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/_/cassandra/" rel="noopener noreferrer"&gt;Imagem Docker do Cassandra&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/r/jupyter/pyspark-notebook/" rel="noopener noreferrer"&gt;Image Docker do Jupyter com Spark&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://spark.apache.org/" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cassandra</category>
      <category>docker</category>
      <category>pyspark</category>
      <category>jupyter</category>
    </item>
    <item>
      <title>O que é o Apache Cassandra e quando usar?</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Wed, 08 Jan 2025 13:22:40 +0000</pubDate>
      <link>https://dev.to/nfo94/o-que-e-o-apache-cassandra-e-quando-usar-gkf</link>
      <guid>https://dev.to/nfo94/o-que-e-o-apache-cassandra-e-quando-usar-gkf</guid>
      <description>

&lt;p&gt;&lt;a href="https://nfo94.github.io/2024/10/27/o-que-e-o-apache-cassandra-e-quando-usar.html" rel="noopener noreferrer"&gt;&lt;em&gt;Texto originalmente publicado aqui&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Hoje falarei um pouco sobre o Apache Cassandra. Usei como base o livro &lt;a href="https://learning.oreilly.com/library/view/cassandra-the-definitive/9781098115159/" rel="noopener noreferrer"&gt;Cassandra The Definitive Guide&lt;/a&gt;, bastante utilizado para entender sobre a tecnologia, e um pouco do já clássico &lt;a href="https://learning.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/" rel="noopener noreferrer"&gt;Designing Data-Intensive Applications&lt;/a&gt;. Abordarei os seguintes tópicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O que é o Apache Cassandra?&lt;/li&gt;
&lt;li&gt;"Row-oriented": o que isso significa?&lt;/li&gt;
&lt;li&gt;Quando utilizar o Cassandra?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é o Apache Cassandra?
&lt;/h2&gt;

&lt;p&gt;O Cassandra é um &lt;strong&gt;banco de dados NoSQL de código aberto, decentralizado, com escalabilidade elástica, altamente disponível, tolerante a falhas e orientado a linhas particionadas, onde os dados são armazenados em tabelas hash multidimensionais esparsas&lt;/strong&gt;. Vamos discutir esses pontos.&lt;/p&gt;

&lt;p&gt;Bancos NoSQL (&lt;em&gt;not only SQL&lt;/em&gt;) são bancos que não seguem os padrões de bancos relacionais, resolvendo problemas um pouco diferentes (em breve farei um texto sobre isso), sendo mais flexíveis (ou totalmente livres) no quesito de &lt;em&gt;schema&lt;/em&gt; (como os dados são organizados, restrições lógicas como nome de tabelas, campos e seus tipos, etc), também chamados de &lt;em&gt;schemaless&lt;/em&gt; ou de &lt;strong&gt;&lt;em&gt;schema on read&lt;/em&gt;&lt;/strong&gt; (schema reforçado apenas na leitura, e não na escrita como os relacionais). No caso do Cassandra podemos dizer que atualmente ele possui um &lt;em&gt;schema flexível&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O Cassandra é capaz de rodar em várias máquinas como um sistema só, por isso é considerado &lt;strong&gt;distribuído&lt;/strong&gt; e foi feito pensando nisso. Faz pouco sentido rodar o Cassandra em um único nó (&lt;em&gt;node&lt;/em&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Grande parte de seu design e base de código são projetados especificamente não apenas para funcionar em muitas máquinas diferentes, mas também para otimizar o desempenho em vários racks de data center e até mesmo para um único cluster Cassandra em execução em data centers geograficamente dispersos. (CARPENTER and HEWITT, 2022)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O Cassandra também é &lt;strong&gt;descentralizado&lt;/strong&gt; porque cada node é idêntico, no sentido de que nenhum node realiza tarefas especializadas como operações de organização; em outras palavras, o Cassandra possui uma arquitetura &lt;strong&gt;&lt;em&gt;peer-to-peer&lt;/em&gt;&lt;/strong&gt;. Como nenhum&lt;br&gt;
node é especializado podemos dizer que &lt;em&gt;não há um único ponto de falha&lt;/em&gt; aqui (&lt;em&gt;single point of failure&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Ser &lt;strong&gt;elasticamente escalável&lt;/strong&gt; significa que o sistema pode continuar servindo para mais usuários sem degradar a performance, podendo escalar e desescalar perfeitamente, sem problemas.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;alta disponibilidade&lt;/strong&gt; do Cassandra é devido a sua alta capacidade de atender requests. Isso está diretamente relacionado com teorema CAP: assumindo uma situação de &lt;em&gt;partitioning&lt;/em&gt;, o Cassandra prioriza &lt;em&gt;availability&lt;/em&gt; em detrimento de &lt;em&gt;consistency&lt;/em&gt;. Entretanto, vale a pena esclarecer que a &lt;strong&gt;consistência no Cassandra é ajustável (&lt;em&gt;tuneable consistency&lt;/em&gt;, é uma configuração)&lt;/strong&gt;. Em minhas leituras entendi que atualmente o CAP theorem é como &lt;em&gt;knobs&lt;/em&gt;, como se pudéssemos ajustar um pouco mais uma ou outra configuração. Recomendo ler um pouco mais sobre o&lt;br&gt;
teorema CAP no capítulo 9 do Designing Data Intensive Application.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;"Row-oriented": o que isso significa?
&lt;/h2&gt;

&lt;p&gt;Na pesquisa para fazer esse artigo e entender melhor o assunto encontrei informações discrepantes, o que me levou a crer que há muita confusão aqui e talvez seja bom evitar algumas fontes da internet. Felizmente estamos seguindo um livro base. Pela definição de Carpenter e Hewitt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O modelo de dados do Cassandra pode ser descrito como um armazenamento de linha particionado, no qual os dados são armazenados em tabelas hash multidimensionais esparsas. &lt;strong&gt;“Esparso” significa que para qualquer linha dada você pode ter uma ou mais colunas, mas cada linha não precisa ter todas as mesmas colunas que outras linhas como ela (como em um modelo relacional)&lt;/strong&gt;. &lt;strong&gt;“Particionado” significa que cada linha tem uma chave de partição exclusiva&lt;/strong&gt; usada para distribuir as linhas em vários armazenamentos de dados. (CARPENTER and HEWITT, 2022)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ou seja, quando for ter uma "imagem mental" dos dados no Cassandra faz sentido pensar numa linha de banco relacional, dadas as devidas diferenças: cada linha pode ter uma ou mais colunas e não precisa ter as mesmas colunas que outra linha, além de ter uma chave de partição única.&lt;/p&gt;

&lt;p&gt;Sobre a confusão de termos que citei anteriormente, você pode ter visto o termo &lt;em&gt;column oriented&lt;/em&gt;, mas o livro base desse texto aborda isso:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O Cassandra tem sido frequentemente chamado de banco de dados orientado a colunas ou colunar, mas isso não é tecnicamente correto. O erro é baseado na confusão entre termos que soam semelhantes. Um banco de dados orientado a colunas é aquele em que os dados são armazenados por colunas, ao contrário de bancos de dados relacionais, que armazenam dados em linhas (daí o termo orientado a linhas). Bancos de dados orientados a colunas, como Apache HBase ou Apache Kudu, são projetados para casos de uso analítico. (CARPENTER and HEWITT, 2022)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Quando utilizar o Cassandra?
&lt;/h2&gt;

&lt;p&gt;O Cassandra pode ser um bom fit para o seu projeto caso você precise lidar com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grandes deployments&lt;/strong&gt;: você precisa de muitos e muitos nodes para a sua aplicação, com a expectativa de escalar muito de forma fácil&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Muita escrita, estatística e análise&lt;/strong&gt;: sua aplicação precisa de muita estatística  e muita escrita concorrent, com poucas leituras. Exemplos: pesquisa documentos, uso de redes sociais, recomendações/avaliações, etc&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribuíção geográfica&lt;/strong&gt;: o Cassandra tem suporte para distribuição geográfica de dados &lt;em&gt;built in&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nuvem híbrida e deployment multicloud&lt;/strong&gt;: você precisa fazer deploy não só em múltiplos data centers, mas também em provedores de cloud diferentes. Exemplo: você precisa da maior disponibilidade possível para um aplicativo &lt;em&gt;mission critical&lt;/em&gt; e por isso utiliza mais de um proveador (se houver problemas com um provedor ainda  haverá o outro)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;CARPENTER, Jeff; HEWITT, Eben. &lt;a href="https://www.amazon.com.br/Cassandra-Definitive-Guide-Revised-English-ebook/dp/B09R2BVFB1/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.6zE2HqOAmHI71tyWkGZRDbLPTVrs-GbLZBOVO4zVkXBUEH3ctz8FfXt05MjA4CO2S8fnSYljlMHa8nClsN4iL3ywFW5EwS_HmtLS10Wg8_sqrX3Wx80y6ObXr73DEps1DHnYOyG7i237Qi5p5jyMD0j_1GpC5Es-d8gdXkVzM0B_HtFHtodOr3S8abb0BZwS6SxF_01I5r9795odj2MzwNWxq70m9qHKp17jfQwuCpusLv36CH-BQKp4_VEiZnTq-69CeJRJ773JYazTAykwViGnLMr0XcDidwWQEtZNlGg.6drW06ZASw4T1RAl41weZ1UXAU2Fi2q-uIMgIlf6_-w&amp;amp;qid=1729416247&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Cassandra: The Difinitive Guide&lt;/a&gt;. O'Reilly, 2022.&lt;/p&gt;

&lt;p&gt;KLEPPMANN, Martin. &lt;a href="https://www.amazon.com.br/Designing-Data-Intensive-Applications-Reliable-Maintainable-ebook/dp/B06XPJML5D/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.5pF53c-4K5lBHgnp-yQa_RJqJfJfPBVyDbdON_9Uqa6GrLYGUQ2pqldnzPh0j8kRTLevdzrF8EseH1lUO7IbFLNQwsJVPs9JQTpBzuD8D_Iv6wY54Mu9j3KGdUDt9z8rE2w3iqoqah8RAxd-S5FqB-fNN6RC1X005uYmHxBIgX56gpYuK28W08MAeoVkHt1YVKfJBhWxZnCTSEC2DfMVvRMpxnMjqVdU7TIGyzvhgx3zfHGygMbP_O0SR0jxDmR26VB7o5vOT7vPejc8xhzKJd_kcfUdT8LhuxCaRsH3zWg.LcAAww-jCWt1_AFannzv6PZ49ZiksTv1LGD_vywgoXQ&amp;amp;qid=1729446561&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Designing Data-Intensive Applications&lt;/a&gt;. O'Reilly, 2017.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.ibm.com/topics/database-schema" rel="noopener noreferrer"&gt;What is a database schema? por IBM&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apachecassandra</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Resumo de conceitos de bancos de dados relacionais</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Mon, 06 Jan 2025 10:37:58 +0000</pubDate>
      <link>https://dev.to/nfo94/resumo-de-conceitos-de-bancos-de-dados-relacionais-598j</link>
      <guid>https://dev.to/nfo94/resumo-de-conceitos-de-bancos-de-dados-relacionais-598j</guid>
      <description>

&lt;p&gt;&lt;em&gt;&lt;a href="https://nfo94.github.io/2024/10/20/resumo-de-bancos-de-dados-relacionais.html" rel="noopener noreferrer"&gt;Texto originalmente publicado aqui&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Nesse texto irei abordar de forma resumida alguns conceitos (não é uma lista exaustiva!) que envolvem bancos de dados relacionais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transações (&lt;em&gt;transactions&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;ACID&lt;/li&gt;
&lt;li&gt;Two-phase commit (2PC)&lt;/li&gt;
&lt;li&gt;Schema&lt;/li&gt;
&lt;li&gt;Sharding&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Transações (&lt;em&gt;transactions&lt;/em&gt;)?
&lt;/h2&gt;

&lt;p&gt;Banco de dados relacionais suportam &lt;strong&gt;transações &lt;em&gt;transactions&lt;/em&gt;)&lt;/strong&gt;, que são como uma &lt;strong&gt;unidade de operação completa&lt;/strong&gt; num banco relacional, que executa primeiro "virtualmente" e &lt;strong&gt;permite que a operação seja desfeita (rollback) se qualquer modificação tenha dado errado&lt;/strong&gt;. No caso de dar tudo certo com todos os passos da transação, ela pode ser &lt;strong&gt;comitada (&lt;em&gt;commited&lt;/em&gt;) com segurança no banco&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Em outras palavras, uma &lt;strong&gt;transação pode ser compreendida como uma transformação de estado que possui as propriedades ACID&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;ACID
&lt;/h2&gt;

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

&lt;p&gt;ACID é um acrônimo para atômico, consistente, isolado e durável. Você pode encontrar a expressão &lt;em&gt;ACID compliant&lt;/em&gt; para se referir a um banco que dê suporte a essas propriedades.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atômico (atomicity)&lt;/strong&gt;: significa "tudo ou nada" em uma transação. Se uma transação é executada, todas as operações que ela contém precisam ser um sucesso. Ou todas as operações são um sucesso ou a transação falha (pense em OR exclusivo aqui).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consitente (consistency)&lt;/strong&gt;: uma transação bem sucedida leva os dados de um estado consistente para outro, sem a possibilidade de usuários verem dados diferentes que não fazem sentido juntos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolado (isolation)&lt;/strong&gt;: as transações que forem executadas concorrentemente não afetarão umas as outras. Ou seja, se uma transação tentar modificar os mesmos dados que outra, ela terá que esperar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durável (durable)&lt;/strong&gt;: uma transação bem sucedida não será perdida, por exemplo, caso ocorra algum desastre com o data center que contém o banco.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Two-phase commit (2PC)
&lt;/h2&gt;

&lt;p&gt;Lidar com transações é um pouco mais difícil quando temos grandes cargas, com vários usuários realizando muitas operações no banco, e quando vamos escalar horizontalmente (adicionando mais máquinas e agora lidando com um sistema distribuído) para lidar com essa carga passamos a lidar também com transações distribuídas (&lt;em&gt;distributed transactions&lt;/em&gt;). Com isso, para manter o banco com propriedades ACID, precisamos ter algum gerenciador de transações para conseguir orquestrar essas transações em vários nodes diferentes.&lt;/p&gt;

&lt;p&gt;É aqui que entra a ideia de &lt;strong&gt;two-phase commit, que é um algortimo pensado para lidar com consenso entre nodes (máquinas) em um sistema distribuído&lt;/strong&gt;. O 2PC possui duas fases, duas interações entre hosts: &lt;strong&gt;fase de preparação&lt;/strong&gt; e &lt;strong&gt;fase de commit&lt;/strong&gt;, as quais bloqueiam os recursos associados. Com esse &lt;em&gt;lock&lt;/em&gt; (bloqueio) de recursos já podemos imaginar que algumas operações podem levar muito tempo para terminar.&lt;/p&gt;

&lt;p&gt;Abaixo uma ilustração do livro Designing Data Intensive Application:&lt;/p&gt;

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

&lt;p&gt;O 2PC espera um node responder, mesmo que o node já tenha morrido e, para não ter um loop rodando para sempre, esperando o node ficar vivo, podemos configurar um &lt;em&gt;timeout&lt;/em&gt;. Ainda assim é possivel que ocorra um loop infinito pois um node pode responder OK para commitar a transação, esperar o gerenciador (&lt;em&gt;coordenador&lt;/em&gt;) de&lt;br&gt;
transações e, se o coordenador está down, o node vai esperar para sempre. Para lidar com esse tipo de problema no mundo relacional temos a ideia de &lt;em&gt;compensation&lt;/em&gt;, onde a transação é imediatamente comitada, e no caso de um erro ser reportado, uma nova operação é feita para retificar o estado.&lt;/p&gt;

&lt;p&gt;Alguns problemas que o 2PC introduz:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perda de disponibilidade (&lt;em&gt;availability&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Maior latência (tempo para chegar de um ponto a outro na rede) em falhas parciais&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para manter o banco relacional &lt;em&gt;ACID compliant&lt;/em&gt; é necessário levar em consideração esses problemas que surgem no cenário de um sistema distribuído.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Schema
&lt;/h2&gt;

&lt;p&gt;Você pode representar seus objetos de domínio em um modelo relacional, onde temos entidades e relacionamentos. Geralmente nos referimos ao modelo relacional como &lt;strong&gt;schema on write&lt;/strong&gt;, em contraste com o schema on read de bancos NoSQL, que são mais flexíveis. &lt;em&gt;Schema on write&lt;/em&gt; é a característica de ter um schema mais rígido que é reforçado na hora da escrita no banco:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As bases de dados relacionais assumem frequentemente que todos os dados na base de dados estão em conformidade com um esquema: embora este esquema possa ser alterado (através de migrações de esquemas; ou seja, instruções &lt;code&gt;ALTER&lt;/code&gt;), existe exatamente um esquema em vigor. Por outro lado, as bases de dados schema-on-read (“sem esquema”) não impõem um esquema, então a base de dados pode conter uma mistura de formatos de dados mais antigos e mais recentes escritos em diferentes momentos(...) (KLEPPMANN, 2017)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Sharding
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sharding é uma forma de escalar o banco de dados relacional dividindo os dados&lt;/strong&gt;, ao invés de tê-los em um único servidor, ou tê-los replicados em todos os servidores do cluster. É como se dividíssemos porções dos dados horizontalmente, hospedados separadamente em mais de um node.&lt;/p&gt;

&lt;p&gt;É necessário pensar muito bem qual será a lógica para dividir os dados. De nada adianta, por exemplo, dividir dados de forma que as partes mais acessadas (&lt;em&gt;hot spots&lt;/em&gt;) continuem juntas, já que não iremos "desafogar", escalar, o banco de fato.&lt;/p&gt;

&lt;p&gt;Existem algumas estratégias bem conhecidas de sharding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Por feature (segmentação funcional)&lt;/li&gt;
&lt;li&gt;Por chave (&lt;em&gt;key-based&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recomendo fortemente a leitura do livro Designing Data Intensive Applications para navegar em assuntos complementares a esse texto:&lt;/p&gt;

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




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;CARPENTER, Jeff; HEWITT, Eben. &lt;a href="https://www.amazon.com.br/Cassandra-Definitive-Guide-Revised-English-ebook/dp/B09R2BVFB1/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.6zE2HqOAmHI71tyWkGZRDbLPTVrs-GbLZBOVO4zVkXBUEH3ctz8FfXt05MjA4CO2S8fnSYljlMHa8nClsN4iL3ywFW5EwS_HmtLS10Wg8_sqrX3Wx80y6ObXr73DEps1DHnYOyG7i237Qi5p5jyMD0j_1GpC5Es-d8gdXkVzM0B_HtFHtodOr3S8abb0BZwS6SxF_01I5r9795odj2MzwNWxq70m9qHKp17jfQwuCpusLv36CH-BQKp4_VEiZnTq-69CeJRJ773JYazTAykwViGnLMr0XcDidwWQEtZNlGg.6drW06ZASw4T1RAl41weZ1UXAU2Fi2q-uIMgIlf6_-w&amp;amp;qid=1729416247&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Cassandra: The Difinitive Guide&lt;/a&gt;. O'Reilly, 2022.&lt;/p&gt;

&lt;p&gt;KLEPPMANN, Martin. &lt;a href="https://www.amazon.com.br/Designing-Data-Intensive-Applications-Reliable-Maintainable-ebook/dp/B06XPJML5D/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.5pF53c-4K5lBHgnp-yQa_RJqJfJfPBVyDbdON_9Uqa6GrLYGUQ2pqldnzPh0j8kRTLevdzrF8EseH1lUO7IbFLNQwsJVPs9JQTpBzuD8D_Iv6wY54Mu9j3KGdUDt9z8rE2w3iqoqah8RAxd-S5FqB-fNN6RC1X005uYmHxBIgX56gpYuK28W08MAeoVkHt1YVKfJBhWxZnCTSEC2DfMVvRMpxnMjqVdU7TIGyzvhgx3zfHGygMbP_O0SR0jxDmR26VB7o5vOT7vPejc8xhzKJd_kcfUdT8LhuxCaRsH3zWg.LcAAww-jCWt1_AFannzv6PZ49ZiksTv1LGD_vywgoXQ&amp;amp;qid=1729446561&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Designing Data-Intensive Applications&lt;/a&gt;. O'Reilly, 2017.&lt;/p&gt;

</description>
      <category>database</category>
      <category>rdbms</category>
      <category>transações</category>
      <category>acid</category>
    </item>
    <item>
      <title>Concorrência e paralelismo em Python</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Thu, 02 Jan 2025 09:03:53 +0000</pubDate>
      <link>https://dev.to/nfo94/concorrencia-e-paralelismo-em-python-9em</link>
      <guid>https://dev.to/nfo94/concorrencia-e-paralelismo-em-python-9em</guid>
      <description>

&lt;p&gt;&lt;em&gt;&lt;a href="https://nfo94.github.io/2024/07/14/concorr%C3%AAncia-e-paralelismo-em-python.html" rel="noopener noreferrer"&gt;Texto originalmenete publicado aqui&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;O objetivo deste texto é dar um resumo direto ao ponto dos &lt;strong&gt;conceitos básicos necessários para entender sobre concorrência a paralelismo na linguagem Python&lt;/strong&gt;. Recomendo ter uma base mínima sobre o assunto ou aliar esse texto com estudo em outras fontes. Todas as referências estão ao final do texto.&lt;/p&gt;

&lt;p&gt;Abordarei os seguintes tópicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O que é um processo?&lt;/li&gt;
&lt;li&gt;O que são threads?&lt;/li&gt;
&lt;li&gt;O que significa I/O bound e CPU bound?&lt;/li&gt;
&lt;li&gt;O que é o GIL do Python?&lt;/li&gt;
&lt;li&gt;O que é concorrência?&lt;/li&gt;
&lt;li&gt;O que é paralelismo?&lt;/li&gt;
&lt;li&gt;A biblioteca asyncio&lt;/li&gt;
&lt;li&gt;A biblioteca threading&lt;/li&gt;
&lt;li&gt;A biblioteca multiprocessing&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Em computação um &lt;strong&gt;processo é uma instância de uma aplicação rodando&lt;/strong&gt;. Se você abrir uma aplicação no seu computador, como o navegador, essa aplicação vai estar associada a algum processo. Um processo é composto por:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contexto de hardware: armazena conteúdo de registradores gerais e específicos da CPU&lt;/li&gt;
&lt;li&gt;Contexto de software: especifica os recursos que podem ser alocados pelo processo&lt;/li&gt;
&lt;li&gt;Espaço de endereçamento: especifica a área da memória que o processo pertence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A imagem a seguir foi retirada do &lt;a href="https://www.amazon.com.br/Arquitetura-Sistemas-Operacionais-Incluindo-Exerc%C3%ADcios/dp/8521622104/ref=sr_1_1?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=150WW8OAI7BK3&amp;amp;dib=eyJ2IjoiMSJ9.A1ZhX8ImePrgue4fqDmOFhTfVbkIf5kIlU2jq5kd4laG4KvRRBXQekMR1rhx34OdkcpofR8kV8Ln0SjtzbN9on9rfe1wq8VNaqPBEYyuFuE.byPfWCKB9260AyrDAXjLab022xEJbcexS5jc_qZgex0&amp;amp;dib_tag=se&amp;amp;keywords=Arquitetura+de+Sistemas+Operacionais%3A+Incluindo+Exerc%C3%ADcios+com+o+Simulador+SOSIM+e+Quest%C3%B5es+do+ENADE&amp;amp;qid=1720896386&amp;amp;sprefix=arquitetura+de+sistemas+operacionais+incluindo+exerc%C3%ADcios+com+o+simulador+sosim+e+quest%C3%B5es+do+enade%2Caps%2C137&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;livro do Francis Machado e do Luis Maia&lt;/a&gt;:&lt;/p&gt;

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

&lt;p&gt;Essas informações são necessárias para a execução de um programa.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que são threads?
&lt;/h2&gt;

&lt;p&gt;Uma &lt;strong&gt;thread é uma sub-rotina de um programa, sendo a menor unidade de execução que um sistema operacional gerencia e componente de um processo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As várias threads de um processo hipotético podem ser executadas concorrentemente (que entenderemos em breve), compartilhando recursos como memória. Diferentes processos não compartilham esses recursos.&lt;/p&gt;

&lt;p&gt;A imagem abaixo foi retirada do &lt;a href="https://en.wikipedia.org/wiki/File:Concepts-_Program_vs._Process_vs._Thread.jpg#filelinks" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;

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

&lt;p&gt;Interpretando a imagem acima, podemos extrair que um programa fica salvo em disco (memória secundária, não-volátil) e inclui várias instruções, podendo ser instanciado (iniciado) em um ou mais processos, e esses por sua vez podem ter várias threads associadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que significa I/O bound e CPU bound?
&lt;/h2&gt;

&lt;p&gt;Essas duas expressões aparecem bastante na discussão sobre concorrência e podem aparecer em português com E/S (entrada/saída) e UCP (unidade central de processamento).&lt;/p&gt;

&lt;p&gt;Quando falamos sobre I/O bound e CPU bound estamos falando dos fatores limitantes que previnem uma operação de rodar mais rápido em nosso computador, e podemos encontrar esse dois tipos de operações na mesma codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uma operação CPU bound faz uso intenso da CPU, e rodará mais rápido se a CPU for mais poderosa&lt;/strong&gt;. Ou seja, se formos de 2GHz para 4GHz de velocidade de clock essa operação provavelmente rodará mais rápido. Estamos falando aqui de operações que realizam muitas computações, cálculos; a exemplo, como calcular Pi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uma operação I/O bound depende da velocidade da rede e velocidade dos dispositivos de entrada e saída&lt;/strong&gt;. Fazer um request a um servidor web ou ler um arquivo do disco são operações I/O bound.&lt;/p&gt;

&lt;p&gt;Ambos os tipos de operações podem se beneficiar do uso de concorrência.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é o GIL do Python?
&lt;/h2&gt;

&lt;p&gt;GIL significa &lt;strong&gt;global interpreter lock (bloqueio do interpretador global), cujo objetivo é prevenir um processo Python de executar mais de um bytecode de instrução Python ao mesmo tempo&lt;/strong&gt;. Para rodar uma thread é necessário "adiquirir" o GIL e enquanto uma thread detém o GIL outra thread não pode adiquiri-lo ao mesmo tempo. Isso não significa que não podemos ter mais de uma thread nesse contexto.&lt;/p&gt;

&lt;p&gt;Aqui estamos considerando a implementação de referência do Python. &lt;strong&gt;O CPython é a implementação padrão do Python&lt;/strong&gt;, usada como referência de como a linguagem se comporta. Existem outras implementações, como Jython ou IronPython. O GIL está presente no CPython e só recentemente tivemos uma &lt;a href="https://peps.python.org/pep-0703/" rel="noopener noreferrer"&gt;PEP (Python Enhancement Proposal - proposta de melhoria do Python) propondo tornar o GIL opcional&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A ideia do GIL é prevenir &lt;em&gt;race conditions&lt;/em&gt;, que podem surgir quando mais de uma thread precisa referenciar um objeto Python ao mesmo tempo. Se mais de uma thread modificar uma variável compartilhada essa variável pode ficar em um estado inesperado. Imagem retirada do &lt;a href="https://www.amazon.com.br/Python-Concurrency-Asyncio-Matthew-Fowler/dp/1617298662/ref=sr_1_3?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=FRBELDMJHT23&amp;amp;dib=eyJ2IjoiMSJ9.5wyYTHKbZ2idvH8GDqdbsq8qRPv7t5SNNgCQixjEVop7TeR9YRqA66AL9DV1wY3BDFdBJN0pwlU42loLLQGPfFRIKTBDWUW3NzW89oL-TWOnyuyCSLBpYg32aUEyvo5Et8n9sA-Feyh4aMTTeEGydk8r9QKSR-i9FHsBOteOdSn9pQuhlgSHG2YU0jZ4FiaBOXUznz3Ka7XEtQc_ctlNnBN0sDGXPuLqYVgpyhEEYAGP6aTFzdY-SsLaB3duqYq9r15Q6Ux3Zat5I4eqg68T6Gf_jVopvKUv8QJ_je91pOA.eYk31md2uMKA_h8es6XGgFyU1luNGSDMeCdmmaPw0Yc&amp;amp;dib_tag=se&amp;amp;keywords=asyncio&amp;amp;qid=1720900096&amp;amp;sprefix=asyncio%2Caps%2C170&amp;amp;sr=8-3&amp;amp;ufe=app_do%3Aamzn1.fos.a492fd4a-f54d-4e8d-8c31-35e0a04ce61e" rel="noopener noreferrer"&gt;livro do Matthew Fowler&lt;/a&gt;:&lt;/p&gt;

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

&lt;p&gt;Na imagem acima duas threads estão tentando incrementar uma reference count simultaneamente, e aí ao invés da contagem dar 2, já que as duas estão incrementando 1, o resultado final dá 1 (cada thread é uma coluna).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é concorrência?
&lt;/h2&gt;

&lt;p&gt;Concorrência em computação acontece quando &lt;strong&gt;lida-se com mais de uma tarefas, sem necessariamente estar executando essas duas tarefas exatamente ao mesmo tempo&lt;/strong&gt;. Uma frase conhecida do &lt;a href="https://en.wikipedia.org/wiki/Rob_Pike" rel="noopener noreferrer"&gt;Rob Pyke&lt;/a&gt; sobre o assunto:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Concorrência significa &lt;strong&gt;lidar&lt;/strong&gt; com muitas coisas ao mesmo tempo. Paralelismo é &lt;strong&gt;fazer&lt;/strong&gt; muitas coisas ao mesmo tempo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pense nessa situação hipotética: se você for fazer dois bolos, pode começar pré-aquecendo o forno e, enquanto isso, prepara a massa do primeiro bolo. Assim que o forno estiver na temperatura correta você já pode colocar a massa do primeiro bolo no forno e, enquanto aguarda o bolo crescer no forno, já pode preparar a massa do segundo bolo. A ideia de concorrência é basicamente essa, você não precisa ficar ocioso, travado, parado, enquanto aguarda uma tarefa completar, você pode fazer um &lt;em&gt;switch&lt;/em&gt; e trocar de tarefa.&lt;/p&gt;

&lt;p&gt;Nesse contexto temos dois tipos de multitasking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cooperative multitasking&lt;/strong&gt;: nesse modelo explicitamos no código os pontos onde se pode fazer o &lt;em&gt;switch&lt;/em&gt; de tarefas. No Python isso é alcançado com o uso de um event loop, um design pattern comum, usando apenas uma thread e um core de CPU, usando, por exemplo, o &lt;code&gt;asyncio&lt;/code&gt; com &lt;code&gt;async&lt;/code&gt; e &lt;code&gt;await&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preemptive multitasking&lt;/strong&gt;: nesse modelo deixamos o sistema operacional lidar com o &lt;em&gt;switch&lt;/em&gt;. No Python isso é alcançado com mais de uma thread e um core de CPU usando, por exemplo, a lib &lt;code&gt;threading&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A imagem abaixo ajuda a sumarizar concorrência em Python:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é paralelismo?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Paralelismo significa que mais de uma task está sendo executada ao mesmo tempo&lt;/strong&gt;. Em outras palavras, paralelismo implica concorrência (lidar com mais de uma task), mas concorrência não implica paralelismo (tasks não estão necessariamente sendo executadas em paralelo, ao mesmo tempo). Para que paralelismo seja possível precisamos de mais de um core de CPU.&lt;/p&gt;

&lt;p&gt;No Python paralelismo é alcançado, por exemplo, com a lib &lt;code&gt;multiprocessing&lt;/code&gt;, onde teremos mais de um processo Python, cada um com seu GIL. A imagem ajuda a ilustrar paralelismo em Python:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;A biblioteca asyncio
&lt;/h2&gt;

&lt;p&gt;Existem formas diferentes de se atingir concorrência e paralelismo em Python e podemos utilizar algumas bibliotecas para otimizar nosso código, a depender do tipo de operação que estamos lidando, I/O bound ou CPU bound. O &lt;a href="https://docs.python.org/pt-br/3/library/asyncio.html" rel="noopener noreferrer"&gt;&lt;code&gt;asyncio&lt;/code&gt;&lt;/a&gt; é uma &lt;strong&gt;lib para atingir concorrência usando o &lt;code&gt;async&lt;/code&gt; e &lt;code&gt;await&lt;/code&gt;&lt;/strong&gt;. Pela documentação:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O asyncio é usado como uma base para várias estruturas assíncronas do Python que fornecem rede e servidores web de alto desempenho, bibliotecas de conexão de banco de dados, filas de tarefas distribuídas etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como você pode imaginar, essa lib é adequada para otimizar tarefas I/O bound, onde temos tempo de espera de network, escrita em disco, etc. Numa operação CPU bound não há espera, dependemos apenas da velocidade de cálculo da CPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;A biblioteca threading
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A lib &lt;a href="https://docs.python.org/pt-br/3/library/threading.html" rel="noopener noreferrer"&gt;&lt;code&gt;threading&lt;/code&gt;&lt;/a&gt; do Python nos permite operar mais de uma thread&lt;/strong&gt;, porém, continuamos a lidar com um core de CPU e um processo Python, e lembre-se de que esse é um caso de preemptive multitasking onde o sistema operacional faz a troca de tarefas por nós. A lib também é mais útil para otimizar operações I/O bound.&lt;/p&gt;

&lt;p&gt;Sobre o &lt;code&gt;threading&lt;/code&gt;, o site &lt;a href="https://realpython.com/python-concurrency" rel="noopener noreferrer"&gt;Real Python&lt;/a&gt; traz alguns pontos importantes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Porque o sistema operacional está no controle de quando uma task será interrompida e outra task irá começar, qualquer dado que for compartilhado entre as threads precisa ser protegido, ou &lt;em&gt;thread-safe&lt;/em&gt;. Infelizmente &lt;code&gt;requests.Session()&lt;/code&gt; não é &lt;em&gt;thread-safe&lt;/em&gt;. Existem várias estratégias para fazer o acesso de dados &lt;em&gt;thread-safe&lt;/em&gt; a depender de que dado é e como você está usando. Uma delas é usar estruturas de dados &lt;em&gt;thread-safe&lt;/em&gt; como &lt;code&gt;Queue&lt;/code&gt; do módulo &lt;code&gt;queue&lt;/code&gt; do Python.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Encontramos a documentação do &lt;a href="https://docs.python.org/pt-br/3/library/queue.html#module-queue" rel="noopener noreferrer"&gt;&lt;code&gt;queue&lt;/code&gt; aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;A biblioteca multiprocessing
&lt;/h2&gt;

&lt;p&gt;Sobre a lib &lt;a href="https://docs.python.org/pt-br/3/library/multiprocessing.html" rel="noopener noreferrer"&gt;&lt;code&gt;multiprocessing&lt;/code&gt;&lt;/a&gt; na documentação do Python:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;multiprocessing&lt;/code&gt; é um pacote que suporta gerar processos usando uma API similar ao módulo &lt;code&gt;threading&lt;/code&gt;. O pacote &lt;code&gt;multiprocessing&lt;/code&gt; oferece concorrência tanto local quanto remota, efetivamente desviando o GIL usando sub-processos ao invés de threads. Por isso o &lt;strong&gt;módulo &lt;code&gt;multiprocessing&lt;/code&gt; permite o programador aproveitar múltiplos processadores em uma máquina&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vale apontar que rodar mais de um processo em diferentes cores de CPU não significa desabilitar o GIL, e sim que cada processo terá o seu próprio GIL. Por aproveitar de mais de um core de CPU, compartilhando workloads pesados de CPU entre os múltiplos cores dispiníveis, a lib é mais adequada a CPU bound.&lt;/p&gt;




&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;FOWLER, Matthew. &lt;a href="https://www.amazon.com.br/Python-Concurrency-asyncio-English-Matthew-ebook/dp/B09S4NBW2X/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;amp;dib_tag=se&amp;amp;dib=eyJ2IjoiMSJ9.hrCR3O_nnpP3z502Q_U-90OBMrmIMAXl3zIBDIRAa6ZtVFLXDmHRGneAJVIt0nU80CejmcvLhZvK60Jk1LpM3sO1Mqe9MtF1AXr4H3gRLKprHITsENvjoIvmTmfRkV0hF7peJqUAB8EJUejNW-0jVMq4kuzVS_6ku0Q-0Ge1M1V1O147m3K1c1gU8BQwioqpdimWwJBO7TUvxtDEIRjC9ASkmKNr46PqT5JL2jpcK-jbEw-_nYSxPk0lHmW_XBMngMORwj2znV96dfoUXACcfQJ04lRRbHDJmYhkyZNaN4k.IURAGkadqEEUNyjwE5NoLWNseUJm58Vopo-2CV2n5U4&amp;amp;qid=1720896914&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Python Concurrency with asyncio&lt;/a&gt;. Manning Publications, 2022.&lt;/p&gt;

&lt;p&gt;MACHADO, Francis Berenger; MAIA, Luiz Paulo. &lt;a href="https://www.amazon.com.br/Arquitetura-Sistemas-Operacionais-Incluindo-Exerc%C3%ADcios/dp/8521622104/ref=sr_1_1?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=150WW8OAI7BK3&amp;amp;dib=eyJ2IjoiMSJ9.A1ZhX8ImePrgue4fqDmOFhTfVbkIf5kIlU2jq5kd4laG4KvRRBXQekMR1rhx34OdkcpofR8kV8Ln0SjtzbN9on9rfe1wq8VNaqPBEYyuFuE.byPfWCKB9260AyrDAXjLab022xEJbcexS5jc_qZgex0&amp;amp;dib_tag=se&amp;amp;keywords=Arquitetura+de+Sistemas+Operacionais%3A+Incluindo+Exerc%C3%ADcios+com+o+Simulador+SOSIM+e+Quest%C3%B5es+do+ENADE&amp;amp;qid=1720896386&amp;amp;sprefix=arquitetura+de+sistemas+operacionais+incluindo+exerc%C3%ADcios+com+o+simulador+sosim+e+quest%C3%B5es+do+enade%2Caps%2C137&amp;amp;sr=8-1" rel="noopener noreferrer"&gt;Arquitetura de Sistemas Operacionais: Incluindo Exercícios com o Simulador SOSIM e Questões do ENADE&lt;/a&gt;. Rio de Janeiro: LTC, 2013.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Thread_(computing)" rel="noopener noreferrer"&gt;Thread (computing) por Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://realpython.com/python-concurrency" rel="noopener noreferrer"&gt;Speed Up Your Python Program With Concurrency por Real Python&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>asyncio</category>
      <category>threading</category>
      <category>multiprocessing</category>
    </item>
    <item>
      <title>Como instalar o Terraform no Linux Mint</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Sun, 24 Mar 2024 22:44:25 +0000</pubDate>
      <link>https://dev.to/nfo94/como-instalar-o-terraform-cli-no-linux-mint-51g9</link>
      <guid>https://dev.to/nfo94/como-instalar-o-terraform-cli-no-linux-mint-51g9</guid>
      <description>&lt;p&gt;Estou utilizando uma máquina virtual com o sistema operacional Linux Mint 21.2 Cinnamon e, ao tentar &lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="noopener noreferrer"&gt;instalar o CLI do Terraform como manda a documentação&lt;/a&gt;, vi um erro de &lt;em&gt;404  Not Found (...) does not have a Release file&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
Err:11 https://apt.releases.hashicorp.com victoria Release
  404  Not Found &lt;span class="o"&gt;[&lt;/span&gt;IP: 3.160.132.112 443]
Reading package lists... Done
E: The repository &lt;span class="s1"&gt;'https://apt.releases.hashicorp.com victoria Release'&lt;/span&gt; does not have a Release file.
N: Updating from such a repository can&lt;span class="s1"&gt;'t be done securely, and is therefore disabled by default.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Mint não encontra o repósitorio apontado do Terraform e falha a atualização desse pacote. Encontrei &lt;a href="https://github.com/hashicorp/terraform/issues/32826" rel="noopener noreferrer"&gt;essa issue do GitHub&lt;/a&gt; onde vemos o mesmo problema e, olhando a resposta, vemos que a HashiCorp &lt;a href="https://www.hashicorp.com/official-packaging-guide?product_intent=terraform" rel="noopener noreferrer"&gt;só dá suporte a determinadas distro Linux&lt;/a&gt; e o Mint não é uma delas:&lt;/p&gt;

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

&lt;p&gt;Tentando resolver esse problema cheguei num &lt;a href="https://hirazone.medium.com/install-terraform-and-docker-in-linux-mint-victoria-21-2-70b15e89abce" rel="noopener noreferrer"&gt;artigo do Medium do Tri Juhari&lt;/a&gt;. Basicamente, para resolver esse problema precisamos mudar o comando da documentação oficial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/hashicorp.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para esse comando aqui:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$UBUNTU_CODENAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/hashicorp.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que mudou foi o comando &lt;code&gt;$(lsb_release -cs)&lt;/code&gt; para &lt;code&gt;$(. /etc/os-release &amp;amp;&amp;amp; echo "$UBUNTU_CODENAME")&lt;/code&gt;. O primeiro vai retornar a versão da distro que estamos usando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;  
victoria
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Terraform não tem suporte para o release &lt;em&gt;victoria&lt;/em&gt;. Se eu rodar o segundo comando terei a versão equivalente ao Ubuntu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$UBUNTU_CODENAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
jammy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando essa versão equivalente do Ubuntu conseguimos instalar o Terraform com sucesso:&lt;/p&gt;

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

</description>
      <category>terraform</category>
      <category>linuxmint</category>
    </item>
    <item>
      <title>O que são microservices (microsserviços)?</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Sat, 25 Nov 2023 20:07:32 +0000</pubDate>
      <link>https://dev.to/nfo94/o-que-sao-microservices-microsservicos-3aef</link>
      <guid>https://dev.to/nfo94/o-que-sao-microservices-microsservicos-3aef</guid>
      <description>&lt;p&gt;Esse texto são anotações breves tiradas do &lt;a href="https://www.youtube.com/watch?v=rv4LlmLmVWk" rel="noopener noreferrer"&gt;vídeo sobre microsevices&lt;/a&gt; do canal &lt;a href="https://www.youtube.com/@TechWorldwithNana" rel="noopener noreferrer"&gt;TechWorld with Nana&lt;/a&gt;. As anotações são sobre os seguintes tópicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arquitetura em monolito&lt;/li&gt;
&lt;li&gt;O que são microsserviços&lt;/li&gt;
&lt;li&gt;Microsserviços, CI/CD, polyrepo e monorepo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Arquitetura em monolito
&lt;/h2&gt;

&lt;p&gt;Quando falamos em um monilito em tech estamos nos referindo a uma &lt;strong&gt;arquitetura onde o código inteiro de uma aplicação é uma unidade&lt;/strong&gt;. Aqui, tudo é desenvolvido, deployado e escalado como uma unidade, e uma stack só.&lt;/p&gt;

&lt;p&gt;Alguns desafios da arquitetura de monolito:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A aplicação se torna complexa demais para entender&lt;/li&gt;
&lt;li&gt;As partes da aplicação se tornam muito entrelaçadas&lt;/li&gt;
&lt;li&gt;Só dá para escalar a aplicação inteira, mesmo que só faça sentido escalar uma parte específica&lt;/li&gt;
&lt;li&gt;Demora no release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como possível solução desses desafios surgiu a arquitetura de microsserviços (em inglês, microservices).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que são microsserviços?
&lt;/h2&gt;

&lt;p&gt;Microsserviços são &lt;strong&gt;aplicações que seguem uma arquitetura onde uma aplicação é dividida entre serviços menores, independentes&lt;/strong&gt;, que podem ter stacks diferentes, sendo desenvolvidos, deployados e escalados separadamente.&lt;/p&gt;

&lt;p&gt;Para se comunicar entre si, é comum que microsserviços utilizem chamadas de APIs. Outra forma de comunicação é através de message brokers, como o RabbitMQ, onde temos filas no modelo publish/subscribe. Além disso, a comunicação pode ser feita também através de service mesh, que é um serviço que lida com toda a lógica de comunicação entre os microsserviços.&lt;/p&gt;

&lt;p&gt;Alguns desafios de microsserviços:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurar a comunicação entre esses diversos serviços&lt;/li&gt;
&lt;li&gt;Conseguir monitorar todos os múltiplos serviços entre servidores&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Microsserviços, CI/CD, polyrepo e monorepo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Polyrepo é uma estratégia de gerência de código onde criamos vários repositórios&lt;/strong&gt;, cada um com seu tracking de Git, por exemplo, e com isso acabamos por ter vários pipelines de CI/CD (continuous integration/continous deployment). É muito comum em empresas que seguem a arquitetura em microsserviços.&lt;/p&gt;

&lt;p&gt;Por outro lado, a estratégia de &lt;strong&gt;monorepo&lt;/strong&gt; nos faz lidar somente com um CI/CD pipeline, já que teremos &lt;strong&gt;várias pastas, com cada serviço, mas sendo trackeadas por um único controle de versão&lt;/strong&gt;, por exemplo.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Fontes&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=rv4LlmLmVWk" rel="noopener noreferrer"&gt;Microservices explained - the What, Why and How?, por TechWorld with Nana&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Esse texto não tem intenção de esgotar o tema. Acrescente nos comentários, e também aponte erros quando os identificar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>microservices</category>
    </item>
    <item>
      <title>Como deixar o Visual Studio Code minimalista</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Sat, 15 Jul 2023 09:18:45 +0000</pubDate>
      <link>https://dev.to/nfo94/como-deixar-o-visual-studio-code-minimalista-1lci</link>
      <guid>https://dev.to/nfo94/como-deixar-o-visual-studio-code-minimalista-1lci</guid>
      <description>&lt;p&gt;Já sentiu seus olhos queimarem com algum esquema de cores no VScode? Enjoou do tema Dracula e está incomodado(a) com a quantidade de ícones que você não usa com frequência? Seus problemas acabaram!&lt;/p&gt;

&lt;p&gt;Felizmente, podemos customizar muita coisa no VSCode. Fiz diversos ajustes no meu para ficar assim:&lt;/p&gt;

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

&lt;p&gt;Quando instalamos o VSCode ele vem com uma barra lateral na esquerda, tabs the outline e timeline, uma tabulação bem apertada na estrutura de pastas do projeto, alguns ícones no canto superior direito, um mini mapa na direita e esse tema padrão:&lt;/p&gt;

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

&lt;p&gt;É muita coisa. Vou mostrar aqui quais as extensões e configurações que uso para deixar a interface mais simples e fluida.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tema minimalista: Plain theme
&lt;/h2&gt;

&lt;p&gt;Alguns temas me lembram de como é usar marca-texto no texto inteiro. Procurei um tema mais simples e finalmente encontrei um: Plain theme. É um tema minimalista que destaca apenas algumas palavras e, que eu saiba, hoje em dia o VSCode por padrão já dá cor à parênteses/chaves/colchetes correspondentes. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=konstantin.plain" rel="noopener noreferrer"&gt;Link para o Plain theme&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Como remover a barra lateral esquerda
&lt;/h2&gt;

&lt;p&gt;Essa barra sempre me incomodou profundamente pois ocupa espaço na tela e nem sempre fico clicando ali. É onde fica o debug, source control, busca, etc. Hoje em dia acesso tudo com atalhos no teclado.&lt;/p&gt;

&lt;p&gt;Para remover a barra lateral coloque isso no arquivo &lt;code&gt;settings.json&lt;/code&gt;, que pode ser acessado com &lt;code&gt;ctrl/cmd+shift+P&lt;/code&gt; e digitando &lt;em&gt;"open user settings (JSON)"&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workbench.activityBar.visible"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Como remover mini mapa
&lt;/h2&gt;

&lt;p&gt;Para remover o mini mapa que fica na direita basta adicionar essa linha no &lt;code&gt;settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"editor.minimap.enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Como aumentar a tabulação do explorer
&lt;/h2&gt;

&lt;p&gt;A tabulação padrão do VSCode é mínima e às vezes é difícil entender a hierarquia das pastas e arquivos. Para aumentar a tabulação adicione essa linha no &lt;code&gt;settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"workbench.tree.indent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O número pode ser o que você achar mais conveniente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Atalhos para abrir explorer, busca, debug e plugins
&lt;/h2&gt;

&lt;p&gt;Removendo a barra lateral, precisei decorar os atalhos das funcionalidades que eu utilizo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ctrl/cmd+shift+X&lt;/code&gt;: abre as extensões/plugins&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl/cmd+shift+B&lt;/code&gt;: abre/fecha a lateral inteira&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl/cmd+shift+F&lt;/code&gt;: abre a busca&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl/cmd+shift+D&lt;/code&gt;: abre o debug&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl/cmd+shift+E&lt;/code&gt;: abre a árvore de pastas e arquivos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para saber todos os atalhos do VSCode você pode olhar esse &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf" rel="noopener noreferrer"&gt;documento em pdf para MacOS&lt;/a&gt; ou &lt;a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf" rel="noopener noreferrer"&gt;para Windows&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como remover tabs da lateral esquerda
&lt;/h2&gt;

&lt;p&gt;No meu caso não utilizo as tabs &lt;em&gt;Outline&lt;/em&gt; ou &lt;em&gt;Timeline&lt;/em&gt;. Para remover qualquer uma das tabs basta clicar com o botão direito do mouse em cima do nome da tab e clicar na opção que você quer habilitar/desabilitar:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Como remover ícones
&lt;/h2&gt;

&lt;p&gt;Todos os ícones podem ser habilitados/desabilitados da interface. Clique em cima deles com o click direito do mouse e veja as opções:&lt;/p&gt;

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

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

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

&lt;p&gt;Se quiser saber como está o meu &lt;code&gt;settings.json&lt;/code&gt; dê uma olhada nesse link do &lt;a href="https://gist.github.com/nfo94/ebdaf7012bb375c66ade47cf23f9c94a" rel="noopener noreferrer"&gt;Gist&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Esse texto não tem intenção de esgotar o tema. Acrescente nos comentários, e também aponte erros quando os identificar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
    </item>
    <item>
      <title>Kubernetes: resumo de conceitos básicos</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Mon, 05 Jun 2023 14:04:36 +0000</pubDate>
      <link>https://dev.to/nfo94/kubernetes-resumo-de-conceitos-basicos-3i86</link>
      <guid>https://dev.to/nfo94/kubernetes-resumo-de-conceitos-basicos-3i86</guid>
      <description>&lt;p&gt;Se você está procurando um conteúdo enxuto e direto ao ponto sobre o básico de Kubernetes, este é o lugar. Todos os conceitos apresentados aqui foram tirados diretamente da documentação do Kubernetes. Irei responder as seguintes perguntas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O que é Kubernetes?&lt;/li&gt;
&lt;li&gt;Para que serve o Kubernetes?&lt;/li&gt;
&lt;li&gt;Quais os componentes básicos do Kubernetes?&lt;/li&gt;
&lt;li&gt;O que é um cluster?&lt;/li&gt;
&lt;li&gt;O que são nodes?&lt;/li&gt;
&lt;li&gt;O que são pods?&lt;/li&gt;
&lt;li&gt;O que é o control plane?&lt;/li&gt;
&lt;li&gt;O que é kubectl?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é Kubernetes?
&lt;/h2&gt;

&lt;p&gt;O Kubernetes é uma &lt;strong&gt;plataforma&lt;/strong&gt; open source portável, extensível, para &lt;strong&gt;gerenciar workloads e serviços containerizados&lt;/strong&gt;, que facilita &lt;strong&gt;configuração declarativa&lt;/strong&gt; e &lt;strong&gt;automação&lt;/strong&gt;. Um workload é uma aplicação rodando no Kubernetes, e um serviço containerizado é quando usamos, por exemplo, o Docker para criar containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Para que serve o Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Além de gerenciar workloads e serviços containerizados, o Kubernetes provê:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service discovery e load balancing&lt;/strong&gt;: ele expõe um container usando o nome DNS ou IP e, se o tráfego estiver alto, ele pode balancear e distribuir pela network. Service discovery é o processo de detectar automaticamente devices e serviços numa rede de computadores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orquestração de armazenamento&lt;/strong&gt;: ele te permite montar um sistema de armazenamento a sua escolha, como local storage e cloud providers públicos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollouts e rollbacks automáticos&lt;/strong&gt;: você pode descrever o estado desejado para o container deployado e o Kubernetes consegue controlar o estado de acordo com o que você descreveu&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bin packing automático&lt;/strong&gt;: você diz o quanto de CPU e RAM cada container precisa e o Kubernetes lida com os recursos descritos da melhor forma&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-healing&lt;/strong&gt;: o Kubernetes reinicia containers que falharam, substitui containers, mata containers que não respondem ao health-check definido e não expõe o container para clientes até que eles estejam prontos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gerenciamento de configuração e secrets&lt;/strong&gt;: ele também te deixa guardar e gerenciar informações sensíveis como senhas, OAuth tokens, SSH keys, etc&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Quais os componentes básicos do Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Os componentes básicos do Kubernetes são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cluster&lt;/li&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;Pod&lt;/li&gt;
&lt;li&gt;Control plane&lt;/li&gt;
&lt;li&gt;Complementos: DNS, &lt;a href="https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/" rel="noopener noreferrer"&gt;dashboard do Kubernetes&lt;/a&gt;, cluster-level logging, entre outros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando fazemos deploy do Kubernetes nós temos um &lt;strong&gt;cluster&lt;/strong&gt;. Para ter um cluster Kubernetes funcionando precisamos desses componentes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd33wubrfki0l68.cloudfront.net%2F2475489eaf20163ec0f54ddc1d92aa8d4c87c96b%2Fe7c81%2Fimages%2Fdocs%2Fcomponents-of-kubernetes.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd33wubrfki0l68.cloudfront.net%2F2475489eaf20163ec0f54ddc1d92aa8d4c87c96b%2Fe7c81%2Fimages%2Fdocs%2Fcomponents-of-kubernetes.svg" alt="kubernetes components" width="331" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é um cluster?
&lt;/h2&gt;

&lt;p&gt;Um cluster é um &lt;strong&gt;conjunto de worker machines&lt;/strong&gt;, que são chamadas de &lt;strong&gt;nodes&lt;/strong&gt;. Cada cluster tem pelo menos um worker node. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que são nodes?
&lt;/h2&gt;

&lt;p&gt;Nodes &lt;strong&gt;rodam aplicações containerizadas no Kubernetes&lt;/strong&gt;, e as worker nodes são hosts para &lt;strong&gt;pods&lt;/strong&gt;. Os nodes têm os seguintes componentes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kubelet&lt;/strong&gt;: um agente que roda em cada node do cluster, verificando se containers estão rodando num pod&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kube-proxy&lt;/strong&gt;: é uma network proxy, ou seja, uma aplicação que atua como intermediário entre um cliente e um servidor, que roda em cada node do cluster, implementando uma parte do conceito de service do Kubernetes. O kube-proxy mantém regras de network nos nodes, e essas regras permitem comunicações de rede para seus pods de sessions dentro ou fora do cluster &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container runtime&lt;/strong&gt;: é o software que é responsável por rodar os containers, como o containerd e o CRI-O &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que são pods?
&lt;/h2&gt;

&lt;p&gt;Um pod é um &lt;strong&gt;conjunto de containers rodando no cluster Kubernetes&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é o control plane?
&lt;/h2&gt;

&lt;p&gt;O control plane &lt;strong&gt;gerencia os worker nodes e os pods no cluster&lt;/strong&gt;. Em ambientes de produção ele geralmente roda em vários computadores e um cluster geralmente roda vários nodes. Os componentes do control plane tomam decisões globais sobre o cluster, detectando e respondendo a eventos do cluster como, por exemplo, startar um pod.&lt;/p&gt;

&lt;p&gt;O control plane é composto de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kube-apiserver&lt;/strong&gt;: expõe a API do Kubernetes, como se fosse o frontend para o Kubernetes control plane&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;etcd&lt;/strong&gt;: armazenamento de chave/valor para todos os dados do cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kube-scheduler&lt;/strong&gt;: é o componente que verifica novos pods criados que estão sem node definido, selecionando um node onde eles possam rodar
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kube-controller-manager&lt;/strong&gt;: componente que roda processos do controller. Cada controller, como o node controller, job controller e o ServiceAccount controller, é um processo separado, entretanto, são todos compilados em um único binário e rodados como um único processo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cloud-controller-manager&lt;/strong&gt;: componente que tem lógica de controle específica do provedor de cloud, permitindo que você link seu cluster com a API do provedor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;O que é kubectl?
&lt;/h2&gt;

&lt;p&gt;É a &lt;strong&gt;ferramenta de linha de comando do Kubernetes para se comunicar com o control plane do cluster&lt;/strong&gt;, usando a API do Kubernetes. Sintaxe do &lt;code&gt;kubectl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;TYPE] &lt;span class="o"&gt;[&lt;/span&gt;NAME] &lt;span class="o"&gt;[&lt;/span&gt;flags]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exemplo de comando para listar todos os pods dentro de um namespace (um namespace é uma forma de isolar um grupo de recursos):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Fontes&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://kubernetes.io/docs/concepts" rel="noopener noreferrer"&gt;Documentação do Kubernetes&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Service_discovery" rel="noopener noreferrer"&gt;Service discovery na Wikipedia&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Proxy_server" rel="noopener noreferrer"&gt;Proxy server na Wikipedia&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Esse texto não tem intenção de esgotar o tema. Acrescente nos comentários, e também aponte erros quando os identificar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Como criar um container com MySQL Server com Docker e conectá-lo no Workbench [Linux]</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Wed, 26 Jan 2022 11:06:40 +0000</pubDate>
      <link>https://dev.to/nfo94/como-criar-um-container-com-mysql-server-com-docker-e-conecta-lo-no-workbench-linux-1blf</link>
      <guid>https://dev.to/nfo94/como-criar-um-container-com-mysql-server-com-docker-e-conecta-lo-no-workbench-linux-1blf</guid>
      <description>&lt;p&gt;Esse texto tem fins educacionais. Fiz o procedimento para acompanhar a matéria de &lt;strong&gt;banco de dados&lt;/strong&gt; na faculdade e espero que te ajude a estudar algumas coisinhas. &lt;/p&gt;

&lt;p&gt;Caso não tenha o Docker instalado ainda, abra o terminal e atualize os pacotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instale esses pacotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    apt-transport-https &lt;span class="se"&gt;\&lt;/span&gt;
    ca-certificates &lt;span class="se"&gt;\&lt;/span&gt;
    curl &lt;span class="se"&gt;\&lt;/span&gt;
    gnupg-agent &lt;span class="se"&gt;\&lt;/span&gt;
    software-properties-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicione a GPG key oficial do Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-key add -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicione o repositório:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="s2"&gt;"deb [arch=amd64] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
   &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
   stable"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atualize os pacotes novamente e adicione o Docker Engine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para evitar ter que usar o &lt;code&gt;sudo&lt;/code&gt; o tempo todo, crie um grupo docker e adicione seu user no grupo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;groupadd docker
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;newgrp docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abra e feche o terminal, depois rode um &lt;code&gt;docker run hello-world&lt;/code&gt; para checar que está tudo ok.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando container com MySQL Server
&lt;/h2&gt;

&lt;p&gt;Para criar um container com o MySQL faça o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3306:3306 &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;seu-container &lt;span class="nt"&gt;-d&lt;/span&gt; mysql/mysql-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando roda um container chamado “seu-container” a partir de uma imagem do MySQL Server e mapeia a porta 3306 do container com a sua de mesmo número. Dê um &lt;code&gt;docker ps&lt;/code&gt; e veja o que tem rodando na sua máquina.&lt;/p&gt;

&lt;h2&gt;
  
  
  Se conectando no MySQL Server e configurando senha
&lt;/h2&gt;

&lt;p&gt;Pegue a senha randômica gerada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs seu-container 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;grep &lt;/span&gt;GENERATED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copie a root password que apareceu e rode o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; seu-container mysql &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cole a password e dê enter. Depois disso, já no server, digite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ALTER USER &lt;span class="s1"&gt;'root'&lt;/span&gt;@&lt;span class="s1"&gt;'localhost'&lt;/span&gt; IDENTIFIED BY &lt;span class="s1"&gt;'12345'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso vai mudar a senha padrão do usuário para 12345. Depois rode o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;update mysql.user &lt;span class="nb"&gt;set &lt;/span&gt;host &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'%'&lt;/span&gt; where &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'root'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando vai permitir que você conecte o Workbench no container. Dê um &lt;code&gt;ctrl-D&lt;/code&gt; e depois um &lt;code&gt;docker restart seu-container&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conectando no MySQL Workbench
&lt;/h2&gt;

&lt;p&gt;Vá ao MySQL Workbench e clique na instância local:&lt;/p&gt;

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

&lt;p&gt;Depois disso você poderá colocar a senha:&lt;/p&gt;

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

&lt;p&gt;Pronto, aparecerá uma telinha e aconselho você a explorar o que tem nela. &lt;/p&gt;




&lt;p&gt;&lt;em&gt;Fontes&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://hub.docker.com/r/mysql/mysql-server/" rel="noopener noreferrer"&gt;MySQL Server Docker&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/33827342/how-to-connect-mysql-workbench-to-running-mysql-inside-docker" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;Install Docker&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Esse texto não tem intenção de esgotar o tema. Acrescente nos comentários, e também aponte erros quando os identificar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>docker</category>
      <category>linux</category>
      <category>workbench</category>
    </item>
    <item>
      <title>Comandos básicos do Vim e configurações úteis</title>
      <dc:creator>Natália Oliveira</dc:creator>
      <pubDate>Wed, 19 Jan 2022 10:13:01 +0000</pubDate>
      <link>https://dev.to/nfo94/comandos-basicos-do-vim-e-configuracoes-uteis-gkn</link>
      <guid>https://dev.to/nfo94/comandos-basicos-do-vim-e-configuracoes-uteis-gkn</guid>
      <description>&lt;p&gt;Hoje vou falar um pouco sobre esse &lt;strong&gt;editor de texto chamado Vim&lt;/strong&gt;. Se você já se pegou perguntando &lt;strong&gt;como entrar no vim&lt;/strong&gt;, &lt;strong&gt;como sair do vim&lt;/strong&gt;, &lt;strong&gt;como editar no vim&lt;/strong&gt;, &lt;strong&gt;como adicionar plugins no vim&lt;/strong&gt; ou coisas do tipo, esse texto é para você.&lt;/p&gt;

&lt;p&gt;A intenção aqui é ser “pá-pum”, bem direto ao ponto, um resuminho para quem nunca usou esse editor de texto hardcore. Me lembro de ter visto alguns &lt;em&gt;handbooks&lt;/em&gt; na época em que comecei, mas o que proponho aqui é bem mais enxuto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como instalar o Vim
&lt;/h2&gt;

&lt;p&gt;A instalação básica que costumo fazer é essa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você for no site oficial do editor de texto verá que há outra forma de instalar, mas por praticidade pode seguir com a acima.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como configurar o Vim
&lt;/h2&gt;

&lt;p&gt;O Vim instalado por si só não tem configurações úteis que nos fariam pensar, por exemplo, em abandonar o VS Code (eu acho rs). Para isso configuramos algumas coisas criando um arquivo chamado &lt;code&gt;.vimrc&lt;/code&gt; para deixá-lo mais esperto.&lt;/p&gt;

&lt;p&gt;Dentro do meu &lt;code&gt;.vimrc&lt;/code&gt; eu tenho algumas configurações, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;number&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;linebreak&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;showbreak&lt;/span&gt;&lt;span class="p"&gt;=+++&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;textwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;autoindent&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;shiftwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;smartindent&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;smarttab&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;softtabstop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;undolevels&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;dark&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;backspace&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;indent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;eol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cada uma dessas configurações tem uma utilidade e te encorajo a pesquisar sobre cada uma delas&lt;/strong&gt;. O &lt;code&gt;set number&lt;/code&gt;, por exemplo, faz com que seja mostrada a numeração de cada linha no editor, o que é muito útil.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nfo94/vimrc/blob/master/.vimrc" rel="noopener noreferrer"&gt;Coloquei meu &lt;code&gt;.vimrc&lt;/code&gt; completo esse repositório no GitHub&lt;/a&gt;, caso tenha curiosidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerenciando plugins
&lt;/h2&gt;

&lt;p&gt;Para o Vim ficar ainda mais interessante, muitas pessoas utilizam um &lt;strong&gt;gerenciador de plugins&lt;/strong&gt; para instalar plugins variados. Atualmente utilizo o &lt;a href="https://github.com/VundleVim/Vundle.vim" rel="noopener noreferrer"&gt;&lt;strong&gt;Vundle Vim&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para instalar o Vundle, digite no seu terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É necessário que o seu &lt;code&gt;.vimrc&lt;/code&gt; tenha algumas informações para funcionar com o Vundle corretamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;nocompatible&lt;/span&gt;              " be iMproved&lt;span class="p"&gt;,&lt;/span&gt; required
&lt;span class="k"&gt;filetype&lt;/span&gt; off                  " required

&lt;span class="c"&gt;" set the runtime path to include Vundle and initialize&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;rtp&lt;/span&gt;&lt;span class="p"&gt;+=~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;bundle/Vundle&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;vim&lt;/span&gt;
&lt;span class="k"&gt;call&lt;/span&gt; vundle#begin&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c"&gt;" alternatively, pass a path where Vundle should install plugins&lt;/span&gt;
&lt;span class="c"&gt;"call vundle#begin('~/some/path/here')&lt;/span&gt;

&lt;span class="c"&gt;" let Vundle manage Vundle, required&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'VundleVim/Vundle.vim'&lt;/span&gt;

&lt;span class="c"&gt;" The following are examples of different formats supported.&lt;/span&gt;
&lt;span class="c"&gt;" Keep Plugin commands between vundle#begin/end.&lt;/span&gt;
&lt;span class="c"&gt;" plugin on GitHub repo&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'tpope/vim-fugitive'&lt;/span&gt;
&lt;span class="c"&gt;" plugin from http://vim-scripts.org/vim/scripts.html&lt;/span&gt;
&lt;span class="c"&gt;" Plugin 'L9'&lt;/span&gt;
&lt;span class="c"&gt;" Git plugin not hosted on GitHub&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'git://git.wincent.com/command-t.git'&lt;/span&gt;
&lt;span class="c"&gt;" git repos on your local machine (i.e. when working on your own plugin)&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'file:///home/gmarik/path/to/plugin'&lt;/span&gt;
&lt;span class="c"&gt;" The sparkup vim script is in a subdirectory of this repo called vim.&lt;/span&gt;
&lt;span class="c"&gt;" Pass the path to set the runtimepath properly.&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'rstacruz/sparkup'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'rtp'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'vim/'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;" Install L9 and avoid a Naming conflict if you've already installed a&lt;/span&gt;
&lt;span class="c"&gt;" different version somewhere else.&lt;/span&gt;
&lt;span class="c"&gt;" Plugin 'ascenator/L9', {'name': 'newL9'}&lt;/span&gt;

&lt;span class="c"&gt;" All of your Plugins must be added before the following line&lt;/span&gt;
&lt;span class="k"&gt;call&lt;/span&gt; vundle#end&lt;span class="p"&gt;()&lt;/span&gt;            " required
&lt;span class="k"&gt;filetype&lt;/span&gt; plugin &lt;span class="nb"&gt;indent&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;    " required
&lt;span class="c"&gt;" To ignore plugin indent changes, instead use:&lt;/span&gt;
&lt;span class="c"&gt;"filetype plugin on&lt;/span&gt;
&lt;span class="c"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;" Brief help&lt;/span&gt;
&lt;span class="c"&gt;" :PluginList       - lists configured plugins&lt;/span&gt;
&lt;span class="c"&gt;" :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate&lt;/span&gt;
&lt;span class="c"&gt;" :PluginSearch foo - searches for foo; append `!` to refresh local cache&lt;/span&gt;
&lt;span class="c"&gt;" :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal&lt;/span&gt;
&lt;span class="c"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;" see :h vundle for more details or wiki for FAQ&lt;/span&gt;
&lt;span class="c"&gt;" Put your non-Plugin stuff after this line&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O texto acima foi retirado diretamente da documentação&lt;/strong&gt; e explica, em comentários (toda linha com aspas duplas é um comentário), algumas opções de como usar o Vundle e onde colocar cada informação no seu &lt;code&gt;.vimrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Na última linha do arquivo temos algo como &lt;em&gt;coloque todas as informações que não são de plugins depois dessa linha&lt;/em&gt;: é no final do arquivo que ficam nossas configurações básicas do Vim que falamos anteriormente. &lt;/p&gt;

&lt;p&gt;Localize as linhas que não estão com aspas duplas que começam com “Plugin”. Pronto, esses são alguns plugins que eles colocam de exemplo nesse arquivo para ilustrar.&lt;/p&gt;

&lt;p&gt;Vamos configurar um &lt;code&gt;.vimrc&lt;/code&gt; com Vundle agora. No seu terminal, digite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vim .vimrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso vai abrir o Vim com o arquivo &lt;code&gt;.vimrc&lt;/code&gt;. Já no editor, &lt;strong&gt;dê um &lt;code&gt;ctrl i&lt;/code&gt; e cole com &lt;code&gt;ctrl shift v&lt;/code&gt;&lt;/strong&gt; (deixei uns comentários para que você possa entender melhor):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" configurações essenciais&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;nocompatible&lt;/span&gt;              " be iMproved&lt;span class="p"&gt;,&lt;/span&gt; required
&lt;span class="k"&gt;filetype&lt;/span&gt; off                  " required
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;rtp&lt;/span&gt;&lt;span class="p"&gt;+=~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;bundle/Vundle&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;vim&lt;/span&gt;
&lt;span class="c"&gt;" início da chamada de plugins&lt;/span&gt;
&lt;span class="k"&gt;call&lt;/span&gt; vundle#begin&lt;span class="p"&gt;()&lt;/span&gt;

Plugin &lt;span class="s1"&gt;'VundleVim/Vundle.vim'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'scrooloose/nerdtree'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'majutsushi/tagbar'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'tpope/vim-surround'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'scrooloose/syntastic'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'jiangmiao/auto-pairs'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'morhetz/gruvbox'&lt;/span&gt;
Plugin &lt;span class="s1"&gt;'valloric/youcompleteme'&lt;/span&gt; 

&lt;span class="c"&gt;" fim da chamada de plugins&lt;/span&gt;
&lt;span class="k"&gt;call&lt;/span&gt; vundle#end&lt;span class="p"&gt;()&lt;/span&gt;            " required
&lt;span class="k"&gt;filetype&lt;/span&gt; plugin &lt;span class="nb"&gt;indent&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;    " required

&lt;span class="c"&gt;" configurações básicas do Vim&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;number&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;linebreak&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;showbreak&lt;/span&gt;&lt;span class="p"&gt;=+++&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;textwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;showmatch&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;hlsearch&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;smartcase&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;ignorecase&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;incsearch&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;autoindent&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;shiftwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;smartindent&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;smarttab&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;softtabstop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;undolevels&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;dark&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;backspace&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;indent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;eol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;start
&lt;span class="k"&gt;colorscheme&lt;/span&gt; gruvbox 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para definir meus plugins fui analisando a necessidade e procurando num site chamado &lt;a href="https://vimawesome.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Vim Awesome&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Essa é a cara do meu Vim atual quando abro algum arquivo:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;A árvore de arquivos e pastas é proporcionada pelo &lt;code&gt;Plugin 'scrooloose/nerdtree'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O tema (&lt;code&gt;colorscheme&lt;/code&gt;) é o &lt;code&gt;Plugin 'morhetz/gruvbox'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A linha com informações no canto inferior da tela vem do &lt;code&gt;Plugin 'majutsushi/tagbar'&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Editando códigos e usando os plugins
&lt;/h2&gt;

&lt;p&gt;No início anotei comandos no papel e fui olhando sempre até decorar. Hoje em dia utilizo um &lt;a href="https://github.com/VSCodeVim/Vim" rel="noopener noreferrer"&gt;plugin no VS Code que me permite utilizar comandos do Vim&lt;/a&gt;, porque acabei me acostumando com a praticidade. &lt;/p&gt;

&lt;p&gt;Mas como gosto de utilizar também alguns comandos do VS Code, precisei adequar algumas coisas nas minhas configurações. Aqui estão as &lt;a href="https://gist.github.com/nfo94/ebdaf7012bb375c66ade47cf23f9c94a" rel="noopener noreferrer"&gt;minhas settings do VS Code&lt;/a&gt;, caso tenha interesse. Tudo que tem &lt;code&gt;vim.handleKeys&lt;/code&gt;  é para que eu possa utilizar “ctrl-alguma tecla” do VS Code ao invés do Vim.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modos do Vim
&lt;/h3&gt;

&lt;p&gt;O Vim tem alguns modos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normal&lt;/strong&gt; mode: para se movimentar pelo texto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insert&lt;/strong&gt; mode: para escrever no texto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual&lt;/strong&gt; mode: para selecionar parte do texto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command&lt;/strong&gt; mode: para dar algum comando ao Vim&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comandos básicos no modo normal
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;esc&lt;/code&gt;: sair do modo atual e ir para o modo de comando&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;j&lt;/code&gt;: mover o cursor para baixo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;k&lt;/code&gt;: mover o cursor para cima&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;h&lt;/code&gt;: mover o cursor para a esquerda&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;l&lt;/code&gt;: mover o cursor para a direita&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl i&lt;/code&gt;: entrar no modo de edição no caracter em que está &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;esc&lt;/code&gt;: sair do modo atual e ir para os comandos&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shift a&lt;/code&gt;: entrar no modo de edição no final da linha
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shift o&lt;/code&gt;: entra no modo de edição em uma nova linha abaixo da atual &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gg&lt;/code&gt;: ir para o início do arquivo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shift g&lt;/code&gt;: ir para o final do arquivo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w&lt;/code&gt;: pular uma palavra para frente&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt;: pular uma palavra para trás&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl ]&lt;/code&gt;: pular um bloco de código para baixo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl [&lt;/code&gt;: pular um bloco de código para cima&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;y&lt;/code&gt;: copiar código&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt;: recortar código&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p&lt;/code&gt;: colar código um caractere depois do atual&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt;: deletar caractere&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dd&lt;/code&gt;: deletar linha&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl u&lt;/code&gt;: desfazer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl r&lt;/code&gt;: refazer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shift o&lt;/code&gt;: abre uma nova linha de edição empurrando para baixo o código da linha&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comandos no modo de comando
&lt;/h3&gt;

&lt;p&gt;Entramos nesse modo depois de dar um &lt;code&gt;esc&lt;/code&gt;. Perceba que aqui nós precisamos digitar dois pontos para dar o comando e dar enter no final. Aqui os comandos aparecem sendo digitados no canto inferior da tela (lá no finzinho).&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:q&lt;/code&gt;:  sair do arquivo atual&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:q!&lt;/code&gt;: saída forçada do arquivo atual&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:w&lt;/code&gt;: salvar&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:wq&lt;/code&gt;: salvar e sair&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comandos no modo visual
&lt;/h3&gt;

&lt;p&gt;Com o &lt;code&gt;v&lt;/code&gt; entramos no visual mode, e com os comandos do modo normal movemos o cursor para que selecione o texto que queremos. Ficará um &lt;code&gt;VISUAL&lt;/code&gt; no canto inferior.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt;: deleta o que está selecionado&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;y&lt;/code&gt;: copia o que está selecionado&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s&lt;/code&gt;: entra no modo de edição substituindo o que tinha antes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt;: recorta o código selecionado&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para copiar o código selecionado em algum lugar, dê um &lt;code&gt;esc&lt;/code&gt; para voltar ao modo normal e depois um &lt;code&gt;p&lt;/code&gt; (paste) no local desejado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comandos do Vundle e do plugin NERDTree
&lt;/h3&gt;

&lt;p&gt;Para instalar os plugins que você definiu no seu &lt;code&gt;.vimrc&lt;/code&gt; entre no Vim e, no modo de comando, digite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;PluginInstall
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vai aparecer uma telinha como essa:&lt;/p&gt;

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

&lt;p&gt;É só dar &lt;code&gt;esc&lt;/code&gt;, depois &lt;code&gt;:q&lt;/code&gt; e enter para sair. Para desinstalar um plugin delete a linha no &lt;code&gt;.vimrc&lt;/code&gt; e depois faça o mesmo esquema só que com &lt;code&gt;:PluginClean&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Para acessar a árvore de comandos que eu instalei, vá para o modo de comando e digite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;NERDTree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode navegar na NERDTree como no normal mode. Para abrir uma pasta pressione &lt;code&gt;o&lt;/code&gt;, para fechá-la, pressione novamente. &lt;/p&gt;

&lt;p&gt;Para abrir um arquivo do lado pressione &lt;code&gt;o&lt;/code&gt; no arquivo. Para abrir outro arquivo na vertical, dividindo a tela com um arquivo já aberto, pressione &lt;code&gt;i&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Para rodar entre os arquivos abertos e a árvore de arquivos pressione &lt;code&gt;ctrl w&lt;/code&gt; e mais uma das teclas principais de navegação (h, j, k, l). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cada plugin tem uma documentação e você deve ler cada uma delas para entender o que fazer&lt;/strong&gt;. Não tem para onde correr!&lt;/p&gt;




&lt;p&gt;Para usar o Vim como editor principal é necessário aprender vários comandos e configurar muita coisa, então veja bem se você tem interesse de desprender esse tempo aprendendo. O importante mesmo é saber usar bem a ferramenta que você escolheu.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Esse texto não tem intenção de esgotar o tema. Acrescente nos comentários, e também aponte erros quando os identificar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vim</category>
      <category>linux</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
