<?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/en/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/en/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/capturando-senhas-no-terminal-go/">terminal password input&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://crg.eti.br/en/post/criptografia-at-rest-com-a-stdlib-go/">encryption at rest&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://crg.eti.br/en/post/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/en/post/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/en/post/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="color:#e6edf3;background-color:#0d1117;-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>db, err &lt;span style="color:#ff7b72;font-weight:bold">:=&lt;/span> sql.&lt;span style="color:#d2a8ff;font-weight:bold">Open&lt;/span>(&lt;span style="color:#a5d6ff">&amp;#34;sqlite&amp;#34;&lt;/span>, &lt;span style="color:#a5d6ff">&amp;#34;:memory:&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff7b72">if&lt;/span> err &lt;span style="color:#ff7b72;font-weight:bold">!=&lt;/span> &lt;span style="color:#79c0ff">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#d2a8ff;font-weight:bold">fatal&lt;/span>(err)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>db.&lt;span style="color:#d2a8ff;font-weight:bold">SetMaxOpenConns&lt;/span>(&lt;span style="color:#a5d6ff">1&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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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="color:#e6edf3;background-color:#0d1117;-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 command
&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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/checksum-com-golang/</guid><description>&lt;p>In the article &lt;a href="https://crg.eti.br/en/post/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/en/post/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/en/post/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/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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/en/post/manipulando-setuid-e-setgid/</guid><description>&lt;p>In the article on &lt;a href="https://crg.eti.br/en/post/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/en/post/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/en/post/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/en/post/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/en/post/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="color:#e6edf3;background-color:#0d1117;-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:#ff7b72">package&lt;/span> main
&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:#ff7b72">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a5d6ff">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a5d6ff">&amp;#34;time&amp;#34;&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>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic">// pi representa a constante matemática Pi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff7b72">const&lt;/span> pi = &lt;span style="color:#a5d6ff">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:#8b949e;font-style:italic">// 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:#8b949e;font-style:italic">// 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:#ff7b72">func&lt;/span> &lt;span style="color:#d2a8ff;font-weight:bold">CalcularArea&lt;/span>(raio &lt;span style="color:#ff7b72">float64&lt;/span>) &lt;span style="color:#ff7b72">float64&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff7b72">return&lt;/span> pi &lt;span style="color:#ff7b72;font-weight:bold">*&lt;/span> raio &lt;span style="color:#ff7b72;font-weight:bold">*&lt;/span> raio
&lt;/span>&lt;/span>&lt;span style="display:flex;">&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:#ff7b72">func&lt;/span> &lt;span style="color:#d2a8ff;font-weight:bold">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> raio &lt;span style="color:#ff7b72;font-weight:bold">:=&lt;/span> &lt;span style="color:#a5d6ff">5.0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> area &lt;span style="color:#ff7b72;font-weight:bold">:=&lt;/span> &lt;span style="color:#d2a8ff;font-weight:bold">CalcularArea&lt;/span>(raio)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#d2a8ff;font-weight:bold">Printf&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a5d6ff">&amp;#34;A área do círculo com raio %.2f é %.2f\n&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> raio,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> area,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&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:#8b949e;font-style:italic">/*
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic"> Formatos úteis:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic"> [time.DateTime]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic"> [time.Kitchen]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic"> [time.RFC3339Nano]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic"> [time.RFC3339]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8b949e;font-style:italic"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> fmt.&lt;span style="color:#d2a8ff;font-weight:bold">Println&lt;/span>(time.&lt;span style="color:#d2a8ff;font-weight:bold">Now&lt;/span>().&lt;span style="color:#d2a8ff;font-weight:bold">Format&lt;/span>(time.DateTime))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&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/en/post/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/en/post/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/pt-br/post/efeito-plasma-no-terminal-com-golang/plasma.webp">
&lt;picture>
&lt;source media="(max-width: 480px)" srcset="https://crg.eti.br/pt-br/post/efeito-plasma-no-terminal-com-golang/plasma_hu_3e89f9757017ba57.webp">
&lt;source media="(max-width: 1080px)" srcset="https://crg.eti.br/pt-br/post/efeito-plasma-no-terminal-com-golang/plasma_hu_3490c725fbb4fdb0.webp">
&lt;img alt="plasma in the terminal with Go" src="https://crg.eti.br/pt-br/post/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/en/post/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/en/post/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/pt-br/post/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/pt-br/post/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/pt-br/post/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/pt-br/post/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></channel></rss>