<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Grupo-Estudos-Golang on Cesar Gimenes</title><link>https://crg.eti.br/tags/grupo-estudos-golang/</link><description>Recent content in Grupo-Estudos-Golang on Cesar Gimenes</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>crg@crg.eti.br (Cesar Gimenes)</managingEditor><webMaster>crg@crg.eti.br (Cesar Gimenes)</webMaster><lastBuildDate>Sat, 06 Jun 2026 11:57:59 -0300</lastBuildDate><atom:link href="https://crg.eti.br/tags/grupo-estudos-golang/index.xml" rel="self" type="application/rss+xml"/><item><title>Overlapping text chunker for RAG pipelines</title><link>https://crg.eti.br/pub/text_chunker/</link><pubDate>Sat, 06 Jun 2026 11:57:59 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/text_chunker/</guid><description>&lt;p>In a RAG (&lt;em>Retrieval-Augmented Generation&lt;/em>) pipeline the first step is almost always the same: take a large text and break it into pieces before vectorizing. The pieces can&amp;rsquo;t be too big, because the model has a context limit, nor too small, because then the embedding loses semantics. And neighbors need to overlap, otherwise an answer that lands right on the boundary gets squeezed between two chunks and the retriever misses.&lt;/p></description></item><item><title>An encrypted vault in Go</title><link>https://crg.eti.br/pub/cofre-cifrado-em-go/</link><pubDate>Sun, 31 May 2026 01:02:01 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/cofre-cifrado-em-go/</guid><description>&lt;p>Let&amp;rsquo;s put together the three previous pieces:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://crg.eti.br/pub/capturando-senhas-no-terminal-go/">terminal password input&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://crg.eti.br/pub/criptografia-at-rest-com-a-stdlib-go/">encryption at rest&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://crg.eti.br/pub/sqlite-na-ram-serialize-deserialize/">SQLite snapshot&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>A SQLite database that lives in RAM and, on disk, exists only as an encrypted blob.&lt;/p>
&lt;p>The database runs in &lt;code>:memory:&lt;/code>.
On exit, we take a &lt;em>snapshot&lt;/em> of the database bytes, encrypt it with the password, and write it out.
On startup, we read the blob, decrypt it with the password, and &lt;em>deserialize&lt;/em> it back into RAM.&lt;/p></description></item><item><title>SQLite in RAM: serialize and deserialize in Go</title><link>https://crg.eti.br/pub/sqlite-na-ram-serialize-deserialize/</link><pubDate>Sun, 31 May 2026 00:46:31 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/sqlite-na-ram-serialize-deserialize/</guid><description>&lt;p>SQLite can run entirely in memory, without ever touching disk. And there is a little-known trick: you can take a &lt;em>snapshot&lt;/em> of the database bytes and load them back later, with no &lt;code>INSERT&lt;/code>, no rebuilding anything. The functions are &lt;code>sqlite3_serialize&lt;/code> and &lt;code>sqlite3_deserialize&lt;/code>.&lt;/p>
&lt;p>I will use the &lt;code>modernc.org/sqlite&lt;/code> driver, which is pure Go, no CGo.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">db&lt;/span>&lt;span style="color:#1f2328">,&lt;/span> &lt;span style="color:#1f2328">err&lt;/span> &lt;span style="color:#0550ae">:=&lt;/span> &lt;span style="color:#1f2328">sql&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#6639ba">Open&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#0a3069">&amp;#34;sqlite&amp;#34;&lt;/span>&lt;span style="color:#1f2328">,&lt;/span> &lt;span style="color:#0a3069">&amp;#34;:memory:&amp;#34;&lt;/span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cf222e">if&lt;/span> &lt;span style="color:#1f2328">err&lt;/span> &lt;span style="color:#0550ae">!=&lt;/span> &lt;span style="color:#cf222e">nil&lt;/span> &lt;span style="color:#1f2328">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#6639ba">fatal&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#1f2328">err&lt;/span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">db&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#6639ba">SetMaxOpenConns&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#0550ae">1&lt;/span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The catch is in &lt;code>SetMaxOpenConns(1)&lt;/code>. A &lt;code>:memory:&lt;/code> database belongs to the connection that opened it. Without limiting it to one connection, the &lt;code>database/sql&lt;/code> pool could open another one, and that one would see a different, empty database.&lt;/p></description></item><item><title>Encryption at rest with Go's stdlib</title><link>https://crg.eti.br/pub/criptografia-at-rest-com-a-stdlib-go/</link><pubDate>Sun, 31 May 2026 00:38:32 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/criptografia-at-rest-com-a-stdlib-go/</guid><description>&lt;p>I want to store a piece of data on disk so that, even if the file leaks, it is only readable with the password and any tampering is detected.&lt;/p>
&lt;p>To do this we protect the data by encrypting it &amp;ldquo;at rest&amp;rdquo;, which basically means the data is protected while it sits on disk and can only be accessed by whoever has the right password.&lt;/p>
&lt;p>You can do this with the standard library alone:&lt;/p></description></item><item><title>Capturing Passwords in the Terminal with Go</title><link>https://crg.eti.br/pub/capturando-senhas-no-terminal-go/</link><pubDate>Sat, 30 May 2026 10:00:00 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/capturando-senhas-no-terminal-go/</guid><description>&lt;p>Reading a password in the terminal looks trivial, but it has two pitfalls: the password shows up on screen if you use ordinary input, and you need to make sure you&amp;rsquo;re really dealing with a terminal and not a redirection. Let&amp;rsquo;s solve both with the &lt;code>golang.org/x/term&lt;/code> package.&lt;/p>
&lt;p>If you read with &lt;code>bufio.Scanner&lt;/code> or &lt;code>fmt.Scanln&lt;/code>, every keystroke shows up on screen. That won&amp;rsquo;t do for a password. &lt;code>term.ReadPassword&lt;/code> reads straight from the terminal, without echo:&lt;/p></description></item><item><title>GoScope: Exploring and Navigating Go Projects</title><link>https://crg.eti.br/pub/goscope-explorando-e-navegando-em-projetos-go/</link><pubDate>Sun, 09 Feb 2025 02:47:39 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/goscope-explorando-e-navegando-em-projetos-go/</guid><description>&lt;p>I often want to quickly analyze a Go project to understand where functions, variables, and types are defined or called. That&amp;rsquo;s why I created two command-line tools: &lt;strong>GoScope&lt;/strong> and &lt;strong>rgs&lt;/strong>. The first scans every &lt;code>.go&lt;/code> file in a project, producing a list of definitions and function calls. The second uses that list to let me navigate interactively to the exact spot in the code.&lt;/p>
&lt;h2 id="goscope">GoScope&lt;/h2>
&lt;p>&lt;a href="https://github.com/crgimenes/GoScope">&lt;strong>GoScope&lt;/strong>&lt;/a> walks through all &lt;code>.go&lt;/code> files recursively starting from the current directory. It prints:&lt;/p></description></item><item><title>Running Remote Commands Interactively with SSH</title><link>https://crg.eti.br/pub/executando-comandos-remotos-de-forma-interativa-com-ssh/</link><pubDate>Sat, 08 Feb 2025 13:38:17 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/executando-comandos-remotos-de-forma-interativa-com-ssh/</guid><description>&lt;p>I often need to run a command on a remote server without starting a full interactive session. I want the program to keep all the characteristics of a local process while running on the remote server.&lt;/p>
&lt;p>At first, I just used the &lt;code>ssh&lt;/code> command, specifying the server and the command to run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh server &lt;span style="color:#6639ba">command&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This method doesn&amp;rsquo;t work well for programs that require a pseudo terminal, like &lt;em>Neovim&lt;/em>. To fix that, I tried the &lt;code>-t&lt;/code> option to force pseudo terminal allocation. With it, programs like &lt;code>ls&lt;/code> display colors, but the user environment isn&amp;rsquo;t loaded. In that case, I need to pass the &lt;code>--color&lt;/code> option to &lt;code>ls&lt;/code>. Even so, programs like &lt;em>Neovim&lt;/em> fail because the &lt;em>shell&lt;/em> doesn&amp;rsquo;t behave as interactive and ANSI codes aren&amp;rsquo;t processed correctly.&lt;/p></description></item><item><title>Traceback in Go: How to Explore the Call Stack</title><link>https://crg.eti.br/pub/tracebacks-em-go/</link><pubDate>Thu, 06 Feb 2025 02:12:46 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/tracebacks-em-go/</guid><description>&lt;p>Many programming languages provide some kind of &amp;ldquo;stack trace&amp;rdquo; or &amp;ldquo;backtrace&amp;rdquo;. Python has the &lt;code>traceback&lt;/code> module, C on Linux offers the &lt;code>backtrace()&lt;/code> function in &lt;code>execinfo.h&lt;/code> (not part of the C standard), and Java includes &lt;code>Thread.dumpStack()&lt;/code> or &lt;code>e.printStackTrace()&lt;/code> for exceptions.&lt;/p>
&lt;h2 id="stack-trace-in-go">Stack Trace in Go&lt;/h2>
&lt;p>Go provides the &lt;code>runtime.Caller&lt;/code> function to get information about the call stack. The following example prints the file, line, and function that called &lt;code>info()&lt;/code>. Note that the argument &lt;code>1&lt;/code> passed to &lt;code>runtime.Caller&lt;/code> means we want information about the function that called &lt;code>info()&lt;/code>:&lt;/p></description></item><item><title>Data Transmission Using Sound: An Experiment with a 'Cup Telephone'</title><link>https://crg.eti.br/pub/transmissao-de-dados-usando-som-via-telefone-de-copos/</link><pubDate>Sat, 25 Jan 2025 21:58:10 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/transmissao-de-dados-usando-som-via-telefone-de-copos/</guid><description>&lt;p>When I started playing with computers, the only way to load a program into the machine was to type it from scratch. My old computer had no storage; there was no hard drive, floppy disk, or any other way to store data. At startup, the machine loaded &lt;em>BASIC&lt;/em> straight from ROM and that was it. Eventually I got a tape recorder, but it was terrible. With no money for a recorder made for computers, I used a household one. It took a long time adjusting the volume and other settings before I could load anything. The equipment was so finicky that I taped the controls down to keep them from moving, because the slightest change would prevent loading.&lt;/p></description></item><item><title>Finding Program Paths on the System with exec.LookPath in Go</title><link>https://crg.eti.br/pub/encontrando-os-paths-de-executaveis-usando-go/</link><pubDate>Sat, 18 Jan 2025 22:58:48 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/encontrando-os-paths-de-executaveis-usando-go/</guid><description>&lt;p>I started a new project that needs to check whether certain programs are installed on the system and get their full paths. For that, I used the &lt;code>exec.LookPath&lt;/code> function from the &lt;code>os/exec&lt;/code> package.&lt;/p>
&lt;p>The &lt;code>exec.LookPath&lt;/code> function searches for an executable in the directories listed in the &lt;code>PATH&lt;/code> environment variable. If it doesn&amp;rsquo;t find one, it returns an error. So I created the &lt;code>programPath&lt;/code> function, which takes the program name and returns the executable&amp;rsquo;s path and a boolean indicating whether the program was found.&lt;/p></description></item><item><title>Optimizing Message Integrity Checks with FNV-1a in Go</title><link>https://crg.eti.br/pub/checksum-com-golang/</link><pubDate>Sat, 18 Jan 2025 00:43:18 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/checksum-com-golang/</guid><description>&lt;p>In the article &lt;a href="https://crg.eti.br/pub/hmac-assinatura-de-mensagens-segura-em-go/">HMAC (Hash-based Message Authentication Code)&lt;/a>, we saw how that technique ensures a message was not altered in transit and confirms the validity of the signature.&lt;/p>
&lt;p>However, while secure, that process is slow and resource-intensive. When we only need to verify message integrity without validating a signature, we can use a faster hash function. For that, we will use the FNV-1a (Fowler-Noll-Vo) algorithm, known for its speed and low collision rate.&lt;/p></description></item><item><title>mTLS: Implementing Mutual Authentication Between Client and Server in Go</title><link>https://crg.eti.br/pub/mtls-implementando-autenticacao-mutua/</link><pubDate>Sat, 11 Jan 2025 19:49:40 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/mtls-implementando-autenticacao-mutua/</guid><description>&lt;p>mTLS (Mutual TLS) authenticates both client and server. Each one presents a digital certificate signed by a trusted certificate authority. By controlling certificate issuance, you ensure that only authorized clients access your service. It also makes it easy to identify the client without needing an API Key or Token. I also recommend using an &lt;a href="https://crg.eti.br/pt-br/pub/hmac-assinatura-de-mensagens-segura-em-go/">HMAC (Hash-based Message Authentication Code)&lt;/a> header as an additional layer of security and message integrity.&lt;/p>
&lt;h2 id="creating-certificates">Creating Certificates&lt;/h2>
&lt;p>In this example, I&amp;rsquo;ll create the certificates in a simple way for local testing. When deploying to production, be careful with the parameters you use. It&amp;rsquo;s important to include Subject Alternative Names (SANs), since relying on the CN (Common Name) alone is no longer recommended.&lt;/p></description></item><item><title>HMAC (Hash-based Message Authentication Code) in Golang</title><link>https://crg.eti.br/pub/hmac-assinatura-de-mensagens-segura-em-go/</link><pubDate>Fri, 10 Jan 2025 23:33:11 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/hmac-assinatura-de-mensagens-segura-em-go/</guid><description>&lt;p>When building APIs, it&amp;rsquo;s a good idea to add an authentication header to guarantee message integrity. For example, when your server sends a request or a webhook, include an &lt;code>X-Signature&lt;/code> header with an HMAC (Hash-based Message Authentication Code) signature.&lt;/p>
&lt;p>To generate the HMAC signature, you use a secret key and the content to be signed, such as the request &lt;em>body&lt;/em>, and send the signature in the header. It&amp;rsquo;s important to make clear exactly what is being signed. I&amp;rsquo;ve run into problems with clients who couldn&amp;rsquo;t validate the signature because they used the &lt;em>body&lt;/em> parsed as JSON instead of the &lt;em>raw body&lt;/em> received in the request.&lt;/p></description></item><item><title>Safe JSON Validation and Integration in Go APIs with json.RawMessage</title><link>https://crg.eti.br/pub/validacao-e-integracao-segura-de-json-em-apis-go/</link><pubDate>Thu, 09 Jan 2025 00:28:29 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/validacao-e-integracao-segura-de-json-em-apis-go/</guid><description>&lt;p>I recently built an API where the user sends a JSON value in one of the fields. The requirement was to log invalid JSON errors but let the rest of the data continue through the system&amp;rsquo;s normal flow.&lt;/p>
&lt;p>It was also important that, if the received JSON was valid, it would be integrated seamlessly into the API responses. Since the JSON could vary and I didn&amp;rsquo;t know its structure, I used &lt;code>json.RawMessage&lt;/code> as the field type. That way, when calling &lt;code>json.Marshal&lt;/code>, the data is correctly embedded into the main JSON.&lt;/p></description></item><item><title>Manipulating Special Permission Bits</title><link>https://crg.eti.br/pub/manipulando-setuid-e-setgid/</link><pubDate>Sat, 04 Jan 2025 00:36:51 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/manipulando-setuid-e-setgid/</guid><description>&lt;p>In the article on &lt;a href="https://crg.eti.br/pub/reducao-de-privilegios-com-golang/">Privilege Reduction in Programs&lt;/a>, we used the &lt;code>sudo&lt;/code> command to run a program with superuser privileges. However, it&amp;rsquo;s possible to do this without an external command.&lt;/p>
&lt;p>For that, we use special file permissions known as the &lt;em>setuid bit&lt;/em> and the &lt;em>setgid bit&lt;/em>. These attributes allow files to be executed with the &lt;strong>privileges of the owning user or group&lt;/strong>.&lt;/p>
&lt;p>To set the &lt;code>setuid&lt;/code> and &lt;code>setgid&lt;/code> bits, we use the &lt;code>chmod&lt;/code> command with the &lt;code>u+s&lt;/code> and &lt;code>g+s&lt;/code> options, respectively.&lt;/p></description></item><item><title>Dropping Privileges in Go Programs to Improve Security</title><link>https://crg.eti.br/pub/reducao-de-privilegios-com-golang/</link><pubDate>Thu, 02 Jan 2025 22:43:45 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/reducao-de-privilegios-com-golang/</guid><description>&lt;p>A good practice for improving the security of a system is to drop a program&amp;rsquo;s execution privileges. Ideally, a program should run with the fewest privileges possible.&lt;/p>
&lt;p>On UNIX-like systems, you can change the user and group a program runs as. Let&amp;rsquo;s walk through how to do that in Go.&lt;/p>
&lt;h2 id="checking-whether-the-program-is-running-as-root">Checking Whether the Program Is Running as Root&lt;/h2>
&lt;p>First, check whether the program is running as root. This matters because we&amp;rsquo;ll use system calls that require root privileges. (There are other ways to grant these privileges, but we&amp;rsquo;ll cover that in another article.)&lt;/p></description></item><item><title>References in Comments with Golang</title><link>https://crg.eti.br/pub/referencias-nos-comentarios-com-golang/</link><pubDate>Wed, 01 Jan 2025 13:28:17 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/referencias-nos-comentarios-com-golang/</guid><description>&lt;p>A quick tip about comments in Go: include references in them. Put the element you want to reference between brackets (&lt;strong>[&lt;/strong> and &lt;strong>]&lt;/strong>). It works with anything that can be referenced, such as variables, constants, functions, and so on.&lt;/p>
&lt;p>Here is an example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cf222e">package&lt;/span> &lt;span style="color:#1f2328">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cf222e">import&lt;/span> &lt;span style="color:#1f2328">(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#0a3069">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#0a3069">&amp;#34;time&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a">// pi representa a constante matemática Pi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cf222e">const&lt;/span> &lt;span style="color:#1f2328">pi&lt;/span> &lt;span style="color:#1f2328">=&lt;/span> &lt;span style="color:#0550ae">3.14159&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a">// CalcularArea calcula a área de um círculo dado o raio.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a">// Utiliza a constante [pi] para o cálculo.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cf222e">func&lt;/span> &lt;span style="color:#6639ba">CalcularArea&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#1f2328">raio&lt;/span> &lt;span style="color:#cf222e">float64&lt;/span>&lt;span style="color:#1f2328">)&lt;/span> &lt;span style="color:#cf222e">float64&lt;/span> &lt;span style="color:#1f2328">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#cf222e">return&lt;/span> &lt;span style="color:#1f2328">pi&lt;/span> &lt;span style="color:#0550ae">*&lt;/span> &lt;span style="color:#1f2328">raio&lt;/span> &lt;span style="color:#0550ae">*&lt;/span> &lt;span style="color:#1f2328">raio&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#cf222e">func&lt;/span> &lt;span style="color:#6639ba">main&lt;/span>&lt;span style="color:#1f2328">()&lt;/span> &lt;span style="color:#1f2328">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">raio&lt;/span> &lt;span style="color:#0550ae">:=&lt;/span> &lt;span style="color:#0550ae">5.0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">area&lt;/span> &lt;span style="color:#0550ae">:=&lt;/span> &lt;span style="color:#6639ba">CalcularArea&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#1f2328">raio&lt;/span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">fmt&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#6639ba">Printf&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#0a3069">&amp;#34;A área do círculo com raio %.2f é %.2f\n&amp;#34;&lt;/span>&lt;span style="color:#1f2328">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">raio&lt;/span>&lt;span style="color:#1f2328">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">area&lt;/span>&lt;span style="color:#1f2328">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#57606a">/*
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a"> Formatos úteis:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a"> [time.DateTime]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a"> [time.Kitchen]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a"> [time.RFC3339Nano]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a"> [time.RFC3339]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#57606a"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#1f2328">fmt&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#6639ba">Println&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#1f2328">time&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#6639ba">Now&lt;/span>&lt;span style="color:#1f2328">().&lt;/span>&lt;span style="color:#6639ba">Format&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#1f2328">time&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#1f2328">DateTime&lt;/span>&lt;span style="color:#1f2328">))&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In Neovim, place the cursor between the brackets and press &lt;code>Ctrl-]&lt;/code> to jump to the definition of the referenced element. To go back, press &lt;code>Ctrl-t&lt;/code>. In VSCode, use the &lt;code>Go to Definition&lt;/code> extension to do the same thing.&lt;/p></description></item><item><title>Plasma Effect in the Terminal with Golang</title><link>https://crg.eti.br/pub/efeito-plasma-no-terminal-com-golang/</link><pubDate>Tue, 31 Dec 2024 17:34:13 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/efeito-plasma-no-terminal-com-golang/</guid><description>&lt;p>One kind of program I&amp;rsquo;ve always found interesting is the &lt;em>demo&lt;/em>: eye-catching graphical effects with code that squeezes every ounce of performance out of the machine. The plasma effect is one of my favorites, simulating a fluid in motion.&lt;/p>
&lt;figure class="media-frame media-center fade-in">&lt;a href="https://crg.eti.br/pub/efeito-plasma-no-terminal-com-golang/plasma.webp">
&lt;picture>
&lt;source media="(max-width: 480px)" srcset="https://crg.eti.br/pub/efeito-plasma-no-terminal-com-golang/plasma_hu_3e89f9757017ba57.webp">
&lt;source media="(max-width: 1080px)" srcset="https://crg.eti.br/pub/efeito-plasma-no-terminal-com-golang/plasma_hu_3490c725fbb4fdb0.webp">
&lt;img alt="plasma in the terminal with Go" src="https://crg.eti.br/pub/efeito-plasma-no-terminal-com-golang/plasma_hu_5639f6b4b1ba2b78.webp" height="832" width="1280" loading="lazy" decoding="async">
&lt;/picture>
&lt;/a>&lt;/figure>&lt;p>To create the plasma effect, I use several trigonometric functions to calculate the background color of each character, passing time as a parameter to generate the animation. The code is relatively simple, but the optimization is a bit more complex.&lt;/p></description></item><item><title>Happy 2025, Fireworks in the Terminal with Golang</title><link>https://crg.eti.br/pub/feliz-2025-com-fogos-de-artificio-no-terminal-com-golang/</link><pubDate>Tue, 31 Dec 2024 13:09:42 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/feliz-2025-com-fogos-de-artificio-no-terminal-com-golang/</guid><description>&lt;p>A small program celebrates the arrival of 2025 with fireworks in the terminal. It includes several interesting tricks to start your year with plenty of code.&lt;/p>
&lt;figure class="media-frame media-center fade-in">&lt;a href="https://crg.eti.br/pub/feliz-2025-com-fogos-de-artificio-no-terminal-com-golang/fireworks-em-golang.webp">
&lt;picture>
&lt;source media="(max-width: 480px)" srcset="https://crg.eti.br/pub/feliz-2025-com-fogos-de-artificio-no-terminal-com-golang/fireworks-em-golang_hu_540d81dfb0c7b7ac.webp">
&lt;source media="(max-width: 1080px)" srcset="https://crg.eti.br/pub/feliz-2025-com-fogos-de-artificio-no-terminal-com-golang/fireworks-em-golang_hu_a9d6cf735954d9aa.webp">
&lt;img alt="fireworks in Go" src="https://crg.eti.br/pub/feliz-2025-com-fogos-de-artificio-no-terminal-com-golang/fireworks-em-golang_hu_87a35e7dddfadd11.webp" height="1532" width="2188" loading="lazy" decoding="async">
&lt;/picture>
&lt;/a>&lt;/figure>&lt;p>We use &lt;code>os.Stdout.WriteString&lt;/code> to write directly to the stdout descriptor, that is, the terminal&amp;rsquo;s standard output. This is the fastest way to write to the terminal, but it is not synchronized. That means there is no guarantee the output will be written in the expected order. In our case, though, this is desirable because it lets the fireworks overlap, giving the impression that they are exploding simultaneously.&lt;/p></description></item><item><title>Hidden Files on UNIX</title><link>https://crg.eti.br/pub/arquivos-ocultos-no-unix/</link><pubDate>Mon, 15 May 2023 06:21:48 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/arquivos-ocultos-no-unix/</guid><description>&lt;p>Everyone knows how to create hidden files in the UNIX/Linux world: just start the file name with a dot (.). But this feature wasn&amp;rsquo;t always there.&lt;/p>
&lt;p>According to Rob Pike in a Google+ post that is now only available on archive.org, around version 2 of UNIX, while the Unix file system design was being worked on, the &amp;ldquo;.&amp;rdquo; and &amp;ldquo;..&amp;rdquo; entries appeared to make directory navigation easier. This probably happened in version 2, when the file system became hierarchical.&lt;/p></description></item><item><title>AI-Assisted Programming</title><link>https://crg.eti.br/pub/programacao-assistida-por-ia/</link><pubDate>Sat, 22 Apr 2023 09:33:12 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/programacao-assistida-por-ia/</guid><description>&lt;p>We have recently seen an explosion in the use of artificial intelligence (AI), with products like ChatGPT, GitHub Copilot, Tabnine, and many others. They are very useful and interesting tools, but not as much as the media claims.&lt;/p>
&lt;p>Think of these tools as a machine that predicts which word is most likely to come next, adds it to the suggestion, and does this repeatedly in a loop until it reaches a certain number of words or until the probability of a good guess drops below an acceptable threshold, whichever comes first.&lt;/p></description></item><item><title>Writing Software That Lasts</title><link>https://crg.eti.br/pub/escrevendo-software-para-durar/</link><pubDate>Fri, 21 Apr 2023 16:28:48 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/escrevendo-software-para-durar/</guid><description>&lt;p>Here I&amp;rsquo;ll present some topics that I believe are important when developing software so that it&amp;rsquo;s highly resilient and lasts for many years. The topics are in no particular order and reflect my opinion, grounded in my experience as a developer.&lt;/p>
&lt;p>Treat this text as a collection of ideas I&amp;rsquo;ve gathered over the years. I tried to keep them as generic as possible, but I don&amp;rsquo;t claim they apply to every scenario. I think they fit best if your team is small and you need to ship fast.&lt;/p></description></item><item><title>Go and Rounding Errors</title><link>https://crg.eti.br/pub/golang-erro-de-arredondamento/</link><pubDate>Wed, 12 Apr 2023 09:24:13 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/golang-erro-de-arredondamento/</guid><description>&lt;p>When we write programs that deal with money, the ideal approach is to always use cents. That way we can use integer variables, and it&amp;rsquo;s much easier to prevent errors caused by &lt;a href="https://en.wikipedia.org/wiki/IEEE_754">how computers store floating-point numbers&lt;/a>.&lt;/p>
&lt;p>But we don&amp;rsquo;t always get to choose. When we consume third-party &lt;em>APIs&lt;/em>, for example, best practices aren&amp;rsquo;t always followed. In fact, in day-to-day work, ideal conditions are a rarity.&lt;/p>
&lt;p>Not long ago I ran into a problem like this: an &lt;em>API&lt;/em> my system needed to consume returned a &lt;em>JSON&lt;/em> where the value field was not only a string but also a floating-point number.&lt;/p></description></item><item><title>Go and the promise of backward compatibility</title><link>https://crg.eti.br/pub/golang-retrocompatibilidade/</link><pubDate>Wed, 12 Apr 2023 09:24:13 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/golang-retrocompatibilidade/</guid><description>&lt;p>When version 1.0 of the Go language was released, its developers made a &lt;a href="https://go.dev/doc/go1compat">commitment to maintain backward compatibility&lt;/a> as new versions came out.&lt;/p>
&lt;p>This commitment brings several interesting results. For example, the code you learn doesn&amp;rsquo;t become outdated. On top of that, keeping the language backward compatible reinforces another important commitment: simplicity and readability of code. That project that sat untouched for months, maybe years, still compiles on the first try. I experienced this personally with code that &lt;em>sat in a drawer&lt;/em> for three years.&lt;/p></description></item><item><title>The Problems with Programming in Golang</title><link>https://crg.eti.br/pub/problemas-programando-em-golang/</link><pubDate>Sun, 01 Mar 2020 11:11:33 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/problemas-programando-em-golang/</guid><description>&lt;p>I love Go. I choose Go for many of my projects. It&amp;rsquo;s simple and robust, with extensive documentation, plenty of examples, and a rich standard library focused on solving today&amp;rsquo;s problems. It&amp;rsquo;s without a doubt an excellent language.&lt;/p>
&lt;p>However, nothing is perfect. Golang has its problems, like any other language. Some will be solved as the compiler evolves. Others, the programmer needs to watch out for. Let&amp;rsquo;s look at some of the most common ones. Some of the issues mentioned here aren&amp;rsquo;t exclusive to Go, but rather the result of bad code design that I&amp;rsquo;ve run into many times and that&amp;rsquo;s worth mentioning.&lt;/p></description></item><item><title>Variable Shadowing in Golang</title><link>https://crg.eti.br/pub/golang-shadow-variaveis/</link><pubDate>Sat, 15 Feb 2020 20:12:16 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/golang-shadow-variaveis/</guid><description>&lt;p>Go is an easy language to work with, and it helps you avoid a lot of common mistakes.&lt;/p>
&lt;p>But one mistake that&amp;rsquo;s easy to make in Go, and that the compiler still doesn&amp;rsquo;t warn you about, is variable shadowing.&lt;/p>
&lt;p>Shadowing happens when you declare a variable in one block and then declare it again, with the same name, in a nested block.&lt;/p>
&lt;p>You then change the value of the variable believing you&amp;rsquo;re updating the one from the outer block, but you&amp;rsquo;re actually only changing the variable in the current block.&lt;/p></description></item><item><title>Using goto and labels in Go</title><link>https://crg.eti.br/pub/goto-label-em-golang/</link><pubDate>Fri, 26 Oct 2018 06:45:14 +0000</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/goto-label-em-golang/</guid><description>&lt;p>The &lt;em>goto&lt;/em> statement has a bad reputation. Back in the BASIC days programmers did not have many options, so they abused &lt;em>goto&lt;/em> and wrote confusing code. Modern languages like Go use goto with judgment and improve code clarity.&lt;/p>
&lt;p>Go lets the &lt;em>break&lt;/em> and &lt;em>continue&lt;/em> statements use labels. Use labels to break out of nested loops or to continue a specific loop. Using &lt;em>break&lt;/em> or &lt;em>continue&lt;/em> with &lt;em>labels&lt;/em> is equivalent to using goto.&lt;/p></description></item><item><title>Golang defer tips</title><link>https://crg.eti.br/pub/dicas-de-go-defer/</link><pubDate>Fri, 24 Mar 2017 20:12:16 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/dicas-de-go-defer/</guid><description>&lt;p>Using &lt;a href="https://blog.golang.org/defer-panic-and-recover">defer&lt;/a> to postpone a command until the function returns, no matter how it returns, is an excellent idea. Imagine a function with several return points, either for errors or for a successful finish. Managing the closing of files, connections, mutexes, and other resources at each return becomes tedious and unsafe. You may forget to close a resource on some return path, and that can cause serious problems.&lt;/p>
&lt;p>However, using &lt;code>defer&lt;/code> has a cost. The runtime pushes the deferred command onto a stack, and deferring it is a few nanoseconds slower than a direct call. That is usually not a problem day to day, but if you need to squeeze the most performance out of your code, it may be worth considering.&lt;/p></description></item><item><title>Golang plugins</title><link>https://crg.eti.br/pub/go-plugins/</link><pubDate>Sun, 05 Feb 2017 11:19:27 -0200</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/go-plugins/</guid><description>&lt;p>Plugins are one of the few nearly forgotten features in Go, and frankly, I advise against using them. Unlike other features of the language, plugins only work on Linux, BSD, and macOS. Because they are built on &lt;code>dlopen&lt;/code>, you cannot unload or replace a plugin once it has been loaded. On top of that, you need CGO, which brings complications of its own.&lt;/p>
&lt;p>Despite the problems, plugins are an interesting feature and can be useful in some cases, such as loading a module dynamically.&lt;/p></description></item><item><title>Handling signals with Go</title><link>https://crg.eti.br/pub/tratando-sinais-com-go/</link><pubDate>Mon, 18 Jul 2016 16:36:22 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/tratando-sinais-com-go/</guid><description>&lt;p>Handling signals is good practice. It lets you shut your program down gracefully, releasing resources and closing databases, instead of just terminating. Handling operating system signals with Golang is simple, because the system delivers the signal to a channel. All you have to do is listen to that channel.&lt;/p>
&lt;p>First, we create a channel:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-golang" data-lang="golang">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">sc&lt;/span> &lt;span style="color:#0550ae">:=&lt;/span> &lt;span style="color:#6639ba">make&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#cf222e">chan&lt;/span> &lt;span style="color:#1f2328">os&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#1f2328">Signal&lt;/span>&lt;span style="color:#1f2328">,&lt;/span> &lt;span style="color:#0550ae">1&lt;/span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Next, we say which signal we care about. In this case ^C, that is, &lt;a href="https://en.wikipedia.org/wiki/Unix_signal#SIGINT">SIGINT&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-golang" data-lang="golang">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#1f2328">signal&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#6639ba">Notify&lt;/span>&lt;span style="color:#1f2328">(&lt;/span>&lt;span style="color:#1f2328">sc&lt;/span>&lt;span style="color:#1f2328">,&lt;/span> &lt;span style="color:#1f2328">os&lt;/span>&lt;span style="color:#1f2328">.&lt;/span>&lt;span style="color:#1f2328">Interrupt&lt;/span>&lt;span style="color:#1f2328">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can register more than one signal. Just add more arguments, for example: &lt;code>signal.Notify(sc, os.Interrupt, syscall.SIGTERM)&lt;/code>.&lt;/p></description></item><item><title>Secure Random Strings in Golang Using crypto/rand</title><link>https://crg.eti.br/pub/go-strings-aleatorias/</link><pubDate>Wed, 13 Apr 2016 11:30:39 -0300</pubDate><author>crg@crg.eti.br (Cesar Gimenes)</author><guid>https://crg.eti.br/pub/go-strings-aleatorias/</guid><description>&lt;p>Generating random strings is extremely useful. You need it in all sorts of places: creating keys for records in distributed databases without risking collisions, creating session IDs, generating passwords, and much more.&lt;/p>
&lt;p>Simple as the task looks, there are a few interesting tricks to it. Computers aren&amp;rsquo;t actually good at creating truly random things. They create predictable things, which is not what you want when the goal is cryptography and security.&lt;/p></description></item></channel></rss>