<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Denis Santos on Medium]]></title>
        <description><![CDATA[Stories by Denis Santos on Medium]]></description>
        <link>https://medium.com/@denis_santos?source=rss-c9075aa3e3d2------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*QzYITUJrrplPuxAHSvZtBg.jpeg</url>
            <title>Stories by Denis Santos on Medium</title>
            <link>https://medium.com/@denis_santos?source=rss-c9075aa3e3d2------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 14:48:32 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@denis_santos/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Como ter um bom MVP]]></title>
            <link>https://medium.com/@denis_santos/como-ter-um-bom-mvp-e833783d3d0c?source=rss-c9075aa3e3d2------2</link>
            <guid isPermaLink="false">https://medium.com/p/e833783d3d0c</guid>
            <category><![CDATA[customer-centric]]></category>
            <category><![CDATA[agile-manifesto]]></category>
            <category><![CDATA[consumer-behavior]]></category>
            <category><![CDATA[customer-centric-culture]]></category>
            <category><![CDATA[mvp]]></category>
            <dc:creator><![CDATA[Denis Santos]]></dc:creator>
            <pubDate>Mon, 09 Mar 2020 15:06:03 GMT</pubDate>
            <atom:updated>2020-03-10T17:18:39.393Z</atom:updated>
            <content:encoded><![CDATA[<h3>A cultura do MVP alinhada aos princípios do Manifesto Ágil</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*70AkE-6WleDQ0jHb.jpg" /></figure><p>Já faz alguns anos que venho trabalhando em empresas que adotaram a Cultura Ágil (desde 2011), cultura que muda a forma como uma empresa cria e orienta os seus times para <strong>PENSAR EM PRODUTO </strong>e não apenas em PROJETO.</p><h3>Bom, mas o que isso tem a ver com MVP?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*H6A5UJ5ScbOk4PQb.jpg" /></figure><p>Exatamente tudo a ver, <strong>MVP</strong> — <strong><em>Minimum Viable Product</em></strong> ou <strong>Produto Mínimo Viável</strong>, consiste em testar uma hipótese com o menor investimento possível.</p><h4>Você ainda deve estar se perguntando, mas o que isso tem a ver com a Cultura Ágil?</h4><p>Para isso vou dar introdução sobre MVP e Cultura Ágil, e na sequência qual a correlação.</p><p><strong>Cultura Ágil</strong>, é um conjunto de práticas que levam como base o <a href="http://www.manifestoagil.com.br/principios.html">Manifesto Ágil</a> (<a href="http://www.manifestoagil.com.br/principios.html">http://www.manifestoagil.com.br/principios.html</a>), ele é a base de muitos outros conceitos e frameworks como o <strong><em>Scrum</em></strong>.</p><p><strong>MVP,</strong> uma prática que permite realizar um conjunto de testes primários sejam feitos para validar a viabilidade do negócio. Nessa prática deve-se trabalhar com o mínimo de recursos possíveis, ele precisa manter sua função de solução para a qual foi criada e entregar valor ao cliente. Além de permitir que você aprenda o mais rápido possível qual o produto ideal para seu cliente, ficando claro se o produto entrega valor ou não.</p><h3>Entendendo a correlação entre MVP e a Cultura Ágil</h3><p>Vou trazer alguns trechos do Manifesto Ágil e em seguida explicar a sua correlação com as práticas do MVP.</p><ul><li><strong>Nossa maior prioridade é satisfazer o cliente, através da entrega adiantada e contínua de software de valor;</strong></li><li><strong>Aceitar mudanças de requisitos, mesmo no fim do desenvolvimento. Processos ágeis se adequam a mudanças, para que o cliente possa tirar vantagens competitivas;</strong></li><li><strong>Entregar software funcionando com frequência, mas não na escala de semanas ou até meses, mas sim em períodos mais curtos e constantes;</strong></li><li><strong>Simplicidade é a arte de maximizar a quantidade de trabalho que não precisou ser feito.</strong></li></ul><p>Então vamos correlacionar, MVP consiste em testar hipóteses com o menor investimento, certo, e o Manifesto Ágil tem como prioridade inicial é satisfazer o cliente através da <strong>entrega adiantada e continua </strong>(menor investimento para se ter valor adiantado). Além disso o Manifesto Ágil aceita mudanças de requisitos para que os <strong>clientes possam tirar vantagem competitiva</strong> <strong>disso</strong>, ou seja, uma hipótese pode estar OK ou não, necessitando testar novas hipóteses de maneira continua.</p><p>Quando dizemos que o MVP busca o menor investimento possível, isso também está relacionado com o tamanho do time e o tempo de desenvolvimento do Produto, tudo isso traz custos, quanto mais rápido é o Feedback de um cliente em relação ao Produto que está sendo testado, <strong>mais rápido eu valido as minhas hipóteses.</strong> Consequentemente, menor será o impacto financeiro disso.</p><p>Além dos pontos anteriores, com a maior velocidade, se atinge uma maior maturidade, isso ajuda a dimensionar melhor o tamanho e as divisões dos times (cultura do <a href="https://www.bizjournals.com/bizjournals/how-to/human-resources/2016/11/jeff-bezos-two-pizza-rule-for-building-productive.html"><strong><em>TWO-PIZZA TEAM</em></strong></a>). Com essa cultura o time trabalha orientado em testar as hipóteses em períodos curtos de tempo, se permitindo a possibilidade de hipóteses que não mostrem resultados positivos.</p><p>Então um time que trabalhe com a prática do MVP junto da cultura Ágil, caminha naturalmente para a cultura do <a href="https://en.wikipedia.org/wiki/Fail-fast"><strong><em>FAIL FAST</em></strong></a><em> </em>e<em> </em><strong><em>CONTINUOUS LEARNING</em></strong>.</p><ul><li>I<em>magine ficar meses criando e desenvolvendo hipóteses, e só testá-las no final de um grande período, e só então descobrir que o Produto não atende as necessidades do seu cliente?</em></li><li><em>Ou descobrir que o seu concorrente fez algo mais inovador e está alcançando o seu público antes de você?</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*IIUoGPW3QYN_oeoc.jpg" /></figure><h3>Seguem algumas dicas para evitar armadilhas</h3><h4>Seja científico na hora de criar e validar as suas hipóteses!</h4><p>Para isso, além de pesquisar e analisar a sua idéia, tenha uma boa forma de medir o Feedback, gerar dados e capturar as impressões, os sentimentos, a experiência e ter números relevantes. Se falarmos de um App Mobile, Website, Dispositivo IoT ou um Software em geral, fica ainda mais fácil, vamos falar sobre alguns exemplos:</p><ul><li><strong>Faça o uso de Analytics</strong> e tenha o máximo de dados atualizados.</li><li><strong>Tome decisões com base em dados e evidências (<em>Data-Driven</em></strong>)</li><li><strong>Faça Teste A/B</strong>, crie hipóteses de maneira científica, ou seja, teste e compare.</li><li><strong>Seja o máximo de</strong> <strong><em>Customer Centric</em></strong> <strong>possível</strong>, faça algo que o seu cliente precisa, no canal, formato e a comunicação certa para eles. Por exemplo, no lugar de desenvolver um Super Mega Mobile App, muitas vezes um simples chatbot por WhatsApp resolveria o problema da melhor maneira.</li><li><strong>Entenda o seu consumidor (<em>Consumer Behavior</em>)</strong>, estude quando e porquê, como e onde eles decidem consumir/utilizar seu produto. Combinando elementos da psicologia, sociologia, economia e antropologia social. Tendo como objetivo compreender o processo de tomada de decisão, tanto individualmente como em grupo.</li><li><strong>Monitore continuamente o seu produto</strong>, garantindo a sua estabilidade, defina métricas e mantenha elas com ótima performance.</li><li><strong>Acompanhe o seu cliente de perto</strong>, fique atento ao que eles dizem e, nunca ignore a opinião e os sentimentos deles, lembre-se sempre de que o produto foi feito para eles.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/0*XywbV7TCo4PYj1Ny.jpg" /><figcaption>Illustration of MVP product development by Henrik Kniberg</figcaption></figure><h3>E aqui temos a cereja do bolo</h3><p>Sempre ouça e aceite a realidade, muitas vezes nós mesmos testamos e validamos o produto que estamos criando. E é nessa hora que achamos tudo muito intuitivo, fácil, bonito, funcional e prático. Porém o seu cliente pode não achar o mesmo, então trabalhe o orientado ao cliente, estando atento e aberto para receber as críticas, reclamações e as sugestões.</p><p>Por isso, quanto mais formos científicos e orientado a dados, mais rápido se toma decisões assertivas, permitindo uma maior adaptação para que se desenvolva produtos que atendam as reais necessidades do cliente.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MwhDjypn3ExaHgCzTuuXZg.png" /></figure><blockquote>Espero que esse texto possa te ajudar a seguir em frente, isso foi o que aprendi sobre MVP de maneira prática. Apenas não acredito em formula mágica para se ter sucesso, mas sim no <strong>compartilhamento de ideias e experiências</strong>, esses dois pilares permitem a evolução em massa através da <strong>cultura colaborativa</strong>.</blockquote><h4><strong>Referências:</strong></h4><ul><li><a href="http://www.manifestoagil.com.br/principios.html"><strong>Manifesto Ágil</strong></a><strong>:<br></strong><a href="http://www.manifestoagil.com.br/principios.html">http://www.manifestoagil.com.br/principios.html</a></li><li><strong><em>Two-Pizza Team</em>:</strong><br><a href="https://www.bizjournals.com/bizjournals/how-to/human-resources/2016/11/jeff-bezos-two-pizza-rule-for-building-productive.html">https://www.bizjournals.com/bizjournals/how-to/human-resources/2016/11/jeff-bezos-two-pizza-rule-for-building-productive.html</a></li><li><strong><em>Fail Fast:</em></strong><br><a href="https://en.wikipedia.org/wiki/Fail-fast">https://en.wikipedia.org/wiki/Fail-fast</a><br><a href="http://www.iinterativa.com.br/infografico-fail-fast-acolhendo-fracasso-para-uma-inovacao-permanente/">http://www.iinterativa.com.br/infografico-fail-fast-acolhendo-fracasso-para-uma-inovacao-permanente/</a></li><li><strong><em>Continuous Learning:</em><br></strong><a href="https://www.linkedin.com/pulse/7-reasons-why-continuous-learning-important-amit-nagpal/">https://www.linkedin.com/pulse/7-reasons-why-continuous-learning-important-amit-nagpal/</a></li><li><strong><em>Cultura Colaborativa:</em></strong><br><a href="https://chiefexecutive.net/commitment-to-continuous-collaborative-innovation/">https://chiefexecutive.net/commitment-to-continuous-collaborative-innovation/</a></li><li><strong><em>Customer Centric:<br></em></strong><a href="https://www.surveymonkey.com/resources/report-customer-centric-culture-happier-employees/">https://www.surveymonkey.com/resources/report-customer-centric-culture-happier-employees/</a></li><li><strong><em>Consumer Behavior:<br></em></strong><a href="https://en.wikipedia.org/wiki/Consumer_behaviour">https://en.wikipedia.org/wiki/Consumer_behaviour</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e833783d3d0c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Google Mobile Site Hackathon]]></title>
            <link>https://medium.com/@denis_santos/google-mobile-site-hackathon-7520af5fafda?source=rss-c9075aa3e3d2------2</link>
            <guid isPermaLink="false">https://medium.com/p/7520af5fafda</guid>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[carrefour-ecommerce]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[hackathons]]></category>
            <category><![CDATA[google]]></category>
            <dc:creator><![CDATA[Denis Santos]]></dc:creator>
            <pubDate>Sun, 17 Sep 2017 14:58:09 GMT</pubDate>
            <atom:updated>2017-09-18T02:51:39.377Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/521/1*98uxfH5D0P_39IX1TQSZVg.png" /></figure><p>Essa semana (15/set/2017), tive a oportunidade de participar de um Hackathon no escritório do Google, onde formamos um squad para representar o <strong>Carrefour Ecommerce Brasil</strong> com pessoas dos mais variados skills em desenvolvimento ágil, sendo Front-End, Back-End, DevOps com muito foco na criação de produtos escaláveis, veja o nosso time:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ojEasjeFy6FA4dwWOwSqGA.png" /></figure><p>Durante o evento, todos fizemos de tudo, melhorias de performance no HTML+ CSS + JS, subimos uma aplicação em Node.js utilizando streams, criamos container com Docker, infraestrutura com soluções em Kubernetes e CDN, processo de SCM com BitBucket e Jenkins. Na minha opinião, tudo isso foi possível pelo espírito de equipe e a boa sinergia/energia entre todos do time.</p><h3>Sobre a motivação desse Hackathon</h3><p>Uma pesquisa realizada pelo Google apontou que 74% dos usuários abandonam sites mobile que levam mais de 5 segundos para carregar. A missão é otimizar para chegar nos 5 segundos.</p><h3>Sobre a organização do evento</h3><h4>Pré-Evento</h4><p>Antes do evento acontecer, os times passaram por algumas etapas que se dividiram em 5 passos:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*61Dmsf_-uJve29ORtMgzGQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/478/1*ijeS52M5I7c4xYVYpIh4OQ.png" /></figure><h4>O Evento</h4><p>Durante o evento, os times de desenvolvedores terão a oportunidade de trabalhar com foco total em performance para mobile, tendo o suporte dos engenheiros do Google para eventuais dúvidas. Ao final do evento, os times serão convidados a apresentar seus projetos e as melhorias realizadas.</p><h4>MÉTRICAS / REGRAS:</h4><p>Será considerado vencedor o competidor que conquistar mais pontos nos seguintes critérios</p><p>1 O menor Speed Index*; <br>1.2 Maior porcentagem de diminuição do Speed Index*;<br>1.3 O projeto/solução mais votado pelos participantes;<br>1.4 Melhorias feitas que foram publicadas em produção <br><em>* Métrica de velocidade do site WebPage Test — </em><a href="http://www.webpagetest.org/"><em>www.webpagetest.org</em></a></p><h3>Como foi organizado o dia</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*bQ0cD9qv3qr9_hYvdHBYNA.png" /></figure><h3>A nossa solução</h3><p>Criamos uma aplicação em Node.js utilizando os pacotes <a href="https://www.npmjs.com/package/httpp-proxy">http-proxy</a>, <a href="https://www.npmjs.com/package/trumpet">trumpet</a>, <a href="https://www.npmjs.com/package/streaming">streaming</a> e <a href="https://www.npmjs.com/package/html">html</a>, tudo isso possibilitou a edição do html em tempo real por Streams, otimizando as páginas com a aplicação de práticas de compressão e melhorias no código, onde é alterado a estrutura do html, css, js e imagens. Além disso, disponibilizamos essa aplicação como microservice utilizando container com deploy automizado em um processo de continuous deployment (BitBucket + Jenkins), tudo isso utilizando um cluster de Kubernetes na Cloud + CDN. Veja como ficou a solução:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KctLuSToYldO1k9Z5A_DcQ.png" /></figure><h3>Resultados</h3><p>Nós escolhemos a página de produto para ser otimizada, pois essa página tem o maior número de pageviews e ela é decisiva no funil de vendas, nela o usuário decide se adiciona o produto no carrinho e segue com o processo de checkout.</p><p>O time do Google mediu a nossa página antes do evento e registrou o tempo de carregamento dessa com 14.9 segundos, após o evento finalizamos com os seguintes números:</p><ul><li>O tempo de carregamento passou de 14.9 para <strong>9.1 segundos</strong>, obtendo <strong>39% de redução de tempo de carregamento</strong> da página;</li><li>O tamanho passou de 3.5 para <strong>1.5 megabytes</strong>, obtendo <strong>58% de redução no tamanho</strong> da página;</li><li>A quantidade de requests passou de 240 para <strong>124 requests</strong>, obtendo <strong>49% de redução na quantidade de requests</strong> da página.</li></ul><h4>Veja alguns gráficos que facilitam o entendimento</h4><ul><li><strong>Cascata durante o carregamento da página, onde alguns itens são sequenciais e outros são paralelos:</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/976/1*lsweRgvU07LcIOWoey-x1g.png" /></figure><p>para o gráfico acima tivemos as técnicas e práticas de compactação de html + css + js, LazyLoad e remoção de scripts de Tag Management sendo utilizados de forma indevida.</p><ul><li><strong>Progresso de carregamento visual onde tivemos uma pequena perda no First Byte Start, porém conseguiremos resolver isso com ajustes do cache de CDN (foi corrido amigo, rs), sendo a legenda Azul (antes) e o Vermelho (depois):</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QZWtQ8mfVWmg6sTO5wAYCg.png" /></figure><ul><li><strong>Comparativo detalhado do tempo de carregamento, sendo a legenda Azul (antes) e o Vermelho (depois):</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C_MzcAn3sj_BcW4zu_HdqQ.png" /></figure><ul><li><strong>Redução da quantidade de requests, sendo a legenda Azul (antes) e o Vermelho (depois):</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xuJhd5D38VtEB-4suUUC8Q.png" /></figure><ul><li><strong>Redução de tamanho por tipo de arquivo que compõe a página, sendo a legenda Azul (antes) e o Vermelho (depois):</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6uQwmmEw_LbU54pgEgxOkQ.png" /></figure><p><strong>Os números foram expressivos</strong>, o nosso time conseguiu entender o problema e a missão, e entregar um produto que permita otimizar o site de forma ágil e continua (todos os times conseguiram atingir números expressivos). O Google além de compartilhar conhecimento e incentivar a criatividade, provou que criar um time focado + ambiente certo, só pode resultar em muito foco e inovação!</p><h3>Algumas fotos do nosso time durante o evento</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EaVgFp7IJKhhzTqCJGrCJg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YYFpUL22HJCpUsPL4oH4vg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WdlwSzWZoevRQD-YT1Rvwg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*scwNkxBzzJPqCcD5Q9dseQ.jpeg" /></figure><h3>Obrigado time! Obrigado Google!</h3><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7520af5fafda" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ops, curtindo a vida com Rundeck]]></title>
            <link>https://medium.com/@denis_santos/ops-curtindo-a-vida-com-rundeck-aa9955b67f46?source=rss-c9075aa3e3d2------2</link>
            <guid isPermaLink="false">https://medium.com/p/aa9955b67f46</guid>
            <category><![CDATA[automation-tools]]></category>
            <category><![CDATA[rundeck]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Denis Santos]]></dc:creator>
            <pubDate>Thu, 07 Sep 2017 12:52:20 GMT</pubDate>
            <atom:updated>2017-09-07T13:17:46.965Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introdução</h3><p>Um gerenciador e orquestrador de tarefas e rotinas que permite criar fluxos de execuções, essas podendo ser organizadas por etapas onde cada etapa pode prosseguir ou interromper toda a tarefa baseado em sucesso ou falha. Outra feature interessante é permitir a configuraração de triggers podendo ser por eventos (Webhook) e/ou agendamentos (schedule).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/1*qu1HQnOBWrrKCKFgPf768g.png" /></figure><p>Essa solução é 100% Open Source e orientada a plugins, o que fomenta ainda mais o jeito colaborativo de se desenvolver um produto, tem sido bem adotada pela comunidade de DevOps para uso em ambientes de Cloud e Data Center, pois ela facilita a comunicação entre o time, gerando o conceito de atendimento através de rotinas e tarefas que podem ser acessadas por interfaces Web com formulários, APIs ou Command Line Tool (CLI Tool). Seu diferencial está na organização das etapas de uma tarefa, que são organizadas em fluxos lógicos (uma tarefa pode ser composta por outras tarefas).</p><p>Outros pontos que se destacam:</p><ul><li><strong>Controle de acesso</strong> de usuários, controlando por grupo de usuários e regras</li><li><strong>Controle de execução</strong> das tarefas podendo ser Single-Thread ou Multi-Thread, evitando execuções simultâneas indesejadas (imagine dois usuários tomando a mesma decisão de forma simultânea e resolvem executar uma tarefa de Scaling manual, com o Single-Thread a tarefa fica bloqueada até que seja finalizada)</li></ul><p>Saiba mais:</p><ul><li><strong>Site: </strong><a href="http://rundeck.org/">http://rundeck.org/</a></li><li><strong>Projeto:</strong> <a href="https://github.com/rundeck/rundeck">https://github.com/rundeck/rundeck </a>(Java + Spring + Grails + Bootstrap)</li></ul><h3>PoC</h3><p>Desenvolver um projeto no Rundeck que permita a interação com:</p><ul><li>interaja com a API de um servidor Git</li></ul><p>Com finalidade de promover automação na criação de repositórios para prover CI com o máximo de automação.</p><h3>Primeiros passos</h3><h4>Ler a documentação</h4><p><a href="http://rundeck.org/docs/">http://rundeck.org/docs/</a></p><h4>Download e Instalação</h4><p><a href="http://rundeck.org/docs/manual/getting-started.html#download-and-installation">http://rundeck.org/docs/manual/getting-started.html#download-and-installation</a></p><p>Vou usar a versão “Self Contained Launcher Install”</p><p>Coloque o arquivo jar no seguinte local:</p><pre>~/rundeck</pre><p>Execute:</p><pre><strong>java -jar rundeck-launcher-2.9.3.jar</strong></pre><p>Após isso, acesse <a href="http://localhost:4440/">http://localhost:4440 </a>e veja a tela de login:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*DavE3K2jDhlyPljVdaeAeQ.png" /></figure><p>No primeiro acesso utilize as credenciais:</p><ul><li>user: <strong>admin</strong></li><li>pass: <strong>admin</strong></li></ul><h3>Criando um projeto</h3><p>Agora já podemos criar um projeto!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/595/1*vjs7_La6hdXQF6BgRp2ciw.png" /></figure><p>Basta preencher o formulário e seguir a documentação <a href="http://rundeck.org/docs/manual/getting-started.html#project-setup">http://rundeck.org/docs/manual/getting-started.html#project-setup</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/886/1*zCr1idLqq7nHKxfb8WFs-Q.png" /></figure><h3>Criando um Job</h3><p>Após criar um projeto, onde nessa PoC foi criado o projeto <strong>git-automation</strong> basta clicar em em JOBS → New Job</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*IX86fMFt2370q7GS4Zm4Og.png" /></figure><h4>Agora vamos entender a configuração de um Job:</h4><p>Existem muitas opções na criação de um Job, como notificação, criar um workflow de etapas de scripts, mas para a nossa tarefa ficou algo bem simples, onde foram definidas as ações de input de dados que em seguida são usadas em num template para preencher dados do nosso script. Nesse caso um comando CURL que faz uma requisição HTTP POST para a criação de um repositório no BitBucket.</p><h4>Job definition</h4><p>Todo Job (tarefa) gera um Job Definition, que serve de <strong>template</strong> para a criação de outros jobs, veja o YAML gerado automaticamente após a criação do nosso Job:</p><pre>- description: &#39;&#39;<br>  executionEnabled: true<br>  id: 87cafb96-f417-461b-bc13-d9815e747643<br>  loglevel: INFO<br>  loglimit: 1MB<br>  loglimitAction: halt<br>  loglimitStatus: &#39;&#39;&#39;failed&#39;&#39;&#39;<br>  multipleExecutions: true<br>  name: bitbucket-repository-create<br>  nodeFilterEditable: false<br>  notification:<br>    onfailure:<br>      email:<br>        attachLog: true<br>        recipients: denissys@gmail.com<br>        subject: Criação de ${option.repository-name} falhou<br>  options:<br>  - name: auth-user<br>    required: true<br>  - name: auth-pass<br>    required: true<br>    secure: true<br>    valueExposed: true<br>  - name: team<br>    required: true<br>    value: ecommerce2steps<br>  - name: project<br>    required: true<br>    value: RDECK<br>  - name: repository-name<br>    required: true<br>  retry:<br>    delay: 5s<br>    retry: &#39;1&#39;<br>  scheduleEnabled: true<br>  sequence:<br>    commands:<br>    - description: curl create repo<br>      plugins:<br>        LogFilter:<br>        - config:<br>            color: red<br>            replacement: &#39;[SECURE]&#39;<br>          type: mask-passwords<br>      script: &#39;curl --user @option.auth-user@:&quot;@option.auth-pass@&quot; -X POST -H &quot;Content-Type:<br>        application/json&quot; -d &#39;&#39;{ &quot;scm&quot;: &quot;git&quot;, &quot;project&quot;: { &quot;key&quot;: &quot;@option.project@&quot;<br>        }, &quot;is_private&quot;: true}&#39;&#39; https://api.bitbucket.org/2.0/repositories/@option.team@/@option.repository-name@&#39;<br>    keepgoing: false<br>    strategy: node-first<br>  timeout: 10s<br>  uuid: 87cafb96-f417-461b-bc13-d9815e747643</pre><h3>O nosso Job de criação de repositório no Bitbucket</h3><p>Basta preencher o formulário, executar o Job e depois acompanhar o resultado da execução. O job possui um mini dashboard com sumário e histórico das execuções, podendo explorar o log de cada execução (essa opção é configurável, como decidir armazenar apenas os logs de execuções que falharam). Outra opção interessante é poder executar um Job em modo debug, isso permite que seja pausada cada etapa do Job, onde você pode analisar o log de cada etapa e avançar manualmente.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/571/1*Jb0SzAx2pJMS70XIcU414A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*ZwYhXHxPIgx-U6ZUCjyqQw.png" /></figure><h3>SCM — Controle de versão de Jobs</h3><p>Já sabemos que o rundeck cria projetos e que um projeto pode ter Jobs, no nível de Projeto temos a feature SCM onde podemos vincular o projeto a um repositório Git para fazer Import e Export dos Jobs, ou seja, sempre que eu criar ou alterar um Job ele será versionado, e através de algumas interfaces podemos controlar as revisões e até fazer rollback de alguma alteração. Vamos ver como isso funciona na prática:</p><h4>Export Job</h4><p>Escolha um projeto, vá no meu <strong>Project</strong> → <strong>Setup SCM…</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/975/1*TH2WsR94SvLVNFSWbysq0g.png" /></figure><p>Em <strong>SCM Export</strong> clique no botão <strong>Setup</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/651/1*EwTmQCJlBxxuFSwriumkkg.png" /></figure><p>Preencha o campo Git URL com o endereço SSH ou HTTPS do seu repositório Git onde os Jobs serão versionados, alem de escolher a branch e mais algumas opções (todas tem um Tool Tip com explicações)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/1*1ZLuCV8Gp6D-mpieaDb_aQ.png" /></figure><p>Agora precisamos configurar a autênticação da aplicação, para isso precisamos criar um arquivo com a senha e passar o caminho do arquivo no campo <strong>Password Storage Path</strong></p><p><strong><em>!! Essa foi a parte díficil, pois não encontrei nada na documentação que explicasse sobre o arquivo de senha deve estar relativo ao diretório do Rundeck, e numa árvore especifica !!</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KzRIVCFDLQsbObOdWPjTsw.png" /></figure><p>Após criar o arquivo de senha e preencher o campo Password Storage Path, basta clicar em Setup para finalizar</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pblW69jCR8HaMJL0arsqBw.png" /></figure><p>Pronto, seus Jobs do projeto em questão estarão aptos a ser versionados</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/938/1*swUCgDfyAQOnf5wM2SWEWw.png" /></figure><h4>Import Job</h4><p>O import Job serve para restaurar os Jobs em um projeto, você pode selecionar os Jobs e associar ao seu projeto, a configuração é exatamente igual a de Export Job, repita os mesmos passos para configurar.</p><h4>Versionando um Job</h4><p>Após fazer alguma alteração num Job, você verá um Warning “Created, Changed”, ao passar o mouse um Tool Tip apresentará a mensagem sobre qual ação de SCM está pendente.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*dNLdOJwdNGhmGPufODsVKw.png" /></figure><p>Clique em <strong>Action</strong> → <strong>Commit Changes to Git</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KR2siiwWl40IrBBO38xERw.png" /></figure><p>Adicione um comentário, marque Push Remotely para fazer o <strong>remote push</strong> e clique no botão <strong>Commit</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/982/1*Pz95HbyKPPsQsbmvSdcpHw.png" /></figure><p>Em seguida clique na seta alteral do seu Job (menu opções do Job) e escolha a opção <strong>View Commit Info</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/1*TNdiZmXgSKOqQGuvlpLO5g.png" /></figure><p>Veja que já foi criada uma timeline representando a árvore de commits do Job</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CAerDZqMZbL04YMLRnd-9A.png" /></figure><p>Aqui podemos ver detalhes de quem alterou, o que foi alterado</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/966/1*DID40WIQ39-MX0uOW1s-Ew.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/918/1*uusVoyxAxvhkXBqjFWHbcg.png" /></figure><p>E para finalizar, vá no seu servidor de Git Repository, abra o repositório e veja que já foi criado o arquivo do Job e os commits já refletem</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qXJW9lOsCcaBR3HyfygYrQ.png" /></figure><h3>Plugins</h3><p>Tudo no Rundeck, pratícamente é um plugin, desde a construção de um projeto, como o processo de SCM e Flows. Veja um exemplo do que ele faz baseado na lista de plugins padrão:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_tjt3mMiEj4CK37zJwTI5A.png" /></figure><p>Além de uma vasta lista de plugins adicionais como Chef, Puppet, Google Cloud Platform, AWS, Telegram, Nexus, veja a lista completa: <a href="http://rundeck.org/plugins/index.html">http://rundeck.org/plugins/index.html</a></p><h3>Impressões</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*uHkO5taQiJabP561WxjosA.gif" /></figure><p>A primeira impressão foi ótima, pois foi extremamente fácil instalar e configurar a ferramenta, a documentação é bem rica e organizada, as releases do produto são constantes, assim como o lançamento de novos plugins. Uma das minhas preocupações era em relação a camada de persistência dos Jobs, porém todos os Jobs geram arquivos de configuração (YAML ou XML) que podem ser persistidos em disco local e versionados num servidor Git, isso por meio de uma interface de configuração de SCM da própria ferramenta. Ele conta com um banco local que pode ser facilmente alterado em um arquivo de configurações.</p><p>No geral superou as minhas expectativas, a ferramenta é completa, expõe Interfaces Web (Mobile first), APIs e CLI, é bem segura e organiza aquele monte de scripts de servidor, e elimina o desenvolvimento de aplicações que se tornam gateway para chamadas de APIs que são usadas em processos de integração continua quando se quer fazer automação.</p><h3>Dicas uteis</h3><ul><li>Rodando rundeck em Container: <a href="https://hub.docker.com/r/jordan/rundeck/">https://hub.docker.com/r/jordan/rundeck/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aa9955b67f46" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tutorial - Conversor numérico em GoLang]]></title>
            <link>https://medium.com/@denis_santos/tutorial-conversor-num%C3%A9rico-em-golang-3a5680ef9bc?source=rss-c9075aa3e3d2------2</link>
            <guid isPermaLink="false">https://medium.com/p/3a5680ef9bc</guid>
            <category><![CDATA[golang-tutorial]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[getting-started]]></category>
            <dc:creator><![CDATA[Denis Santos]]></dc:creator>
            <pubDate>Sat, 01 Jul 2017 17:42:02 GMT</pubDate>
            <atom:updated>2017-07-02T01:42:54.220Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*eKAqNk_UgZ_2tfnYXrhzbQ.png" /></figure><p>É certo que em todo curso ou disciplina de algoritmo nós sempre aprendemos o arroz com feijão da linguagem de programação a ser estudada, isso para que possamos desenvolver a estrutura básica de qualquer algoritmo. Por isso resolvi criar um programa que converta um valor numérico de String para Float, nele teremos a oportunidade de explorar pontos importantes da linguagem Go.</p><p><strong>Segue o fluxo do nosso programa:</strong></p><ul><li><strong>Entrada:</strong> Recebe um valor obrigatório como argumento de entrada;</li><li><strong>Processamento:</strong> Deve validar esse valor e se for possível, convertê-lo em um número;</li><li><strong>Saída:</strong> Exibir uma mensagem dizendo se o valor é numérico ou não.</li></ul><p>Apenas com esse simples algoritmo poderemos aprender <strong>5 coisas importantes da linguagem Go</strong>, sendo elas:</p><p>1 — Trabalhar com argumentos e operações do sistema operacional;</p><p>2 —Entender listas;</p><p>3 — Tomar decisões com o operador condicional IF;</p><p>4 —Usar uma função de conversão;</p><p>5 — Tratamento de erro em Go.</p><p><strong>O nosso programa:</strong></p><pre>package main</pre><pre>import (<br>  &quot;fmt&quot;<br>  &quot;strconv&quot;<br>  &quot;os&quot;<br>)</pre><pre>func main() {<br>  checkNumber(getValue())<br>}</pre><pre>func getValue() string {<br>  if len(os.Args)-1 &lt; 1 {<br>    fmt.Println(&quot;One arg is requerid for this program&quot;)<br>    os.Exit(1)<br>  }<br>  value := os.Args[1]<br>  return value<br>}</pre><pre>func checkNumber(value string) {<br>  fValue, err := strconv.ParseFloat(value, 64)<br>  if err != nil {<br>    fmt.Printf(&quot;The value &lt;%s&gt; is not a number\n&quot;, value)<br>    os.Exit(1)<br>  }<br>  fmt.Printf(&quot;The value &lt;%f&gt; is a valid number\n&quot;, fValue)<br>}</pre><p><strong>GitHub:</strong> <a href="https://github.com/denissys/go-tutorial-converter">https://github.com/denissys/go-tutorial-converter</a></p><p>Crie o arquivo de código-fonte no seu workspace, no meu exemplo vou chamar de <strong>floatconv.go</strong>:</p><pre>../go/workspace/src/converter/floatconv.go</pre><p>Acesse o diretório <strong>src</strong> do seu workspace, e vamos fazer algumas execuções passando valores numéricos válidos para o nosso programa:</p><pre>go run <a href="https://github.com/denissys/go-tutorial-converter">converter</a>/floatconv.go 1<br>go run converter/floatconv.go 22.4<br>go run converter/floatconv.go 13567788.22220921</pre><p>Para os cenários válidos, teremos as seguintes saídas no terminal, indicando que são valores numéricos:</p><pre>The value &lt;1.000000&gt; is a valid number<br>The value &lt;22.400000&gt; is a valid number<br>The value &lt;13567788.222209&gt; is a valid number</pre><p>Agora vamos testar <strong>sem nenhum argumento</strong> e também <strong>passando valores não numéricos</strong>:</p><pre>go run converter/floatconv.go<br>go run converter/floatconv.go asdf<br>go run converter/floatconv.go false</pre><p>Para os cenários com erros, teremos as seguintes saídas no terminal, indicando o argumento obrigatório e em seguida que os valores não são numéricos:</p><pre>One arg is required for this program<br>exit status 1</pre><pre>The value &lt;asdf&gt; is not a number<br>exit status 1</pre><pre>The value &lt;false&gt; is not a number<br>exit status 1</pre><h3>Entendendo o nosso programa por partes</h3><p><strong>1 - Trabalhar com argumentos e operações do sistema operaciona</strong>l</p><p>Repare que importamos o pacote <strong>&quot;os&quot;</strong>, esse pacote tem funções importantes para interagir com o sistema operacional onde seu programa está hospedado. Esse pacote facilita a execução do seu programa em plataformas diferentes, ou seja, permite que ele seja <a href="https://pt.wikipedia.org/wiki/Multiplataforma"><em>multiplataforma</em></a>. No nosso caso, usamos o pacote <strong>&quot;os&quot;</strong> para utilizar a função que captura o argumento passado na execução do nosso programa por linha de comando, podendo interagir com esse valor em nosso código por meios de algumas funções. Repare que na linha de comando, após o nome do arquivo do programa <strong>floatconv.go</strong>, nós passamos um valor numérico <strong>123</strong>, esse é o argumento:</p><pre>go run converter/floatconv.go <strong>123</strong></pre><p>E no código abaixo, nós utilizamos a função <strong>Arg</strong> do pacote <strong>&quot;os&quot;</strong> para recuperar o valor <strong>123</strong> que foi passado como argumento, esse valor é atribuído na variável <strong>value</strong>:</p><pre>value := os.Args[1]</pre><blockquote><em>Observe no código acima que na atribuição do valor na variável</em><strong><em> value</em></strong><em> não foi necessário especificar o tipo da variável </em>(os.Args sempre recebe os valores como string pela linha de comando)<em>, para resolver o tipo da variável </em><strong><em>value</em></strong><em> o compilador saberá atribuir o tipo correto com base no dado (string, int, float, bool …).</em></blockquote><p>Além disso, nós usamos a função <strong>Exit</strong> do pacote <strong>“os”</strong>, no nosso código o <strong>Exit</strong> interrompe a execução do programa nos casos onde determinamos um erro.</p><pre>if len(os.Args)-1 &lt; 1 {<br>    fmt.Println(&quot;One arg is requerid for this program&quot;)<br>    os.Exit(1)<br>}</pre><p>A instrução <strong>os.Exit(1)</strong> recebe o valor <strong>1</strong> como argumento, isso indica para o sistema operacional que o programa foi finalizado com erro, se o valor do argumento fosse zero, indicaria uma execução finalizada normalmente (<em>seguindo os padrões de programas Unix, </em><a href="https://www.shellscript.sh/exitcodes.html"><em>leia mais aqui</em></a>).</p><p><strong>2 - Entender listas</strong></p><p>Em Go existem dois tipos de listas, podendo ser um <strong>array</strong> que é uma lista de tamanho fixo, ou <strong>slices</strong> que são listas dinâmicas onde seu tamanho pode aumentar ou diminuir.</p><blockquote>Obs.: Mais para frente farei um tutorial explorando e explicando com detalhes a diferença entre array e slices.</blockquote><p>No nosso caso usamos o <strong>os.Args</strong> que é um <strong>slice</strong>, nele são armazenados os argumentos que foram passados por linha de comando na execução do nosso programa.</p><p>Usando a função <strong>len()</strong> nós conseguimos obter o tamanho da nossa lista <strong>len(os.Args)</strong>, é importante saber que a primeira posição da lista tem o <strong>índice 0</strong>.</p><pre>if len(os.Args)-1 &lt; 1 {<br>  ...<br>}</pre><p>Na instrução <strong>os.Args[1]</strong> nós usamos colchetes seguido da posição do índice para obter o valor armazenado nessa posição da lista.</p><pre>value := os.Args[1]</pre><blockquote>Obs.: No nosso programa a posição 0 (zero) está ocupada com a informação da execução do programa que foi executado por linha de comando <strong>(os.Args[1] =&gt; /var/folders/fv/p7vn4fts1153tqh5956f40940000gn/T/go-build933283485/command-line-arguments/_obj/exe/floatconv)</strong>, já o dado que passamos como argumento está na posição 1 (um) do índice da lista, ou seja, a nossa lista tem 2 elementos.</blockquote><p><strong>3 - Tomar decisões com o operador condicional IF</strong></p><p>Nós usamos o operador condicional IF duas vezes no nosso código, sendo:</p><pre>if len(os.Args)-1 &lt; 1 { ... )</pre><pre>if err != nil { ... )</pre><p>Em Go apenas expressões do tipo <strong>bool</strong>, ou seja, expressões do tipo <strong>verdadeiro</strong> ou <strong>falso</strong> (true/false) podem ser utilizadas no operador condicional <strong>if</strong>, podendo receber uma variável ou função.</p><p><strong>4 - Usar uma função de conversão</strong></p><p>Para converter o valor do argumento que é <strong>string</strong> para <strong>float</strong>, nós usamos a função <strong>ParseFloat</strong> do pacote<strong> &quot;strconv&quot;</strong> (string conversion), esse pacote fornece muitos outros tipos de conversões de <strong>string</strong> para outros tipos de dados como <strong>decimal</strong>, <strong>float</strong>, <strong>bool</strong>.</p><pre>fValue, err := strconv.ParseFloat(value, 64)</pre><p><strong>5 - Tratamento de erro em Go</strong></p><p>Repare na instrução abaixo:</p><pre>fValue, err := strconv.ParseFloat(value, 64)</pre><p>Viu que além de declarar a variável <strong>fValue</strong>, foi declarado junto a variável <strong>err</strong> (erro de conversão), ou seja, a função retorna dois valores. Isso pode parecer confuso, estranho, diferente, mas temos que lembrar que Go é uma linguagem funcional e com novos paradigmas, e esse é um de seus bons recursos. Nesse casso a variável <strong>err</strong> pode retornar um <strong>nil</strong> (nulo), se isso ocorrer é porque a conversão não retornou nenhum erro, caso contrário é porque um erro ocorreu na conversão do valor.</p><pre>fValue, err := strconv.ParseFloat(value, 64)<br>if err != nil {<br>  fmt.Printf(&quot;The value &lt;%s&gt; is not a number\n&quot;, value)<br>  os.Exit(1)<br>}</pre><blockquote>Em particular, achei ótimo a maneira Go de tratar erros, não precisamos lidar com dezenas de formas de trabalhar com uma ou mais exceções, no inicio pode até parecer verboso, mas pelos códigos que estou desenvolvendo e também os que venho acompanhando, se torna mais simples de lidar com erros em Go. No Java por exemplo, sempre dedico um certo tempo para entender a arquitetura de tratamento de erros que cada um definiu em seu projeto, como também devemos ficar atentos quando é usada uma RuntimeException.</blockquote><p><strong>O próximo passo será fazer o teste unitário em Go:</strong></p><p>Código bom tem que ter cobertura de teste unitário, isso não é diferente em Go, então leia o próximo tutorial onde aprenderemos a testar o nosso algoritmo conversor numérico: <strong>&lt;assim que eu finalizar o tutorial publicarei o link aqui&gt;</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3a5680ef9bc" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tutorial – Primeiros passos com GoLang]]></title>
            <link>https://medium.com/@denis_santos/primeiros-passos-com-golang-c3368f6d707a?source=rss-c9075aa3e3d2------2</link>
            <guid isPermaLink="false">https://medium.com/p/c3368f6d707a</guid>
            <category><![CDATA[getting-started]]></category>
            <category><![CDATA[golang-tutorial]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[Denis Santos]]></dc:creator>
            <pubDate>Wed, 28 Jun 2017 21:20:46 GMT</pubDate>
            <atom:updated>2017-07-02T14:07:30.353Z</atom:updated>
            <content:encoded><![CDATA[<p>Decidi estudar a linguagem Go, e então resolvi publicar um pouco da minha jornada e o passo a passo dela. Conforme os estudos, as PoC&#39;s e opiniões forem evoluindo, publicarei novos textos.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*8DLNosj4fMYMCd0eOaGmaQ.png" /></figure><p><strong>Instalando Go</strong></p><p>Precisamos instalar as ferramentas da linguagem Go para começar a brincadeira, vamos lá:</p><ul><li><strong>Para MacOS e Linux</strong></li></ul><p>No MacOS você pode usar o Installer ou fazer por linha de comando igual no Linux, baixe o installer ou o pacote compactado direto do site de distribuição do Go (o nome deve ser semelhante a este <strong>go1.8.x.linux-amd64.tar.gz</strong>), acesse aqui e baixe <a href="https://golang.org/dl/">https://golang.org/dl/</a></p><pre>sudo tar -C /usr/local -xzf go1.8.x.linux-amd64.tar.gz</pre><p>Pronto, as ferramentas da linguagem <strong>go</strong> estão disponíveis no diretório</p><pre>/usr/local/go</pre><p>Vamos configurar a nossa variável de ambiente para que possamos usar facilmente as instruções das ferramentas do <strong>go</strong> pelo terminal:</p><pre>export PATH=$PATH:/usr/local/go/bin</pre><p><em>PS: Se tiver duvida sobre variável de ambiente, segue um tutorial: </em><a href="https://www.vivaolinux.com.br/artigo/O-que-e-PATH-como-funciona-e-como-trabalhar-com-ele"><em>https://www.vivaolinux.com.br/artigo/O-que-e-PATH-como-funciona-e-como-trabalhar-com-ele</em></a></p><p>Agora validaremos se a configuração deu certo testando um comando <strong>go</strong> no terminal:</p><pre>go version</pre><p>O resultado deverá ser semelhante a este:</p><pre>go version go1.8.3 darwin/amd64</pre><p><strong>Criando uma Workspace para organizar nossos programas</strong></p><p>A workspace será o nosso diretório padrão de trabalho, e todos os nossos programas estarão nessa workspace, nela teremos a seguinte estrutura de diretórios:</p><ul><li><strong>src:</strong> contém o código-fonte dos códigos que escrevemos, como também o código-fonte de pacotes de terceiros importados em nossos programas;</li><li><strong>pkg:</strong> contém objetos referentes aos pacotes;</li><li><strong>bin:</strong> contém arquivos executáveis gerados pelos programas que compilamos.</li></ul><p><strong>Chega de configuração e vamos ao primeiro código em Go!</strong></p><p>Use um editor de texto de sua preferência que suporte o encode UTF-8, caso use outro encode &quot;perdeu playboy&quot;, seu código não será interpretado pelo compilador :P</p><p>Vá no seu diretório de workspace, e dentro do diretório src <strong><em>../workspace/src</em></strong> crie um diretório <strong><em>primeiro-codigo-go </em></strong><em>e nesse diretório crie o arquivo </em><strong>meucodigo.go</strong><em> e escreva o seguinte código:</em></p><pre>package main</pre><pre>import &quot;fmt&quot;</pre><pre>func main() {</pre><pre>     fmt.Println(&quot;Sou um programa em Go, eu existo!&quot;)</pre><pre>}</pre><p>Agora utilizando a ferramenta <strong>go</strong> vamos executar o comando:</p><pre>go run workspace/src/primeiro-codigo-go/meucodigo.go</pre><p>Então, o texto <strong>“Sou um programa em Go, eu existo!”</strong> será exibido no seu terminal.</p><p><strong>Vamos entender a estrutura do nosso código-fonte Go</strong></p><p>Todo código-fonte em <strong>Go</strong> segue uma estrutura simples, que basicamente é dividida em três seções:</p><p><strong>Seção 1:</strong> A package é a definição do nome do pacote;</p><p><strong>Seção 2: </strong>O import é onde são importados os pacotes externos, como o de formatação &quot;fmt&quot; que usamos no nosso primeiro código;</p><p><strong>Seção 3:</strong> Área de código, onde serão implementos as suas funções e algoritmos do seu programa.</p><p><strong>Explorando o código Go</strong></p><p>Quando instalamos e configuramos o Go na nossa máquina, trouxemos todo o código Standard junto, como vimos, nós usamos a função &quot;fmt&quot; no nosso primeiro código Go. Abra o seguinte diretório <strong><em>/usr/local/go/src/fmt</em></strong> e explore os códigos-fonte contido nele, como o <strong>format.go</strong> e <strong>print.go</strong>, essa é uma boa forma de aprender, pois todo o código Standard está a sua disposição.</p><p><strong>Conclusão sobre o nosso primeiro programa</strong></p><p>Todo código Go deve ter uma package, e todo programa deve ter uma package <strong>main</strong> e uma função <strong>main()</strong> para ter um ponto de partida de inicialização do seu programa.</p><blockquote>É isso, por fim, fizemos o nosso primeiro código Go, vamos seguir em frente e entender mais sobre essa linguagem, seus conceitos e paradigmas.</blockquote><h4><strong>Veja o próximo capítulo:</strong></h4><p><a href="https://medium.com/@denis_santos/tutorial-conversor-num%C3%A9rico-em-golang-3a5680ef9bc">Tutorial — Conversor numérico em GoLang</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c3368f6d707a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The war of programming languages]]></title>
            <link>https://medium.com/@denis_santos/the-war-of-programming-languages-1e892cf580e0?source=rss-c9075aa3e3d2------2</link>
            <guid isPermaLink="false">https://medium.com/p/1e892cf580e0</guid>
            <category><![CDATA[agile-development]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[full-stack]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Denis Santos]]></dc:creator>
            <pubDate>Sat, 17 Jun 2017 00:01:42 GMT</pubDate>
            <atom:updated>2017-06-17T00:01:42.273Z</atom:updated>
            <content:encoded><![CDATA[<p>We&#39;re living in an age of war among many programming languages, developers saying that Java is not good, GoLang has a simple syntax, Scala is only for the best developers, C++ is the best and many other phrases, but these developers don’t talk about compilers, algorithms, issues and gaps, power of processing, maths functions, semantic, if this language having a small or big active community, does it have a continuous evolution? Therefore, there are many questions that must be solved before each developer give their opinion.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/452/1*K7PGzxTYhURjh7S5d5VWog.png" /></figure><p>The programming languages are tools like a <strong>Swiss Army Knife</strong>, the more languages you know, more problems you can solve with the correct programming language. This analogy comes to explain that all programming languages are good and each has its function, so let&#39;s stop the war!</p><p>Nowadays, if you know only one programming language, you are like Rambo with your combat knife, can you solve anything? Yes, you can, but it will be very difficult and you will end this war with many blood. You need to understand that each language is better to solve specific problems in different situations and contexts, that&#39;s why you can and should have your opinion and make your comparison among the programming languages, however you should use the correct comparison criteria in the correct context.</p><blockquote><strong>Example</strong>, in my opinion you shouldn’t use Java to create automation in one server as create tasks to automate routines, Java run in a JVM, the JVM is a heavy process into operation system and requires a lot of memory, the Java depends of frameworks to support Shell and have complex process to compile the code. So we have to use a script language such as Python, that give easy support to Shell and the operation system will easily interpret your script code, besides requires little memory to manage this process into operation system. Other strong factor, the DevOps community adopt python for automation in your script codes.</blockquote><p>Well, now that you became a more adaptable developer and promoter of peace, I believe that you’ll create a creative and productive environment among the developers that you know!</p><p><strong>Tip: stay updated about rank and trends:</strong></p><ul><li><strong>Rank:</strong> <a href="https://www.tiobe.com/tiobe-index/">https://www.tiobe.com/tiobe-index</a></li><li><strong>Trends:</strong> <a href="https://www.thoughtworks.com/pt/radar/languages-and-frameworks">https://www.thoughtworks.com/pt/radar/languages-and-frameworks</a></li></ul><p>See ya!</p><p><a href="https://medium.com/u/c9075aa3e3d2">Denis Santos</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1e892cf580e0" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>