<?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"><channel><title><![CDATA[JEFFERSON OTONI LIMA's blog]]></title><description><![CDATA[Senior Software Engineer, Software Architect, Tech Lead, Teacher, Enthusiast and Entrepreneur and most importantly doing what he loves.]]></description><link>https://jeffotoni.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 09 Nov 2026 14:11:23 GMT</lastBuildDate><atom:link href="https://jeffotoni.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[GoLang — Simplifying Complexity “The Beginning”]]></title><description><![CDATA[There are countless programming languages ​​and each one was born with a purpose: “solve problems”. Languages ​​are tools and we will have to know how to…]]></description><link>https://jeffotoni.hashnode.dev/golang-simplifying-complexity-the-beginning</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/golang-simplifying-complexity-the-beginning</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Wed, 26 Apr 2023 18:57:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1682533460670/43390b51-0171-40a8-a7fa-5c37970bb2ea.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are countless programming languages ​​and each one was born with a purpose: “<strong>solve problems</strong>”. Languages ​​are tools and we will have to know how to use them at the right time. Speaking “<strong>as a developer</strong>” the more polyglot you can be the better it will be for your professional career and for a better understanding and understanding of the diversity of this ecosystem.</p>
<p>The <strong>goal</strong> of this post is to introduce what the <strong>Go</strong> language is and why it is so powerful. Introducing <strong>some concepts and important points about the Go language</strong> that are often mistakenly expressed in several articles found on the internet and discussion groups of programming languages. I believe that the weaknesses and problems generated by several other programming languages ​​over these decades made <strong>Go</strong> become what it is today. And to explain how this is possible we will go back to the beginning of everything, where everything began.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-built_in">println</span>(<span class="hljs-string">"Hello all folks!"</span>)
}
</code></pre>
<h1 id="heading-less-is-exponentially-more">Less is exponentially More</h1>
<p>The <strong>Go</strong> development team says that its creation is an attempt to make programmers more productive. Improving the software development process on <em>Google</em>. The first goal was to create a better language to address the challenges of <em>scalable concurrency</em>, ie software that handles many concerns simultaneously, an example would be coordinating a thousand <em>back-end</em> servers sending network traffic all the time.</p>
<p>Keeping the <strong>Go</strong> language small allows for more important goals. Being small makes <strong>Go</strong> easier to <strong>learn</strong>, easier to <strong>understand</strong>, easier to <strong>implement</strong>, easier to <strong>re-implement</strong>, easier to ** debug**, easier to <strong>tweak</strong>, and easier to <strong>evolve</strong>. Doing less allows for more. It's an expression used by the <strong>Go</strong> development team: “<em>Do Less. Enable More</em>” would be the balance between the universe of existing problems and what <strong>Go</strong> can help solve such problems well. <strong>Go</strong> explicitly wasn't designed to solve every problem instead they've done enough for us to create our own custom solutions with ease, but making it very clear that <strong>Go</strong> can't do everything.</p>
<p>Go was designed by <strong>Google</strong> in <strong>2007</strong> to improve programming productivity in an era of <strong>multicore,</strong> network machines and large codebases. The designers wanted to address criticisms of other languages ​​in use at Google, but keep their useful features.</p>
<p>The creators <a target="_blank" href="https://en.wikipedia.org/wiki/Rob_Pike">Rob Pike</a>, <a target="_blank" href="https://en.wikipedia.org/wiki/Ken_Thompson">Ken Thompson</a> and [Robert Griesemer](https:/ /de.wikipedia.org/wiki/Robert_Griesemer) kept the syntax of <strong>Go</strong> similar to <strong>C</strong>. In late 2008 <a target="_blank" href="https://en.wikipedia.org/wiki/Go_(programming_language)">Russ Cox</a> joined the team and helped move the language and libraries from prototype to reality.</p>
<p>The Go language was released in <strong>2009</strong> with the purpose of facilitating problem-solving in areas such as network layers, scalability, performance, productivity, and most importantly, concurrency. <a target="_blank" href="https://en.wikipedia.org/wiki/Rob_Pike">Rob Pike</a> himself stated that "Go was designed to address a set of software engineering problems we faced when building large server software".</p>
<p><strong>Go</strong> was influenced by various programming languages and different paradigms, including <strong>Alef</strong>, <strong>APL</strong>, <strong>BCPL</strong>, <strong>C</strong>, <strong>CSP</strong>, <strong>Limbo</strong>, <strong>Modula</strong>, <strong>Newsqueak</strong>, <strong>Oberon</strong>, <strong>occam</strong>, <strong>Pascal</strong>, <strong>Smalltalk</strong>, and <strong>Crystal</strong>. It is evident that they used the best of what they had and created something new and lean, with the minimum necessary to solve the proposed problems without losing its simplicity. I believe this can be called <strong><em>innovation</em></strong>. <strong>Go</strong> innovated by breaking the paradigms of programming languages and implementing something new in a simple and very powerful way.</p>
<h1 id="heading-controversies">Controversies</h1>
<p>Several features that are present in other modern programming languages were deliberately left out in Go, going against the trend. These features include immutability declarations, pattern-matching data types, generics, exception handling, inheritance, method overloading, and many other points. All of these features were criticized and pointed out to the creators of Go, who responded: "These omissions were simplifications that contribute to Go's strength." There are many things in the Go language and libraries that differ from modern practices, it was a decision made by the Go development team: "Sometimes it's worth trying a different approach."</p>
<p>Everyone is invited to help and contribute if they wish, they can submit proposals for new features and anything related to the language's ecosystem. The Go source code is available on GitHub. The documentation on how you can contribute to the language is provided here.</p>
<h1 id="heading-goroutines-instead-of-threads">Goroutines instead of threads</h1>
<p>One of the main goals of the Go programming language is to make concurrency simpler, faster, and more efficient.</p>
<p>Goroutines are lightweight and take advantage of all available processing power. Goroutines exist only in the Go runtime virtual space and not in the operating system.</p>
<p>A goroutine is a method/function that can be executed independently along with other goroutines. Each concurrent activity in the Go language is generally called a goroutine.<br />One of the most relevant and important points is the work with <strong>concurrency</strong>, which <strong>innovated</strong> by breaking the <strong>traditional model of</strong> <a target="_blank" href="https://en.wikipedia.org/wiki/Thread_(computing)"><strong>threads</strong></a> and its usage by creating a new model, the <a target="_blank" href="https://golang.org/doc/effective_go.html#concurrency"><strong><em>goroutines</em></strong></a>, in <strong>Go</strong>. <strong>Goroutines</strong> are responsible for performing <strong>asynchronous</strong> executions in <strong>Go</strong>. They are very powerful and a simple machine with <strong>1GB of RAM</strong> could run thousands of them.</p>
<p><strong>Goroutines</strong> are part of making <strong>concurrency</strong> easy to use. <strong>Goroutines</strong> can be very cheap: they have little overhead beyond memory for the stack, which is only a few kilobytes. To make stacks small, the <strong>Go</strong> runtime uses resizable and bounded stacks. A newly launched <strong>goroutine</strong> gets a few kilobytes, which is almost always enough. When it's not, the runtime increases (and shrinks) the memory to store the stack automatically, allowing many <strong>goroutines</strong> to live in a <strong>modest amount of memory</strong>. The CPU overhead averages three cheap instructions per function call. It is practical to create <strong>hundreds of thousands of goroutines</strong> in the same address space. If <strong>goroutines</strong> were just <strong>threads</strong>, system resources would run out at a much smaller number.</p>
<p>The design of <strong>Go</strong> was heavily influenced by C.A.R. Hoare's <strong>1978</strong> article "<a target="_blank" href="https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf">Communicating sequential processes</a>".</p>
<h1 id="heading-simultaneity-in-csp-ideas">Simultaneity in CSP Ideas</h1>
<p>One of the most successful models for providing high-level language support for concurrency is <strong><em>Hoare's Communicating Sequential Processes</em></strong> or <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a>. <a target="_blank" href="https://en.wikipedia.org/wiki/Occam_(programming_language)"><strong>Occam</strong></a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Erlang_(programming_language)"><strong>Erlang</strong></a> are two well-known languages that derive from <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a>. <strong>Go</strong>'s concurrency primitives derive from a different part of the genealogical tree whose main contribution is the powerful notion of channels as first-class objects. Experience with several earlier languages showed that the <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a> model fits well into a procedural language framework.</p>
<p>The biggest difference between Go and the CSP model, besides syntax, is that Go models communication channels explicitly as channels, while the processes of Hoare's language send messages directly to each other, similar to Erlang.</p>
<p>In order to achieve this result, Go has once again received criticism for the adopted model. Go incorporates a variant of CSP (Communicating Sequential Processes), a formal language for describing interaction patterns in concurrent systems with first-class channels. A single-write approach was not adopted to enhance the semantics in the context of concurrent computing, as is done in Erlang, instead, they adopted something practical that resulted in something powerful, allowing for simple and safe concurrent programming, but does not prevent incorrect programming. And the created motto was: "Do not communicate by sharing memory, share memory by communicating". The simplicity and support for concurrency offered by Go generate robustness.</p>
<h1 id="heading-concurrency-is-different-from-parallelism">Concurrency is different from Parallelism</h1>
<p>One of the famous phrases is: "Concurrency is about dealing with many things at once. Parallelism is doing many things at once." Concurrency is the composition of independent execution calculations. Concurrency is a way of structuring software and is definitely not parallelism, although it allows for parallelism. If you only have one processor, your program can still be concurrent, but it cannot be parallel. On the other hand, a well-written concurrent program can be efficiently executed in parallel on a multiprocessor. I suggest checking out this talk by Rob Pike, "Concurrency is not Parallelism".</p>
<p>Concurrency in Go is very powerful and also simple to code, which was the intention of the engineers who developed Go. Solving many problems is much more efficient using concurrency, and this is the power of Go, which is why it has become a deity when it comes to concurrency. Therefore, problems encompassed in this universe will be solved very efficiently and, most importantly, with very few computational resources.</p>
<p>When we talk about <strong>concurrency</strong>, we need to highlight that there are some <strong>patterns</strong>, which I describe below, and there are some <strong>types of workloads</strong> that will serve as our compass to determine our balance point when we have to solve problems involving concurrency.</p>
<h1 id="heading-workloads-cpu-bound-andamp-io-bound">Workloads: CPU-Bound &amp; IO-Bound</h1>
<p>A <strong>thread</strong> can perform <strong>two types of workloads (<em>Workloads</em>)</strong>: <strong>CPU-Bound</strong> and <strong>IO-Bound</strong>.</p>
<p><strong>CPU-Bound</strong>: This workload will never create a situation where the <strong>thread</strong> can be put into <strong><em>waiting states</em></strong>. It will be constantly performing calculations. A <strong>thread</strong> calculating <em>pi</em> to the eighteenth power would be limited by the <strong>CPU.</strong> <em>(Fun fact:</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Emma_Haruka_Iwao"><strong><em>Emma Haruka Iwao</em></strong></a> <em>is a Japanese computer scientist and cloud developer engineer at Google. In 2019, Haruka Iwao calculated the most accurate value of pi in the world, which included 31.4 trillion digits).</em> This type of workload, CPU-bound work, requires parallelism to take advantage of concurrency. More Goroutines will not help and will not be efficient, potentially further delaying the workloads to be executed, due to the latency cost (the time spent) of moving Goroutines in and out of the operating system's thread.</p>
<p><strong>IO-Bound</strong>: In this type of workload, threads enter waiting states. A good example would be a request for accessing a resource over the network or making calls to the operating system. A thread that needs to access a database, synchronization events <em>(mutex, atomic)</em>, all of these examples make the thread wait, so we could say they are of the <strong>IO-Bound</strong> type of workload. In this type of workload, you do not need parallelism to use concurrency, a single physical core would be sufficient for the proper execution of several Goroutines. The Goroutines are entering and exiting waiting states as part of their workload. In this type of workload, having more Goroutines than physical cores can speed up execution because the latency cost of moving Goroutines in and out of the operating system's thread is not creating an event. Its workload is naturally interrupted, allowing a different Goroutine to take advantage of the same physical core instead of allowing it to remain idle.</p>
<h1 id="heading-goroutine-and-pattern">Goroutine and Pattern</h1>
<p>There are some patterns for concurrency, among them: <strong>Fan-In</strong> and <strong>Fan-Out</strong>.</p>
<p><strong>Fan-Out:</strong> Multiple functions can read from the same channel until that channel is closed, this is called <strong><em>fan-out</em></strong>. This provides a way to distribute work among a group of workers to make use of <strong>CPU</strong> and <strong>I/O</strong> in a concurrent manner.</p>
<p><a target="_blank" href="https://blog.golang.org/pipelines"><strong>Fan-In</strong></a><strong>:</strong> It is the way to read from multiple inputs and proceed until all of them are closed, multiplexing the input channels into a single channel that is closed when all the inputs are closed. This is called <strong><em>fan-in</em></strong>.</p>
<p><strong>Pipeline:</strong> There is no formal definition of a pipeline in Go, it is just one of the many types of concurrent programs. Informally, a pipeline is a series of <em>stages</em> connected by channels, where each stage is a group of goroutines running the same function. At each stage, the goroutines:</p>
<ul>
<li><p>Receive values from upstream via input channels;</p>
</li>
<li><p>Perform some function on that data, usually producing new values;</p>
</li>
<li><p>Send values downstream via output channels.</p>
</li>
</ul>
<p>Each stage has several input and output channels, except for the first and last stages, which have only input or output channels, respectively.</p>
<p>To give you an idea, on a <strong>1 CPU and 1 GB RAM</strong> machine, we can handle <strong>5k to 6k</strong> requests per second with a simple <strong>Go</strong> API, with few lines of code, using either <a target="_blank" href="https://en.wikipedia.org/wiki/Remote_procedure_call"><strong>RPC</strong></a> or native <strong>TCP</strong> protocols and writing to a relational database like <strong>PostgreSQL</strong>, without crashing it and consuming an average of only <strong>60Mb to 70Mb</strong> of memory and 8% to 15% of CPU. To achieve this, we use a "Worker Poll" that is a <a target="_blank" href="https://blog.golang.org/pipelines">Fan-out</a>.</p>
<p>If you want to delve further into concurrency, you can check out this <a target="_blank" href="https://github.com/golang/go/wiki/LearnConcurrency">link</a>. If you want to test and see some examples, you can <a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/goroutine">click here</a>. We'll create a separate post to talk about <strong>Goroutines</strong>, which is a very detailed and interesting topic. We know that Go's support for concurrency makes it a godsend for problems that are best solved using concurrency.</p>
<p><strong>Go</strong> is a compiled language, a C-like language, very focused on productivity. For simple or complex projects, Go will always be an excellent alternative, as it makes everything simpler and leaner, easy to code and maintain.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    fmt.Printf(<span class="hljs-string">"Hello, I love Go!\n"</span>)
}
</code></pre>
<h1 id="heading-there-is-no-silver-bullet">There is no silver bullet</h1>
<p>There is no solution or tool to solve all problems yet, of course. What we know is that there are countless solutions developed in various languages, each with a purpose and each with its own characteristics. For this reason, there are programming paradigms, which is a way of classifying languages based on their functionalities, making it easier to understand the context in which they will be better inserted, and, of course, giving us a view of their structure and execution of the languages.</p>
<p>It is becoming increasingly common for languages to support multiple paradigms. We know that there are different classes in computing when it comes to solving problems, and the closer we are to these subjects, the more comfortable we will be to choose a certain language to solve problems, and thus know which tool to use at the right time. In practice, this task is not so easy, but what we know is that the silver bullet has not yet been created to solve all problems at once with just one language, if it existed, there would no longer be <a target="_blank" href="https://en.wikipedia.org/wiki/P_versus_NP"><strong>P versus NP</strong></a> and all problems could be solved in polynomial time.</p>
<h1 id="heading-the-good-things-about-go">The Good Things About Go</h1>
<ul>
<li><p>It does not have generics;</p>
</li>
<li><p>It does not have operator overloading;</p>
</li>
<li><p>It does not have pointer arithmetic;</p>
</li>
<li><p>Thread management is not explicitly managed;</p>
</li>
<li><p>It has type inference;</p>
</li>
<li><p>Dependencies are clear;</p>
</li>
<li><p>The syntax is clean;</p>
</li>
<li><p>The semantics are clear;</p>
</li>
<li><p>Composition over inheritance;</p>
</li>
<li><p>Native GC (Garbage collector);</p>
</li>
<li><p>It has Goroutines;</p>
</li>
<li><p>Native support for concurrent programming;</p>
</li>
<li><p>First-class functions (we can pass functions as parameters);</p>
</li>
<li><p>Cross-platform;</p>
</li>
<li><p>Open Source;</p>
</li>
<li><p>Very low learning curve, meaning it is easy to learn;</p>
</li>
<li><p>Highly productive;</p>
</li>
<li><p>Solves scalability problems;</p>
</li>
<li><p>It can drastically reduce server costs;</p>
</li>
<li><p>Various problems thought from the Go perspective become much easier to handle and solve;</p>
</li>
<li><p>It has only 25 reserved keywords;</p>
</li>
<li><p>Multi-paradigm: concurrent, functional, imperative, object-oriented;</p>
</li>
<li><p>Memory Safe.</p>
</li>
</ul>
<p>We know that various points above will be criticized, but in practice and over time, we realized that all the omitted simplifications made Go an even more powerful language.</p>
<h1 id="heading-when-we-didnt-have-generics">When we didn't have Generics</h1>
<p>When we didn't have Generics There are strong reasons why Go didn't implement Generics early in the project, and there's a discussion in the general communities about this topic. Go left out several features, including “Generics”, which in its conception would directly compromise the performance and purpose that the Go language was intended to solve.</p>
<p>Complainants are mainly developers who come from languages that use this feature. On November 29, 2018, the Go source code maintainers opened up the possibility to submit proposals for new features with all the details so that they can analyze them and possibly implement them in the Go 2.0 version, but we know that this happened before in March 2022 version 1.18 was released. To get a good idea, read this file by <a target="_blank" href="https://blog.golang.org/go2-here-we-come">by clicking here.</a></p>
<p>In Go 1.18, the language introduced a new feature called generic types that had been on the wish list of Go developers for some time. In programming, a generic type is a type that can be used in conjunction with many other types. Normally in Go, if you want to use two different types for the same variable, you need to use a specific interface, like io.Reader, or use interface{}, which allows you to use any value. Using the {} interface can make working with these types difficult because you have to translate between several other possible types to interact with them. Using generic types allows you to interact directly with your types, leading to cleaner, easier-to-read code.</p>
<p><strong>Example:</strong></p>
<p>Imagine a method that receives an array of type int and prints it on the screen.<br />Imagine now needing to do the same with the String type and the float type, you would have to create new methods or functions several times, repeating the code.</p>
<p><strong>Solution</strong>: To avoid creating several methods, only one method is created as a generic to be able to receive any type.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> iMyinterface <span class="hljs-keyword">interface</span> {
    <span class="hljs-keyword">int</span> | <span class="hljs-keyword">int64</span> | <span class="hljs-keyword">int32</span>
    ~<span class="hljs-keyword">float64</span>
    ~<span class="hljs-keyword">string</span>
    ~[]<span class="hljs-keyword">byte</span>
    MyMethod()
}
</code></pre>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NoGenericFuncStrs</span><span class="hljs-params">(a, b []<span class="hljs-keyword">string</span>)</span> <span class="hljs-title">bool</span></span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NoGenericFuncInts</span><span class="hljs-params">(a, b []<span class="hljs-keyword">int</span>)</span> <span class="hljs-title">bool</span></span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NoGenericInterface</span><span class="hljs-params">(a, b <span class="hljs-keyword">interface</span>{})</span> <span class="hljs-title">bool</span></span>
</code></pre>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">GenericsFuncStrs</span>[<span class="hljs-title">T</span> <span class="hljs-title">comparable</span>]<span class="hljs-params">(a, b []T)</span> <span class="hljs-title">bool</span></span>
</code></pre>
<p>Note that this is only a problem in languages that need to declare types of variables or functions, etc. In dynamic languages like PHP, for example, this is not necessary. I won't say strongly or weakly typed languages because it's a bit more complex than that, and that would lead to another discussion.</p>
<p>In Go, we can solve all problems of this nature using reflect and other interfaces and now we have Generics to make our work even easier 😎.</p>
<p>Below are three examples with three proposals to solve the problem in this way, and you will be able to understand when we talk about Generics. 😊</p>
<h2 id="heading-copying-and-pasting-functions-with-specific-types">Copying and Pasting Functions with Specific Types</h2>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-comment">// Takes a slice of any type and reverses it.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reverses</span><span class="hljs-params">(list []<span class="hljs-keyword">string</span>)</span> []<span class="hljs-title">string</span></span> {
    i := <span class="hljs-number">0</span>
    j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
    <span class="hljs-keyword">for</span> i &lt; j {
        list[i], list[j] = list[j], list[i]
        i++
        j--
    }
    <span class="hljs-keyword">return</span> list
}

<span class="hljs-comment">// Takes a slice of any type and reverses it.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reversei</span><span class="hljs-params">(list []<span class="hljs-keyword">int</span>)</span> []<span class="hljs-title">int</span></span> {
    i := <span class="hljs-number">0</span>
    j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
    <span class="hljs-keyword">for</span> i &lt; j {
        list[i], list[j] = list[j], list[i]
        i++
        j--
    }
    <span class="hljs-keyword">return</span> list
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    s := []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>,<span class="hljs-string">"jeff"</span>,<span class="hljs-string">"Go"</span>}
    Reverses(s)
    <span class="hljs-built_in">println</span>(s[<span class="hljs-number">0</span>], s[<span class="hljs-number">1</span>], s[<span class="hljs-number">2</span>])

    i := []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>,<span class="hljs-number">2012</span>,<span class="hljs-number">2009</span>}    
    Reversei(i)    
    <span class="hljs-built_in">println</span>(i[<span class="hljs-number">0</span>], i[<span class="hljs-number">1</span>], i[<span class="hljs-number">2</span>])
}
</code></pre>
<h2 id="heading-using-interface">Using Interface</h2>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-comment">// Takes a slice of any type and reverses it.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reverse</span><span class="hljs-params">(in <span class="hljs-keyword">interface</span>{})</span> <span class="hljs-title">interface</span></span>{} {
    <span class="hljs-keyword">switch</span> in.(<span class="hljs-keyword">type</span>) {
        <span class="hljs-keyword">case</span> []<span class="hljs-keyword">string</span>:
        list := []<span class="hljs-keyword">string</span>(in.([]<span class="hljs-keyword">string</span>))
        i := <span class="hljs-number">0</span>
        j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
        <span class="hljs-keyword">for</span> i &lt; j {
                list[i], list[j] = list[j], list[i]
           i++
           j--
            }
            <span class="hljs-keyword">return</span> list

         <span class="hljs-keyword">case</span> []<span class="hljs-keyword">int</span>:
        list := []<span class="hljs-keyword">int</span>(in.([]<span class="hljs-keyword">int</span>))
        i := <span class="hljs-number">0</span>
        j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
        <span class="hljs-keyword">for</span> i &lt; j {
           list[i], list[j] = list[j], list[i]
           i++
           j--
            }
            <span class="hljs-keyword">return</span> list
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    s := []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>,<span class="hljs-string">"jeff"</span>,<span class="hljs-string">"Go"</span>}
    Reverse(s)
    <span class="hljs-built_in">println</span>(s[<span class="hljs-number">0</span>], s[<span class="hljs-number">1</span>], s[<span class="hljs-number">2</span>])

    i := []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>,<span class="hljs-number">2012</span>,<span class="hljs-number">2009</span>}    
    Reverse(i)    
    <span class="hljs-built_in">println</span>(i[<span class="hljs-number">0</span>], i[<span class="hljs-number">1</span>], i[<span class="hljs-number">2</span>])
}
</code></pre>
<h2 id="heading-using-generics">Using Generics</h2>
<pre><code class="lang-go"><span class="hljs-comment">// https://go2goplay.golang.org/</span>
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-comment">// The playground now supports parentheses or square brackets (only one at</span>
<span class="hljs-comment">// a time) for generic type and function declarations and instantiations.</span>
<span class="hljs-comment">// By default, parentheses are expected. To switch to square brackets,</span>
<span class="hljs-comment">// the first generic declaration in the source must use square brackets.</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Print</span>[<span class="hljs-title">type</span> <span class="hljs-title">T</span>] <span class="hljs-params">(s []T)</span></span>{
    <span class="hljs-keyword">for</span> _, v := <span class="hljs-keyword">range</span> s {
        fmt.Print(v)
    }
    fmt.Println(<span class="hljs-string">""</span>)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reverse</span>[<span class="hljs-title">type</span> <span class="hljs-title">T</span>]<span class="hljs-params">(list []T)</span></span> {
    i := <span class="hljs-number">0</span>
    j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
    <span class="hljs-keyword">for</span> i &lt; j {
        list[i], list[j] = list[j], list[i]
        i++
        j--
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">var</span> i []<span class="hljs-keyword">interface</span>{}
        i = <span class="hljs-built_in">append</span>(i, <span class="hljs-string">"jeffotoni"</span>)
        i = <span class="hljs-built_in">append</span>(i, <span class="hljs-string">" ano de 2020 "</span>)
        i = <span class="hljs-built_in">append</span>(i, []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>, <span class="hljs-string">"jeff"</span>, <span class="hljs-string">"Go"</span>})
    i = <span class="hljs-built_in">append</span>(i, []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>, <span class="hljs-number">2012</span>, <span class="hljs-number">2009</span>})
        Print(i)

    s := []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>, <span class="hljs-string">"jeff"</span>, <span class="hljs-string">"Go"</span>}
    Reverse(s)
    Print(s)

    intt := []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>, <span class="hljs-number">2012</span>, <span class="hljs-number">2009</span>}
    Reverse(intt)
    Print(intt)
}
</code></pre>
<h1 id="heading-composition-over-inheritance">Composition over Inheritance</h1>
<p>The approach adopted by Go departs from the norm and is unusual for object-oriented programming, allowing methods of any type, not just classes, but without any form of type-based inheritance, such as subclasses. This means that there is no type hierarchy. This is not a bug, not a disadvantage, nor an error, but an intentional design choice by the developers of Go. Although type hierarchies have been used to build successful software, it is the stance and opinion of the Go development team, that they preferred to take a step back instead of doing the same repetitive model in various languages.</p>
<h2 id="heading-interfaces-are-implicit">Interfaces are implicit</h2>
<p>Instead, Go has interfaces, which are just a set of methods and nothing more.</p>
<p><em>Example:</em></p>
<pre><code class="lang-go"><span class="hljs-keyword">go</span>
</code></pre>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Geometric <span class="hljs-keyword">interface</span> {
  area() <span class="hljs-keyword">float64</span>
  perim() <span class="hljs-keyword">float64</span>
}
</code></pre>
<p>All data types that implement these methods satisfy this interface implicitly, there is no "implements" in the declaration. Interface satisfaction is checked statically at compile time, therefore, despite the decoupling interfaces, they are type-safe.</p>
<p>A type usually satisfies many interfaces, each corresponding to a subset of its methods. This fluidity of interface satisfaction encourages a different approach to software construction, breaking the existing paradigm.</p>
<h2 id="heading-why-arent-interfaces-explicit">Why aren't interfaces explicit?</h2>
<p>Object-oriented programming provides a powerful view: that the <em>behavior</em> of data can be generalized independently of the <em>representation</em> of that data. The model works best when a behavior (set of methods) is fixed, but once you insert a subclass into a type and add a method, <em>the behaviors are no longer identical</em>. If instead, the set of behaviors is fixed, as in interfaces statically defined in Go, the uniformity of behavior allows data and programs to be composed uniformly, orthogonally, and safely. Type hierarchies result in fragile code. Go stimulates composition and not inheritance, using simple interfaces, usually of one method, to define trivial behaviors that serve as clear and understandable boundaries between components and eliminating the type hierarchy also eliminates one form of dependency hierarchy. The designs are not like hierarchical methods <strong>inherited from subtypes</strong>. They are more <strong>loose, organic, decoupled, independent</strong> and therefore <strong>scalable</strong>.</p>
<pre><code class="lang-go"><span class="hljs-keyword">go</span>
</code></pre>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"math"</span>

<span class="hljs-keyword">type</span> Geometric <span class="hljs-keyword">interface</span> {
    area() <span class="hljs-keyword">float64</span>
    perim() <span class="hljs-keyword">float64</span>
}

<span class="hljs-keyword">type</span> rect <span class="hljs-keyword">struct</span> {
    width, height <span class="hljs-keyword">float64</span>
}

<span class="hljs-keyword">type</span> circle <span class="hljs-keyword">struct</span> {
    radius <span class="hljs-keyword">float64</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r rect)</span> <span class="hljs-title">area</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> r.width * r.height
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r rect)</span> <span class="hljs-title">perim</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-number">2</span>*r.width + <span class="hljs-number">2</span>*r.height
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c circle)</span> <span class="hljs-title">area</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> math.Pi * c.radius * c.radius
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c circle)</span> <span class="hljs-title">perim</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-number">2</span> * math.Pi * c.radius
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">measure</span><span class="hljs-params">(g geometry)</span></span> {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    r := rect{width: <span class="hljs-number">3</span>, height: <span class="hljs-number">4</span>}
    c := circle{radius: <span class="hljs-number">5</span>}

    measure(r)
    measure(c)
}
</code></pre>
<h1 id="heading-duck-typing"><strong>Duck typing</strong></h1>
<p>Go supports <strong>"Duck typing",</strong> a typing style in which the <em>methods</em> and <em>properties</em> of an object determine the valid semantics, rather than its inheritance from a particular class or implementation of an explicit interface. The concept's name refers to the <a target="_blank" href="https://en.wikipedia.org/wiki/Duck_test">duck test</a>, attributed to <a target="_blank" href="https://en.wikipedia.org/w/index.php?title=James_Whitcomb_Riley&amp;action=edit&amp;redlink=1">James Whitcomb Riley</a>. This makes Go look like a dynamic language.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Go_(programming_language)">Go</a> uses <strong>"Structural Typing"</strong> in methods to determine the compatibility of a type with an interface. There are no type hierarchies, and <strong>"Structural Typing"</strong> is an interesting alternative to classic inheritance in statically typed languages. It allows you to write generic algorithms without obscuring the definition of a type in a sea of interfaces. Perhaps more importantly, it helps statically typed languages capture the feel and productivity of dynamically typed languages.</p>
<p><strong>"Duck typing"</strong> occurs at runtime and <strong>"Structural Typing"</strong> occurs at compile time. Go does not support object orientation as implemented in languages like C#, Java, or even C++, it has no inheritance and honestly, I am very happy with this, but it does offer some features such as <strong><em>composition and interfaces</em></strong>.</p>
<pre><code class="lang-go"><span class="hljs-keyword">go</span>
</code></pre>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-keyword">type</span> family <span class="hljs-keyword">interface</span> {
    dados() <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">type</span> pai <span class="hljs-keyword">struct</span> {
    Nome  <span class="hljs-keyword">string</span>
    Idade <span class="hljs-keyword">int</span>
    Cpf   <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"campo-x"`</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p pai)</span> <span class="hljs-title">dados</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"Nome: %s, Idade: %d"</span>, p.Nome, p.Idade)
}

<span class="hljs-keyword">type</span> filho <span class="hljs-keyword">struct</span> {
    pai
    email <span class="hljs-keyword">string</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(f filho)</span> <span class="hljs-title">dados</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"Nome: %s, Idade: %d, Email: %s"</span>, f.Nome, f.Idade, f.email)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">mostraDados</span><span class="hljs-params">(membro familia)</span></span> {
    fmt.Println(membro.dados())
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    pai := <span class="hljs-built_in">new</span>(pai)
    pai.Nome = <span class="hljs-string">"Jeff"</span>
    pai.Idade = <span class="hljs-number">50</span>
    pai.Cpf = <span class="hljs-string">"00.xxx.xxx-xx"</span>

    filho := <span class="hljs-built_in">new</span>(filho)
    filho.Nome = <span class="hljs-string">"Arthur"</span>
    filho.Idade = <span class="hljs-number">20</span>
    filho.email = <span class="hljs-string">"arthur@gmail.com"</span>

    mostraDados(pai)
    mostraDados(filho)
 }
</code></pre>
<h1 id="heading-strong-third-party-library-support">Strong third-party library support</h1>
<p>In the current scenario, <strong>Go</strong> has taken off as a programming language and all major, medium, and small existing players are developing their libraries, SDKs, clients, etc. in the <strong>Go</strong> language. There are thousands of initiatives and many third-party libraries. Everything contributes to this, the <strong>Go</strong> community is very strong, it grows every day, it has a very high acceptance curve, and with this, it facilitates its entry into companies and its use by developers.</p>
<p>The result of this is mass dissemination on the internet with libraries written in <strong>Go</strong>. There are also libraries that are abandoned, as in any other language, but functional. But the number of libraries written in <strong>Go</strong> is very, very large. Several companies are rewriting their platforms in <strong>Go</strong>, which is a trend that continues to grow. And day by day the number of tools for <a target="_blank" href="https://www.redhat.com/pt-br/topics/devops"><strong>DevOps</strong></a> grows, and with this, the acceptance and increase of new adherents to Go grows in the <a target="_blank" href="https://en.wikipedia.org/wiki/DevOps"><strong>DevOps</strong></a> culture and community.</p>
<p>After the implementation of version control <strong>VGO</strong> in <strong>Go</strong>, we now have the possibility of not needing our projects to be under $GOPATH, we can now create our projects in any directory outside $GOPATH. This feature is only possible due to version control, when we use <strong><em>"go mod"</em></strong> our project workspaces are controlled in a new way, just run the command <em>"go mod init yourapp"</em> and a file named <strong><em>"go.mod"</em></strong> will be created containing the location of your path and the version in which it is located. Very simple and beautiful. Every time we run our Go project, we can use the environment variable <em>"GO111MODULE=yes|no"</em> to determine whether we will use "go mod" or not.</p>
<h1 id="heading-garbage-collector-gc">Garbage collector (GC)</h1>
<p><strong>GCs</strong> are complex pieces of software, decades of research and implementations, and various attempts by computer scientists to make an improved and reliable GC. It is not a simple task, and due to this, there is a huge chain on the internet describing the pros and cons of a GC. What we have to take into consideration is that regardless of the result, if we didn't have a GC, we would have to build one to solve the allocation problem.</p>
<p>There are usually two ways to allocate memory in <strong>Go</strong>: on the stack and on the heap. Generally, developers are familiar with the stack, just write a recursive program and you will notice a <a target="_blank" href="https://stackoverflow.com/questions/26158/how-does-a-stack-overflow-occur-and-how-do-you-prevent-it">stack overflow</a> if you don't do it correctly. The heap, on the other hand, is a pool of memory that can be used for dynamic allocation.</p>
<p>Stack allocations are great because they only live during the lifetime of the function to which they belong. Heap allocations, however, will not be deallocated automatically when they go out of scope. To avoid the heap becoming dissociated, we must deallocate it explicitly or, in the case of memory-managed programming languages (like Go), rely on the garbage collector to locate and delete unreferenced objects.</p>
<p>In general, in languages with a <strong>GC</strong>, the more you can store on the stack, the better, since these allocations are never seen by the <strong>GC</strong>. Compilers use a technique called <em>escape analysis</em> to determine whether something can be allocated on the stack or should be placed on the heap.</p>
<p>In practice, writing programs that force the compiler to allocate only on the stack can be very limiting, and thus, in Go, we take advantage of its wonderful GC to do the work of keeping our heap clean.</p>
<p>If you want to take a look and delve deeper into the subject, check out this link written by Richard L. Hudson: <a target="_blank" href="https://blog.golang.org/ismmkeynote">https://blog.golang.org/ismmkeynote</a>.</p>
<h1 id="heading-some-types-of-applications-implemented-in-go">Some types of applications implemented in Go</h1>
<p><strong>Go</strong> is a general-purpose language. <a target="_blank" href="https://github.com/nouney/awesome-go">In this link</a>, you can see various applications implemented in <strong>Go</strong> and their respective categories.</p>
<h2 id="heading-some-types">Some types:</h2>
<p>. Web backend <em>(with</em> <a target="_blank" href="https://github.com/nouney/awesome-go#web-frameworks"><em>various frameworks</em></a> <em>available)</em><br />. Web Assembly (<a target="_blank" href="https://github.com/vugu/vugu"><em>one of them is vugu framework</em></a>)<br />. Microservices (<em>some frameworks:</em> <a target="_blank" href="https://micro.mu/"><em>Go Micro</em></a><em>,</em> <a target="_blank" href="https://gokit.io/"><em>Go Kit</em></a><em>,</em> <a target="_blank" href="https://github.com/NYTimes/gizmo"><em>Gizmo</em></a><em>,</em> <a target="_blank" href="https://github.com/koding/kite"><em>Kite</em></a>)<br />. Fragments services (<em>Term mentioned by @jeffotoni in a microservices discussion group</em>)<br />. Lambdas (<em>FaaS</em> <a target="_blank" href="https://www.alexedwards.net/blog/serverless-api-with-go-and-aws-lambda"><em>example</em></a>)<br />. Client Server<br />. Terminal applications (<a target="_blank" href="https://github.com/rivo/tview">using the tview lib</a>)<br />. IoT (<a target="_blank" href="https://github.com/nouney/awesome-go#iot-internet-of-things"><em>some frameworks</em></a>)<br />. Bots (<a target="_blank" href="https://github.com/nouney/awesome-go#bot-building"><em>some here</em></a>)<br />. Client Applications using Web technology<br />. Desktop using Qt+QML, Native Win Lib (<a target="_blank" href="https://github.com/therecipe/qt"><em>example Qt</em></a><em>,</em> <a target="_blank" href="https://therecipe.github.io/widgets_playground/"><em>Qt widgets</em></a><em>,</em> <a target="_blank" href="https://doc.qt.io/qt-5/qtqml-index.html"><em>Qml</em></a>)<br />. Network Applications<br />. Protocol applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> Applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/SOAP">SOAP</a> Applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/GraphQL">GraphQL</a> Applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/Remote_procedure_call">RPC</a> Applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">TCP</a> Applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/GRPC">gRPC</a> Applications<br />. <a target="_blank" href="https://en.wikipedia.org/wiki/WebSocket">WebSocket</a> Applications<br />. GopherJS (<a target="_blank" href="https://github.com/gopherjs"><em>compiles Go to JavaScript</em></a>)</p>
]]></content:encoded></item><item><title><![CDATA[Why We Love Go! ❤]]></title><description><![CDATA[Go: The fastest growing language for backend Go was designed by Google in 2007 to improve programming productivity in an era of multicore, networked…]]></description><link>https://jeffotoni.hashnode.dev/why-we-love-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/why-we-love-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Wed, 26 Apr 2023 17:37:22 GMT</pubDate><content:encoded><![CDATA[<p>Go: The fastest growing language for backend</p>
<p>Go was designed by Google in 2007 to improve programming productivity in an era of multicore, networked machines, and large codebases. The designers wanted to address criticisms of other languages in use at Google, but keep their useful features. The creators Rob Pike, Ken Thompson, and Robert Griesemer kept Go's syntax similar to C. In late 2008, Russ Cox joined the team and helped move the language and libraries from prototype to reality.</p>
<p>The Go language was released in 2009 with the purpose of making it easier to solve problems related to networked layers, scalability, performance, productivity, and most importantly, concurrency. Rob Pike himself declared that "Go was designed to address a set of engineering problems we encountered building large server software."</p>
<p>Go has been influenced by various programming languages and different paradigms, including Alef, APL, BCPL, C, CSP, Limbo, Modula, Newsqueak, Oberon, occam, Pascal, Smalltalk, and Crystal. It is clear that they used what was best and created something new and lean, with the minimum necessary to solve the proposed problems without losing its simplicity. I believe this is what we can call innovation. Go broke the paradigms of languages and implemented something new in a simple and very powerful way.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> mainimport <span class="hljs-string">"fmt"</span><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Hello all folks!"</span>)
}
</code></pre>
<h1 id="heading-less-is-exponentially-more">Less is exponentially more</h1>
<p>The Go developer team say its creation is an attempt to make programmers more productive. Improving the software development process on <em>Google</em>. The first goal was to create a better language to address the challenges of <em>scalable concurrency</em>, ie software that handles many concerns simultaneously, an example would be coordinating a thousand <em>back-end</em> servers sending network traffic all the time.</p>
<p>Keeping the Go language small allows for more important goals. Being small makes Go easier to learn, easier to understand, easier to implement, easier to reimplement, easier to debug, easier to tweak, and easier to evolve. Doing less allows for more. It's an expression used by the Go development team: “<em>Do Less. Enable More</em>” would be the balance between the universe of existing problems and what Go can help to solve such problems well. Go explicitly wasn't designed to solve every problem, instead they've done enough for us to create our own custom solutions with ease, while making it very clear that Go can't do everything.</p>
<h1 id="heading-uproar-in-the-go-community">Uproar in the Go community</h1>
<p>Several features of modern languages were left out, contradicting and going in the opposite direction of other current languages, some features such as: the use of immutability declarations, pattern matching data types, generics, exception handling, inheritance, generic programming, assertion, and method overloading, and many other points. All of the above resources were criticized and pointed out to the creators of Go, who responded: "These omissions were simplifications that contributed and contribute to the strength of Go." There are many things in the Go language and libraries that differ from modern practices, and it was a decision of the Go development team: "Sometimes it's worth trying a different approach."</p>
<p>Everyone is invited to help and contribute if they wish. Interested parties can open proposals for new features and everything related to the language ecosystem. The Go source code is available on GitHub. The documentation on how you can contribute to the language is provided here.</p>
<h1 id="heading-concurrency-is-different-from-parallelism">Concurrency is different from parallelism</h1>
<p>One of the famous phrases is: *“Competition is about dealing with many things at the same time. Parallelism is doing many things at the same time”.*Concurrency is the composition of independently executing calculations. Concurrency is a way of structuring software, and it is definitely not parallelism although it does allow for parallelism.</p>
<p>If you only have one processor, your program can still be concurrent, but not parallel. On the other hand, a well-written concurrent program can run efficiently in parallel on a multiprocessor. I suggest checking out this video of a talk by <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike">Rob Pike</a> “<a target="_blank" href="https://vimeo.com/49718712">Concurrency is not Parallelism</a>”.</p>
<p>Concurrency in Go is very powerful and also simple to code, which was the intent of the engineers who developed Go. Solving many problems is much more efficient using concurrency and this is the power of Go, so it has become a god when it comes to concurrency. Due to this, problems encompassed in this universe will be solved very efficiently and most importantly, with very little computational resources.</p>
<p>The example below is a classic one when referring to concurrency, when we want to balance CPU and I/O we use this parttern <strong>Fan-out</strong>.</p>
<h2 id="heading-what-is-fan-out">What is Fan-out ?</h2>
<p>Multiple functions can read from the same channel until that channel is closed, this is called <strong><em>fan-out</em></strong> . This provides a way to distribute work among a group of workers to parallelize <strong>CPU</strong> and <strong>I/O</strong> usage.</p>
<pre><code class="lang-go"><span class="hljs-comment">/*
* Example Worker
* @package     main
* @author      @jeffotoni
 */</span>

<span class="hljs-comment">// In this example we'll look at how to implement</span>
<span class="hljs-comment">// a _worker pool_ using goroutines and channels.</span>
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"time"</span>

<span class="hljs-comment">// Here's the worker, of which we'll run several</span>
<span class="hljs-comment">// concurrent instances. These workers will receive</span>
<span class="hljs-comment">// work on the `jobs` channel and send the corresponding</span>
<span class="hljs-comment">// results on `results`. We'll sleep a second per job to</span>
<span class="hljs-comment">// simulate an expensive task.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>, jobs &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, results <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">int</span>)</span></span> {

    <span class="hljs-keyword">for</span> j := <span class="hljs-keyword">range</span> jobs {

        fmt.Println(<span class="hljs-string">"worker"</span>, id, <span class="hljs-string">"started  job"</span>, j)

        time.Sleep(time.Second)

        fmt.Println(<span class="hljs-string">"worker"</span>, id, <span class="hljs-string">"finished job"</span>, j)
        results &lt;- j * <span class="hljs-number">2</span>
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// In order to use our pool of workers we need to send</span>
    <span class="hljs-comment">// them work and collect their results. We make 2</span>
    <span class="hljs-comment">// channels for this.</span>
    jobs := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">100</span>)
    results := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">100</span>)

    <span class="hljs-comment">// This starts up 3 workers, initially blocked</span>
    <span class="hljs-comment">// because there are no jobs yet.</span>
    <span class="hljs-keyword">for</span> w := <span class="hljs-number">1</span>; w &lt;= <span class="hljs-number">3</span>; w++ {
        <span class="hljs-keyword">go</span> worker(w, jobs, results)
    }

    <span class="hljs-comment">// Here we send 5 `jobs` and then `close` that</span>
    <span class="hljs-comment">// channel to indicate that's all the work we have.</span>
    <span class="hljs-keyword">for</span> j := <span class="hljs-number">1</span>; j &lt;= <span class="hljs-number">5</span>; j++ {
        jobs &lt;- j
    }

    <span class="hljs-built_in">close</span>(jobs)

    <span class="hljs-comment">// Finally we collect all the results of the work.</span>
    <span class="hljs-keyword">for</span> a := <span class="hljs-number">1</span>; a &lt;= <span class="hljs-number">5</span>; a++ {
        &lt;-results
    }
}
</code></pre>
<h1 id="heading-good-points-of-go">Good points of Go:</h1>
<ul>
<li><p>Does not have Generics;</p>
</li>
<li><p>Does not have operator overload;</p>
</li>
<li><p>Does not have pointer arithmetic;</p>
</li>
<li><p>Threads management is not explicit;</p>
</li>
<li><p>Has type inference;</p>
</li>
<li><p>Dependencies are clear;</p>
</li>
<li><p>The syntax is clean;</p>
</li>
<li><p>The semantics are clear;</p>
</li>
<li><p>Composition and not inheritance;</p>
</li>
<li><p>Native GC (Garbage collector);</p>
</li>
<li><p>Has Goroutines;</p>
</li>
<li><p>Native support for concurrent programming;</p>
</li>
<li><p>First Class Functions (<em>we can pass functions as parameters</em>);</p>
</li>
<li><p>Multiplataform;</p>
</li>
<li><p>Open Source;</p>
</li>
<li><p>Very low Learning Curve or easy to learn;</p>
</li>
<li><p>Highly productive;</p>
</li>
<li><p>Resolves scalability issues;</p>
</li>
<li><p>It can lowers your server costs drastically;</p>
</li>
<li><p>Several problems thought from the Go perspective become much easier to treat and solve them;</p>
</li>
<li><p>It has only 25 reserved words;</p>
</li>
<li><p>Multi-paradigm: concurrent, functional, imperative, object-oriented;</p>
</li>
<li><p>MemorySafe.</p>
</li>
</ul>
<p>We know that several points above will be <em>criticized</em>, but in practice and over time we realized that all the omitted simplifications made Go an even more powerful language. For simple or complex projects, Go will always be an excellent alternative, as it makes everything simpler and leaner, easier to code and maintain.</p>
<p><strong><em>Go is love</em></strong> ❤</p>
]]></content:encoded></item><item><title><![CDATA[Getting Started in Go]]></title><description><![CDATA[Purpose of this post is simply to present a little of why the language Go appeared and present a little of its syntax and demonstrate some areas where Go…]]></description><link>https://jeffotoni.hashnode.dev/getting-started-in-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/getting-started-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Tue, 25 Apr 2023 20:26:44 GMT</pubDate><content:encoded><![CDATA[<p>Purpose of this post is simply to present a little of why the language Go appeared and present a little of its syntax and demonstrate some areas where Go is more applied. For everyone who would like to further increase their arsenal for web development this post will help you to clarify some important points when we are starting and learning a new programming language.</p>
<h1 id="heading-getting-started-in-go">Getting Started in Go❤️</h1>
<p>Before we start, it's important to point out that programming languages ​​are tools and like any good tool, we have to know when to use them. There are scenarios and problems that are only solved with specific languages ​​and there are other universes of problems that we have hundreds or thousands of languages ​​that somehow solve the same problem. So like a good professional, the more tools you know to solve problems, the better it will be for your professional career 🤩.</p>
<p>The Go language in its universe of possibilities is a <strong>common use language</strong> I don't really like this term it seems like it's like a silver bullet and solves all problems but not really, <strong>Go was born by a purpose and solve problems of the web universe and take advantage of the new technology of multicores in servers,</strong> well this was the initial purpose 😂.</p>
<h1 id="heading-history-of-the-go-project">History of the Go project</h1>
<p><em>“Robert Griesemer, Rob Pike, and Ken Thompson began sketching goals for a new language on the whiteboard on September 21, 2007. Within days, the goals settled into a plan to do something and a fair idea of ​​what it would be like. . Design continued part-time in parallel with unrelated work. In January 2008, Ken started work on a compiler to explore ideas; it generated C code as its output. By mid-year, the language had become a full-time project and had established itself enough to try a production compiler. In May 2008, Ian Taylor started independently on a GCC frontend for Go using the preliminary specs. Russ Cox joined in late 2008 and helped move the language and libraries from prototype to reality.”</em></p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*7gKR-qozxb5_kMtghQ3vbg.png" alt class="image--center mx-auto" /></p>
<p>Go became a public open source project on <strong>November 10, 2009</strong>   . Countless people from the community contributed ideas, discussions, and code.</p>
<p><em>“There are now</em> <strong><em>millions of Go programmers</em></strong> <em>“<strong><strong>Gophers</strong></strong>” around the world, and there are more every day. The success of Go far exceeded expectations.”</em></p>
<h1 id="heading-why-they-created-a-new-language">Why they created a new language</h1>
<p><em>“Go was born out of frustration with the existing languages ​​and environments for the work we were doing at Google. Programming had become too difficult and the choice of languages ​​was partly to blame. You had to choose between efficient compilation, efficient execution, or ease of programming; all three were not available in the same primary language. Programmers who might choose ease over security and efficiency, switching to dynamically typed languages ​​like Python and JavaScript rather than C++ or, to a lesser extent, Java.”</em></p>
<p><em>“Go addressed these issues by trying to combine the programming ease of an interpreted, dynamic language with the efficiency and security of a statically compiled language. It was also intended to be modern, with support for networked and multicore computing. Finally, working with Go is intended to be fast: it should take a few seconds at most to build a large executable on a single computer.”</em></p>
<p>A new Go language is born, to meet new needs and solve problems by taking advantage of the computational power as much as possible. And of course creating your mascot for the thousands of <strong>gophers</strong> that saw to emerge from this moment on.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:400/1*o2BRMhO2v4BPBQ_CkqLcBw.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-official-site">Official site</h1>
<p>To start in Go❤️ let's take a few steps back, let's start our whole trajectory knowing the official website of lang this is the official page <a target="_blank" href="http://golang.org">golang.org</a>, here we will find all the information we could know about Go and much more. Here we have the docs, packages, blog and our darling <a target="_blank" href="http://play.golang.org">play.golang.org</a>, language specs, download, Go tour and much more.</p>
<p>The official website apparently looks small but it is very complete and big. So we have practically everything we need to know about Go to start our learning in this language that is a phenomenon.</p>
<p><strong>Where do I start on the Site</strong></p>
<p>I'm going to create a line of reasoning so that we can understand Go in the most practical way possible.</p>
<p>Before installing Go, or running Go through play, let's go through some parts of the doc so that we can understand a little of the history of Go and why a new language was born in this universe of thousands of programming languages.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*bOl58-yIDtx1KtGcDUIEQA.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-effective-go">Effective Go</h1>
<p>This link is the first one that everyone should read first.
Effective Go❤️ on this site you will find all the material you need to get a good idea of ​​the Go language: Control Structure, Functions, Concurrent Programming using Goroutines, Methods, Maps and much more.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*7BRDpycnblhs4cR9E7RrDg.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-a-go-tour">A go tour</h1>
<p>This link would be the second most important link in my hierarchy for us to learn Go.
<a target="_blank" href="https://tour.golang.org/welcome/1">Tour Go</a>❤️ on this site you will be able to test and take a look at some of the features of the Go language 😱 that's right all through the browser without having to install anything on the machine.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*Eyd1h6jGWwOctS3epaes5g.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-playground-go">Playground Go</h1>
<p>Here is very beautiful, you don't need to install anything on the machine to run something quickly in Go, just enter <a target="_blank" href="http://play.golang.org">play.golang.org</a></p>
<p><a target="_blank" href="https://play.golang.org/p/MAohLsrz7JQ">Play Go</a>❤️ on this site you will be able to run Go 😱 that's right we don't need to install anything for now, you can run everything through the browser and get to know the syntax of the language and learning.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*C0igeYAJki0w_6pNsBaJAg.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-frequently-asked-questions">Frequently Asked Questions</h1>
<p>This link would be our third step, I believe you now have several questions, generated by <a target="_blank" href="https://golang.org/doc/effective_go.html">Effective</a> Go and by [Tour](https://tour.golang. org/welcome/1) that did.
<a target="_blank" href="https://golang.org/doc/faq">Faq</a>❤️ this is where you will take a few hours to read this, it doesn't have to be all at once, of course, but you must read it. This page is essential to organize your ideas and really understand a little more about Go  .</p>
<p>This is one of the largest pages and requires more reading, but this page is essential for a better understanding of the Go language, the time you spend reading this page will surely save you hours of work.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*urYIJXS2z4vxF4u3ULjM9w.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-native-go-packages">Native Go packages</h1>
<p>This link would be so you can take a look and understand how they are organized and how is the documentation of the functions, libs, pkgs that we can use in the Go language. This is one of the strengths of the language, it is very complete for web development for servers.
<a target="_blank" href="https://golang.org/pkg/">Pkg</a>❤️ I chose <a target="_blank" href="https://golang.org/pkg/strings/">pkg string</a> here so you can check out how the documentation formatting is language and already with examples that can be executed by the browser, everything to facilitate learning and understanding   .</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*6iBcWbBLUOHDXcVkx6L_sw.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-editors-and-ide">Editors and IDE</h1>
<p>This link is about the IDEs and Editors that you can use when you have <strong>Godando</strong>. The Go language doesn't need much for us to be able to edit our codes, but we have some interesting plugins to make our day to day even easier
<a target="_blank" href="https://golang.org/doc/editors.html">Editors and IDE</a>❤️ This link will not have Sublime and nvim which are two editors that I use around here on a daily basis, <strong>sublime</strong> by the <a target="_blank" href="https://blog.golang.org/survey2020">survey</a> survey, only 7.7% use sublime and <strong>vim</strong> 14% <strong>nvim</strong> is a plugin that they will use in vim. The darling and adopted by the Go team is <strong>VsCode</strong> with 41% adherence.</p>
<h1 id="heading-strengths-of-the-go-language">Strengths of the Go language</h1>
<p>Before we do our famous “Hello World” let's show some strengths of the Language, let's preview the pillars and characteristics of the Go language.</p>
<h2 id="heading-3-pillars">3 Pillars</h2>
<p>We have some well defined pillars in Go, this will help you to further clarify your horizon when it comes to Go.</p>
<ul>
<li><p><strong>Simplicity</strong></p>
</li>
<li><p><strong>Legibility</strong></p>
</li>
<li><p><strong>Productivity</strong></p>
</li>
</ul>
<p>This has become over the years something so standard for those who are developing in the Go universe that it sounds like poetry to the ears. We know that go is an attempt to join two different worlds, the world of compiled languages ​​with interpreted languages, in 2007 the idea was born and with the objective of creating a new programming language.</p>
<h2 id="heading-main-features">Main features</h2>
<p>In Go we have some outstanding features of the language that make it even more powerful for developing web applications for servers.</p>
<ul>
<li><p><strong>Only 25 keywords</strong></p>
</li>
<li><p><strong>Low learning curve</strong></p>
</li>
<li><p><strong>Compiled statically</strong></p>
</li>
<li><p><strong>Multiplatforms now support RISC-V</strong></p>
</li>
<li><p><strong>Concurrent Paradigm</strong></p>
</li>
<li><p><strong>Static Typing</strong></p>
</li>
<li><p><strong>Backward Compatibility</strong></p>
</li>
</ul>
<p>All these points make the language even more interesting, the team of engineers that developed the language did an excellent job or better see doing it, Go is simply fantastic some don't like its designer but it's understandable more than 20 years developing in OO and Functional paradigms as if there is no life on another planet is understandable 😂.</p>
<h1 id="heading-installing-go"><strong>Installing Go</strong></h1>
<p>This is the moment we've all been waiting for, get your hands dirty and install locally, on the official website you can't go wrong, there's nothing simpler than installing Go on your machine so you can program in Go. Taking advantage of this and making it clear that: <strong>We don't need to install Go on the server,</strong> this is exactly what you read, on your server whatever it may be, <em>On-premises, an Ec2 from Aws or a pod on k8s whether it's on Gke, or k8s from DigitalOcean, that is on ECS or EKS</em>, whether it is a serverless or on any hosting server of your choice, what you will need is the binary whether in a docker image for example or not. This <strong>is one of the strengths of Go,</strong> we don't need to carry stuff to the server <strong>this is one of the great benefits of using Go</strong> in web applications on servers and this is what <strong>Go</strong> became known for like the <strong>containers language</strong>😍.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:357/1*AmnDj6Ajc0hHEuP60Yt6Eg.gif" alt class="image--center mx-auto" /></p>
<p>Knowing all this, let's go to install Go and see how complex it is 😜😜, just kidding… 😂</p>
<p><a target="_blank" href="https://golang.org/doc/install">Install Go</a> in this link you will have the step by step on how to install in different Operating Systems but I will leave the installation in Linux here.</p>
<p><strong>Installation on Linux</strong></p>
<p>If you have a previous version of Go installed, be sure to <a target="_blank" href="https://golang.org/doc/manage-install">remove it</a> before installing another one.</p>
<ol>
<li><p><strong>$ sudo rm -rf /usr/local/go</strong></p>
</li>
<li><p>Download the file <a target="_blank" href="https://golang.org/dl/go1.15.6.linux-amd64.tar.gz">by clicking here go1.1</a>5.6 and extract it in <em>/usr/local</em></p>
</li>
<li><p><strong>$ sudo tar -C /usr/local -xzf</strong> [<strong>go1.15.6.linux-amd64.tar.gz</strong>](https://golang.org/dl/go1.15.6.linux -amd64.tar.gz)</p>
</li>
<li><p>Add <em>/usr/local/go/bin</em> to the <code>PATH</code> environment variable.</p>
</li>
<li><p><strong>$ export PATH=$PATH:/usr/local/go/bin</strong></p>
</li>
<li><p>To make what we did above global, that is, every time you enter your terminal “go” is executed, you can do this by adding the following line that I showed above to your $HOME/.profile or <em>/etc/profile</em> (for a system-wide install) or your bash or whatever you're using in your Linux environment.</p>
</li>
<li><p><strong>Note:</strong> Changes made to a profile file may not apply until the next time you log in to your computer. To apply the changes immediately, just run the shell commands directly or run them from the profile using a command like <code>source $HOME/.profile</code>.</p>
</li>
<li><p>Verify that you have installed Go by opening a command prompt and typing the following command:</p>
</li>
</ol>
<pre><code class="lang-go"><span class="hljs-keyword">go</span> version
</code></pre>
<p>If all goes well you will see: <em>“go version go1.15.6 linux/amd64”
</em>beautiful, simply beautiful you can say, very simple.</p>
<h1 id="heading-hello-world">Hello World</h1>
<p>Now it's time for our first "hello world" using Go.</p>
<p>There's no secret, we can use any editor we saw above and go to the top. In Go we don't need to compile when we're <strong>having</strong>, we can simply run our programs without having to turn them into binaries, ie compile.</p>
<p><strong>go run main.go</strong></p>
<p>Below is our first hello world, and just save the file with the .go extension and put the name “_main.go_” then just run it with the command “go run main.go”, in our example I called file from “<em>main.go”</em></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

  <span class="hljs-built_in">println</span>(<span class="hljs-string">"My first Hello World"</span>)

}
</code></pre>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span>(
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

  fmt.Println(<span class="hljs-string">"My first Hello World"</span>)

}
</code></pre>
<pre><code class="lang-go">$ <span class="hljs-keyword">go</span> run main.<span class="hljs-keyword">go</span>
</code></pre>
<p>This hello world of ours is the smallest structure we can assemble to output to the terminal.</p>
<p>To be a little clearer when using the <strong>println</strong> function we have to know that it is a built-in function (at runtime) that can eventually be removed, while the <em>fmt</em> package is in the standard library, which will persist.</p>
<p><strong>go build</strong></p>
<p>Now let's turn it into a binary let's compile it and for that we will use “<strong>go build</strong>” or “<strong>GOARCH=386 GOOS=linux go build -o myprogram main.go</strong>” we are now informing the architecture and operating system that we want to compile our Go program.</p>
<pre><code class="lang-go">$ GOARCH=<span class="hljs-number">386</span> GOOS=linux <span class="hljs-keyword">go</span> build -o myhello main.<span class="hljs-keyword">go</span>
</code></pre>
<p>This command will make the build it will generate an “executable” a binary to run on your operating system. Very easy isn't it? 😍 I would say very beautiful. With this binary you'll be able to run it on your machine or on any server that has the same architecture and operating system that you made for your compilation.</p>
<p>It's important to always emphasize this detail: <strong><em>“We don't install anything Go on our web servers”</em></strong> is exactly what you read, you don't need to install anything, you just need the binary. ❤️ This is why <strong>Go</strong> became known as the <strong>Language of Containers</strong>. Are you saying this isn't fantastic? 😍 To run a web application on your server, just send the binary to it. Wow, that's right just from the binary without needing to take anything else related to your project at all.</p>
<p><strong>Go and Docker</strong></p>
<p>Since we are talking about docker and saying that we only need the binary to run our project on <strong>Go</strong> let's present what our image would look like using docker so that we can now use Go on servers like Google's GKE, AWS's EKS, or k8s from DigitalOcean or simply use with docker.</p>
<pre><code class="lang-go">##################################################
# Dockerfile distroless
##################################################
FROM golang:<span class="hljs-number">1.15</span> as builder
WORKDIR /<span class="hljs-keyword">go</span>/src/main
COPY . .
RUN CGO_ENABLED=<span class="hljs-number">0</span> GOOS=linux <span class="hljs-keyword">go</span> build -o main main.<span class="hljs-keyword">go</span>
RUN cp main /<span class="hljs-keyword">go</span>/bin/main

#############################
# STEP <span class="hljs-number">2</span> build a small image
#############################
FROM gcr.io/distroless/base
COPY --from=builder /<span class="hljs-keyword">go</span>/bin/main /
CMD[<span class="hljs-string">"/main"</span>]
</code></pre>
<p>Look how beautiful😁 just under 10 lines. We have a Go image so we can compile our project and then we do something like S<a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/api-simple/docker-golang-scratch">cratch</a> but we are using distroless which is a very small lean base and contains our binary. I'm sorry, but isn't this fantastic or simply beautiful❤️?</p>
<p>The <strong>distroless</strong> concept is simple, it assumes that we focus on our application and less on the Linux distribution.</p>
<p>Now let's make a small example of a rEST API just to exemplify our Dockerfile and show in practice how simple it is to upload a docker image of our project.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span>(
<span class="hljs-string">"log"</span>
<span class="hljs-string">"net/http"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
mux := http.NewServeMux()
mux.HandleFunc(<span class="hljs-string">"/api/v1/ping"</span>, Ping)
log.Println(<span class="hljs-string">"Run Server 8080"</span>)
log.Fatal(http.ListenAndServe(<span class="hljs-string">":8080"</span>, mux))
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Ping</span><span class="hljs-params">(w http.ResponseWriter, r *http.Request)</span></span> {
log.Println(<span class="hljs-string">"server ok"</span>)
w.WriteHeader(http.StatusOK)
w.Write([]<span class="hljs-keyword">byte</span>(<span class="hljs-string">`{"msg":"pong"}`</span>))
}
</code></pre>
<p>Now we just build our project with the following command:</p>
<p>$ docker build — no-cache -f Dockerfile -t jeffotoni/apisimplego:latest .</p>
<p>this will generate an image locally on your machine and now just run it for us to test.</p>
<p>$ docker run — rm — name apisimplego -p 8080:8080 jeffotoni/apisimplego</p>
<p>Ready now, just shoot to our /api/v1/ping endpoint that we created</p>
<p>$ curl -i <a target="_blank" href="http://localhost:8080/api/v1/ping">localhost:8080/api/v1/ping</a></p>
<p>Say it's not beautiful 😍</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>This post is a simple summary for you who would like to increase your web programming arsenal. I hope you enjoyed.</p>
<p>The channel where the live took place: <a target="_blank" href="https://youtube.com/user/jeffotoni">https://youtube.com/user/jeffotoni</a></p>
<p>The PDF link of the presentation can be found at: <a target="_blank" href="http://speakerdeck.com/jeffotoni">speakerdeck.com/jeffotoni</a></p>
]]></content:encoded></item><item><title><![CDATA[A little about Goroutines in Go!]]></title><description><![CDATA[One of the main goals of the Go programming language is to make concurrency simpler, faster, and more efficient. Goroutines are certainly one of the main…]]></description><link>https://jeffotoni.hashnode.dev/a-little-about-goroutines-in-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/a-little-about-goroutines-in-go</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Go Language]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Tue, 25 Apr 2023 17:41:12 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-goroutines-instead-of-threads">Goroutines instead of threads</h2>
<p>One of the main goals of the <strong>Go programming language</strong> is to make concurrency simpler, faster, and more efficient.</p>
<p>Goroutines are certainly one of the main features of Go and one of the main reasons why Go is so efficient at performing tasks in parallel.</p>
<p>When we create APIs in Go using net/http and receive a large number of requests, what does the pkg net/http use? If your answer is Goroutines, you are correct 😍.</p>
<p>I avoid the term "lightweight threads" as it creates confusion for those who are starting or trying to understand what Goroutines are. Although it is true that Goroutines are similar to "lightweight threads" in other systems, Go uses a different implementation that is optimized for the context of Go. Therefore, it may be better to explain Goroutines in terms of how they work in Go, which I believe will make it even easier for you to understand.</p>
<p>Instead of saying that Goroutines are "lightweight threads", we can say that Goroutines are lightweight units of concurrency that are executed in a single execution thread or in several depending on how the Go runtime decides to manage them. This means that Go can execute many Goroutines simultaneously in a single thread or multiple threads.</p>
<p>Goroutines are managed by the Go runtime and not by the underlying operating system. This means that Goroutines are much lighter and more efficient than traditional operating system threads, and that Go can manage them more effectively to achieve maximum performance and scalability.</p>
<p>One of the goals of Goroutines in Go is to allow you to write concurrent programs easily and efficiently. This means that you can have multiple Goroutines running simultaneously, each executing a different task, without worrying about resource locks, active waits, or other common problems in concurrent programming.</p>
<p>To create a Goroutine in Go, you can simply add the "go" keyword before a function call. For example, consider the following code:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">myFuncJeff</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// your code here.</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// start the Goroutine</span>
    <span class="hljs-keyword">go</span> myFuncJeff()
    <span class="hljs-comment">// you can put something here</span>
}
</code></pre>
<p><strong>Goroutines</strong> are lightweight and take advantage of all available processing power. Goroutines only exist in the virtual space of the Go runtime and not in the operating system.</p>
<p><strong>Goroutine</strong> is a method/function that can be executed independently along with other goroutines. Each concurrent activity in the Go language is usually called a <strong>Goroutine</strong>.</p>
<p><strong>Go</strong> is a <strong>multiparadigm</strong> language and one of the most relevant paradigms is <strong>concurrency</strong>. One of the most relevant and important points in the <strong>Go</strong> language is working with <strong>concurrency</strong>. <strong>Go</strong> <strong>innovated</strong> by breaking the <strong>traditional</strong> model of <a target="_blank" href="https://en.wikipedia.org/wiki/Thread_%28computing%29"><em>threads</em></a> and their usage by creating a new model, <a target="_blank" href="https://golang.org/doc/effective_go.html#concurrency"><em>goroutines</em></a>. <strong>Goroutines</strong> are responsible for executing tasks in <strong>Go</strong> asynchronously. They are very powerful and a simple machine with <strong>1GB</strong> of <strong>RAM and 1 CPU</strong> can run thousands of <strong>goroutines</strong>.</p>
<p>In Go, <strong>Goroutines</strong> make <strong>concurrency</strong> easy to use. <strong>Goroutines</strong> can be very cheap: they have little overhead besides the memory for the stack, which is only a few kilobytes.</p>
<p>To make stacks small, the Go runtime uses resizable, bounded stacks. A newly launched <strong>goroutine</strong> gets a few kilobytes, which is almost always enough. When it's not, the runtime grows (and shrinks) the memory to store the stack automatically, allowing many <strong>goroutines</strong> to live in a modest amount of memory.</p>
<p>The CPU overhead has, on average, three cheap instructions per function call. It's practical to create <strong>hundreds of thousands of goroutines</strong> in the same address space. If <strong>goroutines</strong> were just <strong>threads</strong>, the system resources would run out at a much lower number.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">enviarEmail</span><span class="hljs-params">(...<span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-comment">// Code to send email</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">enviarParaFila</span><span class="hljs-params">(mensagem <span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-comment">// Code sending to queue</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// goroutine sends email</span>
    <span class="hljs-keyword">go</span> enviarEmail(<span class="hljs-string">"jeff@gmail.com"</span>, <span class="hljs-string">"my email"</span>)
    <span class="hljs-comment">// goroutine sends to queue</span>
    <span class="hljs-keyword">go</span> enviarParaFila(<span class="hljs-string">"Message to queue"</span>)
    <span class="hljs-comment">// Do something else here</span>
}
</code></pre>
<p>In this example, we created two functions, enviarEmail and enviarParaFila, which simulate sending an email and sending a message to a queue, respectively. Then, in the main() function, we start two different Goroutines, one to send an email and another to send a message to the queue.</p>
<p>Note that we are using the go keyword before each function call to start a separate Goroutine for each task. This means that the program will continue to run normally, without waiting for the email or queue message to be completed.</p>
<p>The design of Go was heavily influenced by C.A.R. Hoare's 1978 article "Communicating Sequential Processes" (CSP).</p>
<h2 id="heading-simultaneity-in-csp-ideas">Simultaneity in CSP ideas</h2>
<p>One of the most successful models for providing high-level language support for concurrency is Hoare's Communicating Sequential Processes (CSP), Occam and Erlang are two well-known languages that derive from CSP. The concurrency primitives of Go derive from a different part of the genealogy whose main contribution is the powerful notion of channels as first-class objects. Experience with several previous languages showed that the CSP model fits well within a procedural language framework.</p>
<p>The biggest difference between Go and the CSP model, aside from syntax, is that Go models communication channels explicitly as channels, while Hoare's language processes send messages directly to each other, similar to Erlang.</p>
<p>Well, to get to this result, Go again received criticism of the adopted model. Go incorporates a variant of CSP (Communicating Sequential Processes), a formal language for describing interaction patterns in concurrent systems with first-class channels. A single-write approach was not adopted to value semantics in the context of concurrent computing as is done in Erlang, instead they adopted something practical and which resulted in something powerful, allowing for simple and safe concurrent programming, but does not prohibit incorrect programming. And the created motto was: "<em>Don't communicate by sharing memory, share memory by communicating</em>".</p>
<p>The simplicity and concurrency support offered by Go generates robustness.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"net/http"</span>
    <span class="hljs-string">"time"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getSites</span><span class="hljs-params">(url <span class="hljs-keyword">string</span>)</span></span> {
    response, err := http.Get(url)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Printf(<span class="hljs-string">"Error reading %s: %s\n"</span>, url, err)
        <span class="hljs-keyword">return</span>
    }
    <span class="hljs-keyword">defer</span> response.Body.Close()
    fmt.Printf(<span class="hljs-string">"%s read successfully\n"</span>, url)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// URLs we will read</span>
    urls := []<span class="hljs-keyword">string</span>{
        <span class="hljs-string">"https://www.google.com"</span>,
        <span class="hljs-string">"https://www.facebook.com"</span>,
        <span class="hljs-string">"https://www.github.com"</span>,
        <span class="hljs-string">"https://www.linkedin.com"</span>,
    }
    <span class="hljs-comment">// Separate goroutine to read each URL</span>
    <span class="hljs-keyword">for</span> _, url := <span class="hljs-keyword">range</span> urls {
        <span class="hljs-keyword">go</span> getSites(url)
    }
    <span class="hljs-comment">// Do something else here</span>
        <span class="hljs-comment">// ...</span>
    time.Sleep(<span class="hljs-number">5</span> * time.Second)
}
</code></pre>
<p>In this example, we defined a <code>getSite</code> function that uses the <code>net/http</code> package to make an HTTP request to a specific website and read the response. Then, in the <code>main()</code> function, we defined a list of URLs that we want to read and started a separate Goroutine to read each URL.</p>
<p>Note that we're using a <code>for</code> loop to iterate through the list of URLs and start a separate Goroutine for each URL using the <code>go</code> keyword. This means that the program will continue to run normally, without waiting for each HTTP request to complete.</p>
<p>To give the Goroutines time to do their job, we use the <code>time.Sleep()</code> function to suspend the program's execution for a short period of time. In this example, we use a delay of 5 seconds to allow the Goroutines to finish executing.</p>
<p>Now, let's write the same code using <code>sync.WaitGroup</code> to synchronize our Goroutines and gain even better control over them.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"net/http"</span>
    <span class="hljs-string">"sync"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getSite</span><span class="hljs-params">(url <span class="hljs-keyword">string</span>, wg *sync.WaitGroup)</span></span> {
    <span class="hljs-comment">// Signal the WaitGroup when the Goroutine finishes</span>
    <span class="hljs-keyword">defer</span> wg.Done()

    resp, err := http.Get(url)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Printf(<span class="hljs-string">"Error reading %s: %s\n"</span>, url, err)
        <span class="hljs-keyword">return</span>
    }
    <span class="hljs-keyword">defer</span> resp.Body.Close()

    fmt.Printf(<span class="hljs-string">"%s read successfully\n"</span>, url)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// URLs we will read</span>
    urls := []<span class="hljs-keyword">string</span>{
        <span class="hljs-string">"https://www.google.com"</span>,
        <span class="hljs-string">"https://www.facebook.com"</span>,
        <span class="hljs-string">"https://www.github.com"</span>,
        <span class="hljs-string">"https://www.linkedin.com"</span>,
    }
    <span class="hljs-comment">// Create a WaitGroup to synchronize the Goroutines</span>
    <span class="hljs-keyword">var</span> wg sync.WaitGroup
    <span class="hljs-keyword">for</span> _, url := <span class="hljs-keyword">range</span> urls {
        <span class="hljs-comment">// Add WaitGroup for each Goroutine</span>
        wg.Add(<span class="hljs-number">1</span>)
        <span class="hljs-comment">// Pass the WaitGroup as a pointer</span>
        <span class="hljs-keyword">go</span> getSite(url, &amp;wg)
    }
    <span class="hljs-comment">// Wait until all Goroutines finish</span>
    wg.Wait()
    fmt.Println(<span class="hljs-string">"done"</span>)
}
</code></pre>
<p>Using WaitGroup, we can ensure that all Goroutines finish executing before the program continues. This is especially useful when we want the program to only terminate when all concurrent tasks are completed.</p>
<h2 id="heading-concurrency-is-different-from-parallelism">Concurrency is different from Parallelism</h2>
<p>One of the famous quotes is: <em>"Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once."</em> <strong>Concurrency</strong> is the <strong>composition</strong> of independently executing computations. <strong>Concurrency</strong> is a way of structuring software and definitely not parallelism, although it enables parallelism.</p>
<p>If you have only one physical core in your processor, your program can still be concurrent but cannot be parallel. On the other hand, a well-written concurrent program can efficiently run in parallel on a processor that has more than one physical core. I suggest checking out this video of a talk by <a target="_blank" href="https://en.wikipedia.org/wiki/Rob_Pike"><em>Rob Pike</em></a> "<a target="_blank" href="https://vimeo.com/49718712"><em>Concurrency is not Parallelism</em></a>."</p>
<p><strong>Concurrency</strong> in <strong>Go</strong> is very powerful and also easy to use, this was the intention of the engineers who developed <strong>Go</strong>. Solving many problems is much more efficient using <strong>concurrency</strong> and this is the <strong>power</strong> of <strong>Go</strong>, which has become a <strong>god</strong> when it comes to <strong>concurrency</strong>. Due to this, problems encompassed in this universe will be solved with much <strong>efficiency</strong> and most importantly, with very <strong>little computational resources</strong>.</p>
<p>Want to further deepen your understanding of <strong>concurrency</strong>? Just follow this <a target="_blank" href="https://github.com/golang/go/wiki/LearnConcurrency"><em>link</em></a>. Want to test and see some examples? <a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/goroutine"><em>Click here</em></a>.</p>
<p><strong>Goroutine</strong> is a very extensive topic, full of details and many interesting situations. So, it requires us to make a post only about it in the future so that it can be treated with due care and attention.</p>
<p>Check out a simple example.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>{fmt.Println(<span class="hljs-string">"hi I'm a goroutine1!"</span>)}()
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>{fmt.Println(<span class="hljs-string">"hi I'm a goroutine2!"</span>)}()
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>{fmt.Println(<span class="hljs-string">"hi I'm a goroutine3!"</span>)}()
    fmt.Println(<span class="hljs-string">"Hello, we are testing goroutines in Go!"</span>)  
    time.Sleep(time.Second)
}
</code></pre>
<h2 id="heading-channels">Channels</h2>
<p>Channels in Go are a way to synchronize communication between Goroutines and share data. They allow one Goroutine to safely and efficiently send data to another Goroutine without the need for locks or semaphores.</p>
<p>Channels are created using the <strong>make()</strong> function and can be used to send or receive values of a specific type. Channels can be defined with an optional capacity, which specifies how many values can be stored in the channel before it starts to block. If the capacity is not specified, the channel will have a capacity of zero, meaning it can only store one value at a time.</p>
<p>To send a value to a channel, we use the syntax channel &lt;- value. To receive a value from a channel, we use the same syntax but reversed, like value &lt;- channel. When we use the &lt;- syntax without a variable on the left or right side, it is used to block the execution of the Goroutine until a value is sent or received on the channel.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Criando um canal sem buffer</span>
    canalSemBuffer := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
    <span class="hljs-comment">// Criando um canal com buffer de tamanho 3</span>
    canalComBuffer := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">3</span>)

    <span class="hljs-comment">// Enviando valores para o canal sem buffer</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        canalSemBuffer &lt;- <span class="hljs-number">1</span>
        canalSemBuffer &lt;- <span class="hljs-number">2</span>
        canalSemBuffer &lt;- <span class="hljs-number">3</span>
        <span class="hljs-built_in">close</span>(canalSemBuffer)
    }()

    <span class="hljs-comment">// Enviando valores para o canal com buffer</span>
    canalComBuffer &lt;- <span class="hljs-number">1</span>
    canalComBuffer &lt;- <span class="hljs-number">2</span>
    canalComBuffer &lt;- <span class="hljs-number">3</span>
    <span class="hljs-built_in">close</span>(canalComBuffer)

    <span class="hljs-comment">// Recebendo valores do canal sem buffer</span>
    <span class="hljs-keyword">for</span> valor := <span class="hljs-keyword">range</span> canalSemBuffer {
        fmt.Println(<span class="hljs-string">"Valor recebido do canal sem buffer:"</span>, valor)
    }

    <span class="hljs-comment">// Recebendo valores do canal com buffer</span>
    <span class="hljs-keyword">for</span> valor := <span class="hljs-keyword">range</span> canalComBuffer {
        fmt.Println(<span class="hljs-string">"Valor recebido do canal com buffer:"</span>, valor)
    }
}
</code></pre>
<p>In this example, we are creating two channels, one with a buffer size of 0 and another with a buffer size of 3. When a channel has a buffer size greater than 0, it becomes a buffered channel. Buffered channels can hold a limited number of values until they are read. If the buffer is full and more values are sent to the channel, the sending goroutine will block until a value is read from the channel.</p>
<p>In the code above, we are sending three values to the buffered channel without blocking, and then closing the channel. After that, we are receiving these values from the channel using a for range loop.</p>
<p>We are also sending three values to the unbuffered channel using a goroutine, and then closing the channel. After that, we are receiving these values from the channel using a for range loop as well. Since the unbuffered channel has no capacity, the goroutine blocks until a receiver is ready to receive a value from the channel.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">produtor</span><span class="hljs-params">(canal <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++ {
        canal &lt;- i <span class="hljs-comment">// Envia um valor para o canal</span>
    }
    <span class="hljs-built_in">close</span>(canal) <span class="hljs-comment">// Fecha o canal</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">consumidor</span><span class="hljs-params">(canal &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> valor := <span class="hljs-keyword">range</span> canal { <span class="hljs-comment">// Itera sobre os valores recebidos do canal</span>
        fmt.Println(valor) <span class="hljs-comment">// Exibe o valor recebido</span>
    }
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Cria um canal sem capacidade definida</span>
    canal := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
    <span class="hljs-comment">// Goroutine do produtor para enviar valores para o canal</span>
    <span class="hljs-keyword">go</span> produtor(canal)
    <span class="hljs-comment">// Goroutine do consumidor para receber os valores do canal</span>
    consumidor(canal)
}
</code></pre>
<p>In this example, we have two different Goroutines: a producer and a consumer. The producer Goroutine sends values to the channel, while the consumer Goroutine receives them and displays them on the screen.</p>
<p>Note that we use the chan keyword to define the type of the channel. In this example, we are using chan int, which means that we are creating a channel that can be used to send or receive integer values.</p>
<p>We also use the &lt;-chan and chan&lt;- keywords to specify whether the channel should be used to send or receive values. In the case of the producer Goroutine, we are using canal chan&lt;- int, which means that we are creating a channel that can only be used to send integer values. In the consumer Goroutine, we are using canal &lt;-chan int, which means that we are creating a channel that can only be used to receive integer values.</p>
<p>By calling the close() function on the channel in the producer Goroutine, we are signaling that there are no more values to be sent through the channel. This causes the range function in the consumer Goroutine to exit the loop when all values have been received.</p>
<p>Let's reinforce the concept: A <strong>channel</strong> is a communication object used by <strong>Goroutines</strong> and plays a fundamental role in communication <strong>between</strong> Goroutines. Technically, a channel is the transfer of data in which the data can be <strong>passed</strong> or <strong>read</strong>. Thus, a Goroutine can send data to a channel, while other <strong>Goroutines</strong> can read the data from the same channel, like a queue. Channels are the safest way to communicate in the <strong>Go</strong> language. There are other ways to share data in <strong>Go</strong>, not as efficient as <strong>channels</strong>. The team that developed <strong>Go</strong> decided not to close the possibilities, and it is possible to share data <strong>without using channels</strong>.</p>
<h2 id="heading-declaring-a-channel-without-and-with-buffer">Declaring a Channel without and with buffer</h2>
<pre><code class="lang-go">
<span class="hljs-keyword">type</span> Promise <span class="hljs-keyword">struct</span> {
  Result <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>
  Error  <span class="hljs-keyword">chan</span> error
}
<span class="hljs-keyword">var</span> (
  ch1  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> *Promise)  <span class="hljs-comment">// received a pointer from the structure</span>
  ch2  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>, <span class="hljs-number">1</span>) <span class="hljs-comment">// allows only 1 channels</span>
  ch3  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)    <span class="hljs-comment">// allows only 2 channels</span>
  ch4  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">float64</span>)   <span class="hljs-comment">// has not been set can freely receive</span>
  ch5  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> []<span class="hljs-keyword">byte</span>)    <span class="hljs-comment">// by default the capacity is 0</span>
  ch6  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>, <span class="hljs-number">1</span>)   <span class="hljs-comment">// non-zero capacity</span>
  ch7  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> time.Time, <span class="hljs-number">2</span>)
  ch8  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{}, <span class="hljs-number">2</span>)
  ch9  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{})
  ch10 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>](<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)) <span class="hljs-comment">// map channel</span>
  ch11 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> error)
  ch12 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> error, <span class="hljs-number">2</span>)
  <span class="hljs-comment">// receives a zero struct</span>
  ch14 &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{}
  ch15 = <span class="hljs-built_in">make</span>(&lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>)          <span class="hljs-comment">// can only read from</span>
  ch16 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span>&lt;- []os.FileInfo) <span class="hljs-comment">// can only write to// holds another channel as its value</span>
  ch17 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>) <span class="hljs-comment">// can read and write to</span>
)
</code></pre>
<h2 id="heading-receiving-values-on-the-channel">Receiving values on the channel</h2>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  ch2 &lt;- <span class="hljs-string">"okay"</span>
  <span class="hljs-keyword">defer</span> <span class="hljs-built_in">close</span>(ch2)
  fmt.Println(ch2, &amp;ch2, &lt;-ch2)
  ch7 &lt;- time.Now()
  ch7 &lt;- time.Now()
  fmt.Println(ch7, &amp;ch7, &lt;-ch7)
  fmt.Println(ch7, &amp;ch7, &lt;-ch7)
  <span class="hljs-keyword">defer</span> <span class="hljs-built_in">close</span>(ch7)
  ch3 &lt;- <span class="hljs-number">1</span> <span class="hljs-comment">// okay</span>
  ch3 &lt;- <span class="hljs-number">2</span> <span class="hljs-comment">// okay</span>
  <span class="hljs-comment">// deadlock // ch3 &lt;- 3 // does not accept any more </span>
  <span class="hljs-comment">// values, if you do it will error : deadlockdefer close(ch3)</span>
  fmt.Println(ch3, &amp;ch3, &lt;-ch3)
  fmt.Println(ch3, &amp;ch3, &lt;-ch3)
  ch10[<span class="hljs-string">"lambda"</span>] = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)
  ch10[<span class="hljs-string">"lambda"</span>] &lt;- <span class="hljs-number">100</span><span class="hljs-keyword">defer</span> <span class="hljs-built_in">close</span>(ch10[<span class="hljs-string">"lambda"</span>])
  fmt.Println(&lt;-ch10[<span class="hljs-string">"lambda"</span>])
}
</code></pre>
<p>A small example of a goroutine using channels.</p>
<p><em>Example 1:</em></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">goroutine</span><span class="hljs-params">(c <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)</span></span> {
    fmt.Println(<span class="hljs-string">"Eu sou um canal: "</span> + &lt;-c + <span class="hljs-string">"!"</span>)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  fmt.Println(<span class="hljs-string">"start goroutine!"</span>)
  c := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)
  <span class="hljs-keyword">go</span> goroutine(c)
  c &lt;- <span class="hljs-string">"jeffotoni"</span>
}
</code></pre>
<p><em>Example 2:</em></p>
<pre><code class="lang-go">    <span class="hljs-keyword">package</span> main
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"fmt"</span>
        <span class="hljs-string">"time"</span>
    )
    <span class="hljs-comment">// escrevendo no canal</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">write</span><span class="hljs-params">(ch <span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)</span></span> {
        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++ {
            ch &lt;- i
            fmt.Println(<span class="hljs-string">"escrever:"</span>, i, <span class="hljs-string">"to ch"</span>)
        }
        <span class="hljs-built_in">close</span>(ch)
    }
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        <span class="hljs-comment">// channel com buffer</span>
        ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)
        <span class="hljs-comment">// goroutine</span>
        <span class="hljs-keyword">go</span> write(ch)
        <span class="hljs-comment">//aguarde um pouco</span>
        time.Sleep(<span class="hljs-number">1</span> * time.Second)
        <span class="hljs-comment">// listando o canal</span>
        <span class="hljs-keyword">for</span> v := <span class="hljs-keyword">range</span> ch {
            fmt.Println(<span class="hljs-string">"ler"</span>, v, <span class="hljs-string">"from ch"</span>)
            time.Sleep(<span class="hljs-number">2</span> * time.Second)
        }
    }
</code></pre>
<p>In this example, we are defining a variable called ch that is a channel that can only be used to receive values of type struct{}. We use the &lt;-chan keyword to specify that this channel can only be used to receive values.</p>
<p>Check out the code below:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Creates an unbuffered channel</span>
    ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{})
    <span class="hljs-comment">// Starts a Goroutine to send a value to the channel</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        ch &lt;- <span class="hljs-keyword">struct</span>{}{} <span class="hljs-comment">// Sends a value to the channel</span>
    }()
    <span class="hljs-comment">// Receives a value from the channel and prints a message</span>
    &lt;-ch
    fmt.Println(<span class="hljs-string">"Value received from channel"</span>)
}
</code></pre>
<h2 id="heading-select">Select</h2>
<p>The select is a control structure in Go that allows you to monitor multiple channels simultaneously and execute the first operation that is ready. This allows you to write concise and efficient code that responds to events from multiple channels at the same time.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sendMessage</span><span class="hljs-params">(channel <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">string</span>, message <span class="hljs-keyword">string</span>, delay time.Duration)</span></span> {
    <span class="hljs-comment">// Wait for a random period of time</span>
    time.Sleep(delay)
    <span class="hljs-comment">// Send the message to the channel</span>
    channel &lt;- message
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Create two unbuffered channels</span>
    channel1 := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)
    channel2 := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)
    <span class="hljs-comment">// Start two separate goroutines to send messages to the channels</span>
    <span class="hljs-keyword">go</span> sendMessage(channel1, <span class="hljs-string">"Message for channel 1"</span>, time.Second*<span class="hljs-number">2</span>)
    <span class="hljs-keyword">go</span> sendMessage(channel2, <span class="hljs-string">"Message for channel 2"</span>, time.Second*<span class="hljs-number">1</span>)
    <span class="hljs-comment">// Use select to receive the first message that is ready</span>
    <span class="hljs-keyword">select</span> {
    <span class="hljs-keyword">case</span> msg1 := &lt;-channel1:
        fmt.Println(<span class="hljs-string">"Message received from channel 1:"</span>, msg1)
    <span class="hljs-keyword">case</span> msg2 := &lt;-channel2:
        fmt.Println(<span class="hljs-string">"Message received from channel 2:"</span>, msg2)
    }
}
</code></pre>
<p>In this example, we have two different Goroutines that send messages to two different channels. Using select, we are monitoring both channels and displaying the first message that arrives in one of them.</p>
<p>Note that we are using the &lt;- syntax to receive values from the channels inside the select cases. The select will wait until one of the cases is ready, meaning a message has been received from one of the channels.</p>
<p>Additionally, we are using time.Sleep() in the sendMessage() function to simulate a random delay before sending the message to the channel. This is done to demonstrate that the message sent to the channel faster may not be the first one to be received due to the delays.</p>
<p>Select is a powerful tool in Go that can be used to write efficient code that monitors multiple channels at the same time. It is particularly useful for handling asynchronous events and allowing the program to perform multiple tasks simultaneously.</p>
<p>I hope I have helped with a better understanding of Goroutines.</p>
<p>Another complementary and important subject is <a target="_blank" href="https://dev.to/jeffotoni/workloads-em-go-59ab">"Workloads: CPU-Bound and IO-Bound"</a> which I recommend reading to understand even more.</p>
<p>Here you will find more examples:<br /><a target="_blank" href="https://gobootcamp.jeffotoni.com/#goroutines">Go manual at: gobootcamp.jeffotoni</a><br /><a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/goroutine">Various examples of Goroutines at: goexample</a></p>
<p>In <strong>Go</strong>, we have an arsenal to work with Goroutines and manage concurrency without losing simplicity, readability, and productivity.</p>
<p><strong><em>Go</em></strong> <em>is</em> <strong><em>love</em></strong> ❤</p>
]]></content:encoded></item><item><title><![CDATA[Go é orientado a objetos ?]]></title><description><![CDATA[Fala comigo galerinha, a semana começou agitada 😂, este post é sobre Orientação Objeto na linguagem de programação Go. É um assunto que tornou-se…]]></description><link>https://jeffotoni.hashnode.dev/go-e-orientado-a-objetos</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/go-e-orientado-a-objetos</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Mon, 10 Apr 2023 19:58:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681156814022/da73dc6e-c446-4bfc-a5bb-f8f6960b2352.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Fala comigo galerinha, a semana começou agitada 😂, este post é sobre <strong>Orientação Objeto na linguagem de programação Go.</strong> É um assunto que tornou-se recorrente em listas de discussões, meetup, grupos etc. Quando o assunto é <strong>Programação Orientada a Objetos em Go causa uma polêmica.</strong></p>
<p>Sabemos que a Linguagem <strong>Go</strong> é um <strong>Like C</strong> e também sabemos que a linguagem <strong>Go</strong> teve influências de diversas outras linguagens de programação e paradigmas diferentes, dentre elas: <a target="_blank" href="https://en.wikipedia.org/wiki/Go_%28programming_language%29"><em>Alef</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/APL_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>APL</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/BCPL"><em>BCPL</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/C_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>C</em></a><em>, CSP,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Limbo_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Limbo</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Modula"><em>Modula</em></a><em>,</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Newsqueak"><em>Newsqueak</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Oberon_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Oberon</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Occam_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>occam</em></a><em>,</em><a target="_blank" href="https://en.wikipedia.org/wiki/Pascal_%28programming_language%29"><em>Pascal</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Smalltalk"><em>Smalltalk</em></a> <em>e</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Crystal_%28programming_language%29"><em>Cristal</em></a>. Como podem perceber temos uma miscelânea de paradigmas porém o <strong>paradigma</strong> <strong>Imperativo e Concorrente</strong> são os que mais predominam <strong>em Go.</strong></p>
<p>Go é uma linguagem orientada a objetos a resposta para esta pergunta é <strong>SIM e NÃO 😱.</strong> No site oficial Go em faq encontraremos alguns pontos sobre isto caso queira da uma conferida só clicar em: <a target="_blank" href="https://golang.org/doc/faq#Is_Go_an_object-oriented_language">Go Object Oriented Language</a></p>
<p> Em <strong>Go</strong> conseguimos desenvolver um estilo de programação orientada a objetos permitindo construir tipos e métodos porém não há hierarquia de tipos, é bem diferente da implementação que conhecemos em outras linguagens de programação porque não temos um arsenal de recursos como Linguagens desenvolvidas para o paradigma orientadas a objetos. O que temos em <strong>Go</strong> é uma abstração para flexibilizar e ajudar quando precisarmos utilizar diferentes tipos de structs sem nos preocupar qual struct estará sendo utilizada e o mais legal deixa encapsulado seu método de forma segura.</p>
<p>Bem para que isto seja possível em Go temos um coadjuvante que se chama “<strong>interface</strong>” 💪🏼 ou seja <strong>“type MyInterface interface{ ... }”</strong> e sua abordagem como dissemos é diferente das implementações que conhecemos em outras langs, interface é a única forma de permitir o despacho de métodos dinâmicos em <strong>Go</strong>.</p>
<p>Então o que temos até o momento é uma forma de fazer polimorfismo utilizando <strong>"interface",</strong> encapsulamento de métodos e disponibiliza-los de forma dinâmica tudo isto é muito semelhante ao "<strong>Duck typing".</strong></p>
<p>O Go suporta <strong>“Duck typing”</strong>, é um estilo de tipagem em que os <a target="_blank" href="https://pt.wikipedia.org/wiki/M%C3%A9todo_(programa%C3%A7%C3%A3o)"><em>métodos</em></a> <em>e propriedades</em> de um objeto determinam a semântica válida, em vez de sua <a target="_blank" href="https://pt.wikipedia.org/wiki/Heran%C3%A7a">herança</a> de uma classe particular ou implementação de uma interface explicita. O nome do conceito refere-se ao <a target="_blank" href="https://pt.wikipedia.org/wiki/Teste_do_pato">teste do pato</a>, atribuído à <a target="_blank" href="https://pt.wikipedia.org/w/index.php?title=James_Whitcomb_Riley&amp;action=edit&amp;redlink=1">James Whitcomb Riley</a>. Isso faz com que o <strong>Go</strong> se pareça com uma linguagem dinâmica.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Go_(programming_language)">Go</a> usa <strong>“Tipagem Estrutural“</strong> em métodos para determinar a compatibilidade de um tipo com uma interface. Não há hierarquias de tipos e a “Tipagem Estrutural” é uma alternativa interessante à herança clássica em linguagens com tipagem estática. Ele permite que você escreva algoritmos genéricos sem obscurecer a definição de um tipo em um mar de interfaces. Talvez mais importante, ajuda as linguagens com tipagem estática a <strong><em>capturar a sensação e a produtividade das linguagens dinamicamente tipificadas.</em></strong></p>
<p><strong>“Duck typing”</strong> ocorre em tempo de execução e <strong>“Tipagem Estrutural”</strong> que ocorre em tempo de compilação. Go não da suporte a orientação a objetos como é implementado nas linguagens como C#, Java ou mesmo C ++, não possui herança e honestamente fico muito feliz com isto, mas oferece alguns recursos como <strong><em>composição e interfaces</em> como descrevemos acima.</strong></p>
<p>O exemplo abaixo demostra o comportamento do que seria <strong>"Dunk typing"</strong> e <strong>polimorfismo</strong> utilizando <strong>Go</strong>.</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQGPu1b1lkBSQQ/article-inline_image-shrink_1000_1488/0/1598286781231?e=1686182400&amp;v=beta&amp;t=znMwNTSjtZLax4Uawc9HBbnx6GIlL2BSuPd-G-VD52E" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQEwxHcnSK_CyA/article-inline_image-shrink_1000_1488/0/1598287800682?e=1686182400&amp;v=beta&amp;t=gFShzmT--gLeKTe84HPNmZmFTut8b7rIJKPMh5606Qs" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Confira o exemplo completinho aqui: <a target="_blank" href="https://play.golang.org/p/C3VbgbVQnhs"><em>https://play.golang.org/p/C3VbgbVQnhs</em></a>﻿</p>
<p>A <strong>interface</strong> é uma coleção de métodos, além de ser um tipo personalizado.</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQFPlHNTXhB_ng/article-inline_image-shrink_400_744/0/1598287770089?e=1686182400&amp;v=beta&amp;t=FJO-L2-_pmDxTiT-U2VtzXiLyJAyAVL6k2mdVxAN6bw" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Dizemos que algo <em>satisfaz esta interface</em> (ou <em>implementa esta interface</em> ) se tiver um método com a assinatura exata Dados() string.</p>
<p>Por exemplo, a struct Pai satisfaz a interface porque tem um Dados() string definido como método.</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQGIQMBF1y9fNg/article-inline_image-shrink_400_744/0/1598292833565?e=1686182400&amp;v=beta&amp;t=RRFtZBqUtImDb41ljbGo4jWz50Xqlinuy7qjD4nJs2U" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Não é realmente importante o que esse <strong>"Pai"</strong> é ou faz. A única coisa que importa é que tem um método chamado <strong>Dados()</strong> que retorna uma <strong>string</strong>.</p>
<p>Ou, como Filhos, o tipo a seguir <em>também</em> satisfaz a <strong>"interface Familia"</strong> - novamente porque tem um método com a assinatura exata <strong>Dados() string.</strong></p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQETtm1H3jvJbA/article-inline_image-shrink_1000_1488/0/1598300592806?e=1686182400&amp;v=beta&amp;t=jNIFxPcuFVyfDJ2leLqQ66Cq11U9CHVTyyfhlYdBx1w" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>O importante aqui é que temos três tipos diferentes Pai, Filho e Filhos, que fazem coisas diferentes. Mas o que eles têm em comum é que ambos satisfazem a <strong>"interface Familia".</strong></p>
<p>Podemos pensar sobre isto de outra maneira. Se você sabe que um objeto satisfaz a <strong>"interface Familia"</strong>, pode confiar que ele tem um método com a assinatura exata <strong>Dados() string</strong> que pode ser chamada.</p>
<p>Agora vamos conferir nossa função "showDados(...)" que será responsável por acessar todos nossos métodos diferentes atendendo a mesma interface, agora você poderá usar objetos de qualquer tipo desde que satisfaça a interface.</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQFnM2BfRN96Lg/article-inline_image-shrink_1000_1488/0/1598301094495?e=1686182400&amp;v=beta&amp;t=yKUWzZfsFsJ08dkyWTAuVIkguFHvbmkLlzmMyFVdaz4" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Olha o exemplo abaixo, temos vários tipos de objetos sendo passado para a função <strong>showDados(...).</strong></p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQHBd814SfpaxQ/article-inline_image-shrink_1000_1488/0/1598301474133?e=1686182400&amp;v=beta&amp;t=OnCH-6B1sv4j-IcAx8zXUWLHIcSwAbwr32JxEMN1t58" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>As possibilidades são diversas, podemos definir uma interface recebendo outra interface, podemos criar outras funções que satisfaça a interface como o exemplo abaixo:</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQE7spERiPH87A/article-inline_image-shrink_1000_1488/0/1598303876272?e=1686182400&amp;v=beta&amp;t=T5nZ-WRt0s4WzUkoMyC_VpaufpVeIxFJ7qtjjJpwEZc" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>A função <strong>showDados2(f []Familia)</strong> recebe um vetor da "<strong>interface Familia".</strong></p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQGwrRwz2NvLwg/article-inline_image-shrink_1000_1488/0/1598304017398?e=1686182400&amp;v=beta&amp;t=mRsA2Au04fCA7n2BvxpJucERlKXUqCjN-MxTx-q3h_c" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Simples não é ? Com esta definição temos diversas possibilidades que poderá utilizar "interface" em seus projetos. <strong>Clean Architecture</strong> é um bom exemplo desta utilização também, toda sua arquitetura se baseia-se em interfaces caso queiram da uma conferida <a target="_blank" href="https://medium.com/@eminetto/clean-architecture-using-golang-b63587aa5e3f">clean architecture</a> e <a target="_blank" href="https://eltonminetto.net/en/post/2020-07-06-clean-architecture-2years-later">clean architecture 2 years later</a></p>
<p>Existem alguns motivos pelos quais você poderia usar interface em <strong>Go</strong>, vou listar os três mais comuns:</p>
<p>- Para ajudar a reduzir a duplicação ou código padrão.</p>
<p>- Para tornar mais fácil usar mocks em vez de objetos reais em testes de unidade.</p>
<p>- Como uma ferramenta de arquitetura, para ajudar a impor o desacoplamento entre as partes de sua base de código.</p>
<h3 id="heading-algumas-interfaces-utilizada-em-go-em-sua-strand-libray-default"><strong>Algumas interfaces utilizada em Go em sua strand libray default</strong></h3>
<p>Uma pequena lista de algumas das interfaces mais comuns e úteis na biblioteca padrão.</p>
<ul>
<li><p>builtin.Error</p>
</li>
<li><p>fmt.Stringer</p>
</li>
<li><p>io.Reader</p>
</li>
<li><p>io.Writer</p>
</li>
<li><p>io.ReadWriteCloser</p>
</li>
<li><p>http.ResponseWriter</p>
</li>
<li><p>http.Handler</p>
</li>
<li><p>Sort</p>
</li>
</ul>
<h2 id="heading-vamos-da-uma-olhada-no-pkg-sort">Vamos da uma olhada no pkg sort</h2>
<p>Um tipo, normalmente uma coleção, que satisfaz a classificação. A interface pode ser classificada pelas funções neste pacote. Os métodos requerem que os elementos da coleção sejam enumerados por um índice inteiro.</p>
<p>O que vemos logo abaixo são as assinaturas que a interface <strong>Sort</strong> possui</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQHbYB9mu4Xzzg/article-inline_image-shrink_1000_1488/0/1598333376521?e=1686182400&amp;v=beta&amp;t=EKaRkHqOG52djJKr1l_trG9Q5MT-O0Ibx4ts2Zk91R0" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>o formos usar a interface iremos ter que criar os três métodos que satisfaça exatamente a Interface, e o que muda sempre são os tipos e structs que poderão implementar osmétodos que satisfaça a interface como aprendemos.</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQFyMA-fhGozXw/article-inline_image-shrink_1000_1488/0/1598333423207?e=1686182400&amp;v=beta&amp;t=HNoFtMedLbDm8PZ5T_bjZAh2JgyR_51xjbriufxDeTo" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>A desvantagem aqui é que não necessariamente precisaria dos três métodos para Ordenar minha struct precisaria somente do <strong>Less(…),</strong> porém somos obrigados a satisfazer a interface exatamente como ele está assinada ou seja precisaremos sempre implementar <strong>Less(…), Len(…), Swap(…).</strong></p>
<p>Como boa prática sempre é interessante termos interfaces mais enxutas possíveis.</p>
<p>Uma curiosidade aqui neste <strong>pkg</strong> é a possibilidade de utilizar uma <strong>interface incorporada</strong> e que o Reverse use os métodos de implementação de outra interface 😱.</p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQE-PFB4uJWdLw/article-inline_image-shrink_1000_1488/0/1598333473379?e=1686182400&amp;v=beta&amp;t=iSvRZEjEj46SC11OJtR1t6lnqLD-gGANlkDnAw7sDto" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Legal não é ? Ou seja o <strong>Less(...)</strong> retorna o oposto do método <strong>Less(...)</strong> da implementação incorporada.</p>
<p>E para fechar temos diversos tipos diferentes criando e implementando seus próprios métodos <strong>Less(…), Len() e Swap(..)</strong></p>
<p><img src="https://media.licdn.com/dms/image/C4E12AQHkYfcsOpBp5g/article-inline_image-shrink_1000_1488/0/1598333512079?e=1686182400&amp;v=beta&amp;t=eHSdR7KDuqiSTWkWwqr3DhI3pvzEoqGZhjwyoYhsnkM" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Este post está escrito em varias plataformas e existe uma versão mais completa que escrevi que encontra-se neste link <a target="_blank" href="https://medium.com/@jeffotoni/go-%C3%A9-orientada-a-objetos-f600d226b1f6">Go é Orientado a Objeto ?</a></p>
<p>Não tinha como não descrever algumas possibilidades e não aguentei de despejei o que consegui neste post, desculpem pelo tamanho do post.</p>
<h3 id="heading-aqui-uma-lista-completa-de-interfaces-em-go">Aqui uma lista completa de interfaces em Go</h3>
<p><a target="_blank" href="https://gist.github.com/asukakenji/ac8a05644a2e98f1d5ea8c299541fce9">Lista completa de interface Go</a></p>
<p><strong>Caso queiram acessar o código fonte do exemplo apresentado</strong></p>
<p><a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/interface">Código fonte</a></p>
<h2 id="heading-conclusao">Conclusão</h2>
<p>Espero que tenha gostado do resumo e uma breve introdução do que podemos fazer em <strong>Go</strong> quando o assunto é Orientação a Objeto. Qualquer observação, dica, melhoria etc.. no conteúdo por favor só enviar para melhora-lo ainda mais.</p>
]]></content:encoded></item><item><title><![CDATA[No caminho para o Go 2.0]]></title><description><![CDATA[Go está na versão 1.12.7 e caminhando para versão 2.0, este post é para apresentar um pouco deste caminho que está sendo construído pela comunidade e…]]></description><link>https://jeffotoni.hashnode.dev/no-caminho-para-o-go-20</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/no-caminho-para-o-go-20</guid><category><![CDATA[Developer]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Mon, 10 Apr 2023 18:48:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681152503057/6787e968-426b-4517-9a0e-6a3d28039cf3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Go</strong> está na versão <strong>1.12.7</strong> e caminhando para versão 2.0, este post é para apresentar um pouco deste caminho que está sendo construído pela comunidade e equipe de desenvolvimento do <strong>Go</strong>. Estamos todos a caminho para o <strong>Go 2.0</strong> juntos, mas ninguém ainda sabe exatamente para onde ele irá nos levar.</p>
<p><img src="https://media.licdn.com/dms/image/C4D12AQHz1NTARqEdyQ/article-inline_image-shrink_1000_1488/0/1565195119784?e=1686182400&amp;v=beta&amp;t=O2TunHQZ18x-v2Ll1M7ZhTdEGA9kelfIQ1D7DWHGze0" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Uma forma que a equipe de Go encontrou para melhorar ainda mais seu processo evolutivo da linguagem foi experimentando e colocando em prática a própria linguagem. <a target="_blank" href="https://www.linkedin.com/in/swtch/"><strong><em>Russ Cox</em></strong></a> descreveu: <em>"Utilizamos e experimentamos o Go como ele existe agora, para entende-lo melhor, aprender o que funciona bem e o que não funciona. Então, experimentamos possíveis mudanças, para entendê-las melhor, novamente aprendendo o que funciona bem e o que não funciona. Com base no que aprendemos com esses experimentos, simplificamos. E então nós experimentamos novamente. E então nós simplificamos novamente. E assim por diante. E assim por diante."</em></p>
<h3 id="heading-os-quatro-rs-da-simplificacoes">Os quatro R's da simplificações</h3>
<p>Durante esse processo, a equipe de desenvolvimento <strong>Go</strong> apresentou quatro maneiras principais de simplificar a experiência geral de escrever programas <strong>Go</strong>: <strong><em>remodelando, redefinindo, removendo e restringindo.</em></strong></p>
<p><strong>Simplifique remodelando</strong></p>
<p>A primeira maneira que simplificamos é reformular o que existe em uma nova forma, que acaba sendo mais simples no geral.</p>
<p>Cada programa Go que escrevemos serve como uma experiência para testar o próprio Go. Nos primeiros dias do Go, nota-se que aprendem rapidamente a escrever código como essa <strong>addToList</strong>:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">addToList</span><span class="hljs-params">(list []<span class="hljs-keyword">int</span>, x <span class="hljs-keyword">int</span>)</span> []<span class="hljs-title">int</span></span> {
    n := <span class="hljs-built_in">len</span>(list)
    <span class="hljs-keyword">if</span> n+<span class="hljs-number">1</span> &gt; <span class="hljs-built_in">cap</span>(list) {
        big := <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">int</span>, n, (n+<span class="hljs-number">5</span>)*<span class="hljs-number">2</span>)
        <span class="hljs-built_in">copy</span>(big, list)
        list = big
    }
    list = list[:n+<span class="hljs-number">1</span>]
    list[n] = x    
    <span class="hljs-keyword">return</span> list

}
</code></pre>
<p>Basta conferir o código que percebe-se que escreveria o mesmo código para slices de bytes e slices de strings, e assim por diante. Estes programas eram muito complexos, porque o <strong>Go</strong> era muito simples.</p>
<p>Então, a equipe que desenvolve Go pegou as muitas funções, como addToList, e as transformou em uma função fornecida pelo próprio <strong>Go</strong>. A adição <strong>append</strong> tornou a linguagem Go um pouco mais complexa, mas, no geral, tornou a experiência geral de escrever programas Go mais simples, mesmo depois de contabilizar o custo do aprendizado append.</p>
<p>Adicionaram código e complexidade à distribuição Go, mas no final simplificamos a experiência de escrever programas Go. A nova estrutura também criou espaço para outros experimentos interessantes, que veremos mais adiante.</p>
<p><strong>Simplifique redefinindo</strong></p>
<p>Uma segunda maneira que eles encontraram para simplificar é redefinir a funcionalidade que já temos, permitindo que ela faça mais. Como simplificar remodelando, simplificar redefinindo torna os programas mais simples de escrever, mas agora sem nada de novo para aprender.</p>
<p>Por exemplo, append foi originalmente definido para ler somente slices. Ao anexar a uma slice de byte, você poderia acrescentar os bytes de outra slice de byte, mas não os bytes de uma string. Nós redefinimos acrescentar para permitir acrescentar uma string, sem adicionar nada de novo ao idioma.</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> b []<span class="hljs-keyword">byte</span>
<span class="hljs-keyword">var</span> more []<span class="hljs-keyword">byte</span>
b = <span class="hljs-built_in">append</span>(b, more...) <span class="hljs-comment">// ok</span>


<span class="hljs-keyword">var</span> b []<span class="hljs-keyword">byte</span>
<span class="hljs-keyword">var</span> more <span class="hljs-keyword">string</span>
b = <span class="hljs-built_in">append</span>(b, more...) <span class="hljs-comment">// ok later</span>
</code></pre>
<p><strong>Simplifique Removendo</strong></p>
<p>Uma terceira maneira que encontraram para simplificar é removendo a funcionalidade quando ela se tornou menos útil ou menos importante do que esperavam. Remover a funcionalidade significa menos uma coisa para aprender, uma coisa a menos para corrigir erros, uma coisa a menos para se distrair ou usar incorretamente. Evidentemente, a remoção também força os usuários a atualizar os programas existentes, talvez tornando-os mais complexos, para compensar a remoção. Mas o resultado geral ainda pode ser que o processo de escrever programas <strong>Go</strong> se torne mais simples.</p>
<p>Um exemplo disso é quando removeram as formas booleanas de operações de canal sem bloqueio do idioma:</p>
<pre><code class="lang-go">ok := c &lt;- x  <span class="hljs-comment">// before Go 1, was non-blocking send</span>
x, ok := &lt;-c  <span class="hljs-comment">// before Go 1, was non-blocking receive</span>
</code></pre>
<p>Essas operações também foram possíveis de usar select, tornando confuso precisar decidir qual forma usar. Removê-los simplificou a linguagem sem reduzir seu poder.</p>
<p><strong>Simplifique restringindo</strong></p>
<p>Também perceberam outra forma de simplificar restringindo o que é permitido. Desde o primeiro dia, o Go restringiu a codificação dos arquivos-fonte do Go: eles devem ser o UTF-8. Essa restrição faz com que todo programa que tenta ler os arquivos de origem do Go seja mais simples. Esses programas não precisam se preocupar com arquivos de código-fonte Go codificados em Latin-1 ou UTF-16 ou UTF-7 ou qualquer outra coisa.</p>
<p>Outra restrição importante é gofmt para formatação do programa. Nada rejeita o código Go que não é formatado usando gofmt, mas nós estabelecemos uma convenção de que as ferramentas que reescrevem os programas Go as deixam em gofmt. Se você mantiver seus programas em gofmt também, eles não farão nenhuma alteração de formatação. Quando você compara antes e depois, os únicos diffs que você vê são mudanças reais. Esta restrição simplificou reescrever e levou a experiências bem sucedidas, como goimports, gorename, e muitos outros.</p>
<h3 id="heading-processo-de-desenvolvimento-go">Processo de desenvolvimento Go</h3>
<p>Este ciclo de experiência e simplificação é um bom modelo que os integrantes da equipe de desenvolvimento do Go tem feito nos últimos dez anos. mas tem um problema: é simples demais. Não contiveram em apenas experimentar e simplificar.</p>
<p>Tiveram que enviar os resultados, disponibilizá-los para usar. É claro que usá-lo permite mais experimentos e, possivelmente, mais simplificação, e o processo avança e continua.</p>
<p><img src="https://media.licdn.com/dms/image/C4D12AQHUrbN9KrUWmg/article-inline_image-shrink_1000_1488/0/1565197084080?e=1686182400&amp;v=beta&amp;t=AnHYrlDuedETdDQmdOB-slCHY7yGBlT8iZKsXPCZpIY" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<p>Go foi liberado para todos pela primeira vez em <strong>10 de novembro de 2009</strong>. Então, com ajuda de todos da comunidade, enviaram Go 1.0 em <strong>março de 2012</strong>. E já lançaram doze lançamentos <strong>Go</strong> desde então. Todos esses foram marcos importantes, para permitir mais experimentações, toda comunidade colaborou e ajudou a aprender mais sobre o <strong>Go</strong> e, é claro, para disponibilizar o Go para uso em produção.</p>
<p>Quando lançaram o <strong>Go 1</strong>, explicitamente mudaram internamente toda equipe que desenvolveu Go o foco para o uso do Go, para que conseguissem entender melhor a versão da linguagem antes de tentar mais simplificações envolvendo alterações de idioma. Precisavam de um tempo para experimentar, para realmente entender o que funciona e o que não funciona.</p>
<p>Eles estão o tempo todo testando e experimentando, simplificando e atualizando novas versões. Estão bem mais concentrados em maneiras de simplificar o desenvolvimento do Go sem alterações significativas na linguagem e sem interromper os programas existentes do Go. Por exemplo, o Go 1.5 tivemos o primeiro coletor de lixo <strong>(GC)</strong> simultâneo e, em seguida, os seguintes releases o aprimoraram, simplificando o desenvolvimento do Go, removendo os tempos de pausa como uma preocupação constante.</p>
<p>Na Gophercon em 2017, anunciaram que após cinco anos de experimentação, era hora de pensar novamente em mudanças significativas que simplificariam o desenvolvimento do Go. O caminho para o Go 2 é realmente o mesmo que o caminho para o Go 1: experimentar e simplificar e liberar, em direção a um objetivo geral de <strong>simplificar o desenvolvimento do Go.</strong></p>
<p>Para o Go 2, os tópicos concretos que eles consideram mais importantes e o que são abordados nos posts são: <em>manipulação de erros</em>, <em>generics e dependências</em>. Desde então, percebe-se que outro tópico importante é o desenvolvimento de ferramentas.</p>
<h3 id="heading-conclusao">Conclusão</h3>
<p>Foi apresentando um pouco do <em>ciclo de desenvolvimento</em> que a equipe responsável por manter a linguagem Go fazem, isto é explícito para toda comunidade. Toda evolução da linguagem é comunicada pela equipe e abrem um canal de comunicação direto com a comunidade e isto vem dando certo, diversas propostas são lançadas e discutidas a fundo, isto é muito legal e muito positivo. A linguagem cresce dia após dia tornando-se cada vez mais popular e poderosa. O mais bacana de tudo é que não estão preocupados com funcionalidades surrealistas ou apenas para agradar um público específico, eles estão caminhando um passo de cada vez, mantendo o designer inicial que a linguagem propunha, e focando no que realmente importa que é cada vez mais torna a <strong>linguagem simples para os que forem desenvolver em Go</strong>. Neste cenário percebe-se claramente que no designer de Go <em>"Menos é exponencialmente Mais"</em> a equipe de desenvolvedores do <strong>Go</strong> dizem que sua criação é uma tentativa de tornar os programadores mais produtivos e estão cada vez mais próximo deste objetivo. Os caminhos para o <strong>Go 2.0</strong> são os mesmos que utilizaram até o momento e o foco será <em>manipulação de erros</em>, <em>generics e dependências</em>.</p>
]]></content:encoded></item><item><title><![CDATA[Workloads em Go]]></title><description><![CDATA[Concorrência em Go é muito poderosa e também simples de codar está foi a intensão dos engenheiros que desenvolveram Go. A resolução de muitos problemas é…]]></description><link>https://jeffotoni.hashnode.dev/workloads-em-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/workloads-em-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Mon, 10 Apr 2023 18:23:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681151005057/6198027d-131f-47d2-900e-f486325639ce.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Concorrência</strong> em <strong>Go</strong> é muito poderosa e também simples de codar está foi a intensão dos engenheiros que desenvolveram <strong>Go</strong>. A resolução de muitos problemas é bem mais eficiente utilizando <strong>concorrência</strong> e este é o <strong>poder</strong> de <strong>Go</strong>, por isto, se tornou um <strong>Deus</strong> quando o assunto é <strong>concorrência</strong> em backend. Devido a isto, problemas englobados neste universo serão resolvidos com muita <strong>eficiência</strong> e o mais importante, com muito <strong>pouco recurso computacional</strong>.</p>
<p>Quando falamos de <strong>concorrência</strong> temos que ressaltar que existe alguns <strong>tipos de cargas de trabalhos</strong> eles serão nossa bússola para determinar nosso ponto de equilíbrio quando tivermos que resolver problemas evolvendo concorrência.</p>
<p>Uma <strong>thread</strong> pode fazer dois tipos de cargas de trabalhos (<strong><em>Workloads</em></strong>): <strong>CPU-Bound e o IO-Bound.</strong></p>
<h3 id="heading-cpu-bound">CPU-BOUND</h3>
<p>Esta carga de trabalho nunca irá cria uma situação em que a thread pode ser colocado em <em>estados de espera</em>. Ele estará constantemente fazendo cálculos. Uma thread calculando <em>pi</em> para décima oitava potência seria limitado pela CPU. <em>(curiosidade:</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Emma_Haruka_Iwao"><em>Emma Haruka Iwao</em></a> <em>é uma cientista da computação japonesa e Engenheira de Desenvolvimento Cloud do Google. Em 2019, Haruka Iwao calculou o valor de pi mais preciso do mundo, que incluiu 31,4 trilhões de dígitos).</em> </p>
<p>Este tipo de carga de trabalho, trabalhos ligadas à CPU, você precisa do paralelismo para aproveitar a simultaneidade, mais Goroutines não irá ajuda-lo e não serão eficientes, podendo atrasar ainda mais as cargas de trabalho a serem executadas, isto ocorre devido ao custo de latência (o tempo gasto) de mover <strong>Goroutines</strong> dentro e fora da thread do sistema operacional</p>
<h3 id="heading-io-bound"><strong>IO-BOUND</strong></h3>
<p>Neste tipo de carga de trabalho as threads entram em estados de espera. Um bom exemplo seria uma solicitação de acesso a um recurso pela rede ou fazer chamadas para o sistema operacional. Uma thread que precisa acessar um banco de dados, eventos de sincronização <em>(mutex,</em> atomic<em>)</em>, todos estes exemplos fazem com que a thread aguarde então poderíamos dizer que são do tipo de trabalho IO-Bound. Neste tipo de carga de trabalho você não precisa de paralelismo para usar a simultaneidade um único core físico já seria suficiente para uma boa execução de várias <strong>Goroutines</strong>. As <strong>Goroutines</strong> estão entrando e saindo dos estados de espera como parte de sua carga de trabalho.</p>
<p>Neste tipo de carga de trabalho ter mais <strong>Goroutines</strong> do que cores físicos pode acelerar a execução porque o custo de latência de mover Goroutines dentro e fora do thread do sistema operacional não está criando um evento. Sua carga de trabalho é naturalmente interrompida e isso permite que uma <strong>Goroutine</strong> diferente aproveite o mesmo core físico ao invés de permitir que ele fique ocioso.</p>
<h3 id="heading-conclusao"><strong>CONCLUSÃO</strong></h3>
<p>Desta forma saberemos quando usar mais cores físicos de forma paralelos ou quando iremos precisar somente utilizar concorrência com poucos cores físicos ou somente um core. Em Go os patterns que irão nos ajudar a equilibrar esta equação, existirá momentos que precisaremos de ambos os recursos de carga de trabalho. Quer aprofundar um pouco mais sobre o assunto basta clicar neste <a target="_blank" href="https://medium.com/@jeffotoni/golang-simplificando-a-complexidade-o-inicio-145371d67711">link</a> (<a target="_blank" href="https://medium.com/@jeffotoni/golang-simplificando-a-complexidade-o-inicio-145371d67711"><em>Simplificando a complexidade “O Inicio”</em></a>) onde tem um post bem completo.</p>
]]></content:encoded></item><item><title><![CDATA[Pattern Singleton em C e Threads]]></title><description><![CDATA[Sempre deparo com necessidade de fazer um Pattern Singleton mas como seria em C ? Existe algumas pontos importantes e que temos que tomar cuidado, vou…]]></description><link>https://jeffotoni.hashnode.dev/pattern-singleton-em-c-e-threads</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/pattern-singleton-em-c-e-threads</guid><category><![CDATA[Developer]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Mon, 10 Apr 2023 18:09:09 GMT</pubDate><content:encoded><![CDATA[<p>Sempre deparo com necessidade de fazer um <a target="_blank" href="https://pt.wikipedia.org/wiki/Singleton"><strong>Pattern Singleton</strong></a> mas como seria em C ? Existe algumas pontos importantes e que temos que tomar cuidado, vou apresentar formas de fazer o Singleton usando C, a forma “<strong><em>Not Thread Safe</em></strong>” e “<strong><em>Thread Safe</em></strong>”.</p>
<p>Este Artigo é uma abordagem totalmente didática para que possamos entender como poderíamos manter um estado atômico de u ma instância ou <strong><em>variável global</em></strong> em C enquanto utilizamos concorrência usando <strong>threads</strong>.</p>
<p>Em C temos um poderoso recurso que é a utilização de <strong><em>threads</em></strong> para fazermos execuções simultâneas e quando usamos este recurso tudo tem que ser repensado para trabalhar com concorrência, isso afeta diretamente todo o escopo de nosso código, temos que pensar e escrever códigos da <strong><em>forma Assíncrona.</em></strong> Um bom exemplo de possíveis problemas usando concorrência é a utilização de <strong><em>variáveis globais</em></strong>. Devido as threads nossa implementação do <strong><em>Pattern Singleton</em></strong> irá ter que ser escrito para aceitar o uso de concorrência e neste artigo iremos implementar algumas possibilidades e aplicar boas práticas de como escrever nosso código para esta abordagem.</p>
<p>Temos que tentar sempre que possível escrever nosso código usando boas práticas de programação, para tentar mitigar os possíveis bugs sigilosos que podem ocorrer em tempo de execução do seu programa escrito em C.</p>
<h1 id="heading-o-que-e-pattern-singleton">O que é Pattern Singleton?</h1>
<p>A transcrição do que é um Pattern Singleton seria: <em>“Singleton é um padrão de projeto de software. Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto”</em></p>
<p>O <em>Pattern Singleton</em> é uma característica proveniente do paradigma orientado a objeto, então como iremos implementar em C se o mesmo não possui suporte a OO ?</p>
<p>Para responder esta pergunta temos que entender que a programação Orientada a Objeto é um conceito um padrão e pode ser implementando em qualquer linguagem de programação mesmo sendo de outros paradigmas. É claro que o nível de abstração e dificuldade torna-se uma tarefa árdua aumentando muito o nível de complexidade do código dependendo da linguagem, nossa intenção é puramente didática com intuito de entendermos melhor o cenário proposto quando falamos em <em>pattern singleton.</em></p>
<p>Podemos imaginar uma implementação do Pattern Singleton em C, como já sabemos que o OO é somente um conceito, então conseguiríamos implementar OO usando C. Em C singletons são variáveis ​​estáticas com algum encapsulamento. Podemos usar variáveis estáticas globais ou estáticas locais para implementar nosso singleton em C, em nosso exemplo vamos implementar uma variável estática local. No entanto, as variáveis ​​globais geralmente têm muitos malefícios associados a esta abordagem, e acredite elas realmente causam males, então o quanto antes aprendermos sobre isto melhor, Quando falamos em concorrência ou simultaneidade o problema das <strong><em>variáveis globais</em></strong> aumentam exponencialmente tudo vira um caos, neste cenário a forma de escrever o código e pensar diferente e temos.</p>
<p>O exemplo abaixo é uma implementação de um singleton em C, queremos manter uma instância atômica de nossa conexão com banco de dados, sabemos o quão tão isso é custoso, o ideal seria fazer somente uma conexão para a mesma base e manter isso em memória ou cache.</p>
<pre><code class="lang-go"><span class="hljs-comment">/*
* Example Singleton C
* @package     main
* @author      @jeffotoni
* @size        10/09/2018
*/</span>

#include &lt;stdio.h&gt;

<span class="hljs-keyword">int</span> *Connect() {

    <span class="hljs-comment">// variavel static local</span>
    static <span class="hljs-keyword">int</span> conn_pg = <span class="hljs-number">0</span>; <span class="hljs-comment">// nosso ojbeto connexao</span>

     <span class="hljs-comment">// existe connexao ?    </span>
     <span class="hljs-keyword">if</span> (conn_pg == <span class="hljs-number">0</span>) {

         <span class="hljs-comment">// Db.Connect</span>
         conn_pg = <span class="hljs-number">5454</span>;    <span class="hljs-comment">// atribuindo conexao postgres</span>
     }

     <span class="hljs-comment">// conn_pg++; // o valor ser atribuido sempre</span>
     <span class="hljs-comment">// mantendo o valor, somente se for static</span>

     <span class="hljs-comment">// retorna objeto</span>
     <span class="hljs-keyword">return</span> &amp;conn_pg;
 }

 <span class="hljs-keyword">int</span> main() {

    <span class="hljs-keyword">int</span> Db = *Connect();

    printf(<span class="hljs-string">"Connect em C: %d\n"</span>, Db);
    printf(<span class="hljs-string">"Connect em C: %d\n"</span>, *Connect());
    printf(<span class="hljs-string">"Connect em C: %d\n"</span>, *Connect());
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Criamos uma função para retornar nossa referência de memória da nossa instância ou objeto. Nosso objeto será atribuído a um valor uma única vez na chamada da função por que nas próximas chamadas irá sempre retornar somente sua referência sem precisar atribuir novamente o valor. Em uma aplicação síncrona, isto já era suficiente para uma boa execução do programa, porém se fizemos threads em C e tornar o programa assíncrono, com concorrência entre as threads teremos um grande problema na nossa abordagem e nossa instância poderia bugar em tempo de execução.</p>
<p>Temos como melhorar um pouco mais nosso Singleton em C, vamos encapsular nossa variável estática local usando struct e vamos criar uma struct para “Conn” e encapsular nosso objeto “conn_pag”.</p>
<pre><code class="lang-go"><span class="hljs-comment">/*
* Example Singleton C
* @package     main
* @author      @jeffotoni
* @size        10/09/2018
*/</span>

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

<span class="hljs-keyword">struct</span> Conn
{
    <span class="hljs-keyword">int</span> conn_pg;
};

<span class="hljs-keyword">struct</span> Conn* Connect()
{
    static <span class="hljs-keyword">struct</span> Conn *instance = NULL;

    <span class="hljs-comment">// entra somente</span>
    <span class="hljs-comment">// uma unica vez</span>
    <span class="hljs-keyword">if</span>(instance == NULL)
    {
        instance = malloc(sizeof(*instance));
        instance-&gt;conn_pg = <span class="hljs-number">34498</span>;
    }

    <span class="hljs-keyword">return</span> instance;
};

<span class="hljs-keyword">int</span> main() {

    printf(<span class="hljs-string">"Connect em C: %d\n"</span>, Connect()-&gt;conn_pg);
    printf(<span class="hljs-string">"Connect em C: %d\n"</span>, Connect()-&gt;conn_pg);

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>Em C usamos a função malloc para alocarmos dinamicamente nosso tipo “<em>Conn</em>” na memória para que possamos criar uma referência e acessa-lo de forma segura. O que temos que entender é que usamos struct para acessar nosso “<em>conn_pag</em>” e para fazer a chamada de nossa função um ponteiro de instância. Como relatado acima se implementar threads neste código teremos grandes problemas, teríamos que tratar os blocos e variáveis com <em>mutex ou pthread</em>, e neste cenário as coisas iriam complicar um pouco mas teríamos que garantir “<em>Thread Safe</em>”.</p>
<p>Vamos agora colocar nosso código usando threads, em C iremos usar a lib pthread.h para mostrar como ficaria nosso exemplo:</p>
<pre><code class="lang-go"><span class="hljs-comment">/*
* Example Singleton C
* @package     main
* @author      @jeffotoni
* @size        10/09/2018
*/</span>

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;
#include &lt;unistd.h&gt; 

<span class="hljs-keyword">struct</span> Conn
{   
    <span class="hljs-keyword">int</span> conn_pg;
    <span class="hljs-keyword">int</span> thread;
};

<span class="hljs-keyword">struct</span> Conn* Connect()
{
    static <span class="hljs-keyword">struct</span> Conn *instance = NULL;

    <span class="hljs-comment">// entra somente</span>
    <span class="hljs-comment">// uma unica vez</span>
    <span class="hljs-keyword">if</span>(instance == NULL)
    {
        instance = malloc(sizeof(*instance));
        instance-&gt;conn_pg = <span class="hljs-number">34498</span>;
    }

    <span class="hljs-keyword">return</span> instance;
};

void *PConn(void *tmp){

   <span class="hljs-keyword">struct</span> Conn *v = (<span class="hljs-keyword">struct</span> Conn *) tmp;

   <span class="hljs-comment">// aguarde ...</span>
   sleep(rand()%<span class="hljs-number">10</span>)+<span class="hljs-number">1</span>;

   printf(<span class="hljs-string">"Oi eu sou a thread %d\n"</span>, v-&gt;thread);
   printf(<span class="hljs-string">"Connect em C: %d\n"</span>, Connect()-&gt;conn_pg);
}

<span class="hljs-keyword">int</span> main() {

    pthread_t linhas[<span class="hljs-number">10</span>];
    <span class="hljs-keyword">int</span> execute,i;

    <span class="hljs-keyword">struct</span> Conn *conn;


    <span class="hljs-comment">//// thread 1</span>
    printf(<span class="hljs-string">"Criei a thread 1\n"</span>);
    conn = (<span class="hljs-keyword">struct</span> Conn *) malloc(sizeof(<span class="hljs-keyword">struct</span> Conn *));
    conn-&gt;thread = <span class="hljs-number">1</span>;
    execute = pthread_create(&amp;linhas[<span class="hljs-number">0</span>],NULL,PConn,(void *)conn);


    <span class="hljs-comment">//// thread 2</span>
    printf(<span class="hljs-string">"Criei a thread 2\n"</span>);
    conn = (<span class="hljs-keyword">struct</span> Conn *) malloc(sizeof(<span class="hljs-keyword">struct</span> Conn *));
    conn-&gt;thread = <span class="hljs-number">2</span>;
    execute = pthread_create(&amp;linhas[<span class="hljs-number">1</span>],NULL,PConn,(void *)conn);

    <span class="hljs-comment">// aguarde ...</span>
    sleep(rand()%<span class="hljs-number">10</span>)+<span class="hljs-number">2</span>;
    pthread_exit(NULL);

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>O exemplo acima para atribuições de valores em nossa <strong><em>struct</em></strong> teríamos que criar um <strong><em>pthread_mutex_lock e o pthread_mutex_unlock</em></strong> usando <strong><em>pthread_mutex_t</em></strong> junto com <strong><em>pthread_mutex_init</em></strong> p<em>ara termos a certeza e garantia da</em> <strong><em>exclusão mútua*</em></strong>, evitando<em> **</em>race conditions<strong><em> e </em></strong>deadlock’s<em>*</em>.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*JmurtIlIUde3vXLCgOiseg.jpeg" alt /></p>
<p>Não podemos deixar que ocorra um <em>race conditions e nem um</em> Deadlock</p>
<p>Confira nosso exemplo abaixo mostrando exatamente a utilização do mutex em nosso singleton.</p>
<pre><code class="lang-go"><span class="hljs-comment">/*
* Example Singleton C
* @package     main
* @author      @jeffotoni
* @size        10/09/2018
*/</span>

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;
#include &lt;unistd.h&gt; 

typedef <span class="hljs-keyword">struct</span> Conn
{   
    <span class="hljs-keyword">int</span> conn_pg;
    <span class="hljs-keyword">int</span> thread;
}CONNECT;

CONNECT dotstr;
pthread_mutex_t mutexconn;

<span class="hljs-keyword">struct</span> Conn* Connect()
{
    static <span class="hljs-keyword">struct</span> Conn *instance = NULL;

    <span class="hljs-comment">// entra somente</span>
    <span class="hljs-comment">// uma unica vez</span>
    <span class="hljs-keyword">if</span>(instance == NULL)
    {

        instance = malloc(sizeof(*instance));

        pthread_mutex_lock (&amp;mutexconn);
        instance-&gt;conn_pg = <span class="hljs-number">34498</span>;
        pthread_mutex_unlock (&amp;mutexconn);

        pthread_exit((void*) <span class="hljs-number">0</span>);
    }

    <span class="hljs-keyword">return</span> instance;
};

void *PConn(void *tmp){

   <span class="hljs-keyword">struct</span> Conn *v = (<span class="hljs-keyword">struct</span> Conn *) tmp;

   <span class="hljs-comment">// aguarde ...</span>
   sleep(rand()%<span class="hljs-number">10</span>)+<span class="hljs-number">1</span>;

   printf(<span class="hljs-string">"Oi eu sou a thread %d\n"</span>, v-&gt;thread);
   printf(<span class="hljs-string">"Connect em C: %d\n"</span>, Connect()-&gt;conn_pg);
}

<span class="hljs-keyword">int</span> main() {

    pthread_t linhas[<span class="hljs-number">10</span>];
    <span class="hljs-keyword">int</span> execute,i;

    <span class="hljs-keyword">struct</span> Conn *conn;

    pthread_mutex_init(&amp;mutexconn, NULL);

    <span class="hljs-comment">//// thread 1</span>
    printf(<span class="hljs-string">"Criei a thread 1\n"</span>);
    conn = (<span class="hljs-keyword">struct</span> Conn *) malloc(sizeof(<span class="hljs-keyword">struct</span> Conn *));
    conn-&gt;thread = <span class="hljs-number">1</span>;
    execute = pthread_create(&amp;linhas[<span class="hljs-number">0</span>],NULL,PConn,(void *)conn);


    <span class="hljs-comment">//// thread 2</span>
    printf(<span class="hljs-string">"Criei a thread 2\n"</span>);
    conn = (<span class="hljs-keyword">struct</span> Conn *) malloc(sizeof(<span class="hljs-keyword">struct</span> Conn *));
    conn-&gt;thread = <span class="hljs-number">2</span>;
    execute = pthread_create(&amp;linhas[<span class="hljs-number">1</span>],NULL,PConn,(void *)conn);

    <span class="hljs-comment">// aguarde ...</span>
    sleep(rand()%<span class="hljs-number">10</span>)+<span class="hljs-number">2</span>;
    pthread_exit(NULL);
    pthread_mutex_destroy(&amp;mutexconn);

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p><strong>Uma outra perspectiva quando usamos C:</strong></p>
<ul>
<li><p>Cada arquivo em um programa C é efetivamente uma classe singleton que é auto instanciada em tempo de execução e não pode ser subclassificada.</p>
</li>
<li><p>Variáveis ​​estáticas globais são seus membros de classe particulares.</p>
</li>
<li><p>Global estática são públicos (apenas declare-os usando “<em>extern</em>” em algum arquivo de cabeçalho e poderá ser acessado por outros arquivos).</p>
</li>
<li><p>Funções estáticas são métodos privados</p>
</li>
<li><p>Funções não estáticas são as públicas.</p>
</li>
</ul>
<h1 id="heading-conclusao">Conclusão</h1>
<p>Como percebemos acima, trabalhar com C usando “<strong><em>threads</em></strong>” não é uma tarefa simples, e proteger nossa instância e deixa-la atômica torna-se uma tarefa complexa usando C. Uma solução foi utilizar structs e typedef para definirmos e encapsularmos nossas variáveis protegendo o acesso a nossa struct quando acessado simultaneamente pela nossas <em>threads</em>. Foi usado <strong><em>mutex</em></strong> para garantirmos que não ocorra uma <strong><em>race</em></strong> <strong><em>conditions</em></strong> e evitando um <strong><em>deadlock</em></strong> em nosso programa.<br />O artigo é somente uma introdução e uma simples apresentação de como implementar <em>o pattern singleton</em> quando temos <em>threads</em> concorrendo entre si.</p>
<h2 id="heading-codigos-fontes-e-exemplos-do-artigo">Códigos fontes e exemplos do artigo</h2>
<p><a target="_blank" href="http://github.com/jeffotoni/medium-posts/pattern-singleton/example-c">github.com/jeffotoni/medium-posts/pattern-singleton/example-c</a></p>
<p>Espero ter ajudado a esclarecer um pouco as dúvidas sobre utilização do <strong><em>Pattern Singleton</em></strong> em C, utilizando variáveis globais, threads e mutex diversos outros pontos importantes e técnicos abordados no artigo.</p>
<p>No próximo post será mais um desafio bem interessante, que estou preparando… Quem curtiu e chegou até o final deixa uma palminha aí…</p>
]]></content:encoded></item><item><title><![CDATA[Pattern Singleton com Golang]]></title><description><![CDATA[Sempre me deparo com necessidade de implementar o Pattern Singleton em meus projetos, mas em Golang existem algumas particularidades que temos que tomar…]]></description><link>https://jeffotoni.hashnode.dev/pattern-singleton-com-golang</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/pattern-singleton-com-golang</guid><category><![CDATA[Developer]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Mon, 10 Apr 2023 17:38:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681146250404/84c35b69-5b57-4c0e-b92e-30a99b194337.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Sempre me deparo com necessidade de implementar o <a target="_blank" href="https://pt.wikipedia.org/wiki/Singleton"><strong>Pattern Singleton</strong></a> em meus projetos, mas em <a target="_blank" href="http://golang.org/"><strong>Golang</strong></a> existem algumas particularidades que temos que tomar cuidado. Neste artigo, vou apresentar duas formas de implementar o Singleton usando Golang, a forma “<strong><em>Not Thread Safe</em></strong>” e a forma “<strong><em>Thread Safe</em></strong>”. O objetivo é apresentar de forma prática e técnica as formas de implementação e quando temos que implementar o <strong><em>patterns singleton.</em></strong></p>
<h2 id="heading-problema-a-ser-resolvido"><strong>Problema a ser resolvido</strong></h2>
<p>Temos que abrir uma conexão com o banco de dados e mantê-la em uma única instância para não sobrecarregar o banco e termos problemas ou erros com o limite de conexões simultâneas excedido, além, é claro, de otimizarmos nosso código. Sabemos que uma conexão é muito custosa computacionalmente.</p>
<p>Como o banco não dá suporte à pool de conexões de forma nativa, então precisaremos controlar todas as conexões que nossa aplicação irá abrir para se comunicar com ele, assim, em cada ação que formos executar, seja um select, delete, insert ou update, precisaremos de um objeto de conexão em memória de forma atômica e para isso vamos utilizar o <strong><em>pattern singleton</em></strong>.</p>
<p>Antes de implementarmos nossa solução usando <strong>Pattern Singleton</strong> para resolver o problema do pool de conexões, vamos conferir alguns outros exemplos da necessidade da utilização do <strong><em>pattern singleton.</em></strong></p>
<p>Abaixo alguns <strong>exemplos</strong> de diversas formas de tentar proteger nossa <strong><em>variável global.</em></strong></p>
<h2 id="heading-protegendo-variavel-global-exemplo-1"><strong>Protegendo variável Global Exemplo 1</strong></h2>
<pre><code class="lang-go"><span class="hljs-comment">// type global</span>
<span class="hljs-keyword">type</span> singleton <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>

<span class="hljs-keyword">var</span> (
    instance singleton
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewClass</span><span class="hljs-params">()</span> <span class="hljs-title">singleton</span></span> {

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {

        instance = <span class="hljs-built_in">make</span>(singleton) <span class="hljs-comment">// &lt;-- not thread safe</span>
    }

    <span class="hljs-keyword">return</span> instance
}
</code></pre>
<h2 id="heading-protegendo-variavel-global-exemplo-2">Protegendo variável Global Exemplo 2</h2>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-comment">// type global</span>
<span class="hljs-keyword">type</span> singleton <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>

<span class="hljs-keyword">var</span> (
    instance singleton
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewClass</span><span class="hljs-params">()</span> <span class="hljs-title">singleton</span></span> {

    lock.Lock()
    <span class="hljs-keyword">defer</span> lock.Unlock()

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {

        instance = <span class="hljs-built_in">make</span>(singleton) <span class="hljs-comment">// &lt;-- thread safe</span>
    }

    <span class="hljs-keyword">return</span> instance
}
</code></pre>
<h2 id="heading-protegendo-variavel-global-exemplo-3">Protegendo variável Global Exemplo 3</h2>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> once sync.Once

<span class="hljs-comment">// type global</span>
<span class="hljs-keyword">type</span> singleton <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>

<span class="hljs-keyword">var</span> (
    instance singleton
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewClass</span><span class="hljs-params">()</span> <span class="hljs-title">singleton</span></span> {

    once.Do(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> { <span class="hljs-comment">// &lt;-- atomic, does not allow repeating</span>

        instance = <span class="hljs-built_in">make</span>(singleton) <span class="hljs-comment">// &lt;-- thread safe</span>

    })

    <span class="hljs-keyword">return</span> instance
}
</code></pre>
<p>Acima é mostrado três formas de proteger nossa variável global <strong><em>“instance”,</em></strong> para soluções síncronas o <em>exemplo 1</em> já irá funcionar, para soluções assíncronas o <em>exemplo 2 e 3</em> são o mais indicados sendo que o <em>exemplo 3</em> é a melhor solução para protegermos de “<a target="_blank" href="https://blog.golang.org/race-detector"><strong><em>race condition</em></strong></a>” garantindo que a instância seja declarada uma única vez tornando-se atômica.</p>
<p>O objetivo do artigo é mostrar exatamente as formas de tentar proteger a <strong><em>variável global</em></strong>, em Golang temos diversas maneiras de fazermos isso.<br />Abaixo temos mais alguns exemplos para complementar o raciocínio, mostrando como fazemos as instanciações do nosso singleton, seja ele de forma síncrona ou assíncrona usando goroutine.</p>
<h2 id="heading-exemplos-de-como-instanciar-nosso-singleton">Exemplos de como instanciar nosso Singleton</h2>
<p>O código abaixo é um bom exemplo de aberturas de diversas conexões de forma <strong><em>síncrona</em></strong>, dependendo da forma que implementarmos nossa instância de conexão o banco não suportaria.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    objeto := NewClass() <span class="hljs-comment">// instance make</span>

    objeto[<span class="hljs-string">"this"</span>] = <span class="hljs-string">"Object NewClass"</span>
    objeto2 := NewClass() <span class="hljs-comment">// return instance</span>

    fmt.Println(<span class="hljs-string">"This is:"</span>, objeto2[<span class="hljs-string">"this"</span>])

    objeto3 := NewClass() <span class="hljs-comment">// return instance</span>
    objeto4 := NewClass() <span class="hljs-comment">// return instance</span>
    objeto5 := NewClass() <span class="hljs-comment">// return instance</span>

    fmt.Println(<span class="hljs-string">"This is:"</span>, objeto3[<span class="hljs-string">"this"</span>])
    fmt.Println(<span class="hljs-string">"This is:"</span>, objeto4[<span class="hljs-string">"this"</span>])
    fmt.Println(<span class="hljs-string">"This is:"</span>, objeto5[<span class="hljs-string">"this"</span>])
}
</code></pre>
<p>Agora vamos visualizar um exemplo de abertura de conexões de forma <strong><em>assíncrona</em></strong> utilizando <strong><em>goroutine</em></strong>. Fizemos centenas de goroutines e milhares de conexões simultâneas em nosso exemplo abaixo, funciona 100% sem travar e ou bugar a quantidade de conexões do banco de dados.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    objeto := NewClass() <span class="hljs-comment">// instance make</span>

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1000</span>; i++ {

            objeto = NewClass() <span class="hljs-comment">// &lt;-- return instance</span>
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {

            <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

                objeto = NewClass() <span class="hljs-comment">// &lt;-- return instance</span>
            }()
        }
    }()

    fmt.Scanln()
}
</code></pre>
<h1 id="heading-goroutines-e-o-pattern-singleton">Goroutines e o pattern singleton</h1>
<p>Quando pensamos nas possíveis soluções para a implementação do <strong><em>pattern singleton</em></strong> usando Golang, esbarramos nos <em>Goroutines</em> ele será responsável por nos proporcionar que nosso código execute de forma <strong><em>assíncrona</em></strong> e <strong><em>concorrente</em></strong> e quando usamos Goroutine em nossa aplicação toda nossa forma de pensar e implementar muda, ou seja não é mais uma aplicação <strong><em>síncrona</em></strong> e devido a isso temos que pensar da forma <strong><em>Golang de ser</em>.</strong></p>
<p>As <a target="_blank" href="https://tour.golang.org/concurrency/1"><strong><em>Goroutines</em></strong></a> é um poderoso recurso e quando usado corretamente ele torna-se um forte aliado para combatermos as batalhas do dia a dia. Toda vez que implementamos códigos que usam <em>concorrência</em> temos alguns cenários já conhecidos que temos que tratar, o escopo do programa, <strong><em>variáveis globais</em></strong>, locais, passagem de parâmetros, ponteiros tudo isso tem que ser tratado para que possamos trabalhar com concorrência de forma correta e otimizada.</p>
<p>Um bom exemplo de possíveis problemas usando concorrência é a utilização de <strong><em>variáveis globais</em></strong>. Devido as goroutines nossa implementação do <strong><em>Pattern Singleton</em></strong> e nossas possíveis soluções será escrita para aceitar o uso de concorrência. Vamos escrever o nosso código usando boas práticas de programação, para tentar mitigar os possíveis bugs sigilosos que podem ocorrer em tempo de execução do seu programa escrito em <em>Golang</em>.</p>
<h2 id="heading-200-goroutines-sendo-inicializadas">200 goroutines sendo inicializadas</h2>
<p>Em nosso exemplo abaixo está sendo criado <em>200 goroutines</em> e colocando todas em concorrência e <em>dez mil interações</em> estão sendo feitas em nosso banco de dados ou seja “<em>connect e faça: select email from login where id =?</em>”.</p>
<pre><code class="lang-go">    <span class="hljs-keyword">for</span> x := <span class="hljs-number">0</span>; x &lt; <span class="hljs-number">200</span>; x++ {

        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(x <span class="hljs-keyword">int</span>)</span></span> {

            <span class="hljs-keyword">for</span> j := <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">10000</span>; j++ {

                fmt.Println(<span class="hljs-string">" login: "</span>, Conn.Connet().GetUserEmail(x))
                time.Sleep(time.Millisecond * <span class="hljs-number">150</span>)
            }
        }(x)
    }
</code></pre>
<p>O bom entendimento sobre as <em>goroutines</em> irá nos ajudar a escrever códigos melhores e mais poderosos em <em>Golang</em>, isto não tenho dúvidas. Em um próximo artigo iremos descrever alguns cases usando goroutines, estou ansioso para escrever sobre Goroutines e mostrar como resolvemos alguns de nossos problemas na empresa.</p>
<p>O assunto sobre <strong>Pattern Singleton</strong> é tão interessante que tive que fazer uma pesquisa bem mais profunda sobre o assunto antes de escrever este artigo e como uso muito em meu dia a dia decidi colaborar um pouco mostrando alguns pontos importantes deste pattern e por que muita das vezes ele é considerado um <strong><em>Anti Pattern</em></strong>. Descrevendo os detalhes técnicos no artigo percebemos claramente diversas boas práticas que poderemos utilizar em nosso dia dia quando estamos codando em <em>Golang</em>, boas práticas, formas clean de implementação, implementações menos complexas e menos custosas e com maior desempenho.</p>
<h1 id="heading-o-que-e-pattern-singleton">O que é Pattern Singleton?</h1>
<p>A transcrição do que é um Pattern Singleton seria: *“*<strong><em>Singleton</em></strong> *é um padrão de projeto de software. Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto”.*Singleton é um padrão de design que restringe a instanciação a um objeto, temos que garantir que isto ocorra somente uma única vez.</p>
<p>Basicamente <strong>singleton</strong> é uma maneira de usar <strong><em>variáveis ​​globais</em></strong>. Sabemos o quanto é perigoso o uso de variáveis globais, nosso código fica vulnerável ao acesso da <em>variável global</em> ou seja em qualquer parte do sistema podemos alterar seu valor. Portanto, ao tentarmos debugar ou depurar nosso programa não será uma tarefa fácil descobrir qual caminho de código leva ao estado atual, este é um dos motivos que não considero o <strong><em>Pattern Singleton</em></strong> um <strong><em>Anti Pattern</em></strong> e sim uma formas de proteger as <strong><em>variáveis globais.</em></strong></p>
<p>No entanto, o problema com <strong><em>Singleton</em></strong> usando concorrência que será nosso objetivo, em um ambiente multiencadeado, a inicialização deve ser protegida para evitar a reinicialização, de forma atômica.</p>
<p>O <strong><em>Pattern Singleton</em></strong> é uma característica proveniente do paradigma orientado a objeto, então como iremos implementar em <em>Golang</em> se o mesmo não possui suporte a OO ?</p>
<p>Para responder esta pergunta temos que entender que a <strong><em>Programação</em></strong> <strong><em>Orientada a Objeto</em></strong> é um conceito e pode ser implementando em qualquer linguagem de programação mesmo sendo de outros paradigmas. É claro que o nível de abstração e dificuldade torna-se uma tarefa árdua aumentando muito o nível de complexidade do código dependendo da linguagem, nossa intenção é puramente didática com intuito de entendermos melhor o cenário proposto quando falamos em <strong><em>pattern singleton</em></strong>*.*</p>
<h1 id="heading-go-run-race-singletongo">go run -race singleton.go</h1>
<blockquote>
<p>Executa todos os códigos usando -race como parâmetro: go run -race ..</p>
</blockquote>
<p>O <strong><em>“-race detector”</em></strong> é um recurso que temos disponível em Golang para detectar acessos indevidos em memória quando estamos usando concorrência em nossa aplicação. É possível gerar relatório que contém rastreamentos de pilha para acessos conflitantes, bem como pilhas nas quais as goroutines envolvidas foram criadas, em breve vou criar um artigo abordando exatamente este assunto e vamos falar sobre <strong><em>“Profiling“</em></strong> em Go.<br />Abaixo as formas que podemos fazer a chamada do “-race”.</p>
<pre><code class="lang-go">$ <span class="hljs-keyword">go</span> test -race seupkg    <span class="hljs-comment">// to test the package</span>
$ <span class="hljs-keyword">go</span> run -race seusrc.<span class="hljs-keyword">go</span>  <span class="hljs-comment">// to run the source file</span>
$ <span class="hljs-keyword">go</span> build -race seucmd   <span class="hljs-comment">// to build the command</span>
$ <span class="hljs-keyword">go</span> install -race seupkg <span class="hljs-comment">// to install the package</span>
</code></pre>
<h1 id="heading-pattern-singleton-em-golang">Pattern Singleton em Golang</h1>
<p>A solução apresentada abaixo seria ideal se nossa aplicação fosse <strong><em>síncrona,</em></strong> e o problema seria resolvido com código abaixo, mas como nosso objetivo é implementar usando concorrência a solução abaixo está longe de ser a ideal.<br />Vamos conferir o código abaixo e iniciar nossas possibilidades de implementação:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {
        <span class="hljs-comment">// &lt;--- NOT THREAD SAFE / Quando usarmos Goroutine</span>
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {
            time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
            fmt.Println(*Connect(), <span class="hljs-string">" - "</span>, i)
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(*Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>Na implementação acima, temos nossa primeira abordagem implementando <strong><em>Singleton</em></strong> em Golang e com goroutines para executar simultaneamente o nosso <strong><em>Singleton</em></strong>.</p>
<p>O problema visível neste código é que várias rotinas de <strong>goroutine</strong> poderiam avaliar a primeira verificação e todas criariam uma instância do tipo <strong>singleton</strong> e substituiriam uma à outra. Não há garantia de qual <em>instância</em> será retornada no código acima, e outras operações adicionais na instância podem ser inconsistentes com as expectativas do desenvolvedor e problemas sigilosos podem ocorrer em tempo de execução.</p>
<p>Muito ruim esta abordagem, diversos erros muitos sutis podem ocorrer, se as referências à instância singleton estiverem sendo mantidas por meio do código, existe uma grande chance de haver potencialmente várias instâncias do tipo com estados diferentes, gerando potenciais comportamentos de código. Ele também se torna um verdadeiro pesadelo durante a depuração e se torna realmente difícil detectar o bug, já que no tempo de depuração nada parece estar errado devido às pausas de tempo de execução, minimizando o potencial de uma execução “<strong><em>Not Thread Safe</em></strong>”, ofuscando totalmente o problema para quem está codando.</p>
<h1 id="heading-bloqueios-com-mutex">Bloqueios com Mutex</h1>
<p>No código abaixo é uma solução <em>pobre</em> para a tentativa de resolver o problema de “<strong><em>Thread Safe</em></strong>”. Na verdade, isso resolve o problema “<strong><em>Thread Safe</em></strong>”, mas cria outros problemas sérios em potencial. Ele introduz uma contenção nas goroutines executando um <strong><em>bloqueio agressivo</em></strong> de toda a função, vamos conferir o código abaixo:</p>
<pre><code class="lang-go"><span class="hljs-comment">// nosso lock mutex</span>
<span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {
    <span class="hljs-comment">// &lt;--- Desnecessario a lock</span>
    <span class="hljs-comment">// se a instancia já tiver</span>
    <span class="hljs-comment">// sido criada muito agressivo</span>
    lock.Lock()
    <span class="hljs-keyword">defer</span> lock.Unlock()

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {
        <span class="hljs-comment">// ainda não é a melhor implementação devido</span>
        <span class="hljs-comment">// os bloqueios</span>
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {
            time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
            fmt.Println(*Connect(), <span class="hljs-string">" - "</span>, i)
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        fmt.Println(*Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>O problema de “<strong><em>Thread Safe</em></strong>” foi resolvido com a implementação acima usando <strong>sync.Mutex</strong> onde ocorre o Bloqueio antes de criar a instância <strong>Singleton</strong>. O grande problema desta abordagem é o bloqueio excessivo mesmo quando não seria necessário fazer isso, no caso de a instância já ter sido criada e deveríamos simplesmente ter retornado a instância <strong>singleton</strong>. Se nosso programa for escrito para tornar-se altamente concorrente, isso pode gerar um gargalo, pois somente uma rotina de goroutine pode obter a instância <strong>singleton</strong> de cada vez, tornando-se nossa solução mais lenta.</p>
<p>Vamos conferir outra solução, por que está acima não é nossa melhor abordagem.</p>
<h1 id="heading-check-lock-check-em-go">Check-Lock-Check em Go</h1>
<p>Um forma de melhorar e a segurar a garantia de um mínimo de bloqueio e ainda ser seguro para a goroutine é utilizar o padrão chamado “<strong><em>Check-Lock-Check</em></strong>*”*, ao adquirir bloqueios. Usamos este mesmo Patter em C e C++.<br />O padrão funciona com a ideia de verificar primeiro, para minimizar qualquer bloqueio agressivo, já que uma instrução <em>IF</em> é menos dispendiosa do que o <em>bloqueio</em>.</p>
<p>No próximo momento teríamos de esperar e adquirir o bloqueio exclusivo para que apenas uma execução esteja dentro desse bloco em uma única vez. Com a primeira verificação e com bloqueio exclusivo, poderia haver outra goroutine que adquiriu o bloqueio, portanto, precisaríamos verificar novamente dentro do bloqueio para evitar a substituição da instância por outro.</p>
<p><strong><em>Confira o código abaixo:</em></strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-comment">// ainda não está perfeita, não é totalmente atomico</span>
    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {
        lock.Lock()
        <span class="hljs-keyword">defer</span> lock.Unlock()
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }
    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {
            time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
            fmt.Println(*Connect(), <span class="hljs-string">" - "</span>, i)
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(*Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>Está abordagem acima é a melhor até o momento, mas ainda <strong>não</strong> é perfeita. Não há uma verificação atômica no estado de armazenamento da instância. Levando em consideração todas as considerações técnicas, isso ainda não é perfeito. Mas é muito melhor que as abordagens iniciais.</p>
<p>Usando o pacote <em>sync/atomic</em>, podemos carregar e definir de forma atômica um sinalizador que indicará se inicializamos ou não nossa instância.</p>
<p><strong><em>Confira o código abaixo:</em></strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// manter o estado</span>
<span class="hljs-keyword">var</span> atomicinz <span class="hljs-keyword">uint64</span>

<span class="hljs-comment">// lock mutex</span>
<span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-comment">// driver</span>
<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-comment">// instancia Global</span>
<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-comment">// funcao retornando</span>
<span class="hljs-comment">// o ponteiro de nossa</span>
<span class="hljs-comment">// struct</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-comment">// garantindo que já entrou</span>
    <span class="hljs-keyword">if</span> atomic.LoadUint64(&amp;atomicinz) == <span class="hljs-number">1</span> {

        <span class="hljs-keyword">return</span> instance
    }

    lock.Lock()
    <span class="hljs-keyword">defer</span> lock.Unlock()

    <span class="hljs-comment">// entra somente uma</span>
    <span class="hljs-comment">// únic vez</span>
    <span class="hljs-keyword">if</span> atomicinz == <span class="hljs-number">0</span> {

        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
        atomic.StoreUint64(&amp;atomicinz, <span class="hljs-number">1</span>)
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(*Connect())
    }()

    <span class="hljs-comment">// 50 goroutine</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">50</span>; i++ {
        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(i <span class="hljs-keyword">int</span>)</span></span> {
            <span class="hljs-keyword">for</span> {
                time.Sleep(time.Millisecond * <span class="hljs-number">60</span>)
                fmt.Println(Connect().conn, <span class="hljs-string">" - "</span>, i)
            }
        }(i)
    }

    fmt.Scanln()
}
</code></pre>
<p>A biblioteca <strong>sync/atomic</strong> nos permite sinalizar e armazenar um conteúdo de forma segura e garantindo sua unicidade, bem parecido com <a target="_blank" href="http://sync.Map">sync.Map</a>, onde ele está armazenando em um storage e aceitando concorrência em sua implementação. O problema que tivemos que usar mais uma funcionalidade, mais recurso e consecutivamente um pouco mais lento nossa execução.</p>
<h1 id="heading-synconce-clean-e-poderoso">sync.Once clean e poderoso</h1>
<p>Temos o tipo “<strong><em>Once</em></strong>” na biblioteca <strong>sync</strong>, lembrando que esta biblioteca nativa em Golang é muito poderosa e temos que explora-la o máximo que conseguirmos, o objeto <strong><em>sync.Once</em></strong> executará uma ação exatamente uma vez e não mais, era o que faltava para nosso código ficar ainda mais poderoso e clean.</p>
<pre><code class="lang-go"><span class="hljs-comment">// call somente</span>
<span class="hljs-comment">// uma unica vez</span>
<span class="hljs-keyword">var</span> once sync.Once

<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-comment">// variavel Global</span>
<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    once.Do(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    })

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(*Connect())
    }()

    <span class="hljs-comment">// 100 goroutine</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {

        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(ix <span class="hljs-keyword">int</span>)</span></span> {
            time.Sleep(time.Millisecond * <span class="hljs-number">60</span>)
            fmt.Println(ix, <span class="hljs-string">" = "</span>, Connect().conn)
        }(i)
    }

    fmt.Scanln()
}
</code></pre>
<p>Com esta abordagem e cenário proposto nosso código além de ficar mais clean ficou bem melhor, a função <strong><em>sync.Once</em></strong> garante a <strong>unicidade</strong> de nossa instância, nosso código agora pode ter <em>100 goroutines</em> ou muito mais conforme a sua necessidade, coloca-los em concorrência não teremos problemas de “<strong><em>Thread Safe</em></strong>” ou checagem agressiva como vimos acima em outras abordagens. Uma forma simples e segura de escrever o código Golang para implementação do Pattern Singleton.</p>
<h1 id="heading-init-uma-outra-abordagem"><code>init( ) Uma outra abordagem</code></h1>
<p>Uma outra abordagem e também válida é utilizar o <strong><em>init( )</em></strong>, ele é executado somente uma única vez e é chamado antes da função maim.<br />Confere o código abaixo:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">init</span><span class="hljs-params">()</span></span> {

    Connect()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(instance.conn)
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(*Connect())
    }()

    <span class="hljs-comment">// 100 goroutine</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {

        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(ix <span class="hljs-keyword">int</span>)</span></span> {
            time.Sleep(time.Millisecond * <span class="hljs-number">60</span>)
            fmt.Println(ix, <span class="hljs-string">" = "</span>, instance.conn)
        }(i)
    }

    fmt.Scanln()
}
</code></pre>
<p>Porém esta abordagem existe uma desvantagem quando usamos <strong>init( )</strong>. Percebesse claramente que não é segura, nada impede de fazer uma chamada direta na função “<strong><em>Connect</em></strong>” como ocorreu na linha <strong><em>#28</em></strong> além de que existe uma limitação no uso do <strong><em>init</em>( )</strong> com relação ao seu tempo de carregamento e o mais importante em Golang podemos ter vários <strong><em>init</em></strong> sendo executados não somente em um arquivo ou pacote mas em vários, e existe uma ordem de execução entre eles.</p>
<p>A <em>função</em> <strong>init( )</strong> não aceita argumentos nem retorna nenhum valor. Em contraste com nossa abordagem usando <strong><em>sync.Once</em></strong>, o identificador <strong>init()</strong> não é declarado, portanto não pode ser referenciado.</p>
<p>O melhor cenário é escrever códigos que não dependam da ordem de inicialização, em versões anteriores do <em>golang</em> houve algumas reclamações e diversos problemas relatados, não escrevam códigos em um ***init( )***que você precise de garantias de execução em determinado momento. A solução quando precisa de garantia explícita é escrever chamadas explícitas.</p>
<p>Para ter mais detalhes tem um página só disto em Golang <a target="_blank" href="https://golang.org/doc/effective_go.html#initialization">https://golang.org/doc/effective_go.html#initialization,</a> vale a pena a leitura detalhada sobre o <strong><em>init</em></strong>( ), é uma implementação poderosa e robusta nas versões atuais do <strong><em>Golang</em></strong> mas sempre é bom ficar atento.</p>
<h1 id="heading-variavel-recebendo-a-funcao"><code>Variável recebendo a função</code></h1>
<p>Uma outra abordagem e também válida é utilizar uma variável global recebendo a função em um <strong><em>escopo global</em></strong>, sabemos que em <em>Golang</em> as variáveis são atribuídas e declaradas antes da chamada do <strong>init</strong>( ) e da função main, então nesta abordagem o método retorna exatamente uma única vez a instância. Confere o código abaixo:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-keyword">var</span> instanceNew = *Connect()

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {

        <span class="hljs-comment">// &lt;--- NOT THREAD SAFE</span>
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(<span class="hljs-string">"goroutine 1: "</span>, instanceNew.conn)
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(<span class="hljs-string">"goroutine 2: "</span>, *Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>Esta abordagem é falha por que nada garante que a função irá ser chamado novamente em alguma parte do código, como ocorreu na linha <strong><em>#25</em></strong> a função foi chamada novamente, na linha <strong><em>#30</em></strong> é feito a instância do nosso singleton, porém nada garante esta unicidade.</p>
<h1 id="heading-conclusao">Conclusão</h1>
<p>O ideal sem dúvida é utilização do <strong><em>sync.Once</em></strong> que garante com certeza a unicidade e que seja <strong><em>“Thread Safe”</em></strong> nos garantindo que não ocorra uma “<a target="_blank" href="https://blog.golang.org/race-detector"><strong><em>race condition</em></strong></a>”, ele só permite que a função seja executada somente uma única vez Golang flexibilizou e automatizou toda complexidade que teríamos em outras langs se fôssemos trabalhar com concorrência e simultaneidade. Realmente Golang ficou poderoso nestas abordagens, tornando-se simples de implementar e entender.</p>
<p>Quando falamos de concorrência toda nossa forma de pensar e codar as soluções utilizando <strong><em>Golang</em></strong> mudam drasticamente. Existem vários cenários que precisamos aplicar padrões e práticas em nossos projetos para aproveitar o máximo do poder que o <strong><em>Golang</em></strong> oferece.</p>
<p>Todo projeto que participo torna-se quase um “<em>mantra</em>” entre as equipes de desenvolvimento fazer diversos testes e revisões para aproveitar o máximo que a linguagem proporciona. Quanto mais aprofundamos nos estudos mais descobrimos que pouco sabemos sobre a linguagem. O legal de tudo é o desafio, quando trabalhamos com goroutines em <strong><em>Golang</em></strong> precisamos entender o quanto antes as funcionalidades e o que é possível fazer, comportamentos, segurança das goroutines são todos essenciais para melhorar cada vez mais o nosso código.</p>
<p>Caso tenha interesse em acompanhar ou trocar ideias sejam elas a nível iniciante, intermediário ou “<strong><em>hardcore</em></strong>” sobre a linguagem <strong>Golang</strong> existe alguns grupos de Golang espalhados na internet dois deles em especial sempre que possível estou presente é o do <a target="_blank" href="https://t.me/go_br"><strong>https://t.me/go_br</strong></a> <strong>(GoBr)</strong> e o <a target="_blank" href="http://gophers.slack.com"><strong>gophers.slack.com</strong></a>, comunidades ativas usando <em>Golang</em>, sempre estão compartilhando ideias, projetos, vagas e dúvidas todo o tempo e a todo momento estamos reaprendendo.</p>
<p>Espero ter ajudado a esclarecer um pouco as dúvidas sobre utilização do <strong><em>Pattern Singleton</em></strong>, utilizando <strong>variáveis globais</strong>, <strong>goroutines</strong>, <strong><em>sync.Once</em></strong>, <strong>Init</strong>( ), mutex e diversos outros pontos importantes e técnicos abordados no artigo.</p>
<p>Logo abaixo está todos os códigos fontes que utilizamos como exemplo no artigo caso tenha interesse de baixar e testar fique a vontade.</p>
<h2 id="heading-codigos-fontes-e-exemplos-do-artigo">Códigos fontes e exemplos do artigo</h2>
<p><a target="_blank" href="https://github.com/jeffotoni/medium-posts">https://github.com/jeffotoni/medium-posts</a></p>
<p>Gostaria de agradecer alguns colegas que ajudaram na revisão deste artigo para mantermos a qualidade do conteúdo e deixa-lo denso sem ficar complexo e jato. <strong><em>Obrigado</em></strong> :</p>
<p><a target="_blank" href="https://medium.com/u/3f6c1dee6dad?source=post_page-----938d1debe626--------------------------------">Joelson</a></p>
<p>, <a target="_blank" href="https://medium.com/u/a1237dcc0ed2?source=post_page-----938d1debe626--------------------------------">Marco Paganinii,</a> <a target="_blank" href="https://medium.com/u/79525c7eb6d6?source=post_page-----938d1debe626--------------------------------">Francisco Oliveira</a></p>
<p>No próximo artigo que está no forno será sobre lambdas, como escrever lambdas em Golang, será mais um desafio bem interessante, que estou preparando.</p>
<p>Quem curtiu e chegou até o final deixa uma palminha aí… Obrigado 🤘🤓</p>
]]></content:encoded></item><item><title><![CDATA[How singleton pattern works with Golang]]></title><description><![CDATA[I always have to implement Singleton Pattern in my projects, but in Golang there are some peculiarities that we have to take care of. In this article, I…]]></description><link>https://jeffotoni.hashnode.dev/how-singleton-pattern-works-with-golang</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/how-singleton-pattern-works-with-golang</guid><category><![CDATA[Developer]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Mon, 10 Apr 2023 16:29:45 GMT</pubDate><content:encoded><![CDATA[<p>I always have to implement <strong><em>Singleton Pattern</em></strong> in my projects, but in <strong><em>Golang</em></strong> there are some peculiarities that we have to take care of. In this article, I will present two ways to implement Singleton using Golang, the “<strong><em>Not Thread Safe</em></strong>” form and the “<strong><em>Thread Safe</em></strong>” form. The goal is to present in a practical and technical way the forms of implementation and when we have to implement the <strong><em>singleton patterns</em></strong>.</p>
<h2 id="heading-problem-to-be-solved">Problem to be solved</h2>
<p>We have to open a connection to the database and keep it in a single instance so we do not overload the database and have problems or errors with the limit of concurrent connections exceeded, and of course, of optimizing our code. We know that a connection is very costly computationally.</p>
<p>Pooling natively, then we need to control all the connections that our application will open to communicate with it, so in every action we execute, be it a select, delete, insert or update, we need a connection we will use the singleton pattern in the memory of atomic form. Examples of <strong><em>Singleton async</em></strong> and <strong><em>sync connections</em></strong>.</p>
<p>Before we implement our solution using <strong><em>Singleton Pattern</em></strong> to solve the problem of connection pooling, let’s look at some other examples of the need to use the singleton pattern.</p>
<p>Here are some examples of ways to try to protect our <strong><em>global variable</em></strong>.</p>
<h2 id="heading-protecting-global-variable-example-1">Protecting Global Variable Example 1</h2>
<pre><code class="lang-go"><span class="hljs-comment">// type global</span>
<span class="hljs-keyword">type</span> singleton <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>

<span class="hljs-keyword">var</span> (
    instance singleton
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewClass</span><span class="hljs-params">()</span> <span class="hljs-title">singleton</span></span> {

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {

        instance = <span class="hljs-built_in">make</span>(singleton) <span class="hljs-comment">// &lt;-- not thread safe</span>
    }

    <span class="hljs-keyword">return</span> instance
}
</code></pre>
<h2 id="heading-protecting-global-variable-example-2">Protecting Global Variable Example 2</h2>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-comment">// type global</span>
<span class="hljs-keyword">type</span> singleton <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>

<span class="hljs-keyword">var</span> (
    instance singleton
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewClass</span><span class="hljs-params">()</span> <span class="hljs-title">singleton</span></span> {

    lock.Lock()
    <span class="hljs-keyword">defer</span> lock.Unlock()

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {

        instance = <span class="hljs-built_in">make</span>(singleton) <span class="hljs-comment">// &lt;-- thread safe</span>
    }

    <span class="hljs-keyword">return</span> instance
}
</code></pre>
<h2 id="heading-protecting-global-variable-example-3">Protecting Global Variable Example 3</h2>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> once sync.Once

<span class="hljs-comment">// type global</span>
<span class="hljs-keyword">type</span> singleton <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>

<span class="hljs-keyword">var</span> (
    instance singleton
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewClass</span><span class="hljs-params">()</span> <span class="hljs-title">singleton</span></span> {

    once.Do(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> { <span class="hljs-comment">// &lt;-- atomic, does not allow repeating</span>

        instance = <span class="hljs-built_in">make</span>(singleton) <span class="hljs-comment">// &lt;-- thread safe</span>

    })

    <span class="hljs-keyword">return</span> instance
}
</code></pre>
<p>Above we show three ways to protect our global variable “instance”, for synchronous solutions example 1 will already work, for asynchronous solutions example 2 and 3 are the most indicated being that example 3 is the best solution to protect from “<a target="_blank" href="https://blog.golang.org/race-detector"><strong><em>race condition</em></strong></a>“ by ensuring that the instance is declared a single time by becoming atomic.</p>
<p>The purpose of the article is to show exactly how to try to protect the <strong><em>global variable,</em></strong> in Golang we have several ways of doing this.<br />Below are a few more examples to complement the reasoning, showing how we instantiate our <strong>singleton</strong>, be it <em>synchronously or asynchronously</em> using <em>goroutine</em>.</p>
<h2 id="heading-examples-of-how-to-instantiate-our-singleton">Examples of how to instantiate our Singleton</h2>
<p>The code below is a good example of openings for multiple connections in a synchronous way, depending on how we implement our connection instance the bank would not support.</p>
<pre><code class="lang-go"><span class="hljs-comment">// na base</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// conexao</span>
    Db := Conn.Connet()

    <span class="hljs-comment">// busca sempre</span>
    <span class="hljs-comment">// da memoria</span>
    Db = Conn.Connet()
    Db = Conn.Connet()
    Db = Conn.Connet()
    Db = Conn.Connet()
    Db = Conn.Connet()
    Db = Conn.Connet()
    Db = Conn.Connet()

    <span class="hljs-comment">// da memoria</span>
    fmt.Println(<span class="hljs-string">"connect"</span>, Db.Ping())
    fmt.Println(<span class="hljs-string">"connect"</span>, Conn.Connet().Ping())
    fmt.Println(<span class="hljs-string">"connect"</span>, Db.Ping())
    fmt.Println(<span class="hljs-string">"connect"</span>, Conn.Connet().Ping())
    fmt.Println(<span class="hljs-string">"connect"</span>, Db.Ping())
    fmt.Println(<span class="hljs-string">"connect"</span>, Conn.Connet().Ping())

    time.Sleep(time.Second * <span class="hljs-number">1</span>)
}
</code></pre>
<p>Now we will see an example of opening <strong><em>connections asynchronously</em></strong> using <strong><em>goroutine</em></strong>. We made hundreds of goroutines and thousands of concurrent connections in our example below, works 100% without crashing and or bugging the amount of database connections.</p>
<pre><code class="lang-go"><span class="hljs-comment">// na base</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// conexao</span>
    Db := Conn.Connet()

    <span class="hljs-comment">// Exemplo 2 </span>
    <span class="hljs-comment">// criando 200 goroutines</span>
    <span class="hljs-keyword">for</span> x := <span class="hljs-number">0</span>; x &lt; <span class="hljs-number">200</span>; x++ {
        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(x <span class="hljs-keyword">int</span>)</span></span> {
            <span class="hljs-keyword">for</span> j := <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">10000000</span>; j++ {
                fmt.Printf(<span class="hljs-string">"Goroutine2 Connect: %d -&gt; %d"</span>, x, j)
                fmt.Printf(<span class="hljs-string">" login: %s"</span>, Conn.Connet().GetUserEmail(x))
                time.Sleep(time.Millisecond * <span class="hljs-number">150</span>)
            }
        }(x)
    }
    fmt.Scanln()
}
</code></pre>
<h1 id="heading-goroutines-and-the-singleton-pattern">Goroutines and the Singleton Pattern</h1>
<p>When we think of possible solutions for the implementation of the <strong><em>singleton pattern</em></strong> using Golang, we bump into the Goroutines it will be responsible for providing our code to execute <strong><em>asynchronously and concurrently</em></strong> and when we use Goroutine in our application our whole way of thinking and implementing changes, that is is no longer a <strong><em>synchronous</em></strong> application and because of this we have to think of the Golang way of being.</p>
<p>Goroutines is a powerful resource and when used correctly it becomes a strong ally to fight the day-to-day battles. Every time we implement codes that use competition we have some known scenarios that we have to deal with, program scope, global variables, locations, parameter passing, pointers all this has to be handled so we can work with competition in a correct and optimized way .</p>
<p>A good example of possible problems using competition is the use of <strong><em>global variables</em></strong>. Due to the goroutines our implementation of the <strong><em>Singleton Pattern</em></strong> and our possible solutions will be written to accept the use of competition. Let’s write our code using good programming practices to try to mitigate the possible stealth bugs that may occur in runtime of your program written in <strong><em>Golang</em></strong>.</p>
<h2 id="heading-200-goroutines-being-initialized">200 goroutines being initialized</h2>
<p>In our example below we are <strong><em>creating 200 goroutines</em></strong> and putting all of them in competition and ten thousand interactions are being made in our database ie “select email from login where id =?”.</p>
<pre><code class="lang-go"><span class="hljs-keyword">for</span> x := <span class="hljs-number">0</span>; x &lt; <span class="hljs-number">200</span>; x++ {

        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(x <span class="hljs-keyword">int</span>)</span></span> {

            <span class="hljs-keyword">for</span> j := <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">10000</span>; j++ {

                fmt.Println(<span class="hljs-string">" login: "</span>, Conn.Connet().GetUserEmail(x))
                time.Sleep(time.Millisecond * <span class="hljs-number">150</span>)
            }
        }(x)
    }
</code></pre>
<p>Good understanding of the goroutines will help us write better and more powerful codes in Golang, this I have no doubt. In a next article we will describe some cases using goroutines, I am eager to write about Goroutines and show how we solved some of our problems in the company.</p>
<p>The subject about <strong><em>Singleton Pattern</em></strong> is so interesting that I had to do a much deeper research on the subject before writing this article and as I use a lot in my day to day I decided to collaborate a little showing some important points of this pattern and why a lot of the times it is considered an <strong><em>Anti Pattern</em></strong>. Describing the technical details in the article we clearly notice several good practices that we can use on our day when we are coding in Golang, good practices, clean implementation forms, less complex and less costly implementations and with higher performance.</p>
<h1 id="heading-what-is-singleton-pattern">What is Singleton Pattern ?</h1>
<p>The transcript of what is a <strong><em>Singleton Pattern</em></strong> would be: “<strong>Singleton</strong> is a software design standard. This standard guarantees the existence of only one instance of a class, while maintaining a global point of access to its object.”<br /><strong>Singleton</strong> is a design pattern that restricts instantiation to an object, we have to ensure that this occurs only once.</p>
<p>Basically <strong><em>singleton</em></strong> is a way to use <strong><em>global variables</em></strong>. We know how dangerous the use of <em>global variables</em> is, our code is <strong>vulnerable</strong> to the access of the global variable or in any part of the system we can change its value. So when we try to debug our program it will not be an easy task to figure out which code path leads to the current state, which is why I do not consider <strong><em>Singleton Pattern</em></strong> an <strong><em>Anti Pattern</em></strong>, but a way to <strong><em>protect global variables.</em></strong></p>
<p>However, the problem with <strong><em>Singleton</em></strong> using competition that will be our goal, in a <strong><em>multi-threaded</em></strong> environment, initialization must be protected to avoid reboot, atomically.</p>
<p>The <strong><em>Singleton Pattern</em></strong> is a feature derived from the <strong><em>object oriented</em></strong> paradigm, so how will we implement Golang if it does not have OO support?</p>
<p>To answer this question we have to understand that <strong>Object Oriented</strong> Programming is a concept and can be implemented in any programming language even though it is of other paradigms. It is clear that the level of abstraction and difficulty becomes an arduous task greatly increasing the level of complexity of the code depending on the language, our intention is purely didactic in order to better understand the proposed scenario when we speak in <strong>singleton pattern</strong>.</p>
<h1 id="heading-go-run-race-singletongo">go run -race singleton.go</h1>
<blockquote>
<p>It executes all the codes using -race as parameter: go run -race ..</p>
</blockquote>
<p>The “<strong><em>-race detector</em></strong>” is a feature we have available in <em>Golang</em> to detect improper accesses in memory when we are using competition in our application. It is possible to generate report that contains stack traces for conflicting accesses, as well as piles in which the goroutines involved were created, I will soon create an article addressing exactly this subject and we will talk about “<strong><em>Profiling</em></strong>” in Go.<br />Below are the ways we can make the “<strong><em>-race</em></strong>” call.</p>
<pre><code class="lang-go">$ <span class="hljs-keyword">go</span> test -race seupkg    <span class="hljs-comment">// to test the package</span>
$ <span class="hljs-keyword">go</span> run -race seusrc.<span class="hljs-keyword">go</span>  <span class="hljs-comment">// to run the source file</span>
$ <span class="hljs-keyword">go</span> build -race seucmd   <span class="hljs-comment">// to build the command</span>
$ <span class="hljs-keyword">go</span> install -race seupkg <span class="hljs-comment">// to install the package</span>
</code></pre>
<h1 id="heading-singleton-pattern-in-golang">Singleton Pattern in Golang</h1>
<p>The solution presented below would be ideal if our application were synchronous, and the problem would be solved with code below, but as our goal is to implement using competition the solution below is far from ideal.<br />Let’s check the code below and start our implementation possibilities:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {
        <span class="hljs-comment">// &lt;--- NOT THREAD SAFE / Quando usarmos Goroutine</span>
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {
            time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
            fmt.Println(*Connect(), <span class="hljs-string">" - "</span>, i)
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(*Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>In the above implementation, we have our first approach implementing <strong><em>Singleton</em></strong> in <strong><em>Golang</em></strong> and with goroutines to simultaneously run our <strong><em>Singleton</em></strong>.</p>
<p>The problem visible in this code is that <strong><em>several goroutine</em></strong> routines could evaluate the first check and all would create a singleton instance and replace one another. There is no guarantee of which instance will be returned in the code above and other additional operations on the instance may be inconsistent with developer expectations and stealth problems may occur at run time.</p>
<p><strong><em>Too bad this approach</em></strong>, several very subtle errors can occur, if references to the singleton instance are being maintained through code, there is a great chance that there are potentially multiple instances of the type with different states, generating potential code behaviors. It also becomes a real nightmare during debugging and it becomes really difficult to detect the bug, since at debug time nothing seems to be wrong due to runtime breaks, minimizing the potential of a “<strong><em>Not Thread Safe</em></strong>” execution, obfuscating totally the problem for who is coding.</p>
<h1 id="heading-locks-with-mutex">Locks with Mutex</h1>
<p>In the code below is a poor solution for attempting to solve the “<strong><em>Thread Safe</em></strong>” problem. In fact, this solves the “<strong><em>Thread Safe</em></strong>” problem, but creates other serious potential problems. It introduces a containment in the goroutines executing an aggressive blocking of the whole function, let’s check the code below:</p>
<pre><code class="lang-go"><span class="hljs-comment">// nosso lock mutex</span>
<span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {
    <span class="hljs-comment">// &lt;--- Desnecessario a lock</span>
    <span class="hljs-comment">// se a instancia já tiver</span>
    <span class="hljs-comment">// sido criada muito agressivo</span>
    lock.Lock()
    <span class="hljs-keyword">defer</span> lock.Unlock()

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {
        <span class="hljs-comment">// ainda não é a melhor implementação devido</span>
        <span class="hljs-comment">// os bloqueios</span>
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {
            time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
            fmt.Println(*Connect(), <span class="hljs-string">" - "</span>, i)
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        fmt.Println(*Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>The “Thread Safe” issue has been resolved with the above implementation using <strong><em>sync.Mutex</em></strong> where the Lockdown occurs before creating the <strong><em>Singleton</em></strong> instance. The big problem with this approach is excessive blocking even when it would not be necessary to do so in case the instance has already been created and should simply have returned the singleton instance. If our program is written to become highly concurrent, this can generate a bottleneck, since only one goroutine routine can get the <em>singleton</em> instance at a time, making it our slowest solution.</p>
<p>Let’s check another solution, because it is not our best approach above.</p>
<h1 id="heading-check-lock-check-in-go">Check-Lock-Check in Go</h1>
<p>One way to improve and ensure a minimum lock and still be safe for the goroutine is to use the pattern called “<strong>Check-Lock-Check</strong>” when acquiring locks. But you have to use <strong><em>Mutex with atomic</em></strong> so it <strong>is not “<em>the tread safe</em>”</strong> otherwise it will become a “<strong><em>the thread not safe</em></strong>”. We use this same Patter in C and C ++. The pattern works with the idea of checking first, <em>to minimize any aggressive blocking</em>, since an IF statement is less expensive than locking. Next time, we would have to wait and get the exclusive lock so that only one execution is inside that block at a single time. With the first scan and exclusive lock, there may be another goroutine that has the lock, so we would need to double-check inside the lock to avoid replacing the instance with another. <strong><em>Check the code below</em></strong>:</p>
<pre><code class="lang-go"><span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-comment">// ainda não está perfeita, não é totalmente atomico</span>
    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {
        lock.Lock()
        <span class="hljs-keyword">defer</span> lock.Unlock()
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }
    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {
            time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
            fmt.Println(*Connect(), <span class="hljs-string">" - "</span>, i)
        }
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(*Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>The above approach is the best so far, <strong><em>but still not perfect</em></strong>. There <strong><em>is no atomic check</em></strong> on the storage state of the instance. Taking all technical considerations into account, this is still not perfect. But it is much better than the initial approaches.</p>
<p>Using the <strong><em>sync/atomic</em></strong> package, we can load and set atomically a flag that indicates whether or not we initialize our instance.<br /><strong>Check the code below:</strong></p>
<pre><code class="lang-go"><span class="hljs-comment">// manter o estado</span>
<span class="hljs-keyword">var</span> atomicinz <span class="hljs-keyword">uint64</span>

<span class="hljs-comment">// lock mutex</span>
<span class="hljs-keyword">var</span> lock = &amp;sync.Mutex{}

<span class="hljs-comment">// driver</span>
<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-comment">// instancia Global</span>
<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-comment">// funcao retornando</span>
<span class="hljs-comment">// o ponteiro de nossa</span>
<span class="hljs-comment">// struct</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-comment">// garantindo que já entrou</span>
    <span class="hljs-keyword">if</span> atomic.LoadUint64(&amp;atomicinz) == <span class="hljs-number">1</span> {

        <span class="hljs-keyword">return</span> instance
    }

    lock.Lock()
    <span class="hljs-keyword">defer</span> lock.Unlock()

    <span class="hljs-comment">// entra somente uma</span>
    <span class="hljs-comment">// únic vez</span>
    <span class="hljs-keyword">if</span> atomicinz == <span class="hljs-number">0</span> {

        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
        atomic.StoreUint64(&amp;atomicinz, <span class="hljs-number">1</span>)
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(*Connect())
    }()

    <span class="hljs-comment">// 50 goroutine</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">50</span>; i++ {
        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(i <span class="hljs-keyword">int</span>)</span></span> {
            <span class="hljs-keyword">for</span> {
                time.Sleep(time.Millisecond * <span class="hljs-number">60</span>)
                fmt.Println(Connect().conn, <span class="hljs-string">" - "</span>, i)
            }
        }(i)
    }

    fmt.Scanln()
}
</code></pre>
<p>The <strong><em>sync/atomic</em></strong> library allows us to flag and store content securely and ensuring its uniqueness, much like <a target="_blank" href="http://sync.Map"><strong><em>sync.Map</em></strong></a>, where it is storing in a storage and accepting competition in its implementation. The problem we had to use more functionality, more feature and a little slower implementation sequentially.</p>
<h1 id="heading-synconce-clean-and-powerful">sync.Once clean and powerful</h1>
<p>We have the type “<strong><em>Once</em></strong>” in the <strong><em>sync</em></strong> library, remembering that this native library in Golang is very powerful and we have to exploit it as much as we can, the sync.Once object will perform an action exactly once and not more, it was what was missing for our code to get even more powerful and clean.</p>
<pre><code class="lang-go"><span class="hljs-comment">// call somente</span>
<span class="hljs-comment">// uma unica vez</span>
<span class="hljs-keyword">var</span> once sync.Once

<span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-comment">// variavel Global</span>
<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    once.Do(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    })

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(*Connect())
    }()

    <span class="hljs-comment">// 100 goroutine</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {

        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(ix <span class="hljs-keyword">int</span>)</span></span> {
            time.Sleep(time.Millisecond * <span class="hljs-number">60</span>)
            fmt.Println(ix, <span class="hljs-string">" = "</span>, Connect().conn)
        }(i)
    }

    fmt.Scanln()
}
</code></pre>
<p>With this approach and proposed scenario our code in addition to getting cleaner was much better, the sync.Once function guarantees the uniqueness of our instance, our code can now have <strong><em>100 goroutines</em></strong> or more according to its need, puts them in competition not we will have Thread Safe problems or aggressive checking. A simple and secure way to write the Golang code for implementing Singleton Pattern.</p>
<h1 id="heading-init-another-approach">init () Another approach</h1>
<p>Another valid approach is to use <strong><em>init</em></strong>( ), it runs only once and is called before the maim function. Check the code below:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">init</span><span class="hljs-params">()</span></span> {

    Connect()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(instance.conn)
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(*Connect())
    }()

    <span class="hljs-comment">// 100 goroutine</span>
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++ {

        <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(ix <span class="hljs-keyword">int</span>)</span></span> {
            time.Sleep(time.Millisecond * <span class="hljs-number">60</span>)
            fmt.Println(ix, <span class="hljs-string">" = "</span>, instance.conn)
        }(i)
    }

    fmt.Scanln()
}
</code></pre>
<p>But this approach is a disadvantage when we use <strong><em>init</em></strong>( ). Note clearly that it is not secure, nothing prevents you from making a direct call in the “<strong><em>Connect</em></strong>” function as occurred in <strong><em>line #47</em></strong>, in addition there is a limitation in the use of init in relation to its load time and the most important in <em>Golang</em> we can have multiple <strong><em>init</em></strong>( ) running not only on one file or package but on multiple, and there is a running order between them.</p>
<p>The <strong><em>init( )</em></strong> function does not accept arguments nor returns any value. In contrast to our approach using <strong><em>sync.Once</em></strong>, the <strong><em>init ( )</em></strong> identifier is not declared, so it can not be referenced.</p>
<p>The best scenario is to write codes that do not depend on the boot order, in previous versions of <em>golang</em> there were some complaints and several problems reported, do not write codes in an <strong><em>init ( )</em></strong> that you need guarantees of execution at any given time. The solution when it needs explicit assurance is to write explicit calls.</p>
<p>For more details have a page only of this in <em>Golang</em> <a target="_blank" href="https://golang.org/doc/effective_go.html#initialization">https://golang.org/doc/effective_go.html#initialization</a><a target="_blank" href="https://golang.org/doc/effective_go.html#initialization,">,</a> it is worth the detailed reading about <strong><em>init( )</em></strong>, it is a powerful and robust implementation in the current versions of Golang but always it’s good to stay tuned.</p>
<h1 id="heading-variable-receiving-function">Variable receiving function</h1>
<p>Another valid approach is to use a global variable to get the function in a <strong><em>global scope</em></strong>, we know that in Golang the variables are assigned and declared before the <strong><em>init ( )</em></strong> and main function call, so in this approach the method returns exactly one instance. Check the code below:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DriverPg <span class="hljs-keyword">struct</span> {
    conn <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">var</span> instance *DriverPg

<span class="hljs-keyword">var</span> instanceNew = *Connect()

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> *<span class="hljs-title">DriverPg</span></span> {

    <span class="hljs-keyword">if</span> instance == <span class="hljs-literal">nil</span> {

        <span class="hljs-comment">// &lt;--- NOT THREAD SAFE</span>
        instance = &amp;DriverPg{conn: <span class="hljs-string">"DriverConnectPostgres"</span>}
    }

    <span class="hljs-keyword">return</span> instance
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// chamada</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        time.Sleep(time.Millisecond * <span class="hljs-number">600</span>)
        fmt.Println(<span class="hljs-string">"goroutine 1: "</span>, instanceNew.conn)
    }()

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {

        fmt.Println(<span class="hljs-string">"goroutine 2: "</span>, *Connect())
    }()

    fmt.Scanln()
}
</code></pre>
<p>This approach is flawed because nothing guarantees that the function will be called again in some part of the code, as occurred in line #25 the function was called again, in line #30 is made the instance of our singleton, but nothing guarantees this uniqueness .</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>The ideal is undoubtedly the use of <strong><em>sync.Once</em></strong> that guarantees us the uniqueness and that is “<strong>Thread Safe</strong>” guaranteeing that a “<a target="_blank" href="https://blog.golang.org/race-detector"><strong><em>Race Condition</em></strong></a><strong><em>”</em></strong> does not occur, it only allows the function to be executed only once Golang flexibilized and automated all the complexity we would have in other languages if we were to work with competition and simultaneity. Golang really became powerful in these approaches, making it simple to implement and understand.</p>
<p>When we talk about competition our whole way of thinking and coding solutions using <strong><em>Golang</em></strong> changes drastically. <strong><em>There are several scenarios</em></strong> that we need to <strong><em>apply standards</em></strong> and practices in our projects to take full advantage of the power that Golang offers.</p>
<p>Every project I participate in becomes almost a “mantra” among development teams doing various tests and reviews to make the most of what the language provides. The deeper we study, the more we discover that we know little about language. The cool of everything is the challenge, when working with goroutines in <strong><em>Golang</em></strong> we need to understand how soon the features and what it is possible to do, behaviors, security of goroutines are all essential to improve our code more and more.</p>
<p>If you are interested in accompanying or exchanging ideas be they at the beginner, intermediate or hardcore level on the <strong><em>Golang</em></strong> language there are some <strong><em>Golang groups</em></strong> spread on the internet two of them in particular whenever possible I am present is the one from <a target="_blank" href="https://t.me"><strong><em>https://t.me</em></strong></a> <strong><em>/ go_br</em> (GoBr)</strong> and <a target="_blank" href="http://gophers.slack.com"><strong><em>gophers.slack.com</em></strong></a>, active communities using <strong><em>Golang</em></strong>, are always sharing ideas, projects, vacancies and doubts all the time and at all times we are relearning.</p>
<p>I hope I have helped to clarify some doubts about using <strong><em>Singleton Pattern</em></strong>, using <strong><em>global variables</em></strong>, <strong>goroutines, sync.Once, Init, mutex</strong>, and several other important technical points covered in the article.</p>
<p>Below are all the source codes that we use as an example in the article if you are interested in downloading and testing.</p>
<h2 id="heading-source-codes-and-article-examples">Source Codes and Article Examples</h2>
<p><a target="_blank" href="https://github.com/jeffotoni/medium-posts">https://github.com/jeffotoni/medium-posts</a></p>
<p>I would like to thank some colleagues who helped in the review of this article to maintain the quality of the content and leave it dense without getting complex and jet. Thank you:</p>
<p><a target="_blank" href="https://medium.com/u/3f6c1dee6dad?source=post_page-----2fdd61cd5a7f--------------------------------">Joelson</a></p>
<p>, <a target="_blank" href="https://medium.com/u/a1237dcc0ed2?source=post_page-----2fdd61cd5a7f--------------------------------">Marco Paganinii,</a> <a target="_blank" href="https://medium.com/u/79525c7eb6d6?source=post_page-----2fdd61cd5a7f--------------------------------">Francisco Oliveira</a></p>
<p>In the next article that is in the oven will be about lambdas, like writing lambdas in Golang, it will be another very interesting challenge, which I am preparing.</p>
<p>Who liked it and got to the end leaves a stick there … Thanks 🤘🤓</p>
]]></content:encoded></item><item><title><![CDATA[Tipos de aplicações usando Go❤️]]></title><description><![CDATA[Go é uma linguagem de uso geral. A linguagem Go foi lançada em 2009 com propósito de facilitar a resolução de problemas quando o assunto é desenvolvimento…]]></description><link>https://jeffotoni.hashnode.dev/tipos-de-aplicacoes-usando-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/tipos-de-aplicacoes-usando-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Thu, 06 Apr 2023 14:13:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680790380611/f9e87652-1d32-48b4-9a28-f458ae5e62ee.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Go é uma <strong>linguagem de uso geral</strong>. A linguagem Go foi lançada em <strong>2009</strong> com propósito de facilitar a resolução de problemas quando o assunto é desenvolvimento em camadas de rede, <strong>escalabilidade</strong>, <strong>desempenho</strong>, <strong>produtividade</strong> e o mais legal de todos o uso de <strong>concorrência.</strong> Quando o assunto é programação concorrente <strong>Go</strong> torna-se muito poderoso, ele disponibiliza um arsenal de funcionalidades para que possamos trabalhar com concorrência. As <strong>goroutines</strong> são famosas no mundo <strong>Go.</strong></p>
<p>Estou deixando um link aqui onde irá conseguir visualizar diversas aplicações, libs, frameworks serviços implementadas em <strong>Go</strong> e suas respectivas categorias. <a target="_blank" href="https://github.com/nouney/awesome-go">Neste link</a></p>
<p>Cenários como desenvolvimento para <strong>backend</strong> em um âmbito geral <strong>Go</strong>❤️ é muito animal ou melhor <strong>surreal</strong>. Não é uma questão só de linguagem mas de <strong>necessidade,</strong> nos dias atuais o quanto antes conseguirmos diminuir nosso <strong>custo computacional</strong> que é <strong>diretamente relacionado</strong> com nosso <strong>custo financeiro</strong> é bem vindo. A linguagem <strong>Go</strong> tem este objetivo quanto o assunto é recurso computacional, interessante não é ?</p>
<p>Abaixo uma imagem com algumas das aplicações mais utilizadas pela comunidade <strong>DevOps</strong>.</p>
<p><img src="https://media.licdn.com/dms/image/C4D12AQHIaC8l8z7FTg/article-inline_image-shrink_1500_2232/0/1564758376732?e=1686182400&amp;v=beta&amp;t=gGBbU95l06qtCNk1cz3OitG-rtq094mJ45VlqbkL4ts" alt="Não foi fornecido texto alternativo para esta imagem" /></p>
<h2 id="heading-alguns-tipos-de-aplicacoes-que-go-brilha-mais">Alguns tipos de aplicações que Go brilha mais:</h2>
<p>. <strong>Web backend</strong> <em>(com</em> <a target="_blank" href="https://github.com/nouney/awesome-go#web-frameworks"><em>diversos frameworks</em></a> <em>disponíveis)</em></p>
<p>. <strong>Web Assembly</strong> (<a target="_blank" href="https://github.com/vugu/vugu"><em>um dos frameworks vugu</em></a>)</p>
<p>. <strong>Microservices</strong> (<em>alguns frameworks:</em> <a target="_blank" href="https://micro.mu/"><em>Go Micro</em></a><em>,</em> <a target="_blank" href="https://gokit.io/"><em>Go Kit</em></a><em>,</em> <a target="_blank" href="https://github.com/NYTimes/gizmo"><em>Gizmo</em></a><em>,</em> <a target="_blank" href="https://github.com/koding/kite"><em>Kite</em></a>)</p>
<p>. <strong>Fragments services</strong> (<em>Termo citado pelo @jeffotoni em um grupo de discussão de microservices</em>)</p>
<p>. <strong>Lambdas</strong> (<em>FaaS</em> <a target="_blank" href="https://www.alexedwards.net/blog/serverless-api-with-go-and-aws-lambda"><em>example</em></a>)</p>
<p>. <strong>Client Server</strong></p>
<p>. <strong>IoT</strong> (<a target="_blank" href="https://github.com/nouney/awesome-go#iot-internet-of-things"><em>alguns frameworks</em></a>)</p>
<p>. <strong>Boots</strong> (<a target="_blank" href="https://github.com/nouney/awesome-go#bot-building"><em>alguns aqui</em></a>)</p>
<p>. <strong>Aplicações Client que usam tecnologia Web</strong> </p>
<p>. <strong>Desktop Usando Qt+QML</strong>, Lib Nativa Win (<a target="_blank" href="https://github.com/therecipe/qt"><em>example Qt</em></a><em>,</em> <a target="_blank" href="https://therecipe.github.io/widgets_playground/"><em>widgets Qt</em></a><em>,</em> <a target="_blank" href="https://doc.qt.io/qt-5/qtqml-index.html"><em>Qml</em></a>)</p>
<p>. <strong>Aplicações de Rede</strong></p>
<p>. <strong>Aplicações para protocolos</strong></p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/REST">rEST</a>, </p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/SOAP">SOAP</a> </p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/GraphQL">GraphQL</a> </p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto">RCP</a> </p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Transmission_Control_Protocol">TCP</a></p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://en.wikipedia.org/wiki/GRPC">gRPC</a></p>
<p>. <strong>Aplicações</strong> <a target="_blank" href="https://en.wikipedia.org/wiki/WebSocket">Websocket</a></p>
<p>. <strong>GopherJS</strong> (<a target="_blank" href="https://github.com/gopherjs"><em>compiles Go to JavaScript</em></a>)</p>
<p>.  <strong>CLI</strong> (Command Line)</p>
]]></content:encoded></item><item><title><![CDATA[GoLang — Simplificando a complexidade “O Inicio”]]></title><description><![CDATA[Existem inúmeras linguagens de programação e cada uma nasceu com um propósito: “resolver problemas”. As linguagens são ferramentas onde teremos que saber…]]></description><link>https://jeffotoni.hashnode.dev/golang-simplificando-a-complexidade-o-inicio</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/golang-simplificando-a-complexidade-o-inicio</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Thu, 06 Apr 2023 14:00:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680789301744/fdb44188-b9dc-4c47-b357-08bd5546782b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Existem inúmeras linguagens de programação e cada uma nasceu com um propósito: “<strong>resolver problemas</strong>”. As linguagens são ferramentas onde teremos que saber utilizá-las no momento certo. Falando “<strong>como desenvolvedor</strong>” quanto mais poliglota conseguir ser melhor será para sua carreira profissional e para um melhor entendimento e compreensão da diversidade deste ecossistema.</p>
<p>O <strong>objetivo</strong> deste post é apresentar o que é a linguagem <strong>Go</strong> e, porque ela é tão poderosa. Apresentando <strong>alguns conceitos e pontos importantes sobre a linguagem Go</strong> que muita das vezes é expressado de forma equivocada em diversos artigos encontrados na internet e grupos de discussões de linguagens de programação. Acredito que os pontos fracos e problemas gerados por diversas outras linguagens de programação ao longo destas décadas fez com que <strong>Go</strong> torna-se o que é hoje. E para explicarmos como isto é possível iremos voltar ao início de tudo, onde tudo começou.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-built_in">println</span>(<span class="hljs-string">"Hello all folks!"</span>)
}
</code></pre>
<h1 id="heading-menos-e-exponencialmente-mais">Menos é exponencialmente Mais</h1>
<p>A equipe de desenvolvedores do <strong>Go</strong> dizem que sua criação é uma tentativa de tornar os programadores mais produtivos. Melhorando o processo de desenvolvimento de software no <em>Google</em>. O primeiro objetivo foi criar uma linguagem melhor para enfrentar os desafios da <em>simultaneidade escalável</em>, ou seja software que lida com muitas preocupações simultaneamente, um exemplo seria a coordenação de mil servidores <em>back-end</em> enviando tráfego de rede todo o tempo.</p>
<p>Manter a linguagem <strong>Go</strong> pequena permite objetivos mais importantes. Ser pequeno torna o <strong>Go</strong> mais fácil de <strong>aprender</strong>, mais fácil de <strong>entender</strong>, mais fácil de <strong>implementar</strong>, mais fácil de <strong>reimplementar</strong>, mais fácil de <strong>depurar</strong>, mais fácil de <strong>ajustar</strong> e mais fácil de <strong>evoluir</strong>. Fazer menos permite mais. É uma expressão utilizada pela equipe de desenvolvimento do <strong>Go</strong>: “<em>Do Less. Enable More</em>” seria o equilíbrio entre os universo de problemas existentes e o que <strong>Go</strong> poderá ajudar a resolver bem tais problemas. <strong>Go</strong> explicitamente não foi projetado para resolver todos os problemas em vez disso fizeram o suficiente para possamos criar as próprias soluções personalizadas com facilidade, mas deixando bem claro que <strong>Go</strong> não pode fazer tudo.</p>
<p>Go foi projetado pelo <strong>Google</strong> em <strong>2007</strong> para melhorar a produtividade de programação em uma era de <strong>multicore,</strong> rede de máquinas e grandes bases de código. Os designers queriam abordar críticas de outras línguas em uso no Google, mas manter suas características úteis.<br />Os criadores <a target="_blank" href="https://en.wikipedia.org/wiki/Rob_Pike">Rob Pike</a>, <a target="_blank" href="https://en.wikipedia.org/wiki/Ken_Thompson">Ken Thompson</a> e <a target="_blank" href="https://de.wikipedia.org/wiki/Robert_Griesemer">Robert Griesemer</a> mantiveram a sintaxe de <strong>Go</strong> semelhante ao <strong>C</strong>. No final de 2008 <a target="_blank" href="https://en.wikipedia.org/wiki/Go_(programming_language)">Russ Cox</a> juntou-se a equipe e ajudou a mudar a linguagem e as bibliotecas de protótipo para realidade.</p>
<p>A linguagem Go foi lançada em <strong>2009</strong> com propósito de facilitar a resolução de problemas quando o assunto é desenvolvimento em <strong>camadas de rede, escalabilidade, desempenho, produtividade e o mais importante concorrência</strong>. O próprio <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike">Rob Pike</a> declarou que “<em>Go foi projetado para tratar de um conjunto de problemas de engenharia de software a que estávamos expostos na construção de grandes softwares de servidor</em>”.</p>
<p><strong>Go</strong> teve influências de diversas linguagens de programação e <strong>paradigmas</strong> <strong>diferentes</strong> dentre elas<strong>:</strong> <a target="_blank" href="https://en.wikipedia.org/wiki/Go_(programming_language)"><em>Alef</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/APL_(linguagem_de_programa%C3%A7%C3%A3o)"><em>APL</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/BCPL"><em>BCPL</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/C_(linguagem_de_programa%C3%A7%C3%A3o)"><em>C</em></a><em>, CSP,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Limbo_(linguagem_de_programa%C3%A7%C3%A3o)"><em>Limbo</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Modula"><em>Modula</em></a><em>,</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Newsqueak"><em>Newsqueak</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Oberon_(linguagem_de_programa%C3%A7%C3%A3o)"><em>Oberon</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Occam_(linguagem_de_programa%C3%A7%C3%A3o)"><em>occam</em></a><em>,</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Pascal_(programming_language)"><em>Pascal</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Smalltalk"><em>Smalltalk</em></a> <em>e</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Crystal_(programming_language)"><em>Cristal</em></a><em>,</em> percebe-se que utilizaram do que tinham de melhor e criou algo novo e enxuto, com o mínimo necessário para resolver os problemas propostos, sem perder sua simplicidade. Acredito que isto podemos chamar de <strong><em>inovação</em></strong>. <strong>Go</strong> inovou ao quebrar os <strong>paradigmas de linguagens</strong> e implementar algo novo de forma simples e muito poderosa.</p>
<h1 id="heading-polemicas">Polêmicas</h1>
<p>Foram <strong><em>deixadas de fora</em></strong> diversas características que as <strong><em>linguagens modernas</em></strong> contrariando e indo em direção oposta das outras linguagens atuais algumas funcionalidades como o uso de: <strong><em>declarações de imutabilidade, tipos de dados de correspondência de padrões, generics,</em></strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Tratamento_de_exce%C3%A7%C3%A3o"><strong><em>tratamento de exceção</em></strong></a><strong><em>,</em></strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Heran%C3%A7a_(programa%C3%A7%C3%A3o)"><strong><em>Herança</em></strong></a><strong><em>,</em></strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_gen%C3%A9rica"><strong><em>programação genérica</em></strong></a> <strong><em>e</em></strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Sobrecarga"><strong>sobrecarga</strong></a> <strong>de métodos</strong> e diversos outros pontos. Todos os recursos acima foram criticados e apontados para os criadores de <strong><em>Go,</em></strong> que responderam: “<strong><em>Essas omissões foram simplificações que contribuem para a força de Go*</em></strong>”.<em> Há muitas coisas na linguagem e bibliotecas <strong>Go</strong> que diferem das práticas modernas, foi uma decisão da equipe de desenvolvimento do **Go: </em>“<em>**</em>às vezes vale a pena tentar uma abordagem diferente”.*</p>
<p>Todos estão convidados <strong>a ajudar e contribuir</strong> se assim desejar, podem abrir <a target="_blank" href="https://github.com/golang/go/wiki/ExperienceReports"><strong>propostas</strong></a> para novos recursos e tudo relacionado ao ecossistema da linguagem. O código fonte de <strong>Go</strong> está disponível no <a target="_blank" href="https://github.com/golang/go"><strong>GitHub</strong></a> . A documentação sobre como você pode contribuir com o idioma é fornecida <a target="_blank" href="https://golang.org/doc/contribute.html"><strong>aqui</strong></a><strong>.</strong></p>
<h1 id="heading-goroutines-em-vez-de-threads">Goroutines em vez de threads</h1>
<p>Um dos principais objetivos da linguagem de programação Go é tornar a simultaneidade mais simples, rápida e eficiente.</p>
<p>Goroutines são leves e tiram proveito de todo o poder de processamento disponível. Goroutines existe apenas no espaço virtual do tempo de execução Go e não no sistema operacional.</p>
<p>Goroutine é um método/função que pode ser executado independentemente junto com outras goroutines. Cada atividade simultânea na linguagem Go é geralmente denominada Goroutine.</p>
<p>Um dos pontos mais relevantes e importantes é o trabalho com <strong>concorrência</strong>, ele <strong>inovou</strong> ao quebrar o modelo <strong>tradicional de</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Thread_(computa%C3%A7%C3%A3o)"><strong>threads</strong></a> e sua forma de utilização ao criar um novo modelo, as <a target="_blank" href="https://golang.org/doc/effective_go.html#concurrency"><strong><em>goroutines</em></strong></a>. As <strong>goroutines</strong> são responsáveis por realizar execuções em <strong>Go</strong> de forma <strong>assíncrona</strong>. São muito poderosas e uma simples máquina de <strong>1G de Ram</strong> poderá subir milhares delas.</p>
<p><strong>Goroutines</strong> fazem parte de tornar a <strong>simultaneidade</strong> <strong>fácil</strong> de usar. As <strong>goroutines</strong>, pode ser muito barata: eles têm pouca sobrecarga além da memória para a pilha, que é apenas alguns kilobytes. Para tornar as pilhas pequenas, o tempo de execução de <strong>Go</strong> usa pilhas redimensionáveis ​​e delimitadas. Uma <strong>goroutine</strong> recém lançada recebe alguns kilobytes, o que é quase sempre suficiente. Quando não é, o tempo de execução aumenta (e encolhe) a memória para armazenar a pilha automaticamente, permitindo que muitos <strong>goroutines</strong> vivam em uma <strong>quantidade modesta de memória</strong>. A sobrecarga da CPU tem em média três instruções baratas por chamada de função. É prático criar <strong>centenas de milhares de goroutines</strong> no mesmo espaço de endereço. Se <strong>goroutines</strong> fossem apenas <strong>threads</strong>, os recursos do sistema acabariam em um número muito menor.</p>
<p>O design de <strong>Go</strong> foi fortemente influenciado pelo artigo de <a target="_blank" href="https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf">C.A.R. Hoare</a> <strong>1978</strong> “<a target="_blank" href="https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf">Communicating sequential processes</a>” (<em>Comunicação de processos sequenciais</em>).</p>
<h1 id="heading-simultaneidade-nas-ideias-do-csp">Simultaneidade nas ideias do CSP</h1>
<p>Um dos modelos mais bem-sucedidos para fornecer suporte linguístico de alto nível para concorrência é o <strong><em>Hoare’s</em></strong> <strong><em>Communicating Sequential Processes</em></strong>, ou <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a><strong>.</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Occam_(linguagem_de_programa%C3%A7%C3%A3o)"><strong>Occam</strong></a> <strong>e</strong> <a target="_blank" href="https://pt.wikipedia.org/wiki/Erlang_(linguagem_de_programa%C3%A7%C3%A3o)"><strong>Erlang</strong></a> são duas línguas bem conhecidas que derivam de <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a>. As primitivas de concorrência de <strong>Go</strong> derivam de uma parte diferente da árvore genealógica cuja principal contribuição <em>é a poderosa noção de canais como objetos de primeira classe</em>. A experiência com várias linguagens anteriores mostraram que o modelo <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a> se encaixa bem em uma estrutura de linguagem procedural.</p>
<p>A maior diferença entre <strong>Go</strong> e o modelo <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a>, além da sintaxe, é que o <strong>Go</strong> modela os canais de comunicação <strong>simultânea explicitamente como canais</strong>, enquanto os processos da linguagem de <strong><em>Hoare</em></strong> enviam mensagens diretamente uns aos outros, semelhante ao <a target="_blank" href="https://pt.wikipedia.org/wiki/Erlang_(linguagem_de_programa%C3%A7%C3%A3o)"><strong>Erlang</strong></a>.</p>
<p>Bem para chegar neste resultado <strong>Go</strong> novamente sofreu críticas do modelo adotado. <strong>Go</strong> incorpora uma variante do <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><strong>CSP</strong></a> (<em>Comunicação de processos sequenciais</em>) é uma linguagem formal para descrever padrões de interação em sistemas concorrentes com canais de primeira classe. Não foi adotada uma abordagem de gravação única para valorizar a semântica no contexto da <a target="_blank" href="https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_concorrente">computação concorrente</a> como é feita no <a target="_blank" href="https://pt.wikipedia.org/wiki/Erlang_(linguagem_de_programa%C3%A7%C3%A3o)"><strong>Erlang</strong></a>, ao invés disto adotaram algo prático e que resultou em algo <strong>poderoso</strong>, permitindo programação <strong>simultânea simples</strong> e <strong>segura</strong>, mas <em>não proíbe programação incorreta</em>. E o lema criado foi: “<em>Não se comunique compartilhando memória, compartilhe memória comunicando-se</em>”.<br />A simplicidade e o suporte para concorrências oferecidas por <strong>Go</strong> gera robustez.</p>
<h1 id="heading-concorrencia-e-diferente-de-paralelismo">Concorrência é diferente de Paralelismo</h1>
<p>Uma das famosas frases é: <strong><em>“Concorrência é sobre lidar com muitas coisas ao mesmo tempo. Paralelismo é fazer muitas coisas ao mesmo tempo”.</em> Concorrência</strong> é a <strong>composição</strong> de cálculos de execução independente. <strong>Concorrência</strong> é uma maneira de estruturar software, e definitivamente não é paralelismo embora permita o paralelismo.<br />Se você tiver apenas um processador, seu programa ainda pode ser concorrente, mas não pode ser paralelo. Por outro lado, um programa concorrente bem escrito pode ser executado de forma eficiente em paralelo em um multiprocessador. Sugiro dar uma conferida neste vídeo de uma palestra do <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike">Rob Pike</a> “<a target="_blank" href="https://vimeo.com/49718712">Concorrência não é Paralelismo</a>”.</p>
<p><strong>Concorrência</strong> em <strong>Go</strong> é muito poderosa e também simples de codar está foi a intensão dos engenheiros que desenvolveram <strong>Go</strong>. A resolução de muitos problemas é bem mais eficiente utilizando <strong>concorrência</strong> e este é o <strong>poder</strong> de <strong>Go</strong>, por isto, se tornou um <strong>Deus</strong> quando o assunto é <strong>concorrência</strong>. Devido a isto, problemas englobados neste universo serão resolvidos com muita <strong>eficiência</strong> e o mais importante, com muito <strong>pouco recurso computacional</strong>.</p>
<p>Quando falamos de <strong>concorrência</strong> temos que ressaltar que existem alguns <strong>patterns</strong> e descrevo eles logo abaixo, e existe alguns <strong>tipos de cargas de trabalhos</strong> eles serão nossa bússola para determinar nosso ponto de equilíbrio quando tivermos que resolver problemas evolvendo concorrência.</p>
<h1 id="heading-workloads-cpu-bound-amp-io-bound">Workloads: CPU-Bound &amp; IO-Bound</h1>
<p>Uma <strong>thread</strong> pode fazer <strong>dois tipos de cargas de trabalhos (*</strong>Workloads<strong>*)</strong>: <strong>CPU-Bound</strong> e o <strong>IO-Bound.</strong></p>
<p><strong>CPU-Bound</strong>: Esta carga de trabalho nunca irá cria uma situação em que a <strong>thread</strong> pode ser colocado em <strong><em>estados de espera</em></strong>. Ele estará constantemente fazendo cálculos. Uma <strong>thread</strong> calculando <em>pi</em> para décima oitava potência seria limitado pela <strong>CPU.</strong> <em>(curiosidade:</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Emma_Haruka_Iwao"><strong><em>Emma Haruka Iwao</em></strong></a> <em>é uma</em> <strong><em>cientista da computação</em></strong> <em>japonesa e Engenheira de Desenvolvimento Cloud do Google. Em 2019, Haruka Iwao calculou o valor de pi mais preciso do mundo, que incluiu 31,4 trilhões de dígitos).</em> Este tipo de carga de trabalho, trabalhos ligadas à CPU, você precisa do paralelismo para aproveitar a simultaneidade, mais goroutines não irá ajuda-lo e não serão eficientes, podendo atrasar ainda mais as cargas de trabalho a serem executadas, isto ocorre devido ao custo de latência (o tempo gasto) de mover Goroutines dentro e fora da thread do sistema operacional.</p>
<p><strong>IO-Bound</strong>: Neste tipo de carga de trabalho as threads entram em estados de espera. Um bom exemplo seria uma solicitação de acesso a um recurso pela rede ou fazer chamadas para o sistema operacional. Uma thread que precisa acessar um banco de dados, eventos de sincronização <em>(mutex,</em> atomic<em>)</em>, todos estes exemplos fazem com que a thread aguarde então poderíamos dizer que são do tipo de trabalho <strong>IO-Bound</strong>. Neste tipo de carga de trabalho você não precisa de paralelismo para usar a simultaneidade um único core físico já seria suficiente para uma boa execução de várias Goroutines. As Goroutines estão entrando e saindo dos estados de espera como parte de sua carga de trabalho. Neste tipo de carga de trabalho ter mais Goroutines do que cores físicos pode acelerar a execução porque o custo de latência de mover Goroutines dentro e fora do thread do sistema operacional não está criando um evento. Sua carga de trabalho é naturalmente interrompida e isso permite que um Goroutine diferente aproveite o mesmo core físico ao invés de permitir que ele fique ocioso.</p>
<h1 id="heading-goroutine-e-pattern">Goroutine e Pattern</h1>
<p>Existem alguns patterns para concorrência, dentre eles: <strong>Fan-In</strong> e <strong>Fan-Out</strong>.<br /><strong>Fan-Out:  
</strong>Múltiplas funções podem ler do mesmo canal até que esse canal seja fechado, isso é chamado de <strong><em>fan-out</em></strong> . Isso fornece uma maneira de distribuir o trabalho entre um grupo de trabalhadores para fazer uso da <strong>CPU</strong> e <strong>E/S</strong> de forma concorrente.</p>
<p><a target="_blank" href="https://blog.golang.org/pipelines"><strong>Fan-In</strong></a><strong>:</strong><br />É a forma de ler a partir de múltiplas entradas e prosseguir até que todas estejam fechadas, multiplexando os canais de entrada em um único canal que está fechado quando todas as entradas estão fechadas. Isso é chamado <strong><em>fan-in</em></strong>.</p>
<p><strong>Pipeline:  
</strong>Não há definição formal de um pipeline em Go, é apenas um dos muitos tipos de programas concorrentes. Informalmente, um pipeline é uma série de <em>estágios</em> conectados por canais, onde cada estágio é um grupo de goroutines executando a mesma função. Em cada etapa, os goroutines:</p>
<ul>
<li><p>Recebem valores do <em>upstream</em> via canais de <em>entrada;</em></p>
</li>
<li><p>Executam alguma função nesses dados, geralmente produzindo novos valores;</p>
</li>
<li><p>Enviam valores a <em>jusante</em> através de canais de <em>saída.</em></p>
</li>
</ul>
<p>Cada estágio possui vários canais de entrada e saída, exceto o primeiro e o último estágio, que possuem apenas canais de entrada ou saída, respectivamente.</p>
<p>Para se ter uma pequena ideia, em uma máquina de <strong>1CPU e 1G Ram</strong>, conseguimos com uma <strong>API simples</strong> feita em <strong>Go,</strong> com poucas linhas de código, aguentar de <strong>5k a 6k</strong> de requisições por segundo em um protocolo <a target="_blank" href="https://pt.wikipedia.org/wiki/Transmission_Control_Protocol"><strong>TCP</strong></a>, utilizando <a target="_blank" href="https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto"><strong>RPC</strong></a> ou <strong>TCP</strong> nativo e gravando em um banco de dados relacional como o <strong>Postgresql</strong>, sem derrubá-lo e consumindo em média somente <strong>60Mb</strong> a <strong>70Mb</strong> de memória e de 8% a 15% de CPU para que isto seja possível utilizamos um “Worker Poll” que é um <a target="_blank" href="https://blog.golang.org/pipelines">Fan-out</a>.</p>
<p>Que aprofundar ainda mais sobre concorrência? Só entrar neste <a target="_blank" href="https://github.com/golang/go/wiki/LearnConcurrency">link</a>. Quer testar e visualizar alguns exemplos? <a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/goroutine">Click Aqui</a>.<br />Vamos criar um post só para falarmos sobre <strong>Goroutine</strong> é um tópico extenso muito cheio de detalhes e muitas situações interessantes. Sabemos que o suporte a concorrência em <strong>Go</strong> o torna um <strong>Deus</strong> perante aos problemas que são melhores resolvidos usando concorrência.</p>
<p><strong>Go</strong> é uma linguagem <strong>compilada</strong>, um <strong><em>like de C</em></strong>, muito focada na produtividade. Para projetos simples ou complexos Go sempre será uma excelente alternativa, pois torna tudo mais simples e enxuto, fácil de codar e dar manutenção.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    fmt.Printf(<span class="hljs-string">"Olá, eu amo Go!\n"</span>)
}
</code></pre>
<h1 id="heading-nao-existe-ainda-bala-de-prata">Não existe ainda bala de prata</h1>
<p>Uma solução ou ferramenta para resolver todos os problemas não existe ainda é claro. O que sabemos é que existe uma infinidade de soluções desenvolvidas em diversas linguagens todas com um propósito e cada uma delas tem suas características. Por este motivo existem <strong><em>paradigmas de programação</em></strong> é uma forma de classificar as linguagens baseado em suas funcionalidades facilitando o entendimento e o contexto que ela poderá está melhor inserida e é claro com isto teremos uma visão sobre sua estruturação e execução das linguagens.</p>
<p>Esta cada vez mais comum linguagens suportarem múltiplos paradigmas. Sabemos que existem classes diferentes na computação quando o assunto é resolver problemas, quanto mais próximos destes assuntos estivermos, mais confortáveis estaremos para escolher uma determinada linguagem para resolver problemas, e assim sabermos qual ferramenta usar no momento certo. Na prática esta tarefa não é tão fácil mas o que sabemos é que ainda não criaram a bala de prata para resolver todos os problemas de uma única vez com apenas uma linguagem, se existisse não existiria mais <a target="_blank" href="https://pt.wikipedia.org/wiki/P_versus_NP"><strong>P versus NP</strong></a> e todos os problemas poderiam ser resolvidos em tempo polinomial.</p>
<h1 id="heading-as-coisas-boas-de-go">As coisas Boas de Go</h1>
<ul>
<li><p>Não possui Generics;</p>
</li>
<li><p>Não possui sobrecarga do operador;</p>
</li>
<li><p>Não possui aritmética de ponteiros;</p>
</li>
<li><p>Não é explícito o gerenciamento de Threads;</p>
</li>
<li><p>Possui inferência de tipos;</p>
</li>
<li><p>As Dependências são claras;</p>
</li>
<li><p>A sintaxe é limpa;</p>
</li>
<li><p>A semântica é clara;</p>
</li>
<li><p>A composição e não herança;</p>
</li>
<li><p>GC Nativo (Garbage collector);</p>
</li>
<li><p>Possui Goroutines;</p>
</li>
<li><p>Suporte nativo a programação concorrente;</p>
</li>
<li><p>Funções de Primeira Classe (<em>podemos passar funções como parâmetros</em>);</p>
</li>
<li><p>Multiplataforma;</p>
</li>
<li><p>Open Source;</p>
</li>
<li><p>Curva de Aprendizado muito baixa ou seja fácil de aprender;</p>
</li>
<li><p>Altamente produtivo;</p>
</li>
<li><p>Resolve problemas de escalabilidade;</p>
</li>
<li><p>Pode diminui seus custos de servidores drasticamente;</p>
</li>
<li><p>Diversos problemas pensados na perspectiva Go torna-se muito mais fáceis de tratar e resolvê-los;</p>
</li>
<li><p>Possui somente 25 Palavras reservadas;</p>
</li>
<li><p>Multi-paradigma: concorrente, funcional, imperativa, orientada a objeto;</p>
</li>
<li><p>Memory Safe.</p>
</li>
</ul>
<p>Sabemos que diversos pontos acima serão criticados mas na prática e com o tempo percebemos que todas as simplificações omitidas tornaram <strong>Go</strong> uma linguagem ainda mais poderosa.</p>
<h1 id="heading-nao-ha-generics-ainda">Não há Generics ainda</h1>
<p>Existem motivos fortes de <strong>Go</strong> não ter implementado <strong>Generics no inicio do projeto,</strong> há uma discussão nas comunidades em geral sobre este tema. <strong>Go</strong> deixou de fora diversas funcionalidades, dentre elas: <strong>“Generics”</strong> que em sua concepção iria comprometer diretamente o desempenho e propósito que a linguagem <strong>Go</strong> propusera a resolver. Os que reclamam são em sua grande maioria desenvolvedores que vieram de linguagens que usam esse recurso.<br />No dia 29 de novembro de 2018 os responsáveis pela manutenção do código fonte de <strong>Go</strong> abriram a possibilidade de enviarem proposta de novas funcionalidades com todos os detalhes para que possam<br />analisá-las e talvez implementá-las na versão Go 2.0, para terem uma boa noção leiam este arquivo <a target="_blank" href="https://blog.golang.org/go2-here-we-come">clicando aqui.</a></p>
<p><strong>Generics</strong> é uma forma de fazer <strong>cast</strong> de tipos diferentes em métodos e classes. É um tipo de Polimorfismo de inclusão e paramétrico, são funções que operam da mesma forma sobre objetos de tipos diferentes ou seja funções genéricas.</p>
<p><em>Exemplo:</em><br />1. Imagina um método que recebe um vetor do tipo <strong>int</strong>, e imprima na tela.<br />2. Imagina que precise fazer isso agora com tipo String e do tipo <strong>float</strong>, teria que fazer novos métodos ou funções várias vezes, repetindo o código.</p>
<p><em>Solução:  
</em>Para não precisar criar vários métodos é criado somente um método como generics para poder receber qualquer tipo.</p>
<p>Percebe-se que isso só é problemas em linguagens que precisam declarar tipos de variáveis ou funções etc, em linguagens dinâmicas como PHP por exemplo não tem essa necessidade, não vou dizer linguagens fortemente tipadas ou fracamente tipadas pois é um pouco mais complexo que isso e isto levaria a um outra discussão.</p>
<p>Em <strong>Go</strong> conseguimos resolver todos os problemas dessa natureza usando <a target="_blank" href="https://golang.org/pkg/reflect/">reflect</a> e outras usando interface. <strong>Go</strong> adota uma abordagem incomum para programação orientada a objeto então não faz muito sentido no momento ter uma funcionalidade que não agrega tanto para contribuir com o verdadeiro propósito que a linguagem foi construída, além do recurso deixar todo processo de execução e compilação bem mais lento e complexo.</p>
<p>Porém no ano de <strong>2020</strong> a proposta para <strong>Generics</strong> ficou ainda mais próximo de tornar-se realidade não temos dúvidas que veem algo por aí relacionado ao Generics então vamos ver na prática como isto seria possível usando <a target="_blank" href="http://go.xn--s28h/">Go.😎</a></p>
<p>Abaixo três exemplos com três propostas para resolver o problema desta forma irá conseguir perceber quando falamos em Generics😊.</p>
<h2 id="heading-copiando-e-colando-funcoes-com-tipos-especificos">Copiando e Colando funções com tipos específicos</h2>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-comment">// Pega um slice de qualquer tipo e a inverte.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reverses</span><span class="hljs-params">(list []<span class="hljs-keyword">string</span>)</span> []<span class="hljs-title">string</span></span> {
    i := <span class="hljs-number">0</span>
    j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
    <span class="hljs-keyword">for</span> i &lt; j {
        list[i], list[j] = list[j], list[i]
        i++
        j--
    }
    <span class="hljs-keyword">return</span> list
}

<span class="hljs-comment">// Pega um slice de qualquer tipo e a inverte.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reversei</span><span class="hljs-params">(list []<span class="hljs-keyword">int</span>)</span> []<span class="hljs-title">int</span></span> {
    i := <span class="hljs-number">0</span>
    j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
    <span class="hljs-keyword">for</span> i &lt; j {
        list[i], list[j] = list[j], list[i]
        i++
        j--
    }
    <span class="hljs-keyword">return</span> list
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    s := []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>,<span class="hljs-string">"jeff"</span>,<span class="hljs-string">"Go"</span>}
    Reverses(s)
    <span class="hljs-built_in">println</span>(s[<span class="hljs-number">0</span>], s[<span class="hljs-number">1</span>], s[<span class="hljs-number">2</span>])

    i := []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>,<span class="hljs-number">2012</span>,<span class="hljs-number">2009</span>}    
    Reversei(i)    
    <span class="hljs-built_in">println</span>(i[<span class="hljs-number">0</span>], i[<span class="hljs-number">1</span>], i[<span class="hljs-number">2</span>])
}
</code></pre>
<h2 id="heading-usando-interface">Usando Interface</h2>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-comment">// Pega um slice de qualquer tipo e a inverte.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reverse</span><span class="hljs-params">(in <span class="hljs-keyword">interface</span>{})</span> <span class="hljs-title">interface</span></span>{} {
    <span class="hljs-keyword">switch</span> in.(<span class="hljs-keyword">type</span>) {
        <span class="hljs-keyword">case</span> []<span class="hljs-keyword">string</span>:
        list := []<span class="hljs-keyword">string</span>(in.([]<span class="hljs-keyword">string</span>))
        i := <span class="hljs-number">0</span>
        j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
        <span class="hljs-keyword">for</span> i &lt; j {
                list[i], list[j] = list[j], list[i]
           i++
           j--
            }
            <span class="hljs-keyword">return</span> list

         <span class="hljs-keyword">case</span> []<span class="hljs-keyword">int</span>:
        list := []<span class="hljs-keyword">int</span>(in.([]<span class="hljs-keyword">int</span>))
        i := <span class="hljs-number">0</span>
        j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
        <span class="hljs-keyword">for</span> i &lt; j {
           list[i], list[j] = list[j], list[i]
           i++
           j--
            }
            <span class="hljs-keyword">return</span> list
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    s := []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>,<span class="hljs-string">"jeff"</span>,<span class="hljs-string">"Go"</span>}
    Reverse(s)
    <span class="hljs-built_in">println</span>(s[<span class="hljs-number">0</span>], s[<span class="hljs-number">1</span>], s[<span class="hljs-number">2</span>])

    i := []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>,<span class="hljs-number">2012</span>,<span class="hljs-number">2009</span>}    
    Reverse(i)    
    <span class="hljs-built_in">println</span>(i[<span class="hljs-number">0</span>], i[<span class="hljs-number">1</span>], i[<span class="hljs-number">2</span>])
}
</code></pre>
<h2 id="heading-utilizando-generics">Utilizando Generics</h2>
<pre><code class="lang-go"><span class="hljs-comment">// https://go2goplay.golang.org/</span>
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-comment">// The playground now supports parentheses or square brackets (only one at</span>
<span class="hljs-comment">// a time) for generic type and function declarations and instantiations.</span>
<span class="hljs-comment">// By default, parentheses are expected. To switch to square brackets,</span>
<span class="hljs-comment">// the first generic declaration in the source must use square brackets.</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Print</span>[<span class="hljs-title">type</span> <span class="hljs-title">T</span>] <span class="hljs-params">(s []T)</span></span>{
    <span class="hljs-keyword">for</span> _, v := <span class="hljs-keyword">range</span> s {
        fmt.Print(v)
    }
    fmt.Println(<span class="hljs-string">""</span>)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Reverse</span>[<span class="hljs-title">type</span> <span class="hljs-title">T</span>]<span class="hljs-params">(list []T)</span></span> {
    i := <span class="hljs-number">0</span>
    j := <span class="hljs-built_in">len</span>(list) - <span class="hljs-number">1</span>
    <span class="hljs-keyword">for</span> i &lt; j {
        list[i], list[j] = list[j], list[i]
        i++
        j--
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">var</span> i []<span class="hljs-keyword">interface</span>{}
        i = <span class="hljs-built_in">append</span>(i, <span class="hljs-string">"jeffotoni"</span>)
        i = <span class="hljs-built_in">append</span>(i, <span class="hljs-string">" ano de 2020 "</span>)
        i = <span class="hljs-built_in">append</span>(i, []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>, <span class="hljs-string">"jeff"</span>, <span class="hljs-string">"Go"</span>})
    i = <span class="hljs-built_in">append</span>(i, []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>, <span class="hljs-number">2012</span>, <span class="hljs-number">2009</span>})
        Print(i)

    s := []<span class="hljs-keyword">string</span>{<span class="hljs-string">"otoni"</span>, <span class="hljs-string">"jeff"</span>, <span class="hljs-string">"Go"</span>}
    Reverse(s)
    Print(s)

    intt := []<span class="hljs-keyword">int</span>{<span class="hljs-number">2020</span>, <span class="hljs-number">2012</span>, <span class="hljs-number">2009</span>}
    Reverse(intt)
    Print(intt)
}
</code></pre>
<h1 id="heading-composicao-nao-heranca">Composição não herança</h1>
<p>A abordagem adotada por <strong>Go</strong> foge da regra e <strong>é incomum</strong> para <strong><em>programação orientada a objetos*</em></strong>,<em> permitindo métodos em qualquer tipo, não apenas classes, mas sem qualquer forma de herança baseada em tipos, como subclasses. Isso significa que não há hierarquia de tipos. Isto não é um bug, não é uma desvantagem ou erro, é uma escolha intencional de design dos desenvolvedores de <strong>Go</strong>. Embora as hierarquias de tipos tenham sido usadas para construir softwares bem-sucedidos, é uma postura e opinião da equipe de desenvolvedores do <em>*Go,</em></em> onde preferiram dar um passo para trás ao invés de fazerem igual a todos, o mesmo modelo repetitivo em diversas linguagens.</p>
<h2 id="heading-interfaces-sao-implicitas">Interfaces são implícitas</h2>
<p>Em vez disso, o <strong>Go</strong> possui <strong>interfaces,</strong> que são apenas um conjunto de métodos e nada mais.<br /><em>Exemplo:</em></p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Gemetric <span class="hljs-keyword">interface</span> {
  area() <span class="hljs-keyword">float64</span>
  perim() <span class="hljs-keyword">float64</span>
}
</code></pre>
<p>Todos os tipos de dados que implementam esses métodos satisfazem essa interface <strong>implicitamente,</strong> não há <strong><em>implements</em></strong> na declaração. A satisfação da interface é verificada estaticamente em tempo de compilação, portanto, apesar das interfaces de desacoplamento, elas são seguras quanto ao tipo.</p>
<p>Um tipo geralmente satisfaz muitas interfaces, cada uma correspondendo a um subconjunto de seus métodos. Essa fluidez de satisfação de interface incentiva uma abordagem diferente para a construção de software uma quebra no paradigma existente.</p>
<h2 id="heading-por-que-as-interfaces-nao-sao-explicitas">Por que as interfaces não são explícitas ?</h2>
<p>A programação orientada a objetos fornece uma visão poderosa: que o <em>comportamento</em> dos dados pode ser generalizado independentemente da <em>representação</em> desses dados. O modelo funciona melhor quando o comportamento (conjunto de métodos) é fixo, mas depois que você insere uma subclasse em um tipo e adiciona um método, <em>os comportamentos não são mais idênticos</em> . Se, em vez disso, o conjunto de comportamentos for fixo, como nas interfaces definidas estaticamente em Go, a uniformidade de comportamento permite que dados e programas sejam compostos uniformemente, ortogonalmente e com segurança.<br />As hierarquias de tipo resultam em código frágil. <strong>Go</strong> estimula a <em>composição</em> e não herança, usando interfaces simples, geralmente de um método, para definir comportamentos triviais que servem como limites claros e compreensíveis entre os componentes e a eliminação da hierarquia de tipos também elimina uma forma de hierarquia de dependência.<br />Os designs não são como métodos hierárquicos <strong>herdados de subtipo</strong>. Eles são mais <strong>soltos, orgânicos, desacoplados, independentes</strong> e portanto <strong>escaláveis.</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"math"</span>

<span class="hljs-keyword">type</span> Gemetric <span class="hljs-keyword">interface</span> {
    area() <span class="hljs-keyword">float64</span>
    perim() <span class="hljs-keyword">float64</span>
}

<span class="hljs-keyword">type</span> rect <span class="hljs-keyword">struct</span> {
    width, height <span class="hljs-keyword">float64</span>
}

<span class="hljs-keyword">type</span> circle <span class="hljs-keyword">struct</span> {
    radius <span class="hljs-keyword">float64</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r rect)</span> <span class="hljs-title">area</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> r.width * r.height
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r rect)</span> <span class="hljs-title">perim</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-number">2</span>*r.width + <span class="hljs-number">2</span>*r.height
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c circle)</span> <span class="hljs-title">area</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> math.Pi * c.radius * c.radius
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c circle)</span> <span class="hljs-title">perim</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-number">2</span> * math.Pi * c.radius
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">measure</span><span class="hljs-params">(g geometry)</span></span> {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    r := rect{width: <span class="hljs-number">3</span>, height: <span class="hljs-number">4</span>}
    c := circle{radius: <span class="hljs-number">5</span>}

    measure(r)
    measure(c)
}
</code></pre>
<h1 id="heading-duck-typing"><strong>Duck typing</strong></h1>
<p>O Go suporta <strong>“Duck typing”,</strong> é um estilo de tipagem em que os <a target="_blank" href="https://pt.wikipedia.org/wiki/M%C3%A9todo_(programa%C3%A7%C3%A3o)"><em>métodos</em></a> <em>e propriedades</em> de um objeto determinam a semântica válida, em vez de sua <a target="_blank" href="https://pt.wikipedia.org/wiki/Heran%C3%A7a">herança</a> de uma classe particular ou implementação de uma interface explicita. O nome do conceito refere-se ao <a target="_blank" href="https://pt.wikipedia.org/wiki/Teste_do_pato">teste do pato</a>, atribuído à <a target="_blank" href="https://pt.wikipedia.org/w/index.php?title=James_Whitcomb_Riley&amp;action=edit&amp;redlink=1">James Whitcomb Riley</a>. Isso faz com que o Go se pareça com uma linguagem dinâmica.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Go_(programming_language)">Go</a> usa <strong>“Tipagem Estrutural“</strong> em métodos para determinar a compatibilidade de um tipo com uma interface. Não há hierarquias de tipos e a <strong>“Tipagem Estrutural”</strong> é uma alternativa interessante à herança clássica em linguagens com tipagem estática. Ele permite que você escreva algoritmos genéricos sem obscurecer a definição de um tipo em um mar de interfaces. Talvez mais importante, ajuda as linguagens com tipagem estática a capturar a sensação e a produtividade das linguagens dinamicamente tipificadas.</p>
<p><strong>“Duck typing”</strong> ocorre em tempo de execução e “<strong>Tipagem Estrutural”</strong> que ocorre em tempo de compilação. Go não da suporte a orientação a objetos como é implementado nas linguagens como C#, Java ou mesmo C ++, não possui herança e honestamente fico muito feliz com isto, mas oferece alguns recursos como <strong><em>composição e interfaces</em></strong>.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-keyword">type</span> familia <span class="hljs-keyword">interface</span> {
    dados() <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">type</span> pai <span class="hljs-keyword">struct</span> {
    Nome  <span class="hljs-keyword">string</span>
    Idade <span class="hljs-keyword">int</span>
    Cpf   <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"campo-x"`</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p pai)</span> <span class="hljs-title">dados</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"Nome: %s, Idade: %d"</span>, p.Nome, p.Idade)
}

<span class="hljs-keyword">type</span> filho <span class="hljs-keyword">struct</span> {
    pai
    email <span class="hljs-keyword">string</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(f filho)</span> <span class="hljs-title">dados</span><span class="hljs-params">()</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-keyword">return</span> fmt.Sprintf(<span class="hljs-string">"Nome: %s, Idade: %d, Email: %s"</span>, f.Nome, f.Idade, f.email)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">mostraDados</span><span class="hljs-params">(membro familia)</span></span> {
    fmt.Println(membro.dados())
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    pai := <span class="hljs-built_in">new</span>(pai)
    pai.Nome = <span class="hljs-string">"Jeff"</span>
    pai.Idade = <span class="hljs-number">50</span>
    pai.Cpf = <span class="hljs-string">"00.xxx.xxx-xx"</span>

    filho := <span class="hljs-built_in">new</span>(filho)
    filho.Nome = <span class="hljs-string">"Arthur"</span>
    filho.Idade = <span class="hljs-number">20</span>
    filho.email = <span class="hljs-string">"arthur@gmail.com"</span>

    mostraDados(pai)
    mostraDados(filho)
 }
</code></pre>
<h1 id="heading-muito-suporte-a-bibliotecas-de-terceiros">Muito suporte a bibliotecas de terceiros</h1>
<p>No cenário atual <strong>Go</strong> disparou como linguagem de programação e todos os grandes, médios e pequenos players existentes estão desenvolvendo suas libs, sdks, clients etc. na linguagem <strong>Go.</strong> Existe milhares de iniciativas e muitas bibliotecas de terceiros. Tudo colabora para que isto ocorra, a comunidade <strong>Go</strong> é muito forte, cresce a cada dia, tem uma curva de aceitação muito alta e com isto facilita sua entrada nas empresas e sua utilização pelos desenvolvedores.</p>
<p>O resultado disto é a disseminação em massa na internet com bibliotecas escritas em <strong>Go.</strong> Existe também bibliotecas que estão abandonadas, como em qualquer outra linguagem mas funcionais. Mas o número de bibliotecas escritas em <strong>Go</strong> é muito mas muito grande. Diversas empresas estão reescrevendo suas plataformas em <strong>Go</strong> isto é uma vertente que não para de crescer. E dia após dia o número de ferramentas para <a target="_blank" href="https://www.redhat.com/pt-br/topics/devops"><strong>DevOps</strong></a> cresce, e com isto a aceitação e o aumento de novos adeptos em Go cresce na cultura e comunidade <a target="_blank" href="https://pt.wikipedia.org/wiki/DevOps"><strong>DevOps</strong></a>.</p>
<h1 id="heading-gerenciamento-de-dependencias-nativo">Gerenciamento de dependências nativo</h1>
<p><strong>Go</strong> teve um momento de trevas e durante um bom tempo não teve um gerenciador de dependências oficial. Após algumas tentativas e diversos posts e discussões sobre o assunto. O protótipo inicial <a target="_blank" href="https://research.swtch.com/vgo"><strong>VGO</strong></a> foi anunciado em fevereiro de 2018. Em julho de 2018, o suporte para módulos com versão foi instalado no repositório principal. O Go 1.11 foi lançado em agosto de 2018.<br />O Go 1.11 inclui suporte preliminar para módulos com versão, conforme proposto <a target="_blank" href="https://research.swtch.com/vgo-intro">aqui</a> . Mesmo que alguns detalhes possam mudar, versões futuras suportarão módulos definidos usando Go 1.11 ou 1.12, os testes e utilização em massa que estamos atualmente fazendo usando “<strong><em>go mod</em></strong>” acreditamos que não tem volta, ficou simplesmente fantástico, mesmo sendo anunciado como um módulo experimental está muito simples e poderoso.</p>
<p><strong>Go</strong> é uma linguagem muito nova e o que surpreende é que em muito pouco tempo já exista uma infinidade de bibliotecas disponíveis para diversas necessidades e inúmeros tipos especificados de problemas e não para de crescer.</p>
<pre><code class="lang-go">$ <span class="hljs-keyword">go</span> mod init yourapp
$ <span class="hljs-keyword">go</span> build
</code></pre>
<h1 id="heading-nao-e-mais-obrigatorio-o-gopath"><strong>Não é mais obrigatório o $GOPATH</strong></h1>
<p>Após a implementação do controle de versão o <strong>VGO</strong> em <strong>Go</strong>, temos a possibilidade agora de não precisar que nossos projetos estejam abaixo do $GOPATH, agora podemos criar nossos projetos em qualquer diretório fora do $GOPATH. Esta funcionalidade só é possível devido o controle de versão, quando usamos o <strong><em>“go mod”</em></strong> os nossos workspaces de projetos passam a ser controlados de uma nova forma, basta executar o comando <em>“go mod init yourapp”</em> é criado um arquivo <strong><em>“go.mod”</em></strong> nele irá conter a localização do seu path e a versão que ele encontra-se. Muito simples e lindo.<br />Toda vez que formos executar nosso projeto Go podemos utilizar a variável ambiente <em>“GO111MODUL=yes|no”</em> para determinar se iremos utilizar o “go mod” ou não.</p>
<h1 id="heading-garbage-collector-gc">Garbage collector (GC)</h1>
<p>Os <strong>GCs</strong> são peças complexas de software, são décadas de pesquisas e implementações, diversas tentativas de cientistas da computação em fazer um GC melhorado e confiável. Não é uma tarefa simples, devido a isto existe uma corrente muito grande na internet descrevendo os prós e contras de um GC. O que temos que levar em consideração é que independente do resultado, se não tivermos um GC teríamos que construir um para resolver o problema de alocação.</p>
<p>Geralmente existem duas maneiras de alocar memória em <strong>Go</strong>: na pilha e o heap. Em geral os desenvolvedores estão familiarizados com a pilha basta escrever um programa recursivo e irá perceber um <a target="_blank" href="https://stackoverflow.com/questions/26158/how-does-a-stack-overflow-occur-and-how-do-you-prevent-it">estouro</a> da <a target="_blank" href="https://stackoverflow.com/questions/26158/how-does-a-stack-overflow-occur-and-how-do-you-prevent-it">pilha</a> caso não faça corretamente. O <strong>heap</strong>, por outro lado, é um pool de memória que pode ser usado para alocação dinâmica.</p>
<p>As alocações de pilha são ótimas porque elas só vivem durante a vida útil da função da qual fazem parte. As alocações de heap, no entanto, não serão desalocadas automaticamente quando saem do escopo. Para evitar que o heap fique desassociado, devemos desalocar explicitamente ou, no caso de linguagens de programação com gerenciamento de memória (como Go), confiar no coletor de lixo para localizar e excluir objetos que não são mais referenciados.</p>
<p>De um modo geral, em linguagens com um <strong>GC</strong>, quanto mais você puder armazenar na pilha, melhor, uma vez que essas alocações nunca são vistas pelo <strong>GC</strong>. Compiladores usam uma técnica chamada <em>análise de escape</em> para determinar se algo pode ser alocado na pilha ou deve ser colocado no heap.</p>
<p>Na prática, escrever programas que forcem o compilador a somente alocar na pilha pode ser muito limitante, e assim, no Go, nós aproveitamos seu maravilhoso GC para fazer o trabalho de manter nosso heap limpo.</p>
<p>Quer da uma conferida e aprofundar ainda mais no assunto entre neste link escrito por R<em>ichard L. Hudson</em> <a target="_blank" href="https://blog.golang.org/ismmkeynote">https://blog.golang.org/ismmkeynote</a>.</p>
<h1 id="heading-alguns-tipos-de-aplicacoes-implementadas-em-go">Alguns tipos de aplicações implementadas em Go</h1>
<p><strong>Go</strong> é uma linguagem de uso geral. <a target="_blank" href="https://github.com/nouney/awesome-go">Neste link</a> você conseguirá visualizar diversas aplicações implementadas em <strong>Go</strong> e suas respectivas categorias.</p>
<h2 id="heading-alguns-tipos">Alguns tipos:</h2>
<p>. Web backend <em>(com</em> <a target="_blank" href="https://github.com/nouney/awesome-go#web-frameworks"><em>diversos frameworks</em></a> <em>disponíveis)</em><br />. Web Assembly (<a target="_blank" href="https://github.com/vugu/vugu"><em>um dos frameworks vugu</em></a>)<br />. Microservices (<em>alguns frameworks:</em> <a target="_blank" href="https://micro.mu/"><em>Go Micro</em></a><em>,</em> <a target="_blank" href="https://gokit.io/"><em>Go Kit</em></a><em>,</em> <a target="_blank" href="https://github.com/NYTimes/gizmo"><em>Gizmo</em></a><em>,</em> <a target="_blank" href="https://github.com/koding/kite"><em>Kite</em></a>)<br />. Fragments services (<em>Termo citado pelo @jeffotoni em um grupo de discussão de microservices</em>)<br />. Lambdas (<em>FaaS</em> <a target="_blank" href="https://www.alexedwards.net/blog/serverless-api-with-go-and-aws-lambda"><em>example</em></a>)<br />. Client Server<br />. Aplicações em terminal (<a target="_blank" href="https://github.com/rivo/tview">utilizando a lib tview</a>)<br />. IoT (<a target="_blank" href="https://github.com/nouney/awesome-go#iot-internet-of-things"><em>alguns frameworks</em></a>)<br />. Boots (<a target="_blank" href="https://github.com/nouney/awesome-go#bot-building"><em>alguns aqui</em></a>)<br />. Aplicações Client que usam tecnologia Web<br />. Desktop Usando Qt+QML, Lib Nativa Win (<a target="_blank" href="https://github.com/therecipe/qt"><em>example Qt</em></a><em>,</em> <a target="_blank" href="https://therecipe.github.io/widgets_playground/"><em>widgets Qt</em></a><em>,</em> <a target="_blank" href="https://doc.qt.io/qt-5/qtqml-index.html"><em>Qml</em></a>)<br />. Aplicações de Rede<br />. Aplicações para protocolos<br />. Aplicações <a target="_blank" href="https://pt.wikipedia.org/wiki/REST">rEST</a>,<br />. Aplicações <a target="_blank" href="https://pt.wikipedia.org/wiki/SOAP">SOAP</a><br />. Aplicações <a target="_blank" href="https://pt.wikipedia.org/wiki/GraphQL">GraphQL</a><br />. Aplicações <a target="_blank" href="https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto">RCP</a><br />. Aplicações <a target="_blank" href="https://pt.wikipedia.org/wiki/Transmission_Control_Protocol">TCP</a><br />. Aplicações <a target="_blank" href="https://en.wikipedia.org/wiki/GRPC">gRPC</a><br />. Aplicações <a target="_blank" href="https://en.wikipedia.org/wiki/WebSocket">Websocket</a><br />. GopherJS (<a target="_blank" href="https://github.com/gopherjs"><em>compiles Go to JavaScript</em></a>)</p>
]]></content:encoded></item><item><title><![CDATA[Porque Amamos Go! ❤]]></title><description><![CDATA[Go: A linguagem que mais cresce para backend Go foi projetado pelo Google em 2007 para melhorar a produtividade de programação em uma era de multicore…]]></description><link>https://jeffotoni.hashnode.dev/porque-amamos-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/porque-amamos-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Developer]]></category><category><![CDATA[goroutines]]></category><category><![CDATA[programação]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Thu, 06 Apr 2023 13:52:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680789018438/af3f6014-55ed-4b6a-9107-ffcc01cfa55a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-ia"> </h1>
<p>Go: A linguagem que mais cresce para backend</p>
<p>Go foi projetado pelo <em>Google</em> em 2007 para melhorar a produtividade de programação em uma era de multicore, rede de máquinas e grandes bases de código. Os designers queriam abordar críticas de outras línguagens em uso no <em>Google</em>, mas manter suas características úteis. Os criadores <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike">Rob Pike</a>, <a target="_blank" href="https://pt.wikipedia.org/wiki/Ken_Thompson">Ken Thompson</a> e <a target="_blank" href="https://de.wikipedia.org/wiki/Robert_Griesemer">Robert Griesemer</a> mantiveram a sintaxe de Go semelhante ao C. No final de 2008 <em>Russ Cox</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Go_%28programming_language%29"></a>juntou-se a equipe e ajudou a mudar a linguagem e as bibliotecas de protótipo para realidade.</p>
<p>A linguagem Go foi lançada em 2009 com propósito de facilitar a resolução de problemas quando o assunto é desenvolvimento em camadas de rede, escalabilidade, desempenho, produtividade e o mais importante, concorrência. O próprio <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike">Rob Pike</a> declarou que “Go foi projetado para tratar de um conjunto de problemas de engenharia de software a que estávamos expostos na construção de grandes softwares de servidor”.</p>
<p>Go teve influências de diversas linguagens de programação e paradigmas diferentes, dentre elas: <a target="_blank" href="https://en.wikipedia.org/wiki/Go_%28programming_language%29"><em>Alef</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/APL_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>APL</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/BCPL"><em>BCPL</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/C_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>C</em></a><em>, CSP,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Limbo_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Limbo</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Modula"><em>Modula</em></a><em>,</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Newsqueak"><em>Newsqueak</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Oberon_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Oberon</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Occam_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>occam</em></a><em>,</em><a target="_blank" href="https://en.wikipedia.org/wiki/Pascal_%28programming_language%29"><em>Pascal</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Smalltalk"><em>Smalltalk</em></a> <em>e</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Crystal_%28programming_language%29"><em>Cristal</em></a><em>,</em> percebe-se que utilizaram do que tinham de melhor e criou algo novo e enxuto, com o mínimo necessário para resolver os problemas propostos, sem perder sua simplicidade. Acredito que isto podemos chamar de <em>inovação</em>. Go inovou ao quebrar os paradigmas de linguagens e implementar algo novo de forma simples e muito poderosa.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> mainimport <span class="hljs-string">"fmt"</span><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Hello all folks!"</span>)
}
</code></pre>
<h1 id="heading-menos-e-exponencialmente-mais">Menos é exponencialmente mais</h1>
<p>A equipe de desenvolvedores do Go dizem que sua criação é uma tentativa de tornar os programadores mais produtivos. Melhorando o processo de desenvolvimento de software no <em>Google</em>. O primeiro objetivo foi criar uma linguagem melhor para enfrentar os desafios da <em>simultaneidade escalável</em>, ou seja software que lida com muitas preocupações simultaneamente, um exemplo seria a coordenação de mil servidores <em>back-end</em> enviando tráfego de rede todo o tempo.</p>
<p>Manter a linguagem Go pequena permite objetivos mais importantes. Ser pequeno torna o Go mais fácil de aprender, mais fácil de entender, mais fácil de implementar, mais fácil de reimplementar, mais fácil de depurar, mais fácil de ajustar e mais fácil de evoluir. Fazer menos permite mais. É uma expressão utilizada pela equipe de desenvolvimento do Go: “<em>Do Less. Enable More</em>” seria o equilíbrio entre os universo de problemas existentes e o que Go poderá ajudar a resolver bem tais problemas. Go explicitamente não foi projetado para resolver todos os problemas, em vez disso fizeram o suficiente para que possamos criar as próprias soluções personalizadas com facilidade, mas deixando bem claro que Go não pode fazer tudo.</p>
<h1 id="heading-alvoroco-na-comunidade-go">Alvoroço na comunidade Go</h1>
<p>Foram <em>deixadas de fora</em> diversas características das <em>linguagens modernas,</em>contrariando e indo em direção oposta das outras linguagens atuais, algumas funcionalidades como: <em>o uso de declarações de imutabilidade, tipos de dados de correspondência de padrões, generics,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Tratamento_de_exce%C3%A7%C3%A3o"><em>tratamento de exceção</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Heran%C3%A7a_%28programa%C3%A7%C3%A3o%29"><em>Herança</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_gen%C3%A9rica"><em>programação genérica</em></a><em>,</em><a target="_blank" href="https://pt.wikipedia.org/wiki/Asser%C3%A7%C3%A3o"><em>assertion</em></a> <em>e</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Sobrecarga"><em>sobrecarga</em></a> <em>de métodos e diversos outros pontos</em>. Todos os recursos acima foram criticados e apontados para os criadores de <em>Go,</em> que responderam: “<em>Essas omissões foram simplificações que contribuíram e contribuem para a força de Go”.</em> Há muitas coisas na linguagem e bibliotecas Go que diferem das práticas modernas, foi uma decisão da equipe de desenvolvimento do Go: <em>“às vezes vale a pena tentar uma abordagem diferente”.</em></p>
<p>Todos estão convidados a ajudar e contribuir se assim desejar. Os interessados podem abrir <a target="_blank" href="https://github.com/golang/go/wiki/ExperienceReports">propostas</a> para novos recursos e tudo relacionado ao ecossistema da linguagem. O código fonte de Go está disponível no <a target="_blank" href="https://github.com/golang/go">GitHub</a> . A documentação sobre como você pode contribuir com o idioma é fornecida <a target="_blank" href="https://golang.org/doc/contribute.html">aqui</a>.</p>
<h1 id="heading-concorrencia-e-diferente-de-paralelismo">Concorrência é diferente de paralelismo</h1>
<p>Uma das famosas frases é: <em>“Concorrência é sobre lidar com muitas coisas ao mesmo tempo. Paralelismo é fazer muitas coisas ao mesmo tempo”.</em>Concorrência é a composição de cálculos de execução independente. Concorrência é uma maneira de estruturar software, e definitivamente não é paralelismo embora permita o paralelismo.</p>
<p>Se você tiver apenas um processador, seu programa ainda pode ser concorrente, mas não pode ser paralelo. Por outro lado, um programa concorrente bem escrito pode ser executado de forma eficiente em paralelo em um multiprocessador. Sugiro dar uma conferida neste vídeo de uma palestra do <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike">Rob Pike</a> “<a target="_blank" href="https://vimeo.com/49718712">Concorrência não é Paralelismo</a>”.</p>
<p>Concorrência em Go é muito poderosa e também simples de codar está foi a intensão dos engenheiros que desenvolveram Go. A resolução de muitos problemas é bem mais eficiente utilizando concorrência e este é o poder de Go, por isto, se tornou um Deus quando o assunto é concorrência. Devido a isto, problemas englobados neste universo serão resolvidos com muita eficiência e o mais importante, com muito pouco recurso computacional.</p>
<p>O exemplo abaixo é um clássico quando nos referimos a concorrência, quando queremos balancear CPU e E/S usamos este parttern <strong>Fan-out</strong>.</p>
<h2 id="heading-o-que-e-fan-out">O que é Fan-out ?</h2>
<p>São múltiplas funções podem ler do mesmo canal até que esse canal seja fechado, isso é chamado de <strong><em>fan-out</em></strong> . Isso fornece uma maneira de distribuir o trabalho entre um grupo de trabalhadores para paralelizar o uso da <strong>CPU</strong> e <strong>E/S</strong>.</p>
<pre><code class="lang-go"><span class="hljs-comment">/*
* Example Worker
* @package     main
* @author      @jeffotoni
 */</span>

<span class="hljs-comment">// In this example we'll look at how to implement</span>
<span class="hljs-comment">// a _worker pool_ using goroutines and channels.</span>
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"time"</span>

<span class="hljs-comment">// Here's the worker, of which we'll run several</span>
<span class="hljs-comment">// concurrent instances. These workers will receive</span>
<span class="hljs-comment">// work on the `jobs` channel and send the corresponding</span>
<span class="hljs-comment">// results on `results`. We'll sleep a second per job to</span>
<span class="hljs-comment">// simulate an expensive task.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">worker</span><span class="hljs-params">(id <span class="hljs-keyword">int</span>, jobs &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, results <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">int</span>)</span></span> {

    <span class="hljs-keyword">for</span> j := <span class="hljs-keyword">range</span> jobs {

        fmt.Println(<span class="hljs-string">"worker"</span>, id, <span class="hljs-string">"started  job"</span>, j)

        time.Sleep(time.Second)

        fmt.Println(<span class="hljs-string">"worker"</span>, id, <span class="hljs-string">"finished job"</span>, j)
        results &lt;- j * <span class="hljs-number">2</span>
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// In order to use our pool of workers we need to send</span>
    <span class="hljs-comment">// them work and collect their results. We make 2</span>
    <span class="hljs-comment">// channels for this.</span>
    jobs := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">100</span>)
    results := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">100</span>)

    <span class="hljs-comment">// This starts up 3 workers, initially blocked</span>
    <span class="hljs-comment">// because there are no jobs yet.</span>
    <span class="hljs-keyword">for</span> w := <span class="hljs-number">1</span>; w &lt;= <span class="hljs-number">3</span>; w++ {
        <span class="hljs-keyword">go</span> worker(w, jobs, results)
    }

    <span class="hljs-comment">// Here we send 5 `jobs` and then `close` that</span>
    <span class="hljs-comment">// channel to indicate that's all the work we have.</span>
    <span class="hljs-keyword">for</span> j := <span class="hljs-number">1</span>; j &lt;= <span class="hljs-number">5</span>; j++ {
        jobs &lt;- j
    }

    <span class="hljs-built_in">close</span>(jobs)

    <span class="hljs-comment">// Finally we collect all the results of the work.</span>
    <span class="hljs-keyword">for</span> a := <span class="hljs-number">1</span>; a &lt;= <span class="hljs-number">5</span>; a++ {
        &lt;-results
    }
}
</code></pre>
<h1 id="heading-pontos-positivos-de-go">Pontos positivos de Go:</h1>
<ul>
<li><p>Não possui Generics;</p>
</li>
<li><p>Não possui sobrecarga do operador;</p>
</li>
<li><p>Não possui aritmética de ponteiros;</p>
</li>
<li><p>Não é explícito o gerenciamento de Threads;</p>
</li>
<li><p>Possui inferência de tipos;</p>
</li>
<li><p>As Dependências são claras;</p>
</li>
<li><p>A sintaxe é limpa;</p>
</li>
<li><p>A semântica é clara;</p>
</li>
<li><p>A composição e não herança;</p>
</li>
<li><p>GC Nativo (Garbage collector);</p>
</li>
<li><p>Possui Goroutines;</p>
</li>
<li><p>Suporte nativo a programação concorrente;</p>
</li>
<li><p>Funções de Primeira Classe (<em>podemos passar funções como parâmetros</em>);</p>
</li>
<li><p>Multiplataforma;</p>
</li>
<li><p>Open Source;</p>
</li>
<li><p>Curva de Aprendizado muito baixa ou seja fácil de aprender;</p>
</li>
<li><p>Altamente produtivo;</p>
</li>
<li><p>Resolve problemas de escalabilidade;</p>
</li>
<li><p>Pode diminui seus custos de servidores drasticamente;</p>
</li>
<li><p>Diversos problemas pensados na perspectiva Go torna-se muito mais fáceis de tratar e resolvê-los;</p>
</li>
<li><p>Possui somente 25 Palavras reservadas;</p>
</li>
<li><p>Multi-paradigma: concorrente, funcional, imperativa, orientada a objeto;</p>
</li>
<li><p>Memory Safe.</p>
</li>
</ul>
<p>Sabemos que diversos pontos acima serão <em>criticados</em>, mas na prática e com o tempo percebemos que todas as simplificações omitidas tornaram Go uma linguagem ainda mais poderosa. Para projetos simples ou complexos Go sempre será uma excelente alternativa, pois torna tudo mais simples e enxuto, fácil de codar e dar manutenção.</p>
<p><strong><em>Go é amor</em></strong> ❤</p>
]]></content:encoded></item><item><title><![CDATA[Um Pouco Sobre Goroutines em Go!]]></title><description><![CDATA[Um dos principais objetivos da linguagem de programação Go é tornar a simultaneidade mais simples, rápida e eficiente. Com certeza, as Goroutines são uma…]]></description><link>https://jeffotoni.hashnode.dev/um-pouco-sobre-goroutines-em-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/um-pouco-sobre-goroutines-em-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[goroutines]]></category><category><![CDATA[programação]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Thu, 06 Apr 2023 13:44:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680788550273/edc9bbfc-6bfb-4b6c-88fe-30e5e3cf1fe6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-goroutines-em-vez-de-threads">Goroutines em vez de threads</h2>
<p>Um dos principais objetivos da <strong>linguagem de programação Go</strong> é tornar a simultaneidade mais simples, rápida e eficiente.</p>
<p>Com certeza, as Goroutines são uma das principais características do Go e são uma das principais razões pelas quais o Go é tão eficiente na execução de tarefas em paralelo.</p>
<p>Quando criamos apis em Go utilizando net/http e recebemos uma porrada de requisições o que o pkg net/http usa? Se sua resposta for Goroutines você está correto 😍.</p>
<p>Eu evito o termo "threads leves", isto gera uma confusão para quem está iniciando ou tentando entender o que são Goroutines. Embora seja verdade que as Goroutines são semelhantes às "threads leves" em outros sistemas, Go usa uma implementação diferente que é otimizada para o contexto do Go. Portanto, pode ser melhor explicar as Goroutines em termos de como elas funcionam no Go que eu acredito que irá facilitar ainda mais o seu entendimento.</p>
<p>Em vez de dizer que as Goroutines são "threads leves", podemos dizer que as Goroutines são unidades leves de concorrência que são executadas em uma única thread de execução ou em várias dependendo de como o runtime Go decide gerenciá-las. Isso significa que o Go pode executar muitas Goroutines simultaneamente em uma única thread ou diversas threads.</p>
<p>As Goroutines são gerenciadas pelo runtime do Go e não pelo sistema operacional subjacente. Isso significa que as Goroutines são muito mais leves e eficientes do que as threads tradicionais do sistema operacional e que o Go pode gerenciá-las de forma mais eficaz para obter o máximo desempenho e escalabilidade.</p>
<p>Um dos objetivos das Goroutines em Go é permitir que você escreva programas concorrentes de maneira fácil e eficiente. Isso significa que você pode ter várias Goroutines em execução simultaneamente, cada uma executando uma tarefa diferente, sem precisar se preocupar com bloqueios de recursos, espera ativa ou outros problemas comuns de programação concorrente.</p>
<p>Para criar uma Goroutine em Go, você pode simplesmente adicionar a palavra-chave "go" antes de uma chamada de função.<br />Por exemplo, considere o seguinte código:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">myFuncJeff</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// seu gode aqui.</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// inicia a Goroutine</span>
    <span class="hljs-keyword">go</span> myFuncJeff()
    <span class="hljs-comment">// pode colocar algo aqui</span>
}
</code></pre>
<p><strong>Goroutines</strong> são leves e tiram proveito de todo o poder de processamento disponível. Goroutines existe apenas no espaço virtual do tempo de execução Go e não no sistema operacional.</p>
<p><strong>Goroutine</strong> é um método/função que pode ser executado independentemente junto com outras goroutines. Cada atividade simultânea na linguagem Go é geralmente denominada <strong>Goroutine</strong>.</p>
<p><strong>Go</strong> é uma linguagem <strong>multiparadigma</strong> e dentre os mais relevantes é o paradigma <strong>concorrente</strong>. Um dos pontos mais relevantes e importantes na linguagem <strong>Go</strong> é o trabalho com <strong>concorrência</strong>, <strong>Go</strong> <strong>inovou</strong> ao quebrar o modelo <strong>tradicional</strong> de <a target="_blank" href="https://pt.wikipedia.org/wiki/Thread_%28computa%C3%A7%C3%A3o%29"><em>threads</em></a> e sua forma de utilização ao criar um novo modelo, as <a target="_blank" href="https://golang.org/doc/effective_go.html#concurrency"><em>goroutines</em></a>. As <strong>goroutines</strong> são responsáveis por realizar execuções em <strong>Go</strong> de forma <strong>assíncrona</strong>. São muito poderosas e uma simples máquina de <strong>1G</strong> de <strong>Ram e 1CPU</strong> poderá subir milhares de goroutines.</p>
<p>Em Go as <strong>Goroutines</strong> contribuem para tornar a <strong>simultaneidade</strong> <strong>fácil</strong> de usar. As <strong>goroutines</strong> podem ser muito baratas: eles têm pouca sobrecarga além da memória para a pilha, que é apenas alguns kilobytes.</p>
<p>Para tornar as pilhas pequenas, o tempo de execução de <strong>Go</strong> usa pilhas redimensionáveis e delimitadas. Uma <strong>goroutine</strong> recém lançada recebe alguns kilobytes, o que é quase sempre suficiente. Quando não é, o tempo de execução aumenta (e encolhe) a memória para armazenar a pilha automaticamente, permitindo que muitos <strong>goroutines</strong> vivam em uma quantidade <strong>modesta</strong> de memória.</p>
<p>A sobrecarga da CPU tem em média três instruções baratas por chamada de função. É prático criar <strong>centenas de milhares de goroutines</strong> no mesmo espaço de endereço. Se <strong>goroutines</strong> fossem apenas <strong>threads</strong>, os recursos do sistema acabariam em um número muito menor.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">enviarEmail</span><span class="hljs-params">(...<span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-comment">// Código para enviar o e-mail</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">enviarParaFila</span><span class="hljs-params">(mensagem <span class="hljs-keyword">string</span>)</span></span> {
    <span class="hljs-comment">// Código enviando para fila</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// goroutine envia email</span>
    <span class="hljs-keyword">go</span> enviarEmail(<span class="hljs-string">"jeff@gmail.com"</span>, <span class="hljs-string">"meu email"</span>)
    <span class="hljs-comment">// goroutine envia para fila</span>
    <span class="hljs-keyword">go</span> enviarParaFila(<span class="hljs-string">"Mensagem para a fila"</span>)
    <span class="hljs-comment">// Faça alguma outra coisa aqui</span>
}
</code></pre>
<p>Neste exemplo, criamos duas funções, enviarEmail e enviarParaFila, que simulam o envio de um e-mail e o envio de uma mensagem para a fila, respectivamente. Em seguida, na função main(), iniciamos duas Goroutines diferentes, uma para enviar um e-mail e outra para enviar uma mensagem para a fila.</p>
<p>Observe que estamos usando a palavra-chave go antes de cada chamada de função para iniciar uma Goroutine separada para cada tarefa. Isso significa que o programa continuará a ser executado normalmente, sem esperar que o envio de e-mail ou a mensagem da fila sejam concluídos.</p>
<p>O design de <strong>Go</strong> foi fortemente influenciado pelo artigo de <a target="_blank" href="https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf">C.A.R. Hoare</a> <strong>1978</strong> “<a target="_blank" href="https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf">Communicating sequential processes</a>” (<em>Comunicação de processos sequenciais</em>).</p>
<h2 id="heading-simultaneidade-nas-ideias-do-csp">Simultaneidade nas ideias do CSP</h2>
<p>Um dos modelos mais bem-sucedidos para fornecer suporte linguístico de alto nível para concorrência é o <strong><em>Hoare’s</em></strong> <strong><em>Communicating Sequential Processes</em></strong>, ou <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><em>CSP</em></a><em>,</em> <a target="_blank" href="https://pt.wikipedia.org/wiki/Occam_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Occam</em></a> e <a target="_blank" href="https://pt.wikipedia.org/wiki/Erlang_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Erlang</em></a> são duas línguas bem conhecidas que derivam de <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><em>CSP</em></a>. As primitivas de concorrência de <strong>Go</strong> derivam de uma parte diferente da árvore genealógica cuja principal contribuição é <em>a poderosa noção de canais como objetos de primeira classe</em>. A experiência com várias linguagens anteriores mostraram que o modelo <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><em>CSP</em></a> se encaixa bem em uma estrutura de linguagem procedural.</p>
<p>A maior diferença entre <strong>Go</strong> e o modelo <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><em>CSP</em></a>, além da sintaxe, é que o <strong>Go</strong> modela os canais de comunicação <strong>simultânea explicitamente como canais</strong>, enquanto os processos da linguagem de <strong><em>Hoare</em></strong> enviam mensagens diretamente uns aos outros, semelhante ao <a target="_blank" href="https://pt.wikipedia.org/wiki/Erlang_%28linguagem_de_programa%C3%A7%C3%A3o%29">Erlang</a>.</p>
<p>Bem para chegar neste resultado <strong>Go</strong> novamente sofreu críticas do modelo adotado. <strong>Go</strong> incorpora uma variante do <a target="_blank" href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"><em>CSP</em></a> (<em>Comunicação de processos sequenciais</em>) é uma linguagem formal para descrever padrões de interação em sistemas concorrentes com canais de primeira classe. Não foi adotada uma abordagem de gravação única para valorizar a semântica no contexto da <a target="_blank" href="https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_concorrente"><em>computação concorrente</em></a> como é feita no <a target="_blank" href="https://pt.wikipedia.org/wiki/Erlang_%28linguagem_de_programa%C3%A7%C3%A3o%29"><em>Erlang</em></a>, ao invés disto adotaram algo prático e que resultou em algo <strong>poderoso</strong>, permitindo programação <strong>simultânea simples</strong> e <strong>segura</strong>, mas <em>não proíbe programação incorreta</em>. E o lema criado foi: “<strong><em>Não se comunique compartilhando memória, compartilhe memória comunicando-se</em></strong>”.</p>
<p>A simplicidade e o suporte para concorrências oferecidas por <strong>Go</strong> gera robustez.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"net/http"</span>
    <span class="hljs-string">"time"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getSites</span><span class="hljs-params">(url <span class="hljs-keyword">string</span>)</span></span> {
    resposta, err := http.Get(url)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Printf(<span class="hljs-string">"Erro ao ler %s: %s\n"</span>, url, err)
        <span class="hljs-keyword">return</span>
    }
    <span class="hljs-keyword">defer</span> resposta.Body.Close()
    fmt.Printf(<span class="hljs-string">"%s lido com sucesso\n"</span>, url)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// URLs que iremos ler</span>
    urls := []<span class="hljs-keyword">string</span>{
        <span class="hljs-string">"https://www.google.com"</span>,
        <span class="hljs-string">"https://www.facebook.com"</span>,
        <span class="hljs-string">"https://www.github.com"</span>,
        <span class="hljs-string">"https://www.linkedin.com"</span>,
    }
    <span class="hljs-comment">// Goroutine separada para ler cada URL</span>
    <span class="hljs-keyword">for</span> _, url := <span class="hljs-keyword">range</span> urls {
        <span class="hljs-keyword">go</span> getSites(url)
    }
    <span class="hljs-comment">// Faça alguma outra coisa aqui</span>
        <span class="hljs-comment">// ...</span>
    time.Sleep(<span class="hljs-number">5</span> * time.Second)
}
</code></pre>
<p>Neste exemplo, definimos uma função getSite que usa o pacote net/http para fazer uma solicitação HTTP a um site específico e ler a resposta. Em seguida, na função main(), definimos uma lista de URLs que queremos ler e iniciamos uma Goroutine separada para ler cada URL.</p>
<p>Observe que estamos usando um loop for para percorrer a lista de URLs e iniciar uma Goroutine separada para cada URL usando a palavra-chave go. Isso significa que o programa continuará a ser executado normalmente, sem esperar que cada solicitação HTTP seja concluída.</p>
<p>Para dar tempo às Goroutines para que elas possam fazer o seu trabalho, usamos a função time.Sleep() para suspender a execução do programa por um curto período de tempo. Neste exemplo, usamos um atraso de 5 segundos para permitir que as Goroutines terminem de executar.</p>
<p>Vamos fazer o mesmo código agora usando sync.WaitGroup para sincronizar as nossas Goroutines e ficar ainda melhor o controle sobre elas.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"net/http"</span>
    <span class="hljs-string">"sync"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getSite</span><span class="hljs-params">(url <span class="hljs-keyword">string</span>, wg *sync.WaitGroup)</span></span> {
    <span class="hljs-comment">// Sinalize o WaitGroup quando a Goroutine terminar</span>
    <span class="hljs-keyword">defer</span> wg.Done()

    resp, err := http.Get(url)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Printf(<span class="hljs-string">"Erro ao ler %s: %s\n"</span>, url, err)
        <span class="hljs-keyword">return</span>
    }
    <span class="hljs-keyword">defer</span> resp.Body.Close()

    fmt.Printf(<span class="hljs-string">"%s lido com sucesso\n"</span>, url)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// URLs que iremos ler</span>
    urls := []<span class="hljs-keyword">string</span>{
        <span class="hljs-string">"https://www.google.com"</span>,
        <span class="hljs-string">"https://www.facebook.com"</span>,
        <span class="hljs-string">"https://www.github.com"</span>,
        <span class="hljs-string">"https://www.linkedin.com"</span>,
    }
    <span class="hljs-comment">// Crie um WaitGroup </span>
        <span class="hljs-comment">// para sincronizar as Goroutines</span>
    <span class="hljs-keyword">var</span> wg sync.WaitGroup
    <span class="hljs-keyword">for</span> _, url := <span class="hljs-keyword">range</span> urls {
        <span class="hljs-comment">// Adicione WaitGroup para cada Goroutine</span>
        wg.Add(<span class="hljs-number">1</span>)
        <span class="hljs-comment">// Passe o WaitGroup como um ponteiro</span>
        <span class="hljs-keyword">go</span> getSite(url, &amp;wg)
    }
    <span class="hljs-comment">// Espere até que todas as Goroutines terminem</span>
    wg.Wait()
        fmt.Println(<span class="hljs-string">"done"</span>)
}
</code></pre>
<p>Usando o WaitGroup, podemos garantir que todas as Goroutines terminem de executar antes que o programa continue. Isso é especialmente útil quando queremos que o programa termine apenas quando todas as tarefas simultâneas sejam concluídas.</p>
<h2 id="heading-concorrencia-e-diferente-de-paralelismo">Concorrência é diferente de Paralelismo</h2>
<p>Uma das famosas frases é: <em>“<strong><strong>Concorrência é sobre lidar com muitas coisas ao mesmo tempo. Paralelismo é fazer muitas coisas ao mesmo tempo</strong></strong>”.</em> <strong>Concorrência</strong> é a <strong>composição</strong> de cálculos de execução independente. <strong>Concorrência</strong> é uma maneira de estruturar software, e definitivamente não é paralelismo embora permita o paralelismo.</p>
<p>Se você tiver apenas um núcleo físico em seu processador, seu programa ainda pode ser concorrente, mas não pode ser paralelo. Por outro lado, um programa concorrente bem escrito pode ser executado de forma eficiente em paralelo em processador que possua mais de um núcleo físico. Sugiro dar uma conferida neste vídeo de uma palestra do <a target="_blank" href="https://pt.wikipedia.org/wiki/Rob_Pike"><em>Rob Pike</em></a> “<a target="_blank" href="https://vimeo.com/49718712"><em>Concorrência não é Paralelismo</em></a>”.</p>
<p><strong>Concorrência</strong> em <strong>Go</strong> é muito poderosa e também simples de godar, está foi a intensão dos engenheiros que desenvolveram <strong>Go</strong>. A resolução de muitos problemas é bem mais eficiente utilizando <strong>concorrência</strong> e este é o <strong>poder</strong> de <strong>Go</strong>, por isto, se tornou um <strong>Deus</strong> quando o assunto é <strong>concorrência</strong>. Devido a isto, problemas englobados neste universo serão resolvidos com muita <strong>eficiência</strong> e o mais importante, com muito <strong>pouco recurso computacional</strong>.</p>
<p>Quer aprofundar ainda mais sobre <strong>concorrência</strong>? Só entrar neste <a target="_blank" href="https://github.com/golang/go/wiki/LearnConcurrency"><em>link</em></a>. Quer testar e visualizar alguns exemplos? <a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/goroutine"><em>Click Aqui</em></a>.</p>
<p><strong>Goroutine</strong> é um tópico muito extenso, cheio de detalhes e muitas situações interessantes. Então requer que futuramente façamos um post somente sobre isso para que seja tratado com o devido cuidado e atenção.</p>
<p>Confira um exemplo simples.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>{fmt.Println(<span class="hljs-string">"oi sou uma goroutine1!"</span>)}()
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>{fmt.Println(<span class="hljs-string">"oi sou uma goroutine2!"</span>)}()
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span>{fmt.Println(<span class="hljs-string">"oi sou uma goroutine3!"</span>)}()
    fmt.Println(<span class="hljs-string">"Olá, estamos testando as goroutines em Go!"</span>)  
    time.Sleep(time.Second)
}
</code></pre>
<h2 id="heading-canais">Canais</h2>
<p>Os canais em Go são uma forma de sincronizar a comunicação entre Goroutines e compartilhar dados. Eles permitem que uma Goroutine envie dados para outra Goroutine de maneira segura e eficiente, sem a necessidade de usar bloqueios ou semáforos.</p>
<p>Os canais são criados usando a função <strong>make()</strong> e podem ser usados para enviar ou receber valores de um determinado tipo. Os canais podem ser definidos com uma capacidade opcional, que especifica quantos valores podem ser armazenados no canal antes que ele comece a bloquear. Se a capacidade não for especificada, o canal terá uma capacidade de zero, o que significa que ele pode armazenar apenas um valor por vez.</p>
<p>Para enviar um valor para um canal, usamos a sintaxe &lt;-, como em canal &lt;- valor. Para receber um valor de um canal, usamos a mesma sintaxe, mas invertida, como em valor &lt;- canal. Quando usamos a sintaxe &lt;- sem uma variável à esquerda ou à direita, ele é usado para bloquear a execução da Goroutine até que um valor seja enviado ou recebido pelo canal.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">produtor</span><span class="hljs-params">(canal <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++ {
        canal &lt;- i <span class="hljs-comment">// Envia um valor para o canal</span>
    }
    <span class="hljs-built_in">close</span>(canal) <span class="hljs-comment">// Fecha o canal</span>
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">consumidor</span><span class="hljs-params">(canal &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)</span></span> {
    <span class="hljs-keyword">for</span> valor := <span class="hljs-keyword">range</span> canal { <span class="hljs-comment">// Itera sobre os valores recebidos do canal</span>
        fmt.Println(valor) <span class="hljs-comment">// Exibe o valor recebido</span>
    }
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Cria um canal sem capacidade definida</span>
    canal := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)
    <span class="hljs-comment">// Goroutine do produtor para enviar valores para o canal</span>
    <span class="hljs-keyword">go</span> produtor(canal)
    <span class="hljs-comment">// Goroutine do consumidor para receber os valores do canal</span>
    consumidor(canal)
}
</code></pre>
<p>Neste exemplo, temos duas Goroutines diferentes: uma produtora e uma consumidora. A Goroutine produtora envia valores para o canal, enquanto a Goroutine consumidora os recebe e os exibe na tela.</p>
<p>Observe que estamos usando a palavra-chave chan para definir o tipo do canal. No caso deste exemplo, estamos usando chan int, que significa que estamos criando um canal que pode ser usado para enviar ou receber valores inteiros.</p>
<p>Também usamos as palavras-chave &lt;-chan e chan&lt;- para especificar se o canal deve ser usado para enviar ou receber valores. No caso da Goroutine produtora, estamos usando canal chan&lt;- int, o que significa que estamos criando um canal que pode ser usado apenas para enviar valores inteiros. Na Goroutine consumidora, estamos usando canal &lt;-chan int, o que significa que estamos criando um canal que pode ser usado apenas para receber valores inteiros.</p>
<p>Ao chamar a função close() no canal na Goroutine produtora, estamos sinalizando que não há mais valores para serem enviados pelo canal. Isso faz com que a função range na Goroutine consumidora saia do loop quando todos os valores tiverem sido recebidos.</p>
<p>Vamos reforçar o conceito: Um <strong>canal</strong> é um objeto de comunicação usado pelas <strong>goroutines</strong> e que tem o papel fundamental na comunicação <strong>entre</strong> as <strong>goroutines</strong>. Tecnicamente, um canal é a transferência de dados no qual os dados podem ser <strong>passados</strong> ou <strong>lidos</strong> . Assim, uma goroutine pode enviar dados para um canal, enquanto outras <strong>goroutines</strong> podem ler os dados do mesmo canal, como uma fila. Os canais é a forma mais segura de comunicação na linguagem <strong>Go</strong>. Existe outras formas de compartilhar dados em <strong>Go,</strong> não tão eficientes quanto os <strong>canais</strong> a equipe que desenvolveu <strong>Go</strong> decidiram não fechar as possibilidades e é possível compartilhar dados <strong>sem usar canais</strong>.</p>
<h2 id="heading-declarando-um-canal-sem-buffer-e-com-buffer">Declarando um Canal sem buffer e com buffer</h2>
<pre><code class="lang-go">
<span class="hljs-keyword">type</span> Promise <span class="hljs-keyword">struct</span> {
  Result <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>
  Error  <span class="hljs-keyword">chan</span> error
}
<span class="hljs-keyword">var</span> (
  ch1  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> *Promise)  <span class="hljs-comment">// received a pointer from the structure</span>
  ch2  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>, <span class="hljs-number">1</span>) <span class="hljs-comment">// allows only 1 channels</span>
  ch3  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)    <span class="hljs-comment">// allows only 2 channels</span>
  ch4  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">float64</span>)   <span class="hljs-comment">// has not been set can freely receive</span>
  ch5  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> []<span class="hljs-keyword">byte</span>)    <span class="hljs-comment">// by default the capacity is 0</span>
  ch6  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>, <span class="hljs-number">1</span>)   <span class="hljs-comment">// non-zero capacity</span>
  ch7  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> time.Time, <span class="hljs-number">2</span>)
  ch8  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{}, <span class="hljs-number">2</span>)
  ch9  = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{})
  ch10 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>](<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)) <span class="hljs-comment">// map channel</span>
  ch11 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> error)
  ch12 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> error, <span class="hljs-number">2</span>)
  <span class="hljs-comment">// receives a zero struct</span>
  ch14 &lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{}
  ch15 = <span class="hljs-built_in">make</span>(&lt;-<span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>)          <span class="hljs-comment">// can only read from</span>
  ch16 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span>&lt;- []os.FileInfo) <span class="hljs-comment">// can only write to// holds another channel as its value</span>
  ch17 = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">chan</span> <span class="hljs-keyword">bool</span>) <span class="hljs-comment">// can read and write to</span>
)
</code></pre>
<h2 id="heading-recebendo-valores-no-canal">Recebendo valores no canal</h2>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  ch2 &lt;- <span class="hljs-string">"okay"</span>
  <span class="hljs-keyword">defer</span> <span class="hljs-built_in">close</span>(ch2)
  fmt.Println(ch2, &amp;ch2, &lt;-ch2)
  ch7 &lt;- time.Now()
  ch7 &lt;- time.Now()
  fmt.Println(ch7, &amp;ch7, &lt;-ch7)
  fmt.Println(ch7, &amp;ch7, &lt;-ch7)
  <span class="hljs-keyword">defer</span> <span class="hljs-built_in">close</span>(ch7)
  ch3 &lt;- <span class="hljs-number">1</span> <span class="hljs-comment">// okay</span>
  ch3 &lt;- <span class="hljs-number">2</span> <span class="hljs-comment">// okay</span>
  <span class="hljs-comment">// deadlock // ch3 &lt;- 3 // does not accept any more </span>
  <span class="hljs-comment">// values, if you do it will error : deadlockdefer close(ch3)</span>
  fmt.Println(ch3, &amp;ch3, &lt;-ch3)
  fmt.Println(ch3, &amp;ch3, &lt;-ch3)
  ch10[<span class="hljs-string">"lambda"</span>] = <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)
  ch10[<span class="hljs-string">"lambda"</span>] &lt;- <span class="hljs-number">100</span><span class="hljs-keyword">defer</span> <span class="hljs-built_in">close</span>(ch10[<span class="hljs-string">"lambda"</span>])
  fmt.Println(&lt;-ch10[<span class="hljs-string">"lambda"</span>])
}
</code></pre>
<p>Um pequeno exemplo de goroutine utilizando canais.</p>
<p><em>Exemplo1:</em></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">goroutine</span><span class="hljs-params">(c <span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)</span></span> {
    fmt.Println(<span class="hljs-string">"Eu sou um canal: "</span> + &lt;-c + <span class="hljs-string">"!"</span>)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  fmt.Println(<span class="hljs-string">"start goroutine!"</span>)
  c := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)
  <span class="hljs-keyword">go</span> goroutine(c)
  c &lt;- <span class="hljs-string">"jeffotoni"</span>
}
</code></pre>
<p><em>Exemplo2:</em></p>
<pre><code class="lang-go">    <span class="hljs-keyword">package</span> main
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"fmt"</span>
        <span class="hljs-string">"time"</span>
    )
    <span class="hljs-comment">// escrevendo no canal</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">write</span><span class="hljs-params">(ch <span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>)</span></span> {
        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++ {
            ch &lt;- i
            fmt.Println(<span class="hljs-string">"escrever:"</span>, i, <span class="hljs-string">"to ch"</span>)
        }
        <span class="hljs-built_in">close</span>(ch)
    }
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        <span class="hljs-comment">// channel com buffer</span>
        ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">int</span>, <span class="hljs-number">2</span>)
        <span class="hljs-comment">// goroutine</span>
        <span class="hljs-keyword">go</span> write(ch)
        <span class="hljs-comment">//aguarde um pouco</span>
        time.Sleep(<span class="hljs-number">1</span> * time.Second)
        <span class="hljs-comment">// listando o canal</span>
        <span class="hljs-keyword">for</span> v := <span class="hljs-keyword">range</span> ch {
            fmt.Println(<span class="hljs-string">"ler"</span>, v, <span class="hljs-string">"from ch"</span>)
            time.Sleep(<span class="hljs-number">2</span> * time.Second)
        }
    }
</code></pre>
<p>Neste exemplo, estamos definindo uma variável chamada ch que é um canal que só pode ser usado para receber valores do tipo struct{}. Usamos a palavra-chave &lt;-chan para especificar que esse canal só pode ser usado para receber valores.</p>
<p>Confira o código abaixo:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Cria um canal sem capacidade definida</span>
    ch := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">struct</span>{})
    <span class="hljs-comment">// Inicia uma Goroutine para enviar um valor para o canal</span>
    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        ch &lt;- <span class="hljs-keyword">struct</span>{}{} <span class="hljs-comment">// Envia um valor para o canal</span>
    }()
    <span class="hljs-comment">// Recebe um valor do canal e exibe uma mensagem</span>
    &lt;-ch
    fmt.Println(<span class="hljs-string">"Valor recebido do canal"</span>)
}
</code></pre>
<h2 id="heading-select">Select</h2>
<p>O select é uma estrutura de controle em Go que permite que você monitore vários canais simultaneamente e execute a primeira operação que estiver pronta. Isso permite que você escreva código conciso e eficiente que responde a eventos de vários canais ao mesmo tempo.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"time"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">enviarMesg</span><span class="hljs-params">(canal <span class="hljs-keyword">chan</span>&lt;- <span class="hljs-keyword">string</span>, mensagem <span class="hljs-keyword">string</span>, atraso time.Duration)</span></span> {
    <span class="hljs-comment">// Espera por um período de tempo aleatório</span>
    time.Sleep(atraso)
    <span class="hljs-comment">// Envia a mensagem para o canal</span>
    canal &lt;- mensagem
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Cria dois canais sem capacidade definida</span>
    canal1 := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)
    canal2 := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> <span class="hljs-keyword">string</span>)
    <span class="hljs-comment">// Inicia duas Goroutines separadas para enviar mensagens para os canais</span>
    <span class="hljs-keyword">go</span> enviarMesg(canal1, <span class="hljs-string">"Mensagem para o canal 1"</span>, time.Second*<span class="hljs-number">2</span>)
    <span class="hljs-keyword">go</span> enviarMesg(canal2, <span class="hljs-string">"Mensagem para o canal 2"</span>, time.Second*<span class="hljs-number">1</span>)
    <span class="hljs-comment">// Use o select para receber a primeira mensagem que estiver pronta</span>
    <span class="hljs-keyword">select</span> {
    <span class="hljs-keyword">case</span> msg1 := &lt;-canal1:
        fmt.Println(<span class="hljs-string">"Mensagem recebida do canal 1:"</span>, msg1)
    <span class="hljs-keyword">case</span> msg2 := &lt;-canal2:
        fmt.Println(<span class="hljs-string">"Mensagem recebida do canal 2:"</span>, msg2)
    }
}
</code></pre>
<p>Neste exemplo, temos duas Goroutines diferentes que enviam mensagens para dois canais diferentes. Usando o select, estamos monitorando os dois canais e exibimos a primeira mensagem que chega em um deles.</p>
<p>Observe que estamos usando a sintaxe &lt;- para receber valores dos canais dentro dos casos do select. O select aguardará até que um dos casos esteja pronto, o que significa que uma mensagem foi recebida de um dos canais.</p>
<p>Além disso, estamos usando o time.Sleep() na função enviarMsg() para simular um atraso aleatório antes de enviar a mensagem para o canal. Isso é feito para demonstrar que a mensagem enviada ao canal mais rapidamente pode não ser a primeira a ser recebida devido aos atrasos.</p>
<p>O select é uma ferramenta poderosa em Go que pode ser usada para escrever código eficiente que monitora vários canais ao mesmo tempo. É particularmente útil para lidar com eventos assíncronos e permitir que o programa execute várias tarefas simultaneamente.</p>
<p>Espero ter colaborado para melhor entendimento quando o assunto é Goroutine.</p>
<p>Um outro assunto complementar e importante é <a target="_blank" href="https://dev.to/jeffotoni/workloads-em-go-59ab">"Workloads: CPU-Bound e IO-Bound"</a> recomendo a leitura para entender ainda mais.</p>
<p>Aqui você irá encontrar mais exemplos:<br /><a target="_blank" href="https://gobootcamp.jeffotoni.com/#goroutines">manual Go em: gobootcamp.jeffotoni</a><br /><a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/goroutine">Exemplos diversos de Goroutines em: goexample</a></p>
<p>Em <strong>Go</strong> teremos um arsenal para trabalhar com goroutines e gerenciar concorrências mas sem perder a simplicidade, legibilidade e produtividade.</p>
<p><strong><em>Go</em></strong> <em>é</em> <strong><em>amor</em></strong> ❤</p>
]]></content:encoded></item><item><title><![CDATA[Primeiros passos em Go]]></title><description><![CDATA[Objetivo deste post é simplesmente apresentar um pouco do porque a linguagem Go surgiu e apresentar um pouco de sua sintaxe e demostrar algumas áreas onde…]]></description><link>https://jeffotoni.hashnode.dev/primeiros-passos-em-go</link><guid isPermaLink="true">https://jeffotoni.hashnode.dev/primeiros-passos-em-go</guid><category><![CDATA[Go Language]]></category><dc:creator><![CDATA[JEFFERSON OTONI LIMA]]></dc:creator><pubDate>Thu, 06 Apr 2023 13:15:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680784968568/88f94ad2-87c9-4ca7-b287-9db8997959e0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Objetivo deste post é simplesmente apresentar um pouco do porque a linguagem Go surgiu e apresentar um pouco de sua sintaxe e demostrar algumas áreas onde Go é mais aplicado. Para todos que gostariam de aumentar ainda mais seu arsenal para desenvolvimento web este post irá ajuda-lo a esclarecer alguns pontos importantes quando estamos iniciando e aprendendo uma nova linguagem de programação.</p>
<h1 id="heading-iniciando-em-go">Iniciando em Go❤️</h1>
<p>Antes de iniciarmos, é importante salientar que linguagens de programação são ferramentas e como toda boa ferramenta temos que saber quais momentos usa-las. Existem cenários e problemas que só são resolvidos com linguagens específicas e existe outros universos de problemas que temos centenas ou milhares de linguagens que resolvem de alguma forma o mesmo problema. Então como um bom profissional quanto mais ferramentas souber para resolver problemas melhor será para sua carreira profissional🤩.</p>
<p>A linguagem Go em seu universo de possibilidades é uma <strong>linguagem de uso comum</strong> não gosto muito deste termo fica parecendo que ela é tipo uma bala de prata e resolve todos os problemas mas que na verdade não, <strong>Go nasceu por um propósito e resolve problemas do universo web e aproveitar a nova tecnologia de multicores em servidores,</strong> bem este era o propósito inicial 😂.</p>
<h1 id="heading-historia-do-projeto-go">História do projeto Go</h1>
<p><em>“Robert Griesemer, Rob Pike e Ken Thompson começaram a esboçar as metas para uma nova linguagem no quadro branco em 21 de setembro de 2007. Em poucos dias, as metas se estabeleceram em um plano para fazer algo e uma ideia justa do que seria. O design continuou a tempo parcial em paralelo com o trabalho não relacionado. Em janeiro de 2008, Ken começou a trabalhar em um compilador para explorar ideias; ele gerou código C como sua saída. Em meados do ano, a linguagem se tornou um projeto em tempo integral e se estabeleceu o suficiente para tentar um compilador de produção. Em maio de 2008, Ian Taylor começou de forma independente em um front-end GCC para Go usando as especificações preliminares. Russ Cox entrou no final de 2008 e ajudou a mover a linguagem e as bibliotecas do protótipo para a realidade.”</em></p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*7gKR-qozxb5_kMtghQ3vbg.png" alt class="image--center mx-auto" /></p>
<p>Go tornou-se um projeto de código aberto público em <strong>10 de novembro de 2009</strong> 🥳. Inúmeras pessoas da comunidade contribuíram com ideias, discussões e códigos.</p>
<p><em>“Existem agora</em> <strong><em>milhões de programadores Go</em></strong> <em>“<strong><strong>Gophers</strong></strong>” em todo o mundo, e há mais a cada dia. O sucesso de Go excedeu em muito as expectativas.”</em></p>
<h1 id="heading-por-que-criaram-uma-nova-linguagem">Por que criaram uma nova linguagem</h1>
<p><em>“Go nasceu da frustração com os idiomas e ambientes existentes para o trabalho que estávamos fazendo no Google. A programação havia se tornado muito difícil e a escolha das línguas era parcialmente culpada. Era preciso escolher entre compilação eficiente, execução eficiente ou facilidade de programação; todos os três não estavam disponíveis no mesmo idioma principal. Os programadores que poderiam escolher facilidade em vez de segurança e eficiência, mudando para linguagens tipadas dinamicamente, como Python e JavaScript, em vez de C++ ou, em menor grau, Java.”</em></p>
<p><em>“Go tratou dessas questões tentando combinar a facilidade de programação de uma linguagem interpretada e dinâmica com a eficiência e segurança de uma linguagem compilada estaticamente. Também pretendia ser moderno, com suporte para computação em rede e multicore. Finalmente, trabalhar com Go pretende ser rápido : deve demorar no máximo alguns segundos para construir um grande executável em um único computador.”</em></p>
<p>Nasce uma nova linguagem Go, para atender as novas necessidades e resolver problemas aproveitando o máximo possível do poder computacional. E é claro criando o seu mascote para a os milhares de <strong>gophers</strong> que viram a surgir a partir deste momento.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:400/1*o2BRMhO2v4BPBQ_CkqLcBw.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-site-oficial">Site Oficial</h1>
<p>Para iniciarmos em Go❤️ vamos dar alguns passos para trás, vamos começar toda nossa trajetória conhecendo o site oficial da lang esta é a página oficial <a target="_blank" href="http://golang.org">golang.org</a>, aqui encontraremos todas informações que poderíamos saber sobre Go e muito mais. Aqui temos os docs, packages, blog e nosso queridinho <a target="_blank" href="http://play.golang.org">play.golang.org</a>, specs da lingugem, download, tour em Go e muito mais.</p>
<p>O site oficial aparentemente parece pequeno mas ele é muito completo e grande. Então temos praticamente tudo que precisamos saber de Go para iniciarmos nosso aprendizado nesta linguagem que é um fenômeno.</p>
<p><strong>Onde Inicio no Site</strong></p>
<p>Vou criar uma linha de raciocínio para que possamos entender Go de forma mais prática possível.</p>
<p>Antes de instalar Go, ou rodar Go pelo play, vamos da uma passada em algumas partes do doc para que possamos entender um pouco da história do Go e por que nasceu uma nova linguagem neste universo de milhares de linguagens de programação.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*bOl58-yIDtx1KtGcDUIEQA.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-effective-go">Effective Go</h1>
<p>Este link é o primeiro que todos deveriam ler antes de tudo.<br />Effective Go❤️ neste site está todo material que precisa para ter uma boa noção da linguagem Go: Estrutura de controle, funções, Programação concorrente usando Goroutines, métodos, Maps e muito mais.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*7BRDpycnblhs4cR9E7RrDg.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-um-tour-de-go">Um tour de Go</h1>
<p>Este link seria o segundo mais importante na minha hierarquia para aprendermos Go.<br /><a target="_blank" href="https://tour.golang.org/welcome/1">Tour Go</a>❤️ neste site você irá conseguir testar e da uma passada em algumas das funcionalidades da linguagem Go 😱 isto mesmo tudo pelo browser sem precisar instalar nadinha na máquina.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*Eyd1h6jGWwOctS3epaes5g.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-playground-go">Playground Go</h1>
<p>Aqui é muito lindo, você não precisa instalar nadinha na máquina para executar algo rapidamente em Go, basta entrar no <a target="_blank" href="http://play.golang.org">play.golang.org</a></p>
<p><a target="_blank" href="https://play.golang.org/p/MAohLsrz7JQ">Play Go</a>❤️ neste site você irá conseguir executar Go 😱 isto mesmo não precisamos instalar nada por enquanto, da para executar tudo pelo browser e ir conhecendo a sintaxe da linguagem e aprendendo.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*C0igeYAJki0w_6pNsBaJAg.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-perguntas-mais-frequentes">Perguntas mais Frequentes</h1>
<p>Este link seria o nosso terceiro passo, acredito que agora tem diversas dúvidas, geradas pelo <a target="_blank" href="https://golang.org/doc/effective_go.html">Effective</a> Go e pelo <a target="_blank" href="https://tour.golang.org/welcome/1">Tour</a> que fez.<br /><a target="_blank" href="https://golang.org/doc/faq">Faq</a>❤️ é aqui que irá tirar algumas horas para esta leitura não precisa ser tudo de uma vez é claro, mas é necessário que leia. Esta página é essencial para organizar suas ideias e entender realmente um pouco mais sobre Go🥰.</p>
<p>Esta é uma das maiores páginas e requer mais leitura, mas esta página é essencial para o melhor entendimento sobre a linguagem Go, o tempo que irá gastar lendo esta página com certeza irá te economizar horas de trabalho.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*urYIJXS2z4vxF4u3ULjM9w.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-pacotes-nativos-go">Pacotes nativos Go</h1>
<p>Este link seria para que possa da uma passada e entender como são organizados e como é a documentação das funções, libs, pkgs que possamoms utilizar na linguagem Go. Este é um dos pontos fortes da linguagem, ela é muito completa para o desenvolvimento web para servidores.<br /><a target="_blank" href="https://golang.org/pkg/">Pkg</a>❤️ escolhi aqui o <a target="_blank" href="https://golang.org/pkg/strings/">pkg string</a> para que possa da uma conferida como é a formatação da documentação da linguagem e já com exemplos podendo ser executados pelo browser tudo para facilitar o aprendizado e entendimento🥰.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:700/1*6iBcWbBLUOHDXcVkx6L_sw.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-editores-e-ide">Editores e IDE</h1>
<p>Este link é sobre as IDEs e Editores que poderá utilizar quando tiver <strong>Godando</strong>. A linguagem Go não precisa de muito para que possamos editar nossos códigos, mas temos alguns plugins interessantes para facilitar ainda mais nosso dia a dia<br /><a target="_blank" href="https://golang.org/doc/editors.html">Editores e IDE</a>❤️ Neste link não irá ter o Sublime e o nvim que são dois editores que uso por aqui no dia a dia, o <strong>sublime</strong> pela pesquisa do <a target="_blank" href="https://blog.golang.org/survey2020">survey</a> somente 7,7% utilizam sublime e <strong>vim</strong> 14% o <strong>nvim</strong> é um plugin que irá usar no vim. O queridinho e adotado pelo equipe Go é o <strong>VsCode</strong> com 41% de adesão.</p>
<h1 id="heading-pontos-fortes-da-linguagem-go">Pontos Fortes da linguagem Go</h1>
<p>Antes de fazermos nosso famigerado “Hello World” vamos mostrar alguns pontos fortes da Linguagem, vamos fazer uma prévia dos pilares e características da linguagem Go.</p>
<h2 id="heading-3-pilares">3 Pilares</h2>
<p>Temos alguns pilares bem definidos em Go, isto irá ajuda-lo a clarear ainda mais seu horizonte quanto o assunto é Go.</p>
<ul>
<li><p><strong>Simplicidade</strong></p>
</li>
<li><p><strong>Legibilidade</strong></p>
</li>
<li><p><strong>Produtividade</strong></p>
</li>
</ul>
<p>Isto torno-se ao longo dos anos algo tão padrão para quem está desenvolvendo no universo Go que soa como poesia para os ouvidos. Sabemos que go é uma tentativa de juntar dois mundos distintos, o mundo das linguagens compiladas com as linguagens interpretadas, em 2007 nasceu a ideia e com objetivo de criar uma nova linguagem de programação.</p>
<h2 id="heading-caracteristicas-principais">Características principais</h2>
<p>Em Go temos algumas características marcantes da linguagem que torna ela ainda mais poderosa para desenvolvimento de aplicações web para servidores.</p>
<ul>
<li><p><strong>Somente 25 keywords</strong></p>
</li>
<li><p><strong>Curva de aprendizado baixa</strong></p>
</li>
<li><p><strong>Compilada estaticamente</strong></p>
</li>
<li><p><strong>Multiplataformas agora com suporte a RISC-V</strong></p>
</li>
<li><p><strong>Paradigma Concorrente</strong></p>
</li>
<li><p><strong>Tipagem Estática</strong></p>
</li>
<li><p><strong>Retrocompatibilidade</strong></p>
</li>
</ul>
<p>Todos estes pontos torna a linguagem ainda mais interessante, a equipe de engenheiros que desenvolveu a linguagem fizeram um excelente trabalho ou melhor veem fazendo, Go é simplesmente fantástico alguns não gostam do seu designer mas é compreensível mais de 20 anos desenvolvendo em paradigmas OO e Funcional como se não houvesse vida em outro planeta é compreensível 😂.</p>
<h1 id="heading-instalando-go"><strong>Instalando Go</strong></h1>
<p>Este é o momento que todos esperávamos, colocar a mão na massa e instalar local, no site oficial não tem como errar, não tem nada mais simples que instalar o Go em sua máquina para que possa programar em Go. Aproveitando e deixando claro que: <strong>Não precisamos instalar Go no servidor,</strong> isto mesmo que leu, em seu servidor seja ele qual for, <em>On-premises, um Ec2 da Aws ou um pod no k8s seja ele no Gke, ou k8s da DigitalOcean, ou seja em ECS ou EKS</em>, seja um serverless ou em algum servidor de hospedagem de sua preferência, o que irá precisar é do binário seja em uma imagem docker por exemplo ou não. Isto <strong>é um dos pontos fortes do Go,</strong> não precisamos levar tralhas para o servidor <strong>este é um dos grande benefícios de utilizar Go</strong> em aplicações web em servidores e foi por isto que <strong>Go</strong> ficou conhecido como a <strong>linguagem dos Containers</strong>😍.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:357/1*AmnDj6Ajc0hHEuP60Yt6Eg.gif" alt class="image--center mx-auto" /></p>
<p>Sabendo de tudo isto vamos a instalação de Go e vamos ver o tão quanto ela é complexa 😜😜, brincadeirinha… 😂</p>
<p><a target="_blank" href="https://golang.org/doc/install">Install Go</a> neste link terá o passo a passo de como instalar em diversos Sistemas Operacionais mas vou deixar aqui a instalação no Linux.</p>
<p><strong>Instalação no Linux</strong></p>
<p>Se você tiver uma versão anterior do Go instalada, certifique-se de <a target="_blank" href="https://golang.org/doc/manage-install">removê-la</a> antes de instalar outra.</p>
<ol>
<li><p><strong>$ sudo rm -rf /usr/local/go</strong></p>
</li>
<li><p>Baixe o arquivo <a target="_blank" href="https://golang.org/dl/go1.15.6.linux-amd64.tar.gz">clicando aqui go1.1</a>5.6 e extraia-o em <em>/usr/local</em></p>
</li>
<li><p><strong>$ sudo tar -C /usr/local -xzf</strong> <a target="_blank" href="https://golang.org/dl/go1.15.6.linux-amd64.tar.gz"><strong>go1.15.6.linux-amd64.tar.gz</strong></a></p>
</li>
<li><p>Adicione <em>/usr/local/go/bin</em> à <code>PATH</code>variável de ambiente.</p>
</li>
<li><p><strong>$ export PATH=$PATH:/usr/local/go/bin</strong></p>
</li>
<li><p>Para deixar o que fizemos acima global, ou seja toda vez que for entrar em seu terminal “go” seja executado você pode fazer isso adicionando a seguinte linha que mostrei acima ao seu $HOME/.profile ou <em>/etc/profile</em> (para uma instalação em todo o sistema) ou em seu bash ou o que estiver usando em seu ambiente Linux.</p>
</li>
<li><p><strong>Nota:</strong> As alterações feitas em um arquivo de perfil podem não se aplicar até a próxima vez que você efetuar login em seu computador. Para aplicar as alterações imediatamente, basta executar os comandos do shell diretamente ou executá-los a partir do perfil usando um comando como <code>source $HOME/.profile</code>.</p>
</li>
<li><p>Verifique se você instalou o Go abrindo um prompt de comando e digitando o seguinte comando:</p>
</li>
</ol>
<pre><code class="lang-go"><span class="hljs-keyword">go</span> version
</code></pre>
<p>Se tudo correr bem você irá visualizar: <em>“go version go1.15.6 linux/amd64”  
</em>lindo, simplesmente lindo pode falar, muito simples.</p>
<h1 id="heading-hello-world">Hello World</h1>
<p>Agora sim chegou a hora de nossos primeiros “hello world” utilizando Go.</p>
<p>Não tem segredo, podemos utilizar de qualquer editor que vimos acima e irmos para cima. Em Go não precisamos compilar quando estamos <strong>godando</strong> podemos simplesmente executar nossos programas sem precisar transforma-los em binários ou seja compilar.</p>
<p><strong>go run main.go</strong></p>
<p>Abaixo está nosso primeiro hello world, e basta salvar o arquivo com a extensão .go e coloque o nome de “_main.go_” depois basta executar ele com o comando “go run main.go”, em nosso exemplo chamei o arquivo de “<em>main.go”</em></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

  <span class="hljs-built_in">println</span>(<span class="hljs-string">"Meu primeiro Hello World"</span>)

}
</code></pre>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span>(
    <span class="hljs-string">"fmt"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

  fmt.Println(<span class="hljs-string">"Meu primeiro Hello World"</span>)

}
</code></pre>
<pre><code class="lang-go">$ <span class="hljs-keyword">go</span> run main.<span class="hljs-keyword">go</span>
</code></pre>
<p>Este nosso hello world é a menor estrutura que podemos montar para da saída no terminal.</p>
<p>Para ficar um pouquinha mais claro quando usarmos a função <strong>println</strong> temos que saber que que ela é uma função embutida (no tempo de execução) que pode eventualmente ser removida, enquanto o <em>fmt</em> pacote está na biblioteca padrão, que irá persistir.</p>
<p><strong>go build</strong></p>
<p>Agora vamos transformar em binário vamos compilar e para isto vamos utilizar o “<strong>go build</strong>” ou “<strong>GOARCH=386 GOOS=linux go build -o myprogram main.go</strong>” estamos agora informando a arquitetura e sistema operacional que desejamos compilar nosso programa Go.</p>
<pre><code class="lang-go">$ GOARCH=<span class="hljs-number">386</span> GOOS=linux <span class="hljs-keyword">go</span> build -o myhello main.<span class="hljs-keyword">go</span>
</code></pre>
<p>Este comando irá fazer o build ele irá gerar um “executável” um binário para ser executado em seu sistema operacional. Muito fácil não é ?😍 Eu diria muito lindo. Com este binário você irá conseguir executa-lo em sua máquina ou em qualquer servidor que tenha a mesma arquitetura e sistema operacional que tenha feito para sua compilação.</p>
<p>É importante frisar sempre este detalhe: <strong><em>“Não instalamos nada de Go em nossos servidores Web”</em></strong> é exatamente o que leu, não precisa instalar nadinha, só precisa do binário. ❤️ Foi devido a isto que <strong>Go</strong> ficou conhecido por ser a <strong>Linguagem dos Containers</strong>. Diz que isto não é fantástico ? 😍 Para que rode uma aplicação Web em seu servidor basta enviar o binário para ele. Uau, isto mesmo somente do binário sem precisar de levar mais nada referente ao seu projeto nadinha.</p>
<p><strong>Go e Docker</strong></p>
<p>Já que estamos falando do docker e dizendo que só precisamos do binário para executar nosso projeto em <strong>Go</strong> vamos apresentar como seria nossa imagem usando docker para que possamos agora utilizar Go em servidores como GKE do Google, EKS da AWS, ou k8s da DigitalOcean ou simplesmente usar com docker.</p>
<pre><code class="lang-go">#################################################
# Dockerfile distroless
#################################################
FROM golang:<span class="hljs-number">1.15</span> as builder
WORKDIR /<span class="hljs-keyword">go</span>/src/main
COPY . .
RUN CGO_ENABLED=<span class="hljs-number">0</span> GOOS=linux <span class="hljs-keyword">go</span> build -o main main.<span class="hljs-keyword">go</span>
RUN cp main /<span class="hljs-keyword">go</span>/bin/main

############################
# STEP <span class="hljs-number">2</span> build a small image
############################
FROM gcr.io/distroless/base
COPY --from=builder /<span class="hljs-keyword">go</span>/bin/main /
CMD [<span class="hljs-string">"/main"</span>]
</code></pre>
<p>Olha que lindo😁 pouco menos de 10 linhas. Temos uma imagem Go para que possamos compilar nosso projeto e em seguida fazemos algo parecido com S<a target="_blank" href="https://github.com/jeffotoni/goexample/tree/master/api-simple/docker-golang-scratch">cratch</a> porém estamos usando o distroless que é uma base enxuta bem pequena e que contém nosso binário. Desculpa mas diz que isto não é fantástico ou simplesmente lindão❤️ ?</p>
<p>O conceito <strong>distroless</strong> é simples ele parte do pressuposto em focarmos na nossa aplicação e menos na distribuição Linux.</p>
<p>Agora vamos fazer um pequeno exemplo de uma API rEST só para exemplificar nosso Dockerfile e mostrar na prática como é tão simples subirmos uma imagem docker do nosso projeto.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"log"</span>
    <span class="hljs-string">"net/http"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    mux := http.NewServeMux()
    mux.HandleFunc(<span class="hljs-string">"/api/v1/ping"</span>, Ping)
    log.Println(<span class="hljs-string">"Run Server 8080"</span>)
    log.Fatal(http.ListenAndServe(<span class="hljs-string">":8080"</span>, mux))
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Ping</span><span class="hljs-params">(w http.ResponseWriter, r *http.Request)</span></span> {
    log.Println(<span class="hljs-string">"server ok"</span>)
    w.WriteHeader(http.StatusOK)
    w.Write([]<span class="hljs-keyword">byte</span>(<span class="hljs-string">`{"msg":"pong"}`</span>))
}
</code></pre>
<p>Agora basta fazermos build de nosso projeto com o seguinte comando:</p>
<p>$ docker build — no-cache -f Dockerfile -t jeffotoni/apisimplego:latest .</p>
<p>isto irá gerar uma imagem localmente em sua máquina e agora é só executa-la para testarmos.</p>
<p>$ docker run — rm — name apisimplego -p 8080:8080 jeffotoni/apisimplego</p>
<p>Prontinho agora é só disparar para nosso endpoint /api/v1/ping que criamos</p>
<p>$ curl -i <a target="_blank" href="http://localhost:8080/api/v1/ping">localhost:8080/api/v1/ping</a></p>
<p>Diz que não é lindo 😍</p>
<h1 id="heading-conclusao">Conclusão</h1>
<p>Este post é um simples resumo para você que gostaria de aumentar seu arsenal para programação web. Espero que tenham gostado.</p>
<p>O canal que ocorreu a live: <a target="_blank" href="https://youtube.com/user/jeffotoni">https://youtube.com/user/jeffotoni</a></p>
<p>O link do PDF da apresentação pode ser encontrado em: <a target="_blank" href="http://speakerdeck.com/jeffotoni">speakerdeck.com/jeffotoni</a></p>
]]></content:encoded></item></channel></rss>